150 likes | 723 Views
Unix Domain Protocols. Unix domain socket address structure Unix domain socket client-server Descriptor passing with Unix domain socket Readings UNP Sections 14.4 and 14.5, Ch15. Unix Domain Protocols. Used for client-server communication on a single machine
E N D
Unix Domain Protocols • Unix domain socket address structure • Unix domain socket client-server • Descriptor passing with Unix domain socket • Readings • UNP Sections 14.4 and 14.5, Ch15
Unix Domain Protocols • Used for client-server communication on a single machine • Use same API as with regular client-server • Both stream and datagram sockets are supported • Local IPC (inter-process communication) • Why do we need this? • Efficiency (faster than TCP/UDP socket on same machine) • Passing (file) descriptors • More security checks (passing credentials such as pid)
Address Structure • Open a socket using UNIX domain socket socket(AF_LOCAL, SOCK_STREAM, 0) socket(AF_LOCAL, SOCK_DGRAM, 0) • AF_LOCAL, AF_UNIX (historical) • UNIX domain socket address structure #include <sys/un.h> struct sockaddr_un { sa_family_t sun_family; /*AF_LOCAL or AF_UNIX */ char sun_path[104]; /* null-terminated path name */ }
A Few Notes • sun_path is null-terminated file pathname • Must not exist in file system • Should be absolute pathname • connect: access permission of sun_path is verified like open with write-only access • Unix domain stream socket similar to TCP • Unix domain datagram socket similar to UDP • For Unix domain datagram client • connect and sendto will not automatically bind socket to local address • Server cannot return datagram to client without bind
Binding a Unix Domain Socket • example1.c • Use absolute path for path name • bind will fail if the file exists • Pathname can potentially overrun the sun_path buffer • Otherwise, it is very similar to a TCP socket
Client-Server Using Unix Domain Protocols • example2.c and example3.c • Echo server and client • connect needs a pathname that is currently bound to an open UNIX domain socket of the same type • Permission test for connect is the same as that for open with write-only access • connect will fail if the listening queue is full • UNIX domain datagram sockets are similar to UDP sockets • Sender must bind first for the receiver to reply
Full-Duplex Stream Pipe • #include <sys/socket.h> • int socketpair(int family, int type, int protocol, int sockfd[2]); • Create two sockets connected together • Family: AF_LOCAL • Type: SOCK_STREAM or SOCK_DGRAM • Protocol: 0 • Full-duplex stream pipe. Both can be used for read and write • Example example4.c
Passing Descriptors • What we have learned • Parent open files and pass to child processes • What if child wants to pass back file descriptors to parent? • What if two unrelated processes want to pass file descriptors? • Unix domain socket can handle all these
Passing Descriptors • Involves creating a new descriptor in receiving process • referring to the same system open file table entry • It is normal that we see different descriptor numbers in sending and receiving processes • It is OK for the sending process to close the file after calling sendmsg
recvmsg and sendmsg Functions #include <sys/socket.h> ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags); struct msghdr { void *msg_name; //protocol address socklen_t msg_namelen; struct iovec *msg_iov; // array to hold data int msg_iovlen; void *msg_control; // ancillary data // link to cmsghdr struct socklen_t msg_controllen; int msg_flags; }; struct iovec { void *iov_base; // starting address of buffer size_t iov_len; // size of buffer };
Control Message Header struct cmsghdr { socklen_t cmsg_len; // length in bytes int cmsg_level; // socket option level int cmsg_type; // socket option type // followed by unsigned char cmsg_data[] }; • A number of macros provided to access cmsghdr from msghdr • struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *) • struct cmsghdr *CMSG_NXTHDR(struct msghdr *, struct cmsghdr*) • unsigned char *CMSG_DATA(struct cmsghdr *) • etc
Passing Descriptor • Goal: passing open file descriptor in the kernel (process file descriptor entries are used to reference to the kernel entry). • Create a UNIX domain socket • Send open the descriptor with open, pipe etc (get the reference) • Send process build msghdr structure containing the descriptor to pass (using the reference), and call sendmsg • Receiving process call recvmsg to receive the descriptor on the domain socket (the reference can be different, but the kernel open file entry would be the same).
Passing Descriptor Example • Example5.c • Waiting for incoming request to open a specified file • After opening the file, send back the file descriptor • Example6.c • Send specified file to server • After receiving file descriptor returned from server, print the content of the file
Passing Credentials • cmsg_level: SOL_SOCKET • cmsg_type: SCM_CREDS struct cmsgcred { pid_t cmcred_pid; // PID of sending process uid_t cmcred_uid; // real UID uid_t cmcred_euid; // effective UID gid_t cmcred_gid; // real GID short cmcred_ngroups; // num of grps gid_t cmcred_groups[CMGROUP_MAX]; };