1 fd04aace 2003-11-23 devnull #include <u.h>
2 fd04aace 2003-11-23 devnull #define NOPLAN9DEFINES
3 fd04aace 2003-11-23 devnull #include <libc.h>
5 fd04aace 2003-11-23 devnull #include <sys/socket.h>
6 fd04aace 2003-11-23 devnull #include <netinet/in.h>
7 bd2e8020 2004-06-16 devnull #include <netinet/tcp.h>
8 fd04aace 2003-11-23 devnull #include <sys/un.h>
9 32f69c36 2003-12-11 devnull #include <errno.h>
11 1c253ceb 2003-11-23 devnull #undef sun
12 1c253ceb 2003-11-23 devnull #define sun sockun
15 32f69c36 2003-12-11 devnull _p9netfd(char *dir)
19 fd04aace 2003-11-23 devnull if(strncmp(dir, "/dev/fd/", 8) != 0)
20 fd04aace 2003-11-23 devnull return -1;
21 fd04aace 2003-11-23 devnull fd = strtol(dir+8, &dir, 0);
22 fd04aace 2003-11-23 devnull if(*dir != 0)
23 fd04aace 2003-11-23 devnull return -1;
24 fd04aace 2003-11-23 devnull return fd;
27 fd04aace 2003-11-23 devnull static void
28 fd04aace 2003-11-23 devnull putfd(char *dir, int fd)
30 fd04aace 2003-11-23 devnull snprint(dir, NETPATHLEN, "/dev/fd/%d", fd);
33 fd04aace 2003-11-23 devnull #undef unix
34 2e9749ec 2005-07-13 devnull #define unix sockunix
37 3dade5fe 2012-09-04 rsc addrlen(struct sockaddr_storage *ss)
39 3dade5fe 2012-09-04 rsc switch(ss->ss_family){
40 3dade5fe 2012-09-04 rsc case AF_INET:
41 3dade5fe 2012-09-04 rsc return sizeof(struct sockaddr_in);
42 3dade5fe 2012-09-04 rsc case AF_INET6:
43 3dade5fe 2012-09-04 rsc return sizeof(struct sockaddr_in6);
44 3dade5fe 2012-09-04 rsc case AF_UNIX:
45 3dade5fe 2012-09-04 rsc return sizeof(struct sockaddr_un);
51 fd04aace 2003-11-23 devnull p9announce(char *addr, char *dir)
53 fd04aace 2003-11-23 devnull int proto;
54 fd04aace 2003-11-23 devnull char *buf, *unix;
55 fd04aace 2003-11-23 devnull char *net;
56 fd04aace 2003-11-23 devnull int port, s;
58 8ad51794 2004-03-25 devnull socklen_t sn;
59 3409bc9a 2012-06-02 0intro struct sockaddr_storage ss;
61 fd04aace 2003-11-23 devnull buf = strdup(addr);
62 fd04aace 2003-11-23 devnull if(buf == nil)
63 fd04aace 2003-11-23 devnull return -1;
65 3409bc9a 2012-06-02 0intro if(p9dialparse(buf, &net, &unix, &ss, &port) < 0){
66 fd04aace 2003-11-23 devnull free(buf);
67 fd04aace 2003-11-23 devnull return -1;
69 fd04aace 2003-11-23 devnull if(strcmp(net, "tcp") == 0)
70 fd04aace 2003-11-23 devnull proto = SOCK_STREAM;
71 fd04aace 2003-11-23 devnull else if(strcmp(net, "udp") == 0)
72 fd04aace 2003-11-23 devnull proto = SOCK_DGRAM;
73 fd04aace 2003-11-23 devnull else if(strcmp(net, "unix") == 0)
74 fd04aace 2003-11-23 devnull goto Unix;
76 fd04aace 2003-11-23 devnull werrstr("can only handle tcp, udp, and unix: not %s", net);
77 fd04aace 2003-11-23 devnull free(buf);
78 fd04aace 2003-11-23 devnull return -1;
80 fd04aace 2003-11-23 devnull free(buf);
82 3409bc9a 2012-06-02 0intro if((s = socket(ss.ss_family, proto, 0)) < 0)
83 fd04aace 2003-11-23 devnull return -1;
84 fd04aace 2003-11-23 devnull sn = sizeof n;
85 8ad51794 2004-03-25 devnull if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) >= 0
86 fd04aace 2003-11-23 devnull && n == SOCK_STREAM){
88 fd04aace 2003-11-23 devnull setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
90 3dade5fe 2012-09-04 rsc if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){
91 fd04aace 2003-11-23 devnull close(s);
92 fd04aace 2003-11-23 devnull return -1;
94 fd04aace 2003-11-23 devnull if(proto == SOCK_STREAM){
95 fd04aace 2003-11-23 devnull listen(s, 8);
96 fd04aace 2003-11-23 devnull putfd(dir, s);
98 fd04aace 2003-11-23 devnull return s;
101 3409bc9a 2012-06-02 0intro if((s = socket(ss.ss_family, SOCK_STREAM, 0)) < 0)
102 fd04aace 2003-11-23 devnull return -1;
103 3dade5fe 2012-09-04 rsc if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){
104 32f69c36 2003-12-11 devnull if(errno == EADDRINUSE
105 3dade5fe 2012-09-04 rsc && connect(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0
106 32f69c36 2003-12-11 devnull && errno == ECONNREFUSED){
107 32f69c36 2003-12-11 devnull /* dead socket, so remove it */
108 32f69c36 2003-12-11 devnull remove(unix);
109 32f69c36 2003-12-11 devnull close(s);
110 3409bc9a 2012-06-02 0intro if((s = socket(ss.ss_family, SOCK_STREAM, 0)) < 0)
111 32f69c36 2003-12-11 devnull return -1;
112 3dade5fe 2012-09-04 rsc if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) >= 0)
113 32f69c36 2003-12-11 devnull goto Success;
115 fd04aace 2003-11-23 devnull close(s);
116 fd04aace 2003-11-23 devnull return -1;
118 32f69c36 2003-12-11 devnull Success:
119 fd04aace 2003-11-23 devnull listen(s, 8);
120 fd04aace 2003-11-23 devnull putfd(dir, s);
121 fd04aace 2003-11-23 devnull return s;
125 fd04aace 2003-11-23 devnull p9listen(char *dir, char *newdir)
127 bd2e8020 2004-06-16 devnull int fd, one;
129 32f69c36 2003-12-11 devnull if((fd = _p9netfd(dir)) < 0){
130 fd04aace 2003-11-23 devnull werrstr("bad 'directory' in listen: %s", dir);
131 fd04aace 2003-11-23 devnull return -1;
134 fd04aace 2003-11-23 devnull if((fd = accept(fd, nil, nil)) < 0)
135 fd04aace 2003-11-23 devnull return -1;
137 bd2e8020 2004-06-16 devnull one = 1;
138 bd2e8020 2004-06-16 devnull setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
140 fd04aace 2003-11-23 devnull putfd(newdir, fd);
141 fd04aace 2003-11-23 devnull return fd;
145 fd04aace 2003-11-23 devnull p9accept(int cfd, char *dir)
149 32f69c36 2003-12-11 devnull if((fd = _p9netfd(dir)) < 0){
150 fd04aace 2003-11-23 devnull werrstr("bad 'directory' in accept");
151 fd04aace 2003-11-23 devnull return -1;
153 fd04aace 2003-11-23 devnull /* need to dup because the listen fd will be closed */
154 fd04aace 2003-11-23 devnull return dup(fd);