menios icon indicating copy to clipboard operation
menios copied to clipboard

Implement Unix domain sockets for local IPC

Open pbalduino opened this issue 4 months ago • 0 comments

Goal

Implement Unix domain sockets for efficient local inter-process communication using the familiar socket API.

Context

Unix domain sockets provide a socket-based IPC mechanism for local communication between processes on the same machine. They offer better performance than TCP sockets for local communication and integrate well with existing socket infrastructure.

Definition of Done

  • Socket creation: AF_UNIX address family support in socket() syscall
  • Socket types: Support for SOCK_STREAM (reliable) and SOCK_DGRAM (datagram) Unix sockets
  • Filesystem namespace: Named sockets in filesystem namespace
  • Abstract namespace: Abstract socket names (Linux extension)
  • Socket operations: bind(), listen(), accept(), connect() for Unix sockets
  • Data transfer: send(), recv(), sendmsg(), recvmsg() with Unix sockets
  • File descriptor passing: Pass file descriptors between processes via Unix sockets
  • Credential passing: Pass process credentials (PID, UID, GID) via socket
  • Socket cleanup: Proper cleanup of socket files and resources

Socket Types to Support

// Socket families
#define AF_UNIX     1    // Unix domain sockets
#define AF_LOCAL    AF_UNIX  // Alternative name

// Socket types
#define SOCK_STREAM  1   // Reliable, connection-based
#define SOCK_DGRAM   2   // Unreliable, connectionless

Data Structures

struct sockaddr_un {
    sa_family_t sun_family;     // AF_UNIX
    char sun_path[108];         // Socket pathname
};

struct unix_socket {
    struct socket sock;         // Base socket structure
    struct sockaddr_un addr;    // Socket address
    struct unix_socket *peer;   // Connected peer (SOCK_STREAM)
    struct sk_buff_head receive_queue;  // Receive queue
    struct unix_socket *listener;      // Listening socket (for accepted sockets)
    bool bound;                 // Socket is bound to address
    bool connected;             // Socket is connected
};

struct unix_dgram_socket {
    struct unix_socket base;
    struct list_head dgram_list;  // List of datagram sockets
};

Implementation Details

Socket Creation and Binding

  • Create Unix socket with socket(AF_UNIX, type, 0)
  • Bind to filesystem path or abstract name
  • Create filesystem entries for named sockets
  • Handle socket file permissions

Connection Management (SOCK_STREAM)

  • Implement listen queue for accepting connections
  • Connection establishment handshake
  • Bidirectional data transfer
  • Connection cleanup on close

Datagram Sockets (SOCK_DGRAM)

  • Connectionless message delivery
  • Message boundaries preservation
  • Best-effort delivery (can drop messages)
  • Address-based routing

File Descriptor Passing

// Send file descriptor via Unix socket
struct msghdr msg;
struct cmsghdr *cmsg;
char cmsg_buf[CMSG_SPACE(sizeof(int))];

msg.msg_control = cmsg_buf;
msg.msg_controllen = sizeof(cmsg_buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
*(int *)CMSG_DATA(cmsg) = fd_to_send;

Testing Strategy

  • Test socket creation and binding
  • Test connection establishment and data transfer
  • Test datagram message sending/receiving
  • Test file descriptor passing
  • Test credential passing
  • Test abstract namespace sockets
  • Test socket cleanup and error handling
  • Test concurrent connections

Dependencies

  • Socket infrastructure: Issue #71 - Need basic socket API implementation
  • File descriptor management: Issue #96 - Need fd table for socket file descriptors
  • Virtual File System: Issue #65 - Need VFS for socket filesystem entries
  • Process management: Need process identification for credential passing
  • Memory management: Need buffer management for socket data
  • Synchronization: Issue #40 - Need condition variables for blocking operations

Integration Points

  • Extend existing socket infrastructure for AF_UNIX
  • Add Unix socket file operations to VFS
  • Integrate with file descriptor passing mechanism
  • Support socket files in filesystem namespace

Security Considerations

  • Validate socket addresses and paths
  • Check filesystem permissions for socket files
  • Secure file descriptor passing
  • Validate credential information
  • Prevent buffer overflow in socket operations

Files to Create/Modify

  • src/kernel/net/unix/unix_socket.c - Core Unix socket implementation
  • src/kernel/net/unix/unix_socket.h - Unix socket definitions
  • src/kernel/net/unix/af_unix.c - Address family implementation
  • include/sys/un.h - Userspace Unix socket interface
  • include/sys/socket.h - Add AF_UNIX definitions

Error Handling

  • EADDRINUSE for address already in use
  • ENOENT for non-existent socket paths
  • ECONNREFUSED for connection refused
  • EMSGSIZE for oversized messages
  • ENOTCONN for operations on unconnected sockets

Performance Considerations

  • Efficient buffer management
  • Zero-copy data transfer where possible
  • Fast connection establishment
  • Optimized file descriptor passing
  • Minimal syscall overhead

Advanced Features

  • Ancillary data: Support for control messages
  • Socket options: Unix-specific socket options
  • Socket permissions: Extended permission model
  • Socket monitoring: Debug and monitoring interfaces
  • Performance optimization: Splice, sendfile support

Usage Examples

// Server (SOCK_STREAM)
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = {.sun_family = AF_UNIX, .sun_path = "/tmp/server"};
bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));
listen(server_fd, 5);
int client_fd = accept(server_fd, NULL, NULL);

// Client (SOCK_STREAM)
int client_fd = socket(AF_UNIX, SOCK_STREAM, 0);
connect(client_fd, (struct sockaddr*)&addr, sizeof(addr));
send(client_fd, "Hello", 5, 0);

// Datagram socket
int dgram_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
sendto(dgram_fd, "Message", 7, 0, (struct sockaddr*)&addr, sizeof(addr));

pbalduino avatar Sep 28 '25 01:09 pbalduino