#pragma once #include "types.h" // Unix domain sockets. // // These exist for Schcom. A compositor and its clients have to exchange // messages, and a pipe cannot do it: a pipe is one-directional, has no // notion of a connection, and gives no way for a server to be *found* by a // client that starts later. A socket with a name in the filesystem is // exactly the missing piece. // // AF_INET arrived later, and exactly as planned: underneath the same syscalls // rather than reshaping them. A socket carries its domain and every entry point // dispatches on it -- kernel/net/unix.c for AF_UNIX, kernel/net/inet.c (lwIP) // for AF_INET. #define AF_UNIX 1 #define AF_LOCAL 1 #define AF_INET 2 #define SOCK_STREAM 1 #define SOCK_DGRAM 2 #define UNIX_PATH_MAX 108 #define SHUT_RD 0 #define SHUT_WR 1 #define SHUT_RDWR 2 struct sockaddr_un { uint16 sun_family; char sun_path[UNIX_PATH_MAX]; }; // The generic form syscalls take. Same shape as Linux's, so a musl-linked // program's struct lines up byte for byte. struct sockaddr { uint16 sa_family; char sa_data[UNIX_PATH_MAX]; }; // The AF_INET address. Same layout as Linux's, so a musl-linked program's // struct lines up byte for byte. sin_port and sin_addr are network byte order // and stay that way: lwIP wants them so, and converting on the way in and out // again would be two swaps that cancel. struct sockaddr_in { uint16 sin_family; uint16 sin_port; uint32 sin_addr; char sin_zero[8]; }; #ifdef _KERNEL_SOCKET_INTERNALS #define NSOCK 32 // sockets in the system #define SOCKBUF 4096 // receive buffer per connected socket #define NBACKLOG 8 enum sockstate { SS_FREE = 0, SS_UNBOUND, SS_BOUND, SS_LISTENING, SS_CONNECTED, }; // Every field here is protected by the socket table's single lock in // kernel/net/unix.c -- there is deliberately no per-socket lock; see the // comment at the top of that file for why. struct socket { int ref; int type; int state; int domain; // AF_UNIX or AF_INET // For AF_INET: the lwIP-backed socket in kernel/net/inet.c. Opaque here so // that socket.h does not have to drag lwIP's headers into every file that // wants a struct socket. void *inet; char name[UNIX_PATH_MAX]; // the bound path, for a listener // A connected socket's peer. Writing to a socket appends to the *peer's* // buffer, which is what makes one buffer per socket enough for a // bidirectional connection. struct socket *peer; int peer_closed; char data[SOCKBUF]; uint nread, nwrite; // Connections waiting to be accepted, on a listener. struct socket *queue[NBACKLOG]; int nqueue; }; #endif