annotate third_party/libuv/src/unix/udp.c @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents 948de3f54cea
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
160
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
2 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
4 * of this software and associated documentation files (the "Software"), to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
5 * deal in the Software without restriction, including without limitation the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
7 * sell copies of the Software, and to permit persons to whom the Software is
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
8 * furnished to do so, subject to the following conditions:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
9 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
10 * The above copyright notice and this permission notice shall be included in
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
11 * all copies or substantial portions of the Software.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
12 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
19 * IN THE SOFTWARE.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
20 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
21
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
22 #include "uv.h"
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
23 #include "internal.h"
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
24
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
25 #include <assert.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
26 #include <string.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
27 #include <errno.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
28 #include <stdlib.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
29 #include <unistd.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
30 #if defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
31 #include <xti.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
32 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
33 #include <sys/un.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
34
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
35 #if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
36 # define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
37 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
38
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
39 #if defined(IPV6_LEAVE_GROUP) && !defined(IPV6_DROP_MEMBERSHIP)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
40 # define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
41 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
42
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
43 static void uv__udp_run_completed(uv_udp_t* handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
44 static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
45 static void uv__udp_recvmsg(uv_udp_t* handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
46 static void uv__udp_sendmsg(uv_udp_t* handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
47 static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
48 int domain,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
49 unsigned int flags);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
50 static int uv__udp_sendmsg1(int fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
51 const uv_buf_t* bufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
52 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
53 const struct sockaddr* addr);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
54
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
55
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
56 void uv__udp_close(uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
57 uv__io_close(handle->loop, &handle->io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
58 uv__handle_stop(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
59
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
60 if (handle->io_watcher.fd != -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
61 uv__close(handle->io_watcher.fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
62 handle->io_watcher.fd = -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
63 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
64 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
65
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
66
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
67 void uv__udp_finish_close(uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
68 uv_udp_send_t* req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
69 struct uv__queue* q;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
70
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
71 assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
72 assert(handle->io_watcher.fd == -1);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
73
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
74 while (!uv__queue_empty(&handle->write_queue)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
75 q = uv__queue_head(&handle->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
76 uv__queue_remove(q);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
77
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
78 req = uv__queue_data(q, uv_udp_send_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
79 req->status = UV_ECANCELED;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
80 uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
81 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
82
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
83 uv__udp_run_completed(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
84
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
85 assert(handle->send_queue_size == 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
86 assert(handle->send_queue_count == 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
87
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
88 /* Now tear down the handle. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
89 handle->recv_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
90 handle->alloc_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
91 /* but _do not_ touch close_cb */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
92 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
93
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
94
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
95 static void uv__udp_run_completed(uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
96 uv_udp_send_t* req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
97 struct uv__queue* q;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
98
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
99 assert(!(handle->flags & UV_HANDLE_UDP_PROCESSING));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
100 handle->flags |= UV_HANDLE_UDP_PROCESSING;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
101
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
102 while (!uv__queue_empty(&handle->write_completed_queue)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
103 q = uv__queue_head(&handle->write_completed_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
104 uv__queue_remove(q);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
105
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
106 req = uv__queue_data(q, uv_udp_send_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
107 uv__req_unregister(handle->loop);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
108
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
109 handle->send_queue_size -= uv__count_bufs(req->bufs, req->nbufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
110 handle->send_queue_count--;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
111
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
112 if (req->bufs != req->bufsml)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
113 uv__free(req->bufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
114 req->bufs = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
115
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
116 if (req->send_cb == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
117 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
118
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
119 /* req->status >= 0 == bytes written
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
120 * req->status < 0 == errno
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
121 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
122 if (req->status >= 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
123 req->send_cb(req, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
124 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
125 req->send_cb(req, req->status);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
126 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
127
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
128 if (uv__queue_empty(&handle->write_queue)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
129 /* Pending queue and completion queue empty, stop watcher. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
130 uv__io_stop(handle->loop, &handle->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
131 if (!uv__io_active(&handle->io_watcher, POLLIN))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
132 uv__handle_stop(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
133 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
134
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
135 handle->flags &= ~UV_HANDLE_UDP_PROCESSING;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
136 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
137
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
138
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
139 static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
140 uv_udp_t* handle;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
141
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
142 handle = container_of(w, uv_udp_t, io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
143 assert(handle->type == UV_UDP);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
144
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
145 if (revents & POLLIN)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
146 uv__udp_recvmsg(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
147
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
148 if (revents & POLLOUT && !uv__is_closing(handle)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
149 uv__udp_sendmsg(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
150 uv__udp_run_completed(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
151 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
152 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
153
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
154 static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
155 #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
156 struct sockaddr_in6 peers[20];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
157 struct iovec iov[ARRAY_SIZE(peers)];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
158 struct mmsghdr msgs[ARRAY_SIZE(peers)];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
159 ssize_t nread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
160 uv_buf_t chunk_buf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
161 size_t chunks;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
162 int flags;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
163 size_t k;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
164
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
165 /* prepare structures for recvmmsg */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
166 chunks = buf->len / UV__UDP_DGRAM_MAXSIZE;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
167 if (chunks > ARRAY_SIZE(iov))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
168 chunks = ARRAY_SIZE(iov);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
169 for (k = 0; k < chunks; ++k) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
170 iov[k].iov_base = buf->base + k * UV__UDP_DGRAM_MAXSIZE;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
171 iov[k].iov_len = UV__UDP_DGRAM_MAXSIZE;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
172 memset(&msgs[k].msg_hdr, 0, sizeof(msgs[k].msg_hdr));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
173 msgs[k].msg_hdr.msg_iov = iov + k;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
174 msgs[k].msg_hdr.msg_iovlen = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
175 msgs[k].msg_hdr.msg_name = peers + k;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
176 msgs[k].msg_hdr.msg_namelen = sizeof(peers[0]);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
177 msgs[k].msg_hdr.msg_control = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
178 msgs[k].msg_hdr.msg_controllen = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
179 msgs[k].msg_hdr.msg_flags = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
180 msgs[k].msg_len = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
181 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
182
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
183 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
184 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
185 nread = recvmsg_x(handle->io_watcher.fd, msgs, chunks, MSG_DONTWAIT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
186 while (nread == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
187 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
188 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
189 nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
190 while (nread == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
191 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
192
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
193 if (nread < 1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
194 if (nread == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
195 handle->recv_cb(handle, 0, buf, NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
196 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
197 handle->recv_cb(handle, UV__ERR(errno), buf, NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
198 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
199 /* pass each chunk to the application */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
200 for (k = 0; k < (size_t) nread && handle->recv_cb != NULL; k++) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
201 flags = UV_UDP_MMSG_CHUNK;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
202 if (msgs[k].msg_hdr.msg_flags & MSG_TRUNC)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
203 flags |= UV_UDP_PARTIAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
204
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
205 chunk_buf = uv_buf_init(iov[k].iov_base, iov[k].iov_len);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
206 handle->recv_cb(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
207 msgs[k].msg_len,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
208 &chunk_buf,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
209 msgs[k].msg_hdr.msg_name,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
210 flags);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
211 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
212
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
213 /* one last callback so the original buffer is freed */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
214 if (handle->recv_cb != NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
215 handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
216 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
217 return nread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
218 #else /* __linux__ || ____FreeBSD__ || __APPLE__ */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
219 return UV_ENOSYS;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
220 #endif /* __linux__ || ____FreeBSD__ || __APPLE__ */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
221 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
222
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
223 static void uv__udp_recvmsg(uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
224 struct sockaddr_storage peer;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
225 struct msghdr h;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
226 ssize_t nread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
227 uv_buf_t buf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
228 int flags;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
229 int count;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
230
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
231 assert(handle->recv_cb != NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
232 assert(handle->alloc_cb != NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
233
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
234 /* Prevent loop starvation when the data comes in as fast as (or faster than)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
235 * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
236 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
237 count = 32;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
238
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
239 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
240 buf = uv_buf_init(NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
241 handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
242 if (buf.base == NULL || buf.len == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
243 handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
244 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
245 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
246 assert(buf.base != NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
247
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
248 if (uv_udp_using_recvmmsg(handle)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
249 nread = uv__udp_recvmmsg(handle, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
250 if (nread > 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
251 count -= nread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
252 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
253 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
254
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
255 memset(&h, 0, sizeof(h));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
256 memset(&peer, 0, sizeof(peer));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
257 h.msg_name = &peer;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
258 h.msg_namelen = sizeof(peer);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
259 h.msg_iov = (void*) &buf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
260 h.msg_iovlen = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
261
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
262 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
263 nread = recvmsg(handle->io_watcher.fd, &h, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
264 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
265 while (nread == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
266
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
267 if (nread == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
268 if (errno == EAGAIN || errno == EWOULDBLOCK)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
269 handle->recv_cb(handle, 0, &buf, NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
270 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
271 handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
272 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
273 else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
274 flags = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
275 if (h.msg_flags & MSG_TRUNC)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
276 flags |= UV_UDP_PARTIAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
277
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
278 handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
279 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
280 count--;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
281 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
282 /* recv_cb callback may decide to pause or close the handle */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
283 while (nread != -1
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
284 && count > 0
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
285 && handle->io_watcher.fd != -1
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
286 && handle->recv_cb != NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
287 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
288
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
289
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
290 /* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
291 * refinements for programs that use multicast. Therefore we preferentially
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
292 * set SO_REUSEPORT over SO_REUSEADDR here, but we set SO_REUSEPORT only
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
293 * when that socket option doesn't have the capability of load balancing.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
294 * Otherwise, we fall back to SO_REUSEADDR.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
295 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
296 * Linux as of 3.9, DragonflyBSD 3.6, AIX 7.2.5 have the SO_REUSEPORT socket
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
297 * option but with semantics that are different from the BSDs: it _shares_
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
298 * the port rather than steals it from the current listener. While useful,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
299 * it's not something we can emulate on other platforms so we don't enable it.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
300 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
301 * zOS does not support getsockname with SO_REUSEPORT option when using
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
302 * AF_UNIX.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
303 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
304 * Solaris 11.4: SO_REUSEPORT will not load balance when SO_REUSEADDR
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
305 * is also set, but it's not valid for every socket type.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
306 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
307 static int uv__sock_reuseaddr(int fd) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
308 int yes;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
309 yes = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
310
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
311 #if defined(SO_REUSEPORT) && defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
312 struct sockaddr_in sockfd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
313 unsigned int sockfd_len = sizeof(sockfd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
314 if (getsockname(fd, (struct sockaddr*) &sockfd, &sockfd_len) == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
315 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
316 if (sockfd.sin_family == AF_UNIX) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
317 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
318 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
319 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
320 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
321 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
322 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
323 #elif defined(SO_REUSEPORT) && defined(UV__SOLARIS_11_4) && UV__SOLARIS_11_4
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
324 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
325 if (errno != ENOPROTOOPT)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
326 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
327 /* Not all socket types accept SO_REUSEPORT. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
328 errno = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
329 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
330 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
331 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
332 #elif defined(SO_REUSEPORT) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
333 !defined(__linux__) && !defined(__GNU__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
334 !defined(__illumos__) && !defined(__DragonFly__) && !defined(_AIX73)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
335 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
336 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
337 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
338 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
339 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
340 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
341
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
342 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
343 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
344
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
345 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
346 * The Linux kernel suppresses some ICMP error messages by default for UDP
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
347 * sockets. Setting IP_RECVERR/IPV6_RECVERR on the socket enables full ICMP
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
348 * error reporting, hopefully resulting in faster failover to working name
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
349 * servers.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
350 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
351 static int uv__set_recverr(int fd, sa_family_t ss_family) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
352 #if defined(__linux__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
353 int yes;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
354
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
355 yes = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
356 if (ss_family == AF_INET) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
357 if (setsockopt(fd, IPPROTO_IP, IP_RECVERR, &yes, sizeof(yes)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
358 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
359 } else if (ss_family == AF_INET6) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
360 if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVERR, &yes, sizeof(yes)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
361 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
362 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
363 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
364 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
365 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
366
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
367
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
368 int uv__udp_bind(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
369 const struct sockaddr* addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
370 unsigned int addrlen,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
371 unsigned int flags) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
372 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
373 int yes;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
374 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
375
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
376 /* Check for bad flags. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
377 if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR |
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
378 UV_UDP_REUSEPORT | UV_UDP_LINUX_RECVERR))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
379 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
380
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
381 /* Cannot set IPv6-only mode on non-IPv6 socket. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
382 if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
383 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
384
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
385 fd = handle->io_watcher.fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
386 if (fd == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
387 err = uv__socket(addr->sa_family, SOCK_DGRAM, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
388 if (err < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
389 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
390 fd = err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
391 handle->io_watcher.fd = fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
392 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
393
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
394 if (flags & UV_UDP_LINUX_RECVERR) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
395 err = uv__set_recverr(fd, addr->sa_family);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
396 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
397 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
398 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
399
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
400 if (flags & UV_UDP_REUSEADDR) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
401 err = uv__sock_reuseaddr(fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
402 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
403 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
404 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
405
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
406 if (flags & UV_UDP_REUSEPORT) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
407 err = uv__sock_reuseport(fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
408 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
409 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
410 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
411
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
412 if (flags & UV_UDP_IPV6ONLY) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
413 #ifdef IPV6_V6ONLY
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
414 yes = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
415 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
416 err = UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
417 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
418 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
419 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
420 err = UV_ENOTSUP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
421 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
422 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
423 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
424
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
425 if (bind(fd, addr, addrlen)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
426 err = UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
427 if (errno == EAFNOSUPPORT)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
428 /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
429 * socket created with AF_INET to an AF_INET6 address or vice versa. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
430 err = UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
431 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
432 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
433
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
434 if (addr->sa_family == AF_INET6)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
435 handle->flags |= UV_HANDLE_IPV6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
436
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
437 handle->flags |= UV_HANDLE_BOUND;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
438 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
439 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
440
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
441
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
442 static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
443 int domain,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
444 unsigned int flags) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
445 union uv__sockaddr taddr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
446 socklen_t addrlen;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
447
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
448 if (handle->io_watcher.fd != -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
449 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
450
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
451 switch (domain) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
452 case AF_INET:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
453 {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
454 struct sockaddr_in* addr = &taddr.in;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
455 memset(addr, 0, sizeof *addr);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
456 addr->sin_family = AF_INET;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
457 addr->sin_addr.s_addr = INADDR_ANY;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
458 addrlen = sizeof *addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
459 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
460 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
461 case AF_INET6:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
462 {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
463 struct sockaddr_in6* addr = &taddr.in6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
464 memset(addr, 0, sizeof *addr);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
465 addr->sin6_family = AF_INET6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
466 addr->sin6_addr = in6addr_any;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
467 addrlen = sizeof *addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
468 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
469 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
470 default:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
471 assert(0 && "unsupported address family");
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
472 abort();
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
473 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
474
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
475 return uv__udp_bind(handle, &taddr.addr, addrlen, flags);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
476 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
477
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
478
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
479 int uv__udp_connect(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
480 const struct sockaddr* addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
481 unsigned int addrlen) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
482 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
483
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
484 err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
485 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
486 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
487
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
488 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
489 errno = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
490 err = connect(handle->io_watcher.fd, addr, addrlen);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
491 } while (err == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
492
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
493 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
494 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
495
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
496 handle->flags |= UV_HANDLE_UDP_CONNECTED;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
497
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
498 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
499 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
500
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
501 /* From https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
502 * Any of uv supported UNIXs kernel should be standardized, but the kernel
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
503 * implementation logic not same, let's use pseudocode to explain the udp
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
504 * disconnect behaviors:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
505 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
506 * Predefined stubs for pseudocode:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
507 * 1. sodisconnect: The function to perform the real udp disconnect
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
508 * 2. pru_connect: The function to perform the real udp connect
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
509 * 3. so: The kernel object match with socket fd
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
510 * 4. addr: The sockaddr parameter from user space
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
511 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
512 * BSDs:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
513 * if(sodisconnect(so) == 0) { // udp disconnect succeed
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
514 * if (addr->sa_len != so->addr->sa_len) return EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
515 * if (addr->sa_family != so->addr->sa_family) return EAFNOSUPPORT;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
516 * pru_connect(so);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
517 * }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
518 * else return EISCONN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
519 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
520 * z/OS (same with Windows):
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
521 * if(addr->sa_len < so->addr->sa_len) return EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
522 * if (addr->sa_family == AF_UNSPEC) sodisconnect(so);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
523 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
524 * AIX:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
525 * if(addr->sa_len != sizeof(struct sockaddr)) return EINVAL; // ignore ip proto version
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
526 * if (addr->sa_family == AF_UNSPEC) sodisconnect(so);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
527 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
528 * Linux,Others:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
529 * if(addr->sa_len < sizeof(struct sockaddr)) return EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
530 * if (addr->sa_family == AF_UNSPEC) sodisconnect(so);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
531 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
532 int uv__udp_disconnect(uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
533 int r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
534 #if defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
535 struct sockaddr_storage addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
536 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
537 struct sockaddr addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
538 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
539
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
540 memset(&addr, 0, sizeof(addr));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
541
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
542 #if defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
543 addr.ss_family = AF_UNSPEC;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
544 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
545 addr.sa_family = AF_UNSPEC;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
546 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
547
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
548 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
549 errno = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
550 #ifdef __PASE__
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
551 /* On IBMi a connectionless transport socket can be disconnected by
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
552 * either setting the addr parameter to NULL or setting the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
553 * addr_length parameter to zero, and issuing another connect().
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
554 * https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/apis/connec.htm
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
555 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
556 r = connect(handle->io_watcher.fd, (struct sockaddr*) NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
557 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
558 r = connect(handle->io_watcher.fd, (struct sockaddr*) &addr, sizeof(addr));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
559 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
560 } while (r == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
561
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
562 if (r == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
563 #if defined(BSD) /* The macro BSD is from sys/param.h */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
564 if (errno != EAFNOSUPPORT && errno != EINVAL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
565 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
566 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
567 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
568 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
569 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
570
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
571 handle->flags &= ~UV_HANDLE_UDP_CONNECTED;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
572 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
573 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
574
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
575 int uv__udp_send(uv_udp_send_t* req,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
576 uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
577 const uv_buf_t bufs[],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
578 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
579 const struct sockaddr* addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
580 unsigned int addrlen,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
581 uv_udp_send_cb send_cb) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
582 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
583 int empty_queue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
584
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
585 assert(nbufs > 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
586
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
587 if (addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
588 err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
589 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
590 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
591 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
592
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
593 /* It's legal for send_queue_count > 0 even when the write_queue is empty;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
594 * it means there are error-state requests in the write_completed_queue that
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
595 * will touch up send_queue_size/count later.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
596 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
597 empty_queue = (handle->send_queue_count == 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
598
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
599 uv__req_init(handle->loop, req, UV_UDP_SEND);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
600 assert(addrlen <= sizeof(req->u.storage));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
601 if (addr == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
602 req->u.storage.ss_family = AF_UNSPEC;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
603 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
604 memcpy(&req->u.storage, addr, addrlen);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
605 req->send_cb = send_cb;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
606 req->handle = handle;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
607 req->nbufs = nbufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
608
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
609 req->bufs = req->bufsml;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
610 if (nbufs > ARRAY_SIZE(req->bufsml))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
611 req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
612
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
613 if (req->bufs == NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
614 uv__req_unregister(handle->loop);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
615 return UV_ENOMEM;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
616 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
617
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
618 memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
619 handle->send_queue_size += uv__count_bufs(req->bufs, req->nbufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
620 handle->send_queue_count++;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
621 uv__queue_insert_tail(&handle->write_queue, &req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
622 uv__handle_start(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
623
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
624 if (empty_queue && !(handle->flags & UV_HANDLE_UDP_PROCESSING)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
625 uv__udp_sendmsg(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
626
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
627 /* `uv__udp_sendmsg` may not be able to do non-blocking write straight
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
628 * away. In such cases the `io_watcher` has to be queued for asynchronous
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
629 * write.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
630 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
631 if (!uv__queue_empty(&handle->write_queue))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
632 uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
633 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
634 uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
635 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
636
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
637 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
638 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
639
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
640
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
641 int uv__udp_try_send(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
642 const uv_buf_t bufs[],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
643 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
644 const struct sockaddr* addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
645 unsigned int addrlen) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
646 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
647
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
648 if (nbufs < 1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
649 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
650
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
651 /* already sending a message */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
652 if (handle->send_queue_count != 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
653 return UV_EAGAIN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
654
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
655 if (addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
656 err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
657 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
658 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
659 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
660 assert(handle->flags & UV_HANDLE_UDP_CONNECTED);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
661 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
662
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
663 err = uv__udp_sendmsg1(handle->io_watcher.fd, bufs, nbufs, addr);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
664 if (err > 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
665 return uv__count_bufs(bufs, nbufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
666
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
667 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
668 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
669
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
670
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
671 static int uv__udp_set_membership4(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
672 const struct sockaddr_in* multicast_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
673 const char* interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
674 uv_membership membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
675 struct ip_mreq mreq;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
676 int optname;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
677 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
678
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
679 memset(&mreq, 0, sizeof mreq);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
680
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
681 if (interface_addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
682 err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
683 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
684 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
685 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
686 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
687 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
688
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
689 mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
690
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
691 switch (membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
692 case UV_JOIN_GROUP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
693 optname = IP_ADD_MEMBERSHIP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
694 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
695 case UV_LEAVE_GROUP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
696 optname = IP_DROP_MEMBERSHIP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
697 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
698 default:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
699 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
700 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
701
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
702 if (setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
703 IPPROTO_IP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
704 optname,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
705 &mreq,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
706 sizeof(mreq))) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
707 #if defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
708 if (errno == ENXIO)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
709 return UV_ENODEV;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
710 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
711 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
712 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
713
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
714 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
715 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
716
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
717
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
718 static int uv__udp_set_membership6(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
719 const struct sockaddr_in6* multicast_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
720 const char* interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
721 uv_membership membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
722 int optname;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
723 struct ipv6_mreq mreq;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
724 struct sockaddr_in6 addr6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
725
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
726 memset(&mreq, 0, sizeof mreq);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
727
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
728 if (interface_addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
729 if (uv_ip6_addr(interface_addr, 0, &addr6))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
730 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
731 mreq.ipv6mr_interface = addr6.sin6_scope_id;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
732 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
733 mreq.ipv6mr_interface = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
734 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
735
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
736 mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
737
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
738 switch (membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
739 case UV_JOIN_GROUP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
740 optname = IPV6_ADD_MEMBERSHIP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
741 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
742 case UV_LEAVE_GROUP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
743 optname = IPV6_DROP_MEMBERSHIP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
744 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
745 default:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
746 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
747 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
748
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
749 if (setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
750 IPPROTO_IPV6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
751 optname,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
752 &mreq,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
753 sizeof(mreq))) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
754 #if defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
755 if (errno == ENXIO)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
756 return UV_ENODEV;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
757 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
758 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
759 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
760
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
761 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
762 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
763
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
764
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
765 #if !defined(__OpenBSD__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
766 !defined(__NetBSD__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
767 !defined(__ANDROID__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
768 !defined(__DragonFly__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
769 !defined(__QNX__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
770 !defined(__GNU__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
771 static int uv__udp_set_source_membership4(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
772 const struct sockaddr_in* multicast_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
773 const char* interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
774 const struct sockaddr_in* source_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
775 uv_membership membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
776 struct ip_mreq_source mreq;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
777 int optname;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
778 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
779
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
780 err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
781 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
782 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
783
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
784 memset(&mreq, 0, sizeof(mreq));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
785
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
786 if (interface_addr != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
787 err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
788 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
789 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
790 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
791 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
792 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
793
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
794 mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
795 mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
796
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
797 if (membership == UV_JOIN_GROUP)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
798 optname = IP_ADD_SOURCE_MEMBERSHIP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
799 else if (membership == UV_LEAVE_GROUP)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
800 optname = IP_DROP_SOURCE_MEMBERSHIP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
801 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
802 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
803
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
804 if (setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
805 IPPROTO_IP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
806 optname,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
807 &mreq,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
808 sizeof(mreq))) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
809 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
810 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
811
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
812 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
813 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
814
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
815
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
816 static int uv__udp_set_source_membership6(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
817 const struct sockaddr_in6* multicast_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
818 const char* interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
819 const struct sockaddr_in6* source_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
820 uv_membership membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
821 struct group_source_req mreq;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
822 struct sockaddr_in6 addr6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
823 int optname;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
824 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
825
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
826 err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
827 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
828 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
829
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
830 memset(&mreq, 0, sizeof(mreq));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
831
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
832 if (interface_addr != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
833 err = uv_ip6_addr(interface_addr, 0, &addr6);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
834 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
835 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
836 mreq.gsr_interface = addr6.sin6_scope_id;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
837 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
838 mreq.gsr_interface = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
839 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
840
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
841 STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
842 STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
843 memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
844 memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
845
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
846 if (membership == UV_JOIN_GROUP)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
847 optname = MCAST_JOIN_SOURCE_GROUP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
848 else if (membership == UV_LEAVE_GROUP)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
849 optname = MCAST_LEAVE_SOURCE_GROUP;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
850 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
851 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
852
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
853 if (setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
854 IPPROTO_IPV6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
855 optname,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
856 &mreq,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
857 sizeof(mreq))) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
858 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
859 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
860
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
861 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
862 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
863 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
864
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
865
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
866 int uv__udp_init_ex(uv_loop_t* loop,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
867 uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
868 unsigned flags,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
869 int domain) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
870 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
871
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
872 fd = -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
873 if (domain != AF_UNSPEC) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
874 fd = uv__socket(domain, SOCK_DGRAM, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
875 if (fd < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
876 return fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
877 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
878
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
879 uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
880 handle->alloc_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
881 handle->recv_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
882 handle->send_queue_size = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
883 handle->send_queue_count = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
884 uv__io_init(&handle->io_watcher, uv__udp_io, fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
885 uv__queue_init(&handle->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
886 uv__queue_init(&handle->write_completed_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
887
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
888 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
889 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
890
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
891
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
892 int uv_udp_using_recvmmsg(const uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
893 #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
894 if (handle->flags & UV_HANDLE_UDP_RECVMMSG)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
895 return 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
896 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
897 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
898 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
899
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
900
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
901 int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
902 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
903
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
904 /* Check for already active socket. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
905 if (handle->io_watcher.fd != -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
906 return UV_EBUSY;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
907
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
908 if (uv__fd_exists(handle->loop, sock))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
909 return UV_EEXIST;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
910
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
911 err = uv__nonblock(sock, 1);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
912 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
913 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
914
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
915 err = uv__sock_reuseaddr(sock);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
916 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
917 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
918
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
919 handle->io_watcher.fd = sock;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
920 if (uv__udp_is_connected(handle))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
921 handle->flags |= UV_HANDLE_UDP_CONNECTED;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
922
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
923 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
924 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
925
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
926
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
927 int uv_udp_set_membership(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
928 const char* multicast_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
929 const char* interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
930 uv_membership membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
931 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
932 struct sockaddr_in addr4;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
933 struct sockaddr_in6 addr6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
934
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
935 if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
936 err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
937 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
938 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
939 return uv__udp_set_membership4(handle, &addr4, interface_addr, membership);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
940 } else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
941 err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
942 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
943 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
944 return uv__udp_set_membership6(handle, &addr6, interface_addr, membership);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
945 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
946 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
947 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
948 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
949
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
950
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
951 int uv_udp_set_source_membership(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
952 const char* multicast_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
953 const char* interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
954 const char* source_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
955 uv_membership membership) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
956 #if !defined(__OpenBSD__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
957 !defined(__NetBSD__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
958 !defined(__ANDROID__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
959 !defined(__DragonFly__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
960 !defined(__QNX__) && \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
961 !defined(__GNU__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
962 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
963 union uv__sockaddr mcast_addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
964 union uv__sockaddr src_addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
965
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
966 err = uv_ip4_addr(multicast_addr, 0, &mcast_addr.in);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
967 if (err) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
968 err = uv_ip6_addr(multicast_addr, 0, &mcast_addr.in6);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
969 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
970 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
971 err = uv_ip6_addr(source_addr, 0, &src_addr.in6);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
972 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
973 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
974 return uv__udp_set_source_membership6(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
975 &mcast_addr.in6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
976 interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
977 &src_addr.in6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
978 membership);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
979 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
980
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
981 err = uv_ip4_addr(source_addr, 0, &src_addr.in);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
982 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
983 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
984 return uv__udp_set_source_membership4(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
985 &mcast_addr.in,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
986 interface_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
987 &src_addr.in,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
988 membership);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
989 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
990 return UV_ENOSYS;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
991 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
992 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
993
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
994
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
995 static int uv__setsockopt(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
996 int option4,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
997 int option6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
998 const void* val,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
999 socklen_t size) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1000 int r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1001
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1002 if (handle->flags & UV_HANDLE_IPV6)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1003 r = setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1004 IPPROTO_IPV6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1005 option6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1006 val,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1007 size);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1008 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1009 r = setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1010 IPPROTO_IP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1011 option4,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1012 val,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1013 size);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1014 if (r)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1015 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1016
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1017 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1018 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1019
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1020 static int uv__setsockopt_maybe_char(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1021 int option4,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1022 int option6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1023 int val) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1024 #if defined(__sun) || defined(_AIX) || defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1025 char arg = val;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1026 #elif defined(__OpenBSD__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1027 unsigned char arg = val;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1028 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1029 int arg = val;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1030 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1031
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1032 if (val < 0 || val > 255)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1033 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1034
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1035 return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1036 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1037
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1038
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1039 int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1040 if (setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1041 SOL_SOCKET,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1042 SO_BROADCAST,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1043 &on,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1044 sizeof(on))) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1045 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1046 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1047
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1048 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1049 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1050
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1051
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1052 int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1053 if (ttl < 1 || ttl > 255)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1054 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1055
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1056 #if defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1057 if (!(handle->flags & UV_HANDLE_IPV6))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1058 return UV_ENOTSUP; /* zOS does not support setting ttl for IPv4 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1059 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1060
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1061 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1062 * On Solaris and derivatives such as SmartOS, the length of socket options
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1063 * is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1064 * so hardcode the size of these options on this platform,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1065 * and use the general uv__setsockopt_maybe_char call on other platforms.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1066 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1067 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1068 defined(__MVS__) || defined(__QNX__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1069
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1070 return uv__setsockopt(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1071 IP_TTL,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1072 IPV6_UNICAST_HOPS,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1073 &ttl,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1074 sizeof(ttl));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1075
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1076 #else /* !(defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1077 defined(__MVS__) || defined(__QNX__)) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1078
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1079 return uv__setsockopt_maybe_char(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1080 IP_TTL,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1081 IPV6_UNICAST_HOPS,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1082 ttl);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1083
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1084 #endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1085 defined(__MVS__) || defined(__QNX__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1086 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1087
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1088
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1089 int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1090 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1091 * On Solaris and derivatives such as SmartOS, the length of socket options
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1092 * is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1093 * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1094 * and use the general uv__setsockopt_maybe_char call otherwise.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1095 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1096 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1097 defined(__MVS__) || defined(__QNX__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1098 if (handle->flags & UV_HANDLE_IPV6)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1099 return uv__setsockopt(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1100 IP_MULTICAST_TTL,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1101 IPV6_MULTICAST_HOPS,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1102 &ttl,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1103 sizeof(ttl));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1104 #endif /* defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1105 defined(__MVS__) || defined(__QNX__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1106
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1107 return uv__setsockopt_maybe_char(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1108 IP_MULTICAST_TTL,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1109 IPV6_MULTICAST_HOPS,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1110 ttl);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1111 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1112
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1113
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1114 int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1115 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1116 * On Solaris and derivatives such as SmartOS, the length of socket options
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1117 * is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1118 * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1119 * and use the general uv__setsockopt_maybe_char call otherwise.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1120 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1121 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1122 defined(__MVS__) || defined(__QNX__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1123 if (handle->flags & UV_HANDLE_IPV6)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1124 return uv__setsockopt(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1125 IP_MULTICAST_LOOP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1126 IPV6_MULTICAST_LOOP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1127 &on,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1128 sizeof(on));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1129 #endif /* defined(__sun) || defined(_AIX) ||defined(__OpenBSD__) ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1130 defined(__MVS__) || defined(__QNX__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1131
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1132 return uv__setsockopt_maybe_char(handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1133 IP_MULTICAST_LOOP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1134 IPV6_MULTICAST_LOOP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1135 on);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1136 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1137
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1138 int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1139 struct sockaddr_storage addr_st;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1140 struct sockaddr_in* addr4;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1141 struct sockaddr_in6* addr6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1142
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1143 addr4 = (struct sockaddr_in*) &addr_st;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1144 addr6 = (struct sockaddr_in6*) &addr_st;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1145
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1146 if (!interface_addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1147 memset(&addr_st, 0, sizeof addr_st);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1148 if (handle->flags & UV_HANDLE_IPV6) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1149 addr_st.ss_family = AF_INET6;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1150 addr6->sin6_scope_id = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1151 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1152 addr_st.ss_family = AF_INET;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1153 addr4->sin_addr.s_addr = htonl(INADDR_ANY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1154 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1155 } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1156 /* nothing, address was parsed */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1157 } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1158 /* nothing, address was parsed */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1159 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1160 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1161 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1162
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1163 if (addr_st.ss_family == AF_INET) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1164 if (setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1165 IPPROTO_IP,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1166 IP_MULTICAST_IF,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1167 (void*) &addr4->sin_addr,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1168 sizeof(addr4->sin_addr)) == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1169 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1170 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1171 } else if (addr_st.ss_family == AF_INET6) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1172 if (setsockopt(handle->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1173 IPPROTO_IPV6,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1174 IPV6_MULTICAST_IF,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1175 &addr6->sin6_scope_id,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1176 sizeof(addr6->sin6_scope_id)) == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1177 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1178 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1179 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1180 assert(0 && "unexpected address family");
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1181 abort();
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1182 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1183
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1184 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1185 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1186
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1187 int uv_udp_getpeername(const uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1188 struct sockaddr* name,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1189 int* namelen) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1190
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1191 return uv__getsockpeername((const uv_handle_t*) handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1192 getpeername,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1193 name,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1194 namelen);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1195 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1196
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1197 int uv_udp_getsockname(const uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1198 struct sockaddr* name,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1199 int* namelen) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1200
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1201 return uv__getsockpeername((const uv_handle_t*) handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1202 getsockname,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1203 name,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1204 namelen);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1205 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1206
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1207
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1208 int uv__udp_recv_start(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1209 uv_alloc_cb alloc_cb,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1210 uv_udp_recv_cb recv_cb) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1211 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1212
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1213 if (alloc_cb == NULL || recv_cb == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1214 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1215
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1216 if (uv__io_active(&handle->io_watcher, POLLIN))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1217 return UV_EALREADY; /* FIXME(bnoordhuis) Should be UV_EBUSY. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1218
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1219 err = uv__udp_maybe_deferred_bind(handle, AF_INET, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1220 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1221 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1222
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1223 handle->alloc_cb = alloc_cb;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1224 handle->recv_cb = recv_cb;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1225
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1226 uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1227 uv__handle_start(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1228
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1229 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1230 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1231
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1232
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1233 int uv__udp_recv_stop(uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1234 uv__io_stop(handle->loop, &handle->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1235
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1236 if (!uv__io_active(&handle->io_watcher, POLLOUT))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1237 uv__handle_stop(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1238
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1239 handle->alloc_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1240 handle->recv_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1241
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1242 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1243 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1244
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1245
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1246 static int uv__udp_prep_pkt(struct msghdr* h,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1247 const uv_buf_t* bufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1248 const unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1249 const struct sockaddr* addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1250 memset(h, 0, sizeof(*h));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1251 h->msg_name = (void*) addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1252 h->msg_iov = (void*) bufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1253 h->msg_iovlen = nbufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1254 if (addr == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1255 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1256 switch (addr->sa_family) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1257 case AF_INET:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1258 h->msg_namelen = sizeof(struct sockaddr_in);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1259 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1260 case AF_INET6:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1261 h->msg_namelen = sizeof(struct sockaddr_in6);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1262 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1263 case AF_UNIX:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1264 h->msg_namelen = sizeof(struct sockaddr_un);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1265 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1266 case AF_UNSPEC:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1267 h->msg_name = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1268 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1269 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1270 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1271 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1272
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1273
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1274 static int uv__udp_sendmsg1(int fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1275 const uv_buf_t* bufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1276 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1277 const struct sockaddr* addr) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1278 struct msghdr h;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1279 int r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1280
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1281 if ((r = uv__udp_prep_pkt(&h, bufs, nbufs, addr)))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1282 return r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1283
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1284 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1285 r = sendmsg(fd, &h, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1286 while (r == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1287
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1288 if (r < 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1289 r = UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1290 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1291 r = UV_EAGAIN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1292 return r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1293 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1294
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1295 /* UDP sockets don't EOF so we don't have to handle r=0 specially,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1296 * that only happens when the input was a zero-sized buffer.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1297 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1298 return 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1299 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1300
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1301
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1302 static int uv__udp_sendmsgv(int fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1303 unsigned int count,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1304 uv_buf_t* bufs[/*count*/],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1305 unsigned int nbufs[/*count*/],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1306 struct sockaddr* addrs[/*count*/]) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1307 unsigned int i;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1308 int nsent;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1309 int r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1310
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1311 r = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1312 nsent = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1313
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1314 #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1315 (defined(__sun__) && defined(MSG_WAITFORONE))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1316 if (count > 1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1317 for (i = 0; i < count; /*empty*/) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1318 struct mmsghdr m[20];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1319 unsigned int n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1320
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1321 for (n = 0; i < count && n < ARRAY_SIZE(m); i++, n++)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1322 if ((r = uv__udp_prep_pkt(&m[n].msg_hdr, bufs[i], nbufs[i], addrs[i])))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1323 goto exit;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1324
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1325 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1326 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1327 r = sendmsg_x(fd, m, n, MSG_DONTWAIT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1328 #else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1329 r = sendmmsg(fd, m, n, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1330 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1331 while (r == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1332
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1333 if (r < 1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1334 goto exit;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1335
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1336 nsent += r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1337 i += r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1338 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1339
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1340 goto exit;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1341 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1342 #endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1343 * (defined(__sun__) && defined(MSG_WAITFORONE))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1344 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1345
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1346 for (i = 0; i < count; i++, nsent++)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1347 if ((r = uv__udp_sendmsg1(fd, bufs[i], nbufs[i], addrs[i])))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1348 goto exit; /* goto to avoid unused label warning. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1349
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1350 exit:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1351
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1352 if (nsent > 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1353 return nsent;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1354
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1355 if (r < 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1356 r = UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1357 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1358 r = UV_EAGAIN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1359 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1360
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1361 return r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1362 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1363
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1364
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1365 static void uv__udp_sendmsg(uv_udp_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1366 static const int N = 20;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1367 struct sockaddr* addrs[N];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1368 unsigned int nbufs[N];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1369 uv_buf_t* bufs[N];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1370 struct uv__queue* q;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1371 uv_udp_send_t* req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1372 int n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1373
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1374 if (uv__queue_empty(&handle->write_queue))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1375 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1376
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1377 again:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1378 n = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1379 q = uv__queue_head(&handle->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1380 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1381 req = uv__queue_data(q, uv_udp_send_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1382 addrs[n] = &req->u.addr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1383 nbufs[n] = req->nbufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1384 bufs[n] = req->bufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1385 q = uv__queue_next(q);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1386 n++;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1387 } while (n < N && q != &handle->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1388
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1389 n = uv__udp_sendmsgv(handle->io_watcher.fd, n, bufs, nbufs, addrs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1390 while (n > 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1391 q = uv__queue_head(&handle->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1392 req = uv__queue_data(q, uv_udp_send_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1393 req->status = uv__count_bufs(req->bufs, req->nbufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1394 uv__queue_remove(&req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1395 uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1396 n--;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1397 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1398
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1399 if (n == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1400 if (uv__queue_empty(&handle->write_queue))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1401 goto feed;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1402 goto again;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1403 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1404
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1405 if (n == UV_EAGAIN)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1406 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1407
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1408 /* Register the error against first request in queue because that
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1409 * is the request that uv__udp_sendmsgv tried but failed to send,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1410 * because if it did send any requests, it won't return an error.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1411 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1412 q = uv__queue_head(&handle->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1413 req = uv__queue_data(q, uv_udp_send_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1414 req->status = n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1415 uv__queue_remove(&req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1416 uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1417 feed:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1418 uv__io_feed(handle->loop, &handle->io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1419 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1420
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1421
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1422 int uv__udp_try_send2(uv_udp_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1423 unsigned int count,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1424 uv_buf_t* bufs[/*count*/],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1425 unsigned int nbufs[/*count*/],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1426 struct sockaddr* addrs[/*count*/]) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1427 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1428
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1429 fd = handle->io_watcher.fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1430 if (fd == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1431 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1432
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1433 return uv__udp_sendmsgv(fd, count, bufs, nbufs, addrs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1434 }