menios
menios copied to clipboard
Implement Unix domain sockets for local IPC
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));