diff --git a/src/include/kernel/socket.h b/src/include/kernel/socket.h index 62412d7..693fb7a 100644 --- a/src/include/kernel/socket.h +++ b/src/include/kernel/socket.h @@ -50,10 +50,11 @@ typedef struct SocketDescriptor { Process *process; struct sockaddr address; bool listener; - int type, protocol, backlog; + int type, protocol, backlogMax, backlogCount; int inboundCount, outboundCount; void **inbound, **outbound; - struct SocketDescriptor *peer; + struct SocketDescriptor **backlog; // for incoming connections via connect() + struct SocketDescriptor *peer; // for peer-to-peer connections } SocketDescriptor; void socketInit(); diff --git a/src/ipc/connection.c b/src/ipc/connection.c new file mode 100644 index 0000000..d15785f --- /dev/null +++ b/src/ipc/connection.c @@ -0,0 +1,50 @@ +/* + * lux - a lightweight unix-like operating system + * Omar Elghoul, 2024 + * + * Core Microkernel + */ + +/* Socket Connection Functions */ +/* connect(), listen(), and accept() are implemented here */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* connect(): creates a socket connection + * params: t - calling thread, NULL for kernel threads + * params: sd - socket descriptor + * params: addr - peer address + * params: len - length of peer address + * returns: zero on success, negative error code on fail + */ + +int connect(Thread *t, int sd, const struct sockaddr *addr, socklen_t len) { + Process *p; + if(t) p = getProcess(t->pid); + else p = getProcess(getPid()); + if(!p) return -ESRCH; + + if(!p->io[sd].valid || !p->io[sd].data || (p->io[sd].type != IO_SOCKET)) + return -ENOTSOCK; + + SocketDescriptor *self = (SocketDescriptor *) p->io[sd].data; + SocketDescriptor *peer = getLocalSocket(addr, len); + + if(!peer) return -EADDRNOTAVAIL; + if(!peer->listener || !peer->backlogMax || !peer->backlog) return -ECONNREFUSED; + if(peer->backlogCount >= peer->backlogMax) return -ETIMEDOUT; + + // at this point we're sure it's safe to create a connection + socketLock(); + peer->backlog[peer->backlogCount] = self; + peer->backlogCount++; + socketRelease(); + return 0; +}