Skip to content

Commit 8fea888

Browse files
UnixSocket::accept(): initial implementation
* VM: more deadlock fixes * mlibc::sys_getsockopt and mlibc::sys_setsockopt stubs * syscall::accept: fix signature Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 1ccb02b commit 8fea888

File tree

5 files changed

+202
-40
lines changed

5 files changed

+202
-40
lines changed

patches/mlibc/mlibc.patch

Lines changed: 116 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
From 32d24edf161f338847c32fa2f44dc80422d4795e Mon Sep 17 00:00:00 2001
1+
From bb17d740b50e98b67c4bdc6449e874568993aa84 Mon Sep 17 00:00:00 2001
22
From: Andy-Python-Programmer <[email protected]>
33
Date: Fri, 8 Jul 2022 12:32:32 +1000
44
Subject: [PATCH] yes
@@ -8,11 +8,11 @@ Signed-off-by: Andy-Python-Programmer <[email protected]>
88
options/ansi/generic/stdlib-stubs.cpp | 142 +++++++++++++++++++++-----
99
options/glibc/generic/execinfo.cpp | 5 +-
1010
options/rtdl/generic/linker.cpp | 2 +-
11-
sysdeps/aero/generic/aero.cpp | 14 +--
11+
sysdeps/aero/generic/aero.cpp | 38 +++----
1212
sysdeps/aero/generic/filesystem.cpp | 25 ++++-
13-
sysdeps/aero/generic/sockets.cpp | 4 +-
13+
sysdeps/aero/generic/sockets.cpp | 65 +++++++++++-
1414
sysdeps/aero/include/aero/syscall.h | 2 +
15-
7 files changed, 152 insertions(+), 42 deletions(-)
15+
7 files changed, 225 insertions(+), 54 deletions(-)
1616

1717
diff --git a/options/ansi/generic/stdlib-stubs.cpp b/options/ansi/generic/stdlib-stubs.cpp
1818
index 4836391e..2a73c6d0 100644
@@ -198,9 +198,44 @@ index 6716ef4f..e5ec8cff 100644
198198
constexpr bool eagerBinding = true;
199199

200200
diff --git a/sysdeps/aero/generic/aero.cpp b/sysdeps/aero/generic/aero.cpp
201-
index 29fb9610..645a84d5 100644
201+
index 29fb9610..a27da559 100644
202202
--- a/sysdeps/aero/generic/aero.cpp
203203
+++ b/sysdeps/aero/generic/aero.cpp
204+
@@ -69,22 +69,22 @@ int sys_futex_tid() {
205+
}
206+
207+
int sys_futex_wait(int *pointer, int expected, const struct timespec *time) {
208+
- auto result = syscall(SYS_FUTEX_WAIT, pointer, expected, time);
209+
-
210+
- if (result < 0) {
211+
- return -result;
212+
- }
213+
-
214+
+ // auto result = syscall(SYS_FUTEX_WAIT, pointer, expected, time);
215+
+ //
216+
+ // if (result < 0) {
217+
+ // return -result;
218+
+ // }
219+
+ //
220+
return 0;
221+
}
222+
223+
int sys_futex_wake(int *pointer) {
224+
- auto result = syscall(SYS_FUTEX_WAKE, pointer);
225+
-
226+
- if (result < 0) {
227+
- return -result;
228+
- }
229+
-
230+
+ // auto result = syscall(SYS_FUTEX_WAKE, pointer);
231+
+ //
232+
+ // if (result < 0) {
233+
+ // return -result;
234+
+ // }
235+
+ //
236+
return 0;
237+
}
238+
204239
@@ -124,7 +124,9 @@ int sys_anon_free(void *pointer, size_t size) {
205240
}
206241

@@ -240,7 +275,7 @@ index 29fb9610..645a84d5 100644
240275
}
241276

242277
diff --git a/sysdeps/aero/generic/filesystem.cpp b/sysdeps/aero/generic/filesystem.cpp
243-
index a3e2aca2..09e6444f 100644
278+
index a3e2aca2..4187059e 100644
244279
--- a/sysdeps/aero/generic/filesystem.cpp
245280
+++ b/sysdeps/aero/generic/filesystem.cpp
246281
@@ -158,11 +158,6 @@ int sys_tcsetattr(int fd, int optional_action, const struct termios *attr) {
@@ -269,7 +304,7 @@ index a3e2aca2..09e6444f 100644
269304
+ }
270305
+
271306
+ *num_events = result;
272-
+ return 0;
307+
+ return 0;
273308
+}
274309
+
275310
+int sys_poll(struct pollfd *fds, nfds_t count, int timeout, int *num_events) {
@@ -281,10 +316,17 @@ index a3e2aca2..09e6444f 100644
281316
+}
282317
} // namespace mlibc
283318
diff --git a/sysdeps/aero/generic/sockets.cpp b/sysdeps/aero/generic/sockets.cpp
284-
index b6b18fe7..111dc570 100644
319+
index b6b18fe7..33609ca4 100644
285320
--- a/sysdeps/aero/generic/sockets.cpp
286321
+++ b/sysdeps/aero/generic/sockets.cpp
287-
@@ -46,8 +46,8 @@ int sys_listen(int fd, int backlog) {
322+
@@ -1,5 +1,6 @@
323+
#include <mlibc/all-sysdeps.hpp>
324+
#include <mlibc/thread-entry.hpp>
325+
+#include <mlibc/debug.hpp>
326+
327+
#include <aero/syscall.h>
328+
#include <stdint.h>
329+
@@ -46,8 +47,8 @@ int sys_listen(int fd, int backlog) {
288330
return 0;
289331
}
290332

@@ -295,6 +337,71 @@ index b6b18fe7..111dc570 100644
295337

296338
if (result < 0) {
297339
return -result;
340+
@@ -56,4 +57,64 @@ int sys_accept(int fd, int *newfd) {
341+
*newfd = result;
342+
return 0;
343+
}
344+
+
345+
+int sys_getsockopt(int fd, int layer, int number, void *__restrict buffer, socklen_t *__restrict size) {
346+
+ (void)fd; (void)size;
347+
+ if (layer == SOL_SOCKET && number == SO_PEERCRED) {
348+
+ mlibc::infoLogger() << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and SO_PEERCRED is unimplemented\e[39m" << frg::endlog;
349+
+ *(int *)buffer = 0;
350+
+ return 0;
351+
+ } else if(layer == SOL_SOCKET && number == SO_SNDBUF) {
352+
+ mlibc::infoLogger() << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and SO_SNDBUF is unimplemented\e[39m" << frg::endlog;
353+
+ *(int *)buffer = 4096;
354+
+ return 0;
355+
+ } else if(layer == SOL_SOCKET && number == SO_TYPE) {
356+
+ mlibc::infoLogger() << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and SO_TYPE is unimplemented, hardcoding SOCK_STREAM\e[39m" << frg::endlog;
357+
+ *(int *)buffer = SOCK_STREAM;
358+
+ return 0;
359+
+ } else if(layer == SOL_SOCKET && number == SO_ERROR) {
360+
+ mlibc::infoLogger() << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and SO_ERROR is unimplemented, hardcoding 0\e[39m" << frg::endlog;
361+
+ *(int *)buffer = 0;
362+
+ return 0;
363+
+ } else if(layer == SOL_SOCKET && number == SO_KEEPALIVE) {
364+
+ mlibc::infoLogger() << "\e[31mmlibc: getsockopt() call with SOL_SOCKET and SO_KEEPALIVE is unimplemented, hardcoding 0\e[39m" << frg::endlog;
365+
+ *(int *)buffer = 0;
366+
+ return 0;
367+
+ } else{
368+
+ mlibc::panicLogger() << "\e[31mmlibc: Unexpected getsockopt() call, layer: " << layer << " number: " << number << "\e[39m" << frg::endlog;
369+
+ __builtin_unreachable();
370+
+ }
371+
+
372+
+ return 0;
373+
+}
374+
+
375+
+int sys_setsockopt(int fd, int layer, int number, const void *buffer, socklen_t size) {
376+
+ (void)fd; (void)buffer; (void)size;
377+
+
378+
+ if (layer == SOL_SOCKET && number == SO_PASSCRED) {
379+
+ mlibc::infoLogger() << "\e[31mmlibc: setsockopt(SO_PASSCRED) is not implemented correctly\e[39m" << frg::endlog;
380+
+ return 0;
381+
+ } else if (layer == SOL_SOCKET && number == SO_ATTACH_FILTER) {
382+
+ mlibc::infoLogger() << "\e[31mmlibc: setsockopt(SO_ATTACH_FILTER) is not implemented correctly\e[39m" << frg::endlog;
383+
+ return 0;
384+
+ } else if (layer == SOL_SOCKET && number == SO_RCVBUFFORCE) {
385+
+ mlibc::infoLogger() << "\e[31mmlibc: setsockopt(SO_RCVBUFFORCE) is not implemented correctly\e[39m" << frg::endlog;
386+
+ return 0;
387+
+ } else if (layer == SOL_SOCKET && number == SO_SNDBUF) {
388+
+ mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_SOCKET and SO_SNDBUF is unimplemented\e[39m" << frg::endlog;
389+
+ return 0;
390+
+ } else if (layer == SOL_SOCKET && number == SO_KEEPALIVE) {
391+
+ mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_SOCKET and SO_KEEPALIVE is unimplemented\e[39m" << frg::endlog;
392+
+ return 0;
393+
+ } else if (layer == SOL_SOCKET && number == SO_REUSEADDR) {
394+
+ mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_SOCKET and SO_REUSEADDR is unimplemented\e[39m" << frg::endlog;
395+
+ return 0;
396+
+ } else if (layer == AF_NETLINK && number == SO_ACCEPTCONN) {
397+
+ mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with AF_NETLINK and SO_ACCEPTCONN is unimplemented\e[39m" << frg::endlog;
398+
+ return 0;
399+
+ } else {
400+
+ mlibc::panicLogger() << "\e[31mmlibc: Unexpected setsockopt() call, layer: " << layer << " number: " << number << "\e[39m" << frg::endlog;
401+
+ __builtin_unreachable();
402+
+ }
403+
+}
404+
} // namespace mlibc
298405
diff --git a/sysdeps/aero/include/aero/syscall.h b/sysdeps/aero/include/aero/syscall.h
299406
index 12f8dc61..fcc219a9 100644
300407
--- a/sysdeps/aero/include/aero/syscall.h

src/aero_kernel/src/fs/inode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use intrusive_collections::UnsafeRef;
3030
use spin::Once;
3131

3232
use crate::mem::paging::PhysFrame;
33+
use crate::socket::unix::UnixSocket;
3334
use crate::socket::SocketAddr;
3435
use crate::userland::scheduler;
3536
use crate::utils::sync::BlockQueue;
@@ -226,7 +227,7 @@ pub trait INodeInterface: Send + Sync {
226227
Err(FileSystemError::NotSocket)
227228
}
228229

229-
fn accept(&self, _address: SocketAddr) -> Result<()> {
230+
fn accept(&self, _address: &mut SocketAddr) -> Result<Arc<UnixSocket>> {
230231
Err(FileSystemError::NotSocket)
231232
}
232233

src/aero_kernel/src/socket/unix.rs

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ use aero_syscall::SocketAddrUnix;
2121

2222
use alloc::sync::{Arc, Weak};
2323
use alloc::vec::Vec;
24-
use spin::RwLock;
2524

2625
use crate::fs;
2726
use crate::fs::inode::{DirEntry, FileType, INodeInterface, Metadata, PollFlags, PollTable};
2827
use crate::fs::{FileSystemError, Path, Result};
29-
use crate::utils::sync::BlockQueue;
28+
use crate::utils::sync::{BlockQueue, Mutex};
3029

3130
use super::SocketAddr;
3231

@@ -66,6 +65,10 @@ impl UnixSocketBacklog {
6665
self.backlog.as_ref().map(|e| e.len()).unwrap_or_default()
6766
}
6867

68+
pub fn pop(&mut self) -> Option<Arc<UnixSocket>> {
69+
self.backlog.as_mut().map(|e| e.pop()).unwrap_or_default()
70+
}
71+
6972
pub fn update_capacity(&mut self, capacity: usize) {
7073
assert!(
7174
self.backlog.is_none(),
@@ -80,29 +83,43 @@ impl UnixSocketBacklog {
8083
struct UnixSocketInner {
8184
backlog: UnixSocketBacklog,
8285
listening: bool,
86+
peer: Option<Arc<UnixSocket>>,
87+
connected: bool,
8388
}
8489

8590
pub struct UnixSocket {
86-
inner: RwLock<UnixSocketInner>,
91+
inner: Mutex<UnixSocketInner>,
8792
wq: BlockQueue,
8893
weak: Weak<UnixSocket>,
8994
}
9095

9196
impl UnixSocket {
92-
pub fn new() -> Arc<UnixSocket> {
93-
Arc::new_cyclic(|weak| UnixSocket {
94-
inner: RwLock::new(UnixSocketInner::default()),
97+
pub fn new(peer: Option<Arc<UnixSocket>>) -> Arc<Self> {
98+
Arc::new_cyclic(|weak| Self {
99+
inner: Mutex::new(UnixSocketInner {
100+
peer,
101+
..Default::default()
102+
}),
103+
95104
wq: BlockQueue::new(),
96105
weak: weak.clone(),
97106
})
98107
}
99108

100-
pub fn sref(&self) -> Arc<UnixSocket> {
109+
pub fn sref(&self) -> Arc<Self> {
101110
self.weak.upgrade().unwrap()
102111
}
103112
}
104113

105114
impl INodeInterface for UnixSocket {
115+
fn read_at(&self, _offset: usize, _buffer: &mut [u8]) -> Result<usize> {
116+
unimplemented!()
117+
}
118+
119+
fn write_at(&self, _offset: usize, _buffer: &[u8]) -> Result<usize> {
120+
unimplemented!()
121+
}
122+
106123
fn metadata(&self) -> Result<Metadata> {
107124
Ok(Metadata {
108125
id: 0,
@@ -140,7 +157,7 @@ impl INodeInterface for UnixSocket {
140157
.downcast_arc::<UnixSocket>()
141158
.ok_or(FileSystemError::NotSocket)?; // NOTE: the provided socket was not a unix socket.
142159

143-
let mut itarget = target.inner.write();
160+
let mut itarget = target.inner.lock_irq();
144161

145162
// ensure that the target socket is listening for new connections.
146163
if !itarget.listening {
@@ -149,30 +166,62 @@ impl INodeInterface for UnixSocket {
149166

150167
itarget.backlog.push(self.sref());
151168
target.wq.notify_complete();
169+
core::mem::drop(itarget); // release the lock
152170

171+
let _ = self.wq.block_on(&self.inner, |e| e.connected);
153172
Ok(())
154173
}
155174

156175
fn listen(&self, backlog: usize) -> Result<()> {
157-
let mut this = self.inner.write();
176+
let mut this = self.inner.lock_irq();
158177

159178
this.backlog.update_capacity(backlog);
160179
this.listening = true;
161180

162181
Ok(())
163182
}
164183

165-
fn accept(&self, _address: SocketAddr) -> Result<()> {
166-
unimplemented!()
184+
fn accept(&self, _address: &mut SocketAddr) -> Result<Arc<UnixSocket>> {
185+
if !self.inner.lock_irq().listening {
186+
return Err(FileSystemError::ConnectionRefused);
187+
}
188+
189+
let mut this = self.wq.block_on(&self.inner, |e| e.backlog.len() != 0)?;
190+
191+
let peer = this
192+
.backlog
193+
.pop()
194+
.expect("UnixSocket::accept(): backlog is empty");
195+
196+
let sock = Self::new(Some(peer.clone()));
197+
198+
{
199+
let mut sock_inner = sock.inner.lock_irq();
200+
sock_inner.connected = true;
201+
}
202+
203+
{
204+
let mut peer_data = peer.inner.lock_irq();
205+
peer_data.peer = Some(sock.clone());
206+
peer_data.connected = true;
207+
}
208+
209+
peer.wq.notify_complete();
210+
Ok(sock)
167211
}
168212

169213
fn poll(&self, table: Option<&mut PollTable>) -> Result<PollFlags> {
170214
table.map(|e| e.insert(&self.wq));
171215

172216
let mut events = PollFlags::empty();
217+
let sock_data = self.inner.lock_irq();
218+
219+
if sock_data.backlog.len() > 0 {
220+
events.insert(PollFlags::IN | PollFlags::OUT);
221+
}
173222

174-
if self.inner.read().backlog.len() > 0 {
175-
events.insert(PollFlags::OUT);
223+
if sock_data.connected {
224+
events.insert(PollFlags::IN | PollFlags::OUT);
176225
}
177226

178227
Ok(events)

src/aero_kernel/src/syscall/net.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,21 @@ pub fn connect(fd: usize, address: usize, length: usize) -> Result<usize, Syscal
3535

3636
/// Accept a connection on a socket.
3737
#[syscall]
38-
pub fn accept(fd: usize, address: usize, _length: &mut u32) -> Result<usize, SyscallError> {
39-
let address = socket_addr_from_addr(VirtAddr::new(address as u64))?;
40-
let file = scheduler::get_scheduler()
41-
.current_task()
42-
.file_table
43-
.get_handle(fd)
44-
.ok_or(SyscallError::EINVAL)?;
45-
46-
file.inode().accept(address)?;
47-
Ok(0)
38+
pub fn accept(
39+
fd: usize,
40+
address: &mut SocketAddr,
41+
_length: &mut u32,
42+
) -> Result<usize, SyscallError> {
43+
let file_table = scheduler::get_scheduler().current_task().file_table.clone();
44+
let socket = file_table.get_handle(fd).ok_or(SyscallError::EINVAL)?;
45+
46+
let connection_sock = socket.inode().accept(address)?;
47+
let handle = file_table.open_file(
48+
DirEntry::from_inode(connection_sock, String::from("<socket>")),
49+
OpenFlags::O_RDWR,
50+
)?;
51+
52+
Ok(handle)
4853
}
4954

5055
/// Marks the socket as a passive socket (i.e. as a socket that will be used to accept incoming
@@ -64,7 +69,7 @@ pub fn listen(fd: usize, backlog: usize) -> Result<usize, SyscallError> {
6469
#[syscall]
6570
pub fn socket(domain: usize, socket_type: usize, protocol: usize) -> Result<usize, SyscallError> {
6671
let socket = match domain as u32 {
67-
AF_UNIX => UnixSocket::new(),
72+
AF_UNIX => UnixSocket::new(None),
6873
_ => {
6974
log::warn!(
7075
"unsupported socket type: domain={domain}, socket_type={socket_type}, protocol={protocol}"

0 commit comments

Comments
 (0)