From 37ed9632723d5a8a6dd9f5b3c18868964acacce1 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 30 Mar 2020 10:59:25 +0300 Subject: [PATCH] Clean implementation of socket classes --- etc/make/conf.mk | 1 + include/fs/ofile.h | 7 +- include/net/class.h | 29 +++++++++ include/net/inet.h | 4 -- include/net/net.h | 20 ------ include/net/raw.h | 10 --- include/net/socket.h | 30 +++++++++ include/net/udp.h | 9 --- include/user/inet.h | 6 ++ net/icmp.c | 1 + net/net.c | 141 ---------------------------------------- net/raw.c | 95 +++++++++++++++++++-------- net/socket.c | 117 +++++++++++++++++++++++++++++++++ net/tcp.c | 1 + net/udp.c | 150 ++++++++++++++++++++++++++++--------------- sys/sys_file.c | 2 +- sys/sys_net.c | 3 +- sys/thread.c | 2 +- 18 files changed, 361 insertions(+), 267 deletions(-) create mode 100644 include/net/class.h create mode 100644 include/net/socket.h create mode 100644 net/socket.c diff --git a/etc/make/conf.mk b/etc/make/conf.mk index 448d464..4464f92 100644 --- a/etc/make/conf.mk +++ b/etc/make/conf.mk @@ -105,6 +105,7 @@ OBJS+=$(O)/sys/sys_net.o \ $(O)/net/raw.o \ $(O)/net/tcp.o \ $(O)/net/if.o \ + $(O)/net/socket.o \ $(O)/net/util.o DIRS+=$(O)/net diff --git a/include/fs/ofile.h b/include/fs/ofile.h index ea32fb8..6e6af31 100644 --- a/include/fs/ofile.h +++ b/include/fs/ofile.h @@ -1,5 +1,6 @@ #pragma once #include "node.h" +#include "net/socket.h" #include #define OF_WRITABLE (1 << 0) @@ -19,10 +20,6 @@ struct ofile { size_t pos; void *priv_data; } file; - struct { - int domain; - int type; - void *sock; - } socket; + struct socket socket; }; }; diff --git a/include/net/class.h b/include/net/class.h new file mode 100644 index 0000000..f251e8b --- /dev/null +++ b/include/net/class.h @@ -0,0 +1,29 @@ +#pragma once +#include "sys/types.h" +#include "sys/list.h" + +struct sockaddr; +struct socket; + +struct sockops { + ssize_t (*recvfrom) (struct socket *, void *, size_t, struct sockaddr *, size_t *); + ssize_t (*sendto) (struct socket *, const void *, size_t, struct sockaddr *, size_t); + + int (*open) (struct socket *); + void (*close) (struct socket *); + + int (*bind) (struct socket *, struct sockaddr *, size_t); + int (*setsockopt) (struct socket *, int, void *, size_t); +}; + +struct socket_class { + const char *name; + int domain, type; + int (*supports) (int proto); + + struct sockops *ops; + + struct list_head link; +}; + +void socket_class_register(struct socket_class *cls); diff --git a/include/net/inet.h b/include/net/inet.h index a0299b6..6b0556b 100644 --- a/include/net/inet.h +++ b/include/net/inet.h @@ -1,10 +1,6 @@ #pragma once #include "sys/types.h" -#define INET_P_ICMP 1 -#define INET_P_TCP 6 -#define INET_P_UDP 17 - struct inet_frame { uint8_t ihl:4; uint8_t version:4; diff --git a/include/net/net.h b/include/net/net.h index 45dc8d7..a7f56ca 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -1,27 +1,7 @@ #pragma once #include "sys/types.h" -struct sockaddr; -struct vfs_ioctx; -struct ofile; struct netdev; int net_receive(struct netdev *dev, const void *data, size_t len); -int net_socket_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto); -ssize_t net_sendto(struct vfs_ioctx *ioctx, - struct ofile *fd, - const void *buf, - size_t len, - struct sockaddr *sa, - size_t salen); -ssize_t net_recvfrom(struct vfs_ioctx *ioctx, - struct ofile *fd, - void *buf, - size_t len, - struct sockaddr *sa, - size_t *salen); -int net_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr *sa, size_t len); -int net_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void *optval, size_t optlen); -void net_close(struct vfs_ioctx *ioctx, struct ofile *fd); - void net_daemon_start(void); diff --git a/include/net/raw.h b/include/net/raw.h index b1a5fd6..d1230a0 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -1,16 +1,6 @@ #pragma once #include "sys/types.h" -struct vfs_ioctx; -struct ofile; -struct sockaddr; struct packet; -int raw_socket_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto); -ssize_t raw_socket_send(struct vfs_ioctx *ioctx, struct ofile *fd, const void *buf, size_t lim, struct sockaddr *sa, size_t salen); -ssize_t raw_socket_recv(struct vfs_ioctx *ioctx, struct ofile *fd, void *buf, size_t lim, struct sockaddr *sa, size_t *salen); -int raw_socket_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr *sa, size_t len); -int raw_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void *optval, size_t optlen); -void raw_socket_close(struct vfs_ioctx *ioctx, struct ofile *fd); - void raw_packet_handle(struct packet *p); diff --git a/include/net/socket.h b/include/net/socket.h new file mode 100644 index 0000000..98e5d2b --- /dev/null +++ b/include/net/socket.h @@ -0,0 +1,30 @@ +#pragma once +#include "sys/types.h" + +struct sockaddr; +struct vfs_ioctx; +struct ofile; +struct netdev; + +struct socket { + struct sockops *op; + struct vfs_ioctx *ioctx; + void *data; +}; + +int net_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto); +ssize_t net_sendto(struct vfs_ioctx *ioctx, + struct ofile *fd, + const void *buf, + size_t len, + struct sockaddr *sa, + size_t salen); +ssize_t net_recvfrom(struct vfs_ioctx *ioctx, + struct ofile *fd, + void *buf, + size_t len, + struct sockaddr *sa, + size_t *salen); +int net_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr *sa, size_t len); +int net_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void *optval, size_t optlen); +void net_close(struct vfs_ioctx *ioctx, struct ofile *fd); diff --git a/include/net/udp.h b/include/net/udp.h index 4c06bef..2d19bad 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -11,14 +11,5 @@ struct udp_frame { struct eth_frame; struct inet_frame; struct packet; -struct vfs_ioctx; -struct ofile; -struct sockaddr; void udp_handle_frame(struct packet *p, struct eth_frame *eth, struct inet_frame *ip, void *data, size_t len); -int udp_socket_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto); -ssize_t udp_socket_send(struct vfs_ioctx *ioctx, struct ofile *fd, const void *buf, size_t lim, struct sockaddr *sa, size_t salen); -ssize_t udp_socket_recv(struct vfs_ioctx *ioctx, struct ofile *fd, void *buf, size_t lim, struct sockaddr *sa, size_t *salen); -int udp_socket_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr *sa, size_t len); -int udp_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void *optval, size_t optlen); -void udp_socket_close(struct vfs_ioctx *ioctx, struct ofile *fd); diff --git a/include/user/inet.h b/include/user/inet.h index e056368..e01bc1d 100644 --- a/include/user/inet.h +++ b/include/user/inet.h @@ -4,6 +4,12 @@ #define INADDR_ANY 0 #define INADDR_BROADCAST 0xFFFFFFFF +#define INET_P_ICMP 1 +#define INET_P_TCP 6 +#define INET_P_UDP 17 + +#define IPPROTO_ICMP (INET_P_ICMP) +#define IPPROTO_UDP (INET_P_UDP) struct sockaddr_in { uint16_t sin_family; diff --git a/net/icmp.c b/net/icmp.c index 77eb7d2..00cfd4e 100644 --- a/net/icmp.c +++ b/net/icmp.c @@ -1,5 +1,6 @@ #include "net/packet.h" #include "sys/string.h" +#include "user/inet.h" #include "sys/debug.h" #include "net/util.h" #include "net/inet.h" diff --git a/net/net.c b/net/net.c index deaf513..b8b3127 100644 --- a/net/net.c +++ b/net/net.c @@ -150,144 +150,3 @@ void net_daemon_start(void) { netd_thread.pid = thread_alloc_pid(0); sched_queue(&netd_thread); } - -int net_socket_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto) { - _assert(fd); - fd->flags = OF_SOCKET; - - switch (dom) { - case AF_INET: - switch (type) { - case SOCK_DGRAM: - return udp_socket_open(ioctx, fd, dom, type, proto); - default: - break; - } - break; - case AF_PACKET: - switch (type) { - case SOCK_RAW: - return raw_socket_open(ioctx, fd, dom, type, proto); - default: - break; - } - break; - default: - break; - } - return -EINVAL; -} - -void net_close(struct vfs_ioctx *ioctx, struct ofile *fd) { - _assert(fd); - _assert(fd->flags & OF_SOCKET); - - switch (fd->socket.domain) { - case AF_INET: - switch (fd->socket.type) { - case SOCK_DGRAM: - udp_socket_close(ioctx, fd); - break; - default: - break; - } - break; - case AF_PACKET: - switch (fd->socket.type) { - case SOCK_RAW: - raw_socket_close(ioctx, fd); - break; - default: - break; - } - break; - } -} - -ssize_t net_sendto(struct vfs_ioctx *ioctx, - struct ofile *fd, - const void *buf, - size_t len, - struct sockaddr *sa, - size_t salen) { - _assert(fd); - _assert(fd->flags & OF_SOCKET); - - if (fd->socket.domain != AF_INET) { - kwarn("Unknown socket family: %d\n", fd->socket.domain); - return -EINVAL; - } - - switch (fd->socket.type) { - case SOCK_DGRAM: - return udp_socket_send(ioctx, fd, buf, len, sa, salen); - default: - return -EINVAL; - } -} - -ssize_t net_recvfrom(struct vfs_ioctx *ioctx, - struct ofile *fd, - void *buf, - size_t len, - struct sockaddr *sa, - size_t *salen) { - _assert(fd); - _assert(fd->flags & OF_SOCKET); - - switch (fd->socket.domain) { - case AF_INET: - switch (fd->socket.type) { - case SOCK_DGRAM: - return udp_socket_recv(ioctx, fd, buf, len, sa, salen); - default: - return -EINVAL; - } - break; - case AF_PACKET: - switch (fd->socket.type) { - case SOCK_RAW: - return raw_socket_recv(ioctx, fd, buf, len, sa, salen); - default: - break; - } - break; - default: - kwarn("Unknown socket family: %d\n", fd->socket.domain); - break; - } - - return -EINVAL; -} - -int net_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr *sa, size_t len) { - _assert(fd); - - if (fd->socket.domain != AF_INET) { - kwarn("Unknown socket family: %d\n", fd->socket.domain); - return -EINVAL; - } - - switch (fd->socket.type) { - case SOCK_DGRAM: - return udp_socket_bind(ioctx, fd, sa, len); - default: - return -EINVAL; - } -} - -int net_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void *optval, size_t optlen) { - _assert(fd); - - if (fd->socket.domain != AF_INET) { - kwarn("Unknown socket family: %d\n", fd->socket.domain); - return -EINVAL; - } - - switch (fd->socket.type) { - case SOCK_DGRAM: - return udp_setsockopt(ioctx, fd, optname, optval, optlen); - default: - return -EINVAL; - } -} diff --git a/net/raw.c b/net/raw.c index 780e8c9..3215bc9 100644 --- a/net/raw.c +++ b/net/raw.c @@ -4,12 +4,46 @@ #include "net/packet.h" #include "sys/thread.h" #include "sys/string.h" +#include "net/socket.h" +#include "net/class.h" #include "sys/sched.h" #include "sys/debug.h" #include "fs/ofile.h" #include "sys/heap.h" +#include "sys/attr.h" #include "net/raw.h" +static int raw_class_supports(int proto) { + return proto == 0; +} + +static int raw_socket_open(struct socket *s); +static ssize_t raw_socket_recvfrom(struct socket *s, + void *buf, + size_t lim, + struct sockaddr *sa, + size_t *salen); +static void raw_socket_close(struct socket *s); +static struct sockops raw_socket_ops = { + .open = raw_socket_open, + .close = raw_socket_close, + + .sendto = NULL, + .recvfrom = raw_socket_recvfrom, + + .bind = NULL, + .setsockopt = NULL, +}; +static struct socket_class raw_socket_class = { + .name = "raw-packet", + .ops = &raw_socket_ops, + .domain = AF_PACKET, + .type = SOCK_DGRAM, + .supports = raw_class_supports, +}; + +//// + struct raw_socket { struct thread *wait; struct packet_queue queue; @@ -19,7 +53,31 @@ struct raw_socket { static spin_t g_raw_lock = 0; static struct raw_socket *g_raw_sockets = NULL; -int raw_socket_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto) { +void raw_packet_handle(struct packet *p) { + // Queue the packet for all the sockets + uintptr_t irq; + // TODO: too much time spent in spinlocked region? + spin_lock_irqsave(&g_raw_lock, &irq); + for (struct raw_socket *r = g_raw_sockets; r; r = r->next) { + packet_ref(p); + packet_queue_push(&r->queue, p); + struct thread *w = r->wait; + if (w) { + r->wait = NULL; + sched_queue(w); + } + } + spin_release_irqrestore(&g_raw_lock, &irq); +} + +static __init void raw_class_register(void) { + socket_class_register(&raw_socket_class); +} + +////////// +// Socket implementation + +static int raw_socket_open(struct socket *s) { // TODO: check your privilege struct raw_socket *r_sock = kmalloc(sizeof(struct raw_socket)); _assert(r_sock); @@ -30,16 +88,17 @@ int raw_socket_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type r_sock->wait = NULL; g_raw_sockets = r_sock; - fd->flags |= OF_SOCKET; - fd->socket.sock = r_sock; - fd->socket.domain = PF_PACKET; - fd->socket.type = SOCK_RAW; + s->data = r_sock; return 0; } -ssize_t raw_socket_recv(struct vfs_ioctx *ioctx, struct ofile *fd, void *buf, size_t lim, struct sockaddr *sa, size_t *salen) { - struct raw_socket *sock = fd->socket.sock; +static ssize_t raw_socket_recvfrom(struct socket *s, + void *buf, + size_t lim, + struct sockaddr *sa, + size_t *salen) { + struct raw_socket *sock = s->data; _assert(sock); struct thread *t = thread_self; _assert(t); @@ -69,9 +128,9 @@ ssize_t raw_socket_recv(struct vfs_ioctx *ioctx, struct ofile *fd, void *buf, si return p_size; } -void raw_socket_close(struct vfs_ioctx *ioctx, struct ofile *fd) { +static void raw_socket_close(struct socket *s) { uintptr_t irq; - struct raw_socket *r_sock = fd->socket.sock; + struct raw_socket *r_sock = s->data; _assert(r_sock); spin_lock_irqsave(&g_raw_lock, &irq); @@ -92,21 +151,7 @@ void raw_socket_close(struct vfs_ioctx *ioctx, struct ofile *fd) { struct packet *p = packet_queue_pop(&r_sock->queue); packet_unref(p); } -} -void raw_packet_handle(struct packet *p) { - // Queue the packet for all the sockets - uintptr_t irq; - // TODO: too much time spent in spinlocked region? - spin_lock_irqsave(&g_raw_lock, &irq); - for (struct raw_socket *r = g_raw_sockets; r; r = r->next) { - packet_ref(p); - packet_queue_push(&r->queue, p); - struct thread *w = r->wait; - if (w) { - r->wait = NULL; - sched_queue(w); - } - } - spin_release_irqrestore(&g_raw_lock, &irq); + kfree(r_sock); + s->data = NULL; } diff --git a/net/socket.c b/net/socket.c new file mode 100644 index 0000000..7545857 --- /dev/null +++ b/net/socket.c @@ -0,0 +1,117 @@ +#include "user/socket.h" +#include "user/errno.h" +#include "sys/assert.h" +#include "user/inet.h" +#include "sys/debug.h" +#include "net/class.h" +#include "fs/ofile.h" + +static LIST_HEAD(g_socket_class_head); + +void socket_class_register(struct socket_class *cls) { + list_head_init(&cls->link); + list_add(&cls->link, &g_socket_class_head); +} + +int net_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto) { + struct socket_class *cls, *iter; + + cls = NULL; + list_for_each_entry(iter, &g_socket_class_head, link) { + if (iter->domain == dom && iter->type == type) { + _assert(iter->supports); + + if (iter->supports(proto)) { + cls = iter; + break; + } + } + } + + if (!cls) { + // No support for (dom:type:proto) tuple + return -EINVAL; + } + + _assert(cls->ops && cls->ops->open); + + fd->flags = OF_SOCKET; + fd->socket.ioctx = ioctx; + fd->socket.op = cls->ops; + + return cls->ops->open(&fd->socket); +} + +void net_close(struct vfs_ioctx *ioctx, struct ofile *fd) { + _assert(fd); + _assert(fd->flags & OF_SOCKET); + _assert(fd->socket.ioctx == ioctx); + _assert(fd->socket.op); + + if (fd->socket.op->close) { + fd->socket.op->close(&fd->socket); + } + fd->flags &= ~OF_SOCKET; +} + +ssize_t net_sendto(struct vfs_ioctx *ioctx, + struct ofile *fd, + const void *buf, + size_t len, + struct sockaddr *sa, + size_t salen) { + _assert(fd); + _assert(fd->flags & OF_SOCKET); + _assert(fd->socket.ioctx == ioctx); + _assert(fd->socket.op); + + if (fd->socket.op->sendto) { + return fd->socket.op->sendto(&fd->socket, buf, len, sa, salen); + } else { + return -EINVAL; + } +} + +ssize_t net_recvfrom(struct vfs_ioctx *ioctx, + struct ofile *fd, + void *buf, + size_t len, + struct sockaddr *sa, + size_t *salen) { + _assert(fd); + _assert(fd->flags & OF_SOCKET); + _assert(fd->socket.ioctx == ioctx); + _assert(fd->socket.op); + + if (fd->socket.op->recvfrom) { + return fd->socket.op->recvfrom(&fd->socket, buf, len, sa, salen); + } else { + return -EINVAL; + } +} + +int net_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr *sa, size_t len) { + _assert(fd); + _assert(fd->flags & OF_SOCKET); + _assert(fd->socket.ioctx == ioctx); + _assert(fd->socket.op); + + if (fd->socket.op->bind) { + return fd->socket.op->bind(&fd->socket, sa, len); + } else { + return -EINVAL; + } +} + +int net_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void *optval, size_t optlen) { + _assert(fd); + _assert(fd->flags & OF_SOCKET); + _assert(fd->socket.ioctx == ioctx); + _assert(fd->socket.op); + + if (fd->socket.op->setsockopt) { + return fd->socket.op->setsockopt(&fd->socket, optname, optval, optlen); + } else { + return -EINVAL; + } +} diff --git a/net/tcp.c b/net/tcp.c index 1e3c5c6..d7768d8 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -1,6 +1,7 @@ #include "net/packet.h" #include "sys/string.h" #include "sys/debug.h" +#include "user/inet.h" #include "sys/panic.h" #include "net/inet.h" #include "net/util.h" diff --git a/net/udp.c b/net/udp.c index d35b08b..ec93085 100644 --- a/net/udp.c +++ b/net/udp.c @@ -5,17 +5,56 @@ #include "net/packet.h" #include "sys/assert.h" #include "sys/string.h" +#include "net/class.h" #include "sys/sched.h" #include "user/inet.h" #include "sys/debug.h" #include "net/util.h" #include "sys/heap.h" +#include "sys/attr.h" #include "fs/ofile.h" #include "net/inet.h" #include "net/udp.h" #include "net/eth.h" #include "net/if.h" +static int udp_class_supports(int proto) { + return proto == IPPROTO_UDP || proto == 0; +} + +static int udp_socket_open(struct socket *sock); +static void udp_socket_close(struct socket *sock); +static ssize_t udp_socket_recvfrom(struct socket *s, + void *buf, + size_t lim, + struct sockaddr *sa, + size_t *salen); +static ssize_t udp_socket_sendto(struct socket *s, + const void *buf, + size_t lim, + struct sockaddr *sa, + size_t salen); +static int udp_socket_bind(struct socket *s, struct sockaddr *sa, size_t len); +static int udp_socket_setsockopt(struct socket *s, int optname, void *optval, size_t optlen); + +static struct sockops udp_socket_ops = { + .open = udp_socket_open, + .close = udp_socket_close, + + .sendto = udp_socket_sendto, + .recvfrom = udp_socket_recvfrom, + + .bind = udp_socket_bind, + .setsockopt = udp_socket_setsockopt, +}; +static struct socket_class udp_socket_class = { + .name = "udp", + .ops = &udp_socket_ops, + .domain = AF_INET, + .type = SOCK_DGRAM, + .supports = udp_class_supports, +}; + // Accept any packet (for receiving socket) #define UDP_SOCKET_ANY (1 << 0) // Accept port match (when calling recvfrom) @@ -54,19 +93,57 @@ struct udp_socket *udp_socket_create(void) { return sock; } -int udp_socket_open(struct vfs_ioctx *ioctx, struct ofile *fd, int dom, int type, int proto) { - struct udp_socket *sock = udp_socket_create(); - _assert(sock); +void udp_handle_frame(struct packet *p, struct eth_frame *eth, struct inet_frame *ip, void *data, size_t len) { + struct udp_frame *udp; - fd->socket.domain = AF_INET; - fd->socket.type = SOCK_DGRAM; - fd->socket.sock = sock; + if (len < sizeof(struct udp_frame)) { + return; + } + + udp = data; + + uint16_t dpt = ntohs(udp->dst_port); + + if (dpt >= UDP_BIND_START && (dpt - UDP_BIND_START) < UDP_BIND_COUNT) { + // Check if it's a packet for one of "listening" sockets + struct udp_socket *sock = udp_ports[dpt - UDP_BIND_START]; + + if (sock) { + // Add "pending" packet for this socket + packet_ref(p); + packet_queue_push(&sock->pending, p); + + if (sock->flags & UDP_SOCKET_PENDING) { + sock->flags &= ~UDP_SOCKET_PENDING; + sched_queue(sock->owner); + } + } else { + kdebug("Packet is destined to unbound port: %u\n", dpt); + } + } +} + +static __init void udp_class_register(void) { + socket_class_register(&udp_socket_class); +} + +///////////// +// Socket impl. + +static int udp_socket_open(struct socket *sock) { + struct udp_socket *usock = udp_socket_create(); + _assert(usock); + sock->data = usock; return 0; } -ssize_t udp_socket_recv(struct vfs_ioctx *ioctx, struct ofile *fd, void *buf, size_t lim, struct sockaddr *sa, size_t *salen) { - struct udp_socket *sock = fd->socket.sock; +static ssize_t udp_socket_recvfrom(struct socket *s, + void *buf, + size_t lim, + struct sockaddr *sa, + size_t *salen) { + struct udp_socket *sock = s->data; _assert(sock); struct thread *t = thread_self; struct packet *p; @@ -102,8 +179,12 @@ ssize_t udp_socket_recv(struct vfs_ioctx *ioctx, struct ofile *fd, void *buf, si return p_size; } -ssize_t udp_socket_send(struct vfs_ioctx *ioctx, struct ofile *fd, const void *buf, size_t lim, struct sockaddr *sa, size_t salen) { - struct udp_socket *sock = fd->socket.sock; +static ssize_t udp_socket_sendto(struct socket *s, + const void *buf, + size_t lim, + struct sockaddr *sa, + size_t salen) { + struct udp_socket *sock = s->data; struct sockaddr_in *sin; int res; uint16_t port; @@ -148,8 +229,8 @@ ssize_t udp_socket_send(struct vfs_ioctx *ioctx, struct ofile *fd, const void *b return lim; } -int udp_socket_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr *sa, size_t len) { - struct udp_socket *sock = fd->socket.sock; +static int udp_socket_bind(struct socket *s, struct sockaddr *sa, size_t len) { + struct udp_socket *sock = s->data; struct sockaddr_in *sin; _assert(sa); _assert(sock); @@ -172,8 +253,8 @@ int udp_socket_bind(struct vfs_ioctx *ioctx, struct ofile *fd, struct sockaddr * return 0; } -int udp_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void *optval, size_t optlen) { - struct udp_socket *sock = fd->socket.sock; +static int udp_socket_setsockopt(struct socket *s, int optname, void *optval, size_t optlen) { + struct udp_socket *sock = s->data; _assert(sock); switch (optname) { @@ -188,47 +269,16 @@ int udp_setsockopt(struct vfs_ioctx *ioctx, struct ofile *fd, int optname, void } } -void udp_socket_close(struct vfs_ioctx *ioctx, struct ofile *fd) { - struct udp_socket *sock = fd->socket.sock; +static void udp_socket_close(struct socket *s) { + struct udp_socket *sock = s->data; _assert(sock); - sock->flags &= ~UDP_SOCKET_ANY; - if (sock->flags & UDP_SOCKET_ANY) { udp_ports[sock->recv_port - UDP_BIND_START] = NULL; } + sock->flags &= ~UDP_SOCKET_ANY; + kfree(sock); - fd->socket.sock = NULL; - fd->flags &= ~OF_SOCKET; -} - -void udp_handle_frame(struct packet *p, struct eth_frame *eth, struct inet_frame *ip, void *data, size_t len) { - struct udp_frame *udp; - - if (len < sizeof(struct udp_frame)) { - return; - } - - udp = data; - - uint16_t dpt = ntohs(udp->dst_port); - - if (dpt >= UDP_BIND_START && (dpt - UDP_BIND_START) < UDP_BIND_COUNT) { - // Check if it's a packet for one of "listening" sockets - struct udp_socket *sock = udp_ports[dpt - UDP_BIND_START]; - - if (sock) { - // Add "pending" packet for this socket - packet_ref(p); - packet_queue_push(&sock->pending, p); - - if (sock->flags & UDP_SOCKET_PENDING) { - sock->flags &= ~UDP_SOCKET_PENDING; - sched_queue(sock->owner); - } - } else { - kdebug("Packet is destined to unbound port: %u\n", dpt); - } - } + s->data = NULL; } diff --git a/sys/sys_file.c b/sys/sys_file.c index 9746b7d..e23588f 100644 --- a/sys/sys_file.c +++ b/sys/sys_file.c @@ -7,9 +7,9 @@ #include "sys/thread.h" #include "sys/assert.h" #include "sys/string.h" +#include "net/socket.h" #include "sys/debug.h" #include "sys/heap.h" -#include "net/net.h" ssize_t sys_read(int fd, void *data, size_t lim) { struct thread *thr = thread_self; diff --git a/sys/sys_net.c b/sys/sys_net.c index 96e23ba..9eea43c 100644 --- a/sys/sys_net.c +++ b/sys/sys_net.c @@ -2,6 +2,7 @@ #include "sys/sys_net.h" #include "sys/assert.h" #include "sys/thread.h" +#include "net/socket.h" #include "user/errno.h" #include "sys/debug.h" #include "sys/heap.h" @@ -40,7 +41,7 @@ int sys_socket(int domain, int type, int protocol) { struct ofile *ofile = kmalloc(sizeof(struct ofile)); _assert(ofile); - if ((res = net_socket_open(&thr->ioctx, ofile, domain, type, protocol)) != 0) { + if ((res = net_open(&thr->ioctx, ofile, domain, type, protocol)) != 0) { kfree(ofile); return res; } diff --git a/sys/thread.c b/sys/thread.c index 40aa25e..9d9e8db 100644 --- a/sys/thread.c +++ b/sys/thread.c @@ -5,6 +5,7 @@ #include "arch/amd64/mm/map.h" #include "arch/amd64/cpu.h" #include "sys/binfmt_elf.h" +#include "net/socket.h" #include "fs/ofile.h" #include "sys/sys_proc.h" #include "sys/vmalloc.h" @@ -18,7 +19,6 @@ #include "sys/sched.h" #include "sys/debug.h" #include "sys/heap.h" -#include "net/net.h" #include "sys/mm.h" struct sys_fork_frame {