1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. |
2 | * |
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
4 | * of this software and associated documentation files (the "Software"), to |
5 | * deal in the Software without restriction, including without limitation the |
6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
7 | * sell copies of the Software, and to permit persons to whom the Software is |
8 | * furnished to do so, subject to the following conditions: |
9 | * |
10 | * The above copyright notice and this permission notice shall be included in |
11 | * all copies or substantial portions of the Software. |
12 | * |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
19 | * IN THE SOFTWARE. |
20 | */ |
21 | |
22 | #include "uv.h" |
23 | #include "internal.h" |
24 | |
25 | #include <stdlib.h> |
26 | #include <unistd.h> |
27 | #include <assert.h> |
28 | #include <errno.h> |
29 | |
30 | |
31 | static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { |
32 | struct sockaddr_storage saddr; |
33 | socklen_t slen; |
34 | int sockfd; |
35 | int err; |
36 | |
37 | err = uv__socket(domain, SOCK_STREAM, 0); |
38 | if (err < 0) |
39 | return err; |
40 | sockfd = err; |
41 | |
42 | err = uv__stream_open((uv_stream_t*) handle, sockfd, flags); |
43 | if (err) { |
44 | uv__close(sockfd); |
45 | return err; |
46 | } |
47 | |
48 | if (flags & UV_HANDLE_BOUND) { |
49 | /* Bind this new socket to an arbitrary port */ |
50 | slen = sizeof(saddr); |
51 | memset(&saddr, 0, sizeof(saddr)); |
52 | if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) { |
53 | uv__close(sockfd); |
54 | return UV__ERR(errno); |
55 | } |
56 | |
57 | if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) { |
58 | uv__close(sockfd); |
59 | return UV__ERR(errno); |
60 | } |
61 | } |
62 | |
63 | return 0; |
64 | } |
65 | |
66 | |
67 | static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { |
68 | struct sockaddr_storage saddr; |
69 | socklen_t slen; |
70 | |
71 | if (domain == AF_UNSPEC) { |
72 | handle->flags |= flags; |
73 | return 0; |
74 | } |
75 | |
76 | if (uv__stream_fd(handle) != -1) { |
77 | |
78 | if (flags & UV_HANDLE_BOUND) { |
79 | |
80 | if (handle->flags & UV_HANDLE_BOUND) { |
81 | /* It is already bound to a port. */ |
82 | handle->flags |= flags; |
83 | return 0; |
84 | } |
85 | |
86 | /* Query to see if tcp socket is bound. */ |
87 | slen = sizeof(saddr); |
88 | memset(&saddr, 0, sizeof(saddr)); |
89 | if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) |
90 | return UV__ERR(errno); |
91 | |
92 | if ((saddr.ss_family == AF_INET6 && |
93 | ((struct sockaddr_in6*) &saddr)->sin6_port != 0) || |
94 | (saddr.ss_family == AF_INET && |
95 | ((struct sockaddr_in*) &saddr)->sin_port != 0)) { |
96 | /* Handle is already bound to a port. */ |
97 | handle->flags |= flags; |
98 | return 0; |
99 | } |
100 | |
101 | /* Bind to arbitrary port */ |
102 | if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) |
103 | return UV__ERR(errno); |
104 | } |
105 | |
106 | handle->flags |= flags; |
107 | return 0; |
108 | } |
109 | |
110 | return new_socket(handle, domain, flags); |
111 | } |
112 | |
113 | |
114 | int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* tcp, unsigned int flags) { |
115 | int domain; |
116 | |
117 | /* Use the lower 8 bits for the domain */ |
118 | domain = flags & 0xFF; |
119 | if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) |
120 | return UV_EINVAL; |
121 | |
122 | if (flags & ~0xFF) |
123 | return UV_EINVAL; |
124 | |
125 | uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP); |
126 | |
127 | /* If anything fails beyond this point we need to remove the handle from |
128 | * the handle queue, since it was added by uv__handle_init in uv_stream_init. |
129 | */ |
130 | |
131 | if (domain != AF_UNSPEC) { |
132 | int err = maybe_new_socket(tcp, domain, 0); |
133 | if (err) { |
134 | QUEUE_REMOVE(&tcp->handle_queue); |
135 | return err; |
136 | } |
137 | } |
138 | |
139 | return 0; |
140 | } |
141 | |
142 | |
143 | int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) { |
144 | return uv_tcp_init_ex(loop, tcp, AF_UNSPEC); |
145 | } |
146 | |
147 | |
148 | int uv__tcp_bind(uv_tcp_t* tcp, |
149 | const struct sockaddr* addr, |
150 | unsigned int addrlen, |
151 | unsigned int flags) { |
152 | int err; |
153 | int on; |
154 | |
155 | /* Cannot set IPv6-only mode on non-IPv6 socket. */ |
156 | if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) |
157 | return UV_EINVAL; |
158 | |
159 | err = maybe_new_socket(tcp, addr->sa_family, 0); |
160 | if (err) |
161 | return err; |
162 | |
163 | on = 1; |
164 | if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) |
165 | return UV__ERR(errno); |
166 | |
167 | #ifndef __OpenBSD__ |
168 | #ifdef IPV6_V6ONLY |
169 | if (addr->sa_family == AF_INET6) { |
170 | on = (flags & UV_TCP_IPV6ONLY) != 0; |
171 | if (setsockopt(tcp->io_watcher.fd, |
172 | IPPROTO_IPV6, |
173 | IPV6_V6ONLY, |
174 | &on, |
175 | sizeof on) == -1) { |
176 | #if defined(__MVS__) |
177 | if (errno == EOPNOTSUPP) |
178 | return UV_EINVAL; |
179 | #endif |
180 | return UV__ERR(errno); |
181 | } |
182 | } |
183 | #endif |
184 | #endif |
185 | |
186 | errno = 0; |
187 | if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE) { |
188 | if (errno == EAFNOSUPPORT) |
189 | /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a |
190 | * socket created with AF_INET to an AF_INET6 address or vice versa. */ |
191 | return UV_EINVAL; |
192 | return UV__ERR(errno); |
193 | } |
194 | tcp->delayed_error = UV__ERR(errno); |
195 | |
196 | tcp->flags |= UV_HANDLE_BOUND; |
197 | if (addr->sa_family == AF_INET6) |
198 | tcp->flags |= UV_HANDLE_IPV6; |
199 | |
200 | return 0; |
201 | } |
202 | |
203 | |
204 | int uv__tcp_connect(uv_connect_t* req, |
205 | uv_tcp_t* handle, |
206 | const struct sockaddr* addr, |
207 | unsigned int addrlen, |
208 | uv_connect_cb cb) { |
209 | int err; |
210 | int r; |
211 | |
212 | assert(handle->type == UV_TCP); |
213 | |
214 | if (handle->connect_req != NULL) |
215 | return UV_EALREADY; /* FIXME(bnoordhuis) UV_EINVAL or maybe UV_EBUSY. */ |
216 | |
217 | err = maybe_new_socket(handle, |
218 | addr->sa_family, |
219 | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); |
220 | if (err) |
221 | return err; |
222 | |
223 | handle->delayed_error = 0; |
224 | |
225 | do { |
226 | errno = 0; |
227 | r = connect(uv__stream_fd(handle), addr, addrlen); |
228 | } while (r == -1 && errno == EINTR); |
229 | |
230 | /* We not only check the return value, but also check the errno != 0. |
231 | * Because in rare cases connect() will return -1 but the errno |
232 | * is 0 (for example, on Android 4.3, OnePlus phone A0001_12_150227) |
233 | * and actually the tcp three-way handshake is completed. |
234 | */ |
235 | if (r == -1 && errno != 0) { |
236 | if (errno == EINPROGRESS) |
237 | ; /* not an error */ |
238 | else if (errno == ECONNREFUSED |
239 | #if defined(__OpenBSD__) |
240 | || errno == EINVAL |
241 | #endif |
242 | ) |
243 | /* If we get ECONNREFUSED (Solaris) or EINVAL (OpenBSD) wait until the |
244 | * next tick to report the error. Solaris and OpenBSD wants to report |
245 | * immediately -- other unixes want to wait. |
246 | */ |
247 | handle->delayed_error = UV__ERR(ECONNREFUSED); |
248 | else |
249 | return UV__ERR(errno); |
250 | } |
251 | |
252 | uv__req_init(handle->loop, req, UV_CONNECT); |
253 | req->cb = cb; |
254 | req->handle = (uv_stream_t*) handle; |
255 | QUEUE_INIT(&req->queue); |
256 | handle->connect_req = req; |
257 | |
258 | uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); |
259 | |
260 | if (handle->delayed_error) |
261 | uv__io_feed(handle->loop, &handle->io_watcher); |
262 | |
263 | return 0; |
264 | } |
265 | |
266 | |
267 | int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { |
268 | int err; |
269 | |
270 | if (uv__fd_exists(handle->loop, sock)) |
271 | return UV_EEXIST; |
272 | |
273 | err = uv__nonblock(sock, 1); |
274 | if (err) |
275 | return err; |
276 | |
277 | return uv__stream_open((uv_stream_t*)handle, |
278 | sock, |
279 | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); |
280 | } |
281 | |
282 | |
283 | int uv_tcp_getsockname(const uv_tcp_t* handle, |
284 | struct sockaddr* name, |
285 | int* namelen) { |
286 | |
287 | if (handle->delayed_error) |
288 | return handle->delayed_error; |
289 | |
290 | return uv__getsockpeername((const uv_handle_t*) handle, |
291 | getsockname, |
292 | name, |
293 | namelen); |
294 | } |
295 | |
296 | |
297 | int uv_tcp_getpeername(const uv_tcp_t* handle, |
298 | struct sockaddr* name, |
299 | int* namelen) { |
300 | |
301 | if (handle->delayed_error) |
302 | return handle->delayed_error; |
303 | |
304 | return uv__getsockpeername((const uv_handle_t*) handle, |
305 | getpeername, |
306 | name, |
307 | namelen); |
308 | } |
309 | |
310 | |
311 | int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { |
312 | static int single_accept = -1; |
313 | unsigned long flags; |
314 | int err; |
315 | |
316 | if (tcp->delayed_error) |
317 | return tcp->delayed_error; |
318 | |
319 | if (single_accept == -1) { |
320 | const char* val = getenv("UV_TCP_SINGLE_ACCEPT" ); |
321 | single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */ |
322 | } |
323 | |
324 | if (single_accept) |
325 | tcp->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; |
326 | |
327 | flags = 0; |
328 | #if defined(__MVS__) |
329 | /* on zOS the listen call does not bind automatically |
330 | if the socket is unbound. Hence the manual binding to |
331 | an arbitrary port is required to be done manually |
332 | */ |
333 | flags |= UV_HANDLE_BOUND; |
334 | #endif |
335 | err = maybe_new_socket(tcp, AF_INET, flags); |
336 | if (err) |
337 | return err; |
338 | |
339 | if (listen(tcp->io_watcher.fd, backlog)) |
340 | return UV__ERR(errno); |
341 | |
342 | tcp->connection_cb = cb; |
343 | tcp->flags |= UV_HANDLE_BOUND; |
344 | |
345 | /* Start listening for connections. */ |
346 | tcp->io_watcher.cb = uv__server_io; |
347 | uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN); |
348 | |
349 | return 0; |
350 | } |
351 | |
352 | |
353 | int uv__tcp_nodelay(int fd, int on) { |
354 | if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on))) |
355 | return UV__ERR(errno); |
356 | return 0; |
357 | } |
358 | |
359 | |
360 | int uv__tcp_keepalive(int fd, int on, unsigned int delay) { |
361 | if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) |
362 | return UV__ERR(errno); |
363 | |
364 | #ifdef TCP_KEEPIDLE |
365 | if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) |
366 | return UV__ERR(errno); |
367 | #endif |
368 | |
369 | /* Solaris/SmartOS, if you don't support keep-alive, |
370 | * then don't advertise it in your system headers... |
371 | */ |
372 | /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */ |
373 | #if defined(TCP_KEEPALIVE) && !defined(__sun) |
374 | if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay))) |
375 | return UV__ERR(errno); |
376 | #endif |
377 | |
378 | return 0; |
379 | } |
380 | |
381 | |
382 | int uv_tcp_nodelay(uv_tcp_t* handle, int on) { |
383 | int err; |
384 | |
385 | if (uv__stream_fd(handle) != -1) { |
386 | err = uv__tcp_nodelay(uv__stream_fd(handle), on); |
387 | if (err) |
388 | return err; |
389 | } |
390 | |
391 | if (on) |
392 | handle->flags |= UV_HANDLE_TCP_NODELAY; |
393 | else |
394 | handle->flags &= ~UV_HANDLE_TCP_NODELAY; |
395 | |
396 | return 0; |
397 | } |
398 | |
399 | |
400 | int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) { |
401 | int err; |
402 | |
403 | if (uv__stream_fd(handle) != -1) { |
404 | err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay); |
405 | if (err) |
406 | return err; |
407 | } |
408 | |
409 | if (on) |
410 | handle->flags |= UV_HANDLE_TCP_KEEPALIVE; |
411 | else |
412 | handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; |
413 | |
414 | /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge |
415 | * uv_tcp_t with an int that's almost never used... |
416 | */ |
417 | |
418 | return 0; |
419 | } |
420 | |
421 | |
422 | int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { |
423 | if (enable) |
424 | handle->flags &= ~UV_HANDLE_TCP_SINGLE_ACCEPT; |
425 | else |
426 | handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; |
427 | return 0; |
428 | } |
429 | |
430 | |
431 | void uv__tcp_close(uv_tcp_t* handle) { |
432 | uv__stream_close((uv_stream_t*)handle); |
433 | } |
434 | |