1 / 21

Chapter 14

Chapter 14. Unix domain protocol. contents. Introduction unix domain socket address structure socketpair socket function unix domain stream client-server unix domain datagram client-server passing descriptors receiving sender credentials. Introduction. Unix domain protocol

cahil
Download Presentation

Chapter 14

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 14 Unix domain protocol

  2. contents • Introduction • unix domain socket address structure • socketpair • socket function • unix domain stream client-server • unix domain datagram client-server • passing descriptors • receiving sender credentials

  3. Introduction • Unix domain protocol • perform client-server communication on a single host using same API that is used for client-server model on the different hosts.

  4. unix domain socket address structure • <sys/un.h> struct sockaddr_un{ uint8_t sun_len; sa_family_t sun_family; /*AF_LOCAL*/ char sun_path[104]; /*null terminated pathname*/ }; • sun_path => must null terminated

  5. #include "unp.h" int main(int argc, char **argv) { int sockfd; socklen_t len; struct sockaddr_un addr1, addr2; if (argc != 2) err_quit("usage: unixbind <pathname>"); sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0); unlink(argv[1]); /* OK if this fails */ bzero(&addr1, sizeof(addr1)); addr1.sun_family = AF_LOCAL; strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1); Bind(sockfd, (SA *) &addr1, SUN_LEN(&addr1)); len = sizeof(addr2); Getsockname(sockfd, (SA *) &addr2, &len); printf("bound name = %s, returned len = %d\n", addr2.sun_path, len); exit(0); }

  6. socketpair Function • Create two sockets that are then connected together(only available in unix domain socket) • family must be AF_LOCAL • protocol must be 0 #include<sys/socket.h> int socketpair(int family, int type, int protocol, int sockfd[2]); return: nonzero if OK, -1 on error

  7. socket function(restriction) • Default file access permition created by bind shiuld be 0777, modified by the current umask value • path name must be absolute pathname not a relative path name • the path name in the connect must be a pathname that is currently bound to an open unix domain socket of the same type. • Unix domain stream socket are similar to TCP socket • unix domain datagram are similar to UDP socket • unlike UDP socket, sending a datagram on an unbound unix domain datagram does not bind a pathname to the socket

  8. unix domain stream client-server #include "unp.h" int main(int argc, char **argv) { int listenfd, connfd; pid_t childpid; socklen_t clilen; struct sockaddr_un cliaddr, servaddr; void sig_chld(int); listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0); unlink(UNIXSTR_PATH); bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXSTR_PATH); Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); Listen(listenfd, LISTENQ); Signal(SIGCHLD, sig_chld);

  9. unix domain stream client-server(2) for ( ; ; ) { clilen = sizeof(cliaddr); if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) { if (errno == EINTR) continue; /* back to for() */ else err_sys("accept error"); } if ( (childpid = Fork()) == 0) { /* child process */ Close(listenfd); /* close listening socket */ str_echo(connfd); /* process the request */ exit(0); } Close(connfd); /* parent closes connected socket */ } }

  10. unix domain datagram client-server #include "unp.h" int main(int argc, char **argv) { int sockfd; struct sockaddr_un servaddr; sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXSTR_PATH); Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); str_cli(stdin, sockfd); /* do it all */ exit(0); } /* unix domain stream protocol echo client */

  11. unix domain datagram client-server(2) #include "unp.h" int main(int argc, char **argv) { int sockfd; struct sockaddr_un servaddr, cliaddr; sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0); unlink(UNIXDG_PATH); bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXDG_PATH); Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); }/* unix domain datagram protocol echo server */

  12. unix domain datagram client-server(3) #include "unp.h" int main(int argc, char **argv) { int sockfd; struct sockaddr_un cliaddr, servaddr; sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0); bzero(&cliaddr, sizeof(cliaddr)); /* bind an address for us */ cliaddr.sun_family = AF_LOCAL; strcpy(cliaddr.sun_path, tmpnam(NULL)); Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr)); bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */ servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXDG_PATH); dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); exit(0); } /* unix domain datagram protocol echo client */

  13. passing descriptors • Current unix system provide a way to pass any open descriptor from one process to any other process.(using sendmsg)

  14. passing descriptors(2) 1)Create a unix domain socket(stream or datagram) 2)one process opens a descriptor by calling any of the unix function that returns a descriptor 3)the sending process build a msghdr structure containing the descriptor to be passed 4)the receiving process calls recvmsg to receive the descriptor on the unix domain socket from step 1)

  15. Descriptor passing example mycat [0] [1] Figure 14.7) mycat program after create stream pipe using socketpair

  16. fork mycat openfile [0] [1] Exec(command-line args) descriptor Figure 14.8) mycat program after invoking openfile program

  17. #include "unp.h" int my_open(const char *, int); int main(int argc, char **argv) { int fd, n; char buff[BUFFSIZE]; if (argc != 2) err_quit("usage: mycat <pathname>"); if ( (fd = my_open(argv[1], O_RDONLY)) < 0) err_sys("cannot open %s", argv[1]); while ( (n = Read(fd, buff, BUFFSIZE)) > 0) Write(STDOUT_FILENO, buff, n); exit(0); } mycat program show in Figure 14.7)

  18. #include "unp.h" int my_open(const char *pathname, int mode) { int fd, sockfd[2], status; pid_t childpid; char c, argsockfd[10], argmode[10]; Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); if ( (childpid = Fork()) == 0) { /* child process */ Close(sockfd[0]); snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]); snprintf(argmode, sizeof(argmode), "%d", mode); execl("./openfile", "openfile", argsockfd, pathname, argmode, (char *) NULL); err_sys("execl error"); } myopen function(1) : open a file and return a descriptor

  19. /* parent process - wait for the child to terminate */ Close(sockfd[1]); /* close the end we don't use */ Waitpid(childpid, &status, 0); if (WIFEXITED(status) == 0) err_quit("child did not terminate"); if ( (status = WEXITSTATUS(status)) == 0) Read_fd(sockfd[0], &c, 1, &fd); else { errno = status; /* set errno value from child's status */ fd = -1; } Close(sockfd[0]); return(fd); } myopen function(2) : open a file and return a descriptor

  20. receiving sender credentials • User credentials via fcred structure Struct fcred{ uid_t fc_ruid; /*real user ID*/ gid_t fc_rgid; /*real group ID*/ char fc_login[MAXLOGNAME];/*setlogin() name*/ uid_t fc_uid; /*effectivr user ID*/ short fc_ngroups; /*number of groups*/ gid_t fc_groups[NGROUPS]; /*supplemenary group IDs*/ }; #define fc_gid fc_groups[0] /* effective group ID */

  21. receiving sender credentials(2) • Usally MAXLOGNAME is 16 • NGROUP is 16 • fc_ngroups is at least 1 • the credentials are sent as ancillary data when data is sent on unix domain socket.(only if receiver of data has enabled the LOCAL_CREDS socket option) • on a datagram socket , the credentials accompany every datagram. • Credentials cannot be sent along with a descriptor • user are not able to forge credentials

More Related