Blame


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>
4 fd04aace 2003-11-23 devnull
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>
10 fd04aace 2003-11-23 devnull
11 1c253ceb 2003-11-23 devnull #undef sun
12 1c253ceb 2003-11-23 devnull #define sun sockun
13 fd04aace 2003-11-23 devnull
14 32f69c36 2003-12-11 devnull int
15 32f69c36 2003-12-11 devnull _p9netfd(char *dir)
16 fd04aace 2003-11-23 devnull {
17 fd04aace 2003-11-23 devnull int fd;
18 fd04aace 2003-11-23 devnull
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;
25 fd04aace 2003-11-23 devnull }
26 fd04aace 2003-11-23 devnull
27 fd04aace 2003-11-23 devnull static void
28 fd04aace 2003-11-23 devnull putfd(char *dir, int fd)
29 fd04aace 2003-11-23 devnull {
30 fd04aace 2003-11-23 devnull snprint(dir, NETPATHLEN, "/dev/fd/%d", fd);
31 fd04aace 2003-11-23 devnull }
32 fd04aace 2003-11-23 devnull
33 fd04aace 2003-11-23 devnull #undef unix
34 2e9749ec 2005-07-13 devnull #define unix sockunix
35 fd04aace 2003-11-23 devnull
36 fd04aace 2003-11-23 devnull int
37 fd04aace 2003-11-23 devnull p9announce(char *addr, char *dir)
38 fd04aace 2003-11-23 devnull {
39 fd04aace 2003-11-23 devnull int proto;
40 fd04aace 2003-11-23 devnull char *buf, *unix;
41 fd04aace 2003-11-23 devnull char *net;
42 fd04aace 2003-11-23 devnull u32int host;
43 fd04aace 2003-11-23 devnull int port, s;
44 8ad51794 2004-03-25 devnull int n;
45 8ad51794 2004-03-25 devnull socklen_t sn;
46 fd04aace 2003-11-23 devnull struct sockaddr_in sa;
47 fd04aace 2003-11-23 devnull struct sockaddr_un sun;
48 fd04aace 2003-11-23 devnull
49 fd04aace 2003-11-23 devnull buf = strdup(addr);
50 fd04aace 2003-11-23 devnull if(buf == nil)
51 fd04aace 2003-11-23 devnull return -1;
52 fd04aace 2003-11-23 devnull
53 e42882dc 2004-06-16 devnull if(p9dialparse(buf, &net, &unix, &host, &port) < 0){
54 fd04aace 2003-11-23 devnull free(buf);
55 fd04aace 2003-11-23 devnull return -1;
56 fd04aace 2003-11-23 devnull }
57 fd04aace 2003-11-23 devnull if(strcmp(net, "tcp") == 0)
58 fd04aace 2003-11-23 devnull proto = SOCK_STREAM;
59 fd04aace 2003-11-23 devnull else if(strcmp(net, "udp") == 0)
60 fd04aace 2003-11-23 devnull proto = SOCK_DGRAM;
61 fd04aace 2003-11-23 devnull else if(strcmp(net, "unix") == 0)
62 fd04aace 2003-11-23 devnull goto Unix;
63 fd04aace 2003-11-23 devnull else{
64 fd04aace 2003-11-23 devnull werrstr("can only handle tcp, udp, and unix: not %s", net);
65 fd04aace 2003-11-23 devnull free(buf);
66 fd04aace 2003-11-23 devnull return -1;
67 fd04aace 2003-11-23 devnull }
68 fd04aace 2003-11-23 devnull free(buf);
69 fd04aace 2003-11-23 devnull
70 fd04aace 2003-11-23 devnull memset(&sa, 0, sizeof sa);
71 fd04aace 2003-11-23 devnull memmove(&sa.sin_addr, &host, 4);
72 fd04aace 2003-11-23 devnull sa.sin_family = AF_INET;
73 fd04aace 2003-11-23 devnull sa.sin_port = htons(port);
74 fd04aace 2003-11-23 devnull if((s = socket(AF_INET, proto, 0)) < 0)
75 fd04aace 2003-11-23 devnull return -1;
76 fd04aace 2003-11-23 devnull sn = sizeof n;
77 8ad51794 2004-03-25 devnull if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) >= 0
78 fd04aace 2003-11-23 devnull && n == SOCK_STREAM){
79 fd04aace 2003-11-23 devnull n = 1;
80 fd04aace 2003-11-23 devnull setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
81 fd04aace 2003-11-23 devnull }
82 fd04aace 2003-11-23 devnull if(bind(s, (struct sockaddr*)&sa, sizeof sa) < 0){
83 fd04aace 2003-11-23 devnull close(s);
84 fd04aace 2003-11-23 devnull return -1;
85 fd04aace 2003-11-23 devnull }
86 fd04aace 2003-11-23 devnull if(proto == SOCK_STREAM){
87 fd04aace 2003-11-23 devnull listen(s, 8);
88 fd04aace 2003-11-23 devnull putfd(dir, s);
89 fd04aace 2003-11-23 devnull }
90 fd04aace 2003-11-23 devnull return s;
91 fd04aace 2003-11-23 devnull
92 fd04aace 2003-11-23 devnull Unix:
93 fd04aace 2003-11-23 devnull memset(&sun, 0, sizeof sun);
94 fd04aace 2003-11-23 devnull sun.sun_family = AF_UNIX;
95 fd04aace 2003-11-23 devnull strcpy(sun.sun_path, unix);
96 fd04aace 2003-11-23 devnull if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
97 fd04aace 2003-11-23 devnull return -1;
98 fd04aace 2003-11-23 devnull sn = sizeof sun;
99 fd04aace 2003-11-23 devnull if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){
100 32f69c36 2003-12-11 devnull if(errno == EADDRINUSE
101 32f69c36 2003-12-11 devnull && connect(s, (struct sockaddr*)&sun, sizeof sun) < 0
102 32f69c36 2003-12-11 devnull && errno == ECONNREFUSED){
103 32f69c36 2003-12-11 devnull /* dead socket, so remove it */
104 32f69c36 2003-12-11 devnull remove(unix);
105 32f69c36 2003-12-11 devnull close(s);
106 32f69c36 2003-12-11 devnull if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
107 32f69c36 2003-12-11 devnull return -1;
108 32f69c36 2003-12-11 devnull if(bind(s, (struct sockaddr*)&sun, sizeof sun) >= 0)
109 32f69c36 2003-12-11 devnull goto Success;
110 32f69c36 2003-12-11 devnull }
111 fd04aace 2003-11-23 devnull close(s);
112 fd04aace 2003-11-23 devnull return -1;
113 fd04aace 2003-11-23 devnull }
114 32f69c36 2003-12-11 devnull Success:
115 fd04aace 2003-11-23 devnull listen(s, 8);
116 fd04aace 2003-11-23 devnull putfd(dir, s);
117 fd04aace 2003-11-23 devnull return s;
118 fd04aace 2003-11-23 devnull }
119 fd04aace 2003-11-23 devnull
120 fd04aace 2003-11-23 devnull int
121 fd04aace 2003-11-23 devnull p9listen(char *dir, char *newdir)
122 fd04aace 2003-11-23 devnull {
123 bd2e8020 2004-06-16 devnull int fd, one;
124 fd04aace 2003-11-23 devnull
125 32f69c36 2003-12-11 devnull if((fd = _p9netfd(dir)) < 0){
126 fd04aace 2003-11-23 devnull werrstr("bad 'directory' in listen: %s", dir);
127 fd04aace 2003-11-23 devnull return -1;
128 fd04aace 2003-11-23 devnull }
129 fd04aace 2003-11-23 devnull
130 fd04aace 2003-11-23 devnull if((fd = accept(fd, nil, nil)) < 0)
131 fd04aace 2003-11-23 devnull return -1;
132 fd04aace 2003-11-23 devnull
133 bd2e8020 2004-06-16 devnull one = 1;
134 bd2e8020 2004-06-16 devnull setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
135 bd2e8020 2004-06-16 devnull
136 fd04aace 2003-11-23 devnull putfd(newdir, fd);
137 fd04aace 2003-11-23 devnull return fd;
138 fd04aace 2003-11-23 devnull }
139 fd04aace 2003-11-23 devnull
140 fd04aace 2003-11-23 devnull int
141 fd04aace 2003-11-23 devnull p9accept(int cfd, char *dir)
142 fd04aace 2003-11-23 devnull {
143 fd04aace 2003-11-23 devnull int fd;
144 fd04aace 2003-11-23 devnull
145 32f69c36 2003-12-11 devnull if((fd = _p9netfd(dir)) < 0){
146 fd04aace 2003-11-23 devnull werrstr("bad 'directory' in accept");
147 fd04aace 2003-11-23 devnull return -1;
148 fd04aace 2003-11-23 devnull }
149 fd04aace 2003-11-23 devnull /* need to dup because the listen fd will be closed */
150 fd04aace 2003-11-23 devnull return dup(fd);
151 fd04aace 2003-11-23 devnull }
152 fd04aace 2003-11-23 devnull