34
36
/* A zero-size buffer for use by uv_udp_read */
35
37
static char uv_zero_[] = "";
37
/* Counter to keep track of active udp streams */
38
static unsigned int active_udp_streams = 0;
41
39
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
43
41
uv_loop_t* loop = handle->loop;
61
static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
59
static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
64
62
WSAPROTOCOL_INFOW info;
67
65
assert(handle->socket == INVALID_SOCKET);
67
/* Set SO_REUSEADDR on the socket. */
68
if (setsockopt(socket,
72
sizeof yes) == SOCKET_ERROR) {
73
uv__set_sys_error(loop, WSAGetLastError());
69
77
/* Set the socket to nonblocking mode */
70
78
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
71
79
uv__set_sys_error(loop, WSAGetLastError());
121
129
handle->socket = socket;
131
if (family == AF_INET6) {
132
handle->flags |= UV_HANDLE_IPV6;
134
assert(!(handle->flags & UV_HANDLE_IPV6));
127
141
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
128
handle->type = UV_UDP;
142
uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
129
144
handle->socket = INVALID_SOCKET;
130
145
handle->reqs_pending = 0;
146
handle->activecnt = 0;
133
147
handle->func_wsarecv = WSARecv;
134
148
handle->func_wsarecvfrom = WSARecvFrom;
137
151
handle->recv_req.type = UV_UDP_RECV;
138
152
handle->recv_req.data = handle;
142
loop->counters.handle_init++;
143
loop->counters.udp_init++;
158
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
159
uv_udp_recv_stop(handle);
160
closesocket(handle->socket);
162
uv__handle_closing(handle);
164
if (handle->reqs_pending == 0) {
165
uv_want_endgame(loop, (uv_handle_t*) handle);
149
170
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
150
if (handle->flags & UV_HANDLE_CLOSING &&
171
if (handle->flags & UV__HANDLE_CLOSING &&
151
172
handle->reqs_pending == 0) {
152
173
assert(!(handle->flags & UV_HANDLE_CLOSED));
153
handle->flags |= UV_HANDLE_CLOSED;
155
if (handle->close_cb) {
156
handle->close_cb((uv_handle_t*)handle);
174
uv__handle_close(handle);
164
179
static int uv__bind(uv_udp_t* handle,
166
181
struct sockaddr* addr,
168
183
unsigned int flags) {
170
DWORD no = 0, yes = 1;
172
if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
187
if ((flags & UV_UDP_IPV6ONLY) && family != AF_INET6) {
173
188
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
174
189
uv__set_artificial_error(handle->loop, UV_EINVAL);
178
193
if (handle->socket == INVALID_SOCKET) {
179
SOCKET sock = socket(domain, SOCK_DGRAM, 0);
194
SOCKET sock = socket(family, SOCK_DGRAM, 0);
180
195
if (sock == INVALID_SOCKET) {
181
196
uv__set_sys_error(handle->loop, WSAGetLastError());
185
if (uv_udp_set_socket(handle->loop, handle, sock) == -1) {
200
if (uv_udp_set_socket(handle->loop, handle, sock, family) < 0) {
186
201
closesocket(sock);
205
if (family == AF_INET6)
206
handle->flags |= UV_HANDLE_IPV6;
191
if (domain == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
209
if (family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
192
210
/* On windows IPV6ONLY is on by default. */
193
211
/* If the user doesn't specify it libuv turns it off. */
205
r = setsockopt(handle->socket,
210
if (r == SOCKET_ERROR) {
211
uv__set_sys_error(handle->loop, WSAGetLastError());
215
223
r = bind(handle->socket, addr, addrsize);
216
224
if (r == SOCKET_ERROR) {
217
225
uv__set_sys_error(handle->loop, WSAGetLastError());
237
245
int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
238
246
unsigned int flags) {
240
handle->flags |= UV_HANDLE_IPV6;
241
return uv__bind(handle,
243
(struct sockaddr*) &addr,
244
sizeof(struct sockaddr_in6),
247
uv__set_sys_error(handle->loop, WSAEAFNOSUPPORT);
247
return uv__bind(handle,
249
(struct sockaddr*) &addr,
250
sizeof(struct sockaddr_in6),
266
268
* Preallocate a read buffer if the number of active streams is below
269
if (active_udp_streams < uv_active_udp_streams_threshold) {
271
if (loop->active_udp_streams < uv_active_udp_streams_threshold) {
270
272
handle->flags &= ~UV_HANDLE_ZERO_READ;
272
274
handle->recv_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536);
342
int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
344
int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
343
345
uv_udp_recv_cb recv_cb) {
344
346
uv_loop_t* loop = handle->loop;
356
358
handle->flags |= UV_HANDLE_READING;
357
active_udp_streams++;
359
INCREASE_ACTIVE_COUNT(loop, handle);
360
loop->active_udp_streams++;
359
362
handle->recv_cb = recv_cb;
360
363
handle->alloc_cb = alloc_cb;
371
int uv_udp_recv_stop(uv_udp_t* handle) {
374
int uv__udp_recv_stop(uv_udp_t* handle) {
372
375
if (handle->flags & UV_HANDLE_READING) {
373
376
handle->flags &= ~UV_HANDLE_READING;
374
active_udp_streams--;
377
handle->loop->active_udp_streams--;
378
DECREASE_ACTIVE_COUNT(loop, handle);
381
static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
385
static int uv__send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
382
386
int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) {
383
387
uv_loop_t* loop = handle->loop;
384
388
DWORD result, bytes;
403
407
/* Request completed immediately. */
404
408
req->queued_bytes = 0;
405
409
handle->reqs_pending++;
410
REGISTER_HANDLE_REQ(loop, handle, req);
407
411
uv_insert_pending_req(loop, (uv_req_t*)req);
408
412
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
409
413
/* Request queued by the kernel. */
410
414
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
411
415
handle->reqs_pending++;
416
REGISTER_HANDLE_REQ(loop, handle, req);
414
418
/* Send failed due to an error. */
415
419
uv__set_sys_error(loop, WSAGetLastError());
423
int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
427
int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
424
428
int bufcnt, struct sockaddr_in addr, uv_udp_send_cb cb) {
426
430
if (!(handle->flags & UV_HANDLE_BOUND) &&
431
return uv__udp_send(req,
435
(struct sockaddr*) &addr,
439
(struct sockaddr*) &addr,
441
int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
445
int uv__udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
442
446
int bufcnt, struct sockaddr_in6 addr, uv_udp_send_cb cb) {
444
448
if (!(handle->flags & UV_HANDLE_BOUND) &&
613
618
optname = IP_DROP_MEMBERSHIP;
616
uv__set_artificial_error(handle->loop, UV_EFAULT);
621
return uv__set_artificial_error(handle->loop, UV_EINVAL);
620
624
if (setsockopt(handle->socket,
654
#define SOCKOPT_SETTER(name, option4, option6) \
658
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
659
WSAPROTOCOL_INFOW protocol_info;
662
/* Detect the address family of the socket. */
663
opt_len = (int) sizeof protocol_info;
667
(char*) &protocol_info,
668
&opt_len) == SOCKET_ERROR) {
669
uv__set_sys_error(handle->loop, GetLastError());
673
if (uv_udp_set_socket(handle->loop,
676
protocol_info.iAddressFamily) < 0) {
684
#define SOCKOPT_SETTER(name, option4, option6, validate) \
655
685
int uv_udp_set_##name(uv_udp_t* handle, int value) { \
656
686
DWORD optval = (DWORD) value; \
688
if (!(validate(value))) { \
689
uv__set_artificial_error(handle->loop, UV_EINVAL); \
658
693
/* If the socket is unbound, bind to inaddr_any. */ \
659
694
if (!(handle->flags & UV_HANDLE_BOUND) && \
660
695
uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) { \
688
SOCKOPT_SETTER(multicast_loop, IP_MULTICAST_LOOP, IPV6_MULTICAST_LOOP)
689
SOCKOPT_SETTER(multicast_ttl, IP_MULTICAST_TTL, IPV6_MULTICAST_HOPS)
690
SOCKOPT_SETTER(ttl, IP_TTL, IPV6_HOPLIMIT)
723
#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255)
724
#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255)
725
#define VALIDATE_MULTICAST_LOOP(value) (1)
731
SOCKOPT_SETTER(multicast_ttl,
734
VALIDATE_MULTICAST_TTL)
735
SOCKOPT_SETTER(multicast_loop,
738
VALIDATE_MULTICAST_LOOP)
692
740
#undef SOCKOPT_SETTER
742
#undef VALIDATE_MULTICAST_TTL
743
#undef VALIDATE_MULTICAST_LOOP