Rizin
unix-like reverse engineering framework and cli tools
udp.c File Reference
#include "uv.h"
#include "internal.h"
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>

Go to the source code of this file.

Classes

union  uv__sockaddr
 

Macros

#define UV__UDP_DGRAM_MAXSIZE   (64 * 1024)
 

Functions

static void uv__udp_run_completed (uv_udp_t *handle)
 
static void uv__udp_io (uv_loop_t *loop, uv__io_t *w, unsigned int revents)
 
static void uv__udp_recvmsg (uv_udp_t *handle)
 
static void uv__udp_sendmsg (uv_udp_t *handle)
 
static int uv__udp_maybe_deferred_bind (uv_udp_t *handle, int domain, unsigned int flags)
 
void uv__udp_close (uv_udp_t *handle)
 
void uv__udp_finish_close (uv_udp_t *handle)
 
static int uv__set_reuse (int fd)
 
int uv__udp_bind (uv_udp_t *handle, const struct sockaddr *addr, unsigned int addrlen, unsigned int flags)
 
int uv__udp_connect (uv_udp_t *handle, const struct sockaddr *addr, unsigned int addrlen)
 
int uv__udp_disconnect (uv_udp_t *handle)
 
int uv__udp_send (uv_udp_send_t *req, uv_udp_t *handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr *addr, unsigned int addrlen, uv_udp_send_cb send_cb)
 
int uv__udp_try_send (uv_udp_t *handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr *addr, unsigned int addrlen)
 
static int uv__udp_set_membership4 (uv_udp_t *handle, const struct sockaddr_in *multicast_addr, const char *interface_addr, uv_membership membership)
 
static int uv__udp_set_membership6 (uv_udp_t *handle, const struct sockaddr_in6 *multicast_addr, const char *interface_addr, uv_membership membership)
 
static int uv__udp_set_source_membership4 (uv_udp_t *handle, const struct sockaddr_in *multicast_addr, const char *interface_addr, const struct sockaddr_in *source_addr, uv_membership membership)
 
static int uv__udp_set_source_membership6 (uv_udp_t *handle, const struct sockaddr_in6 *multicast_addr, const char *interface_addr, const struct sockaddr_in6 *source_addr, uv_membership membership)
 
int uv__udp_init_ex (uv_loop_t *loop, uv_udp_t *handle, unsigned flags, int domain)
 
int uv_udp_using_recvmmsg (const uv_udp_t *handle)
 
int uv_udp_open (uv_udp_t *handle, uv_os_sock_t sock)
 
int uv_udp_set_membership (uv_udp_t *handle, const char *multicast_addr, const char *interface_addr, uv_membership membership)
 
int uv_udp_set_source_membership (uv_udp_t *handle, const char *multicast_addr, const char *interface_addr, const char *source_addr, uv_membership membership)
 
static int uv__setsockopt (uv_udp_t *handle, int option4, int option6, const void *val, socklen_t size)
 
static int uv__setsockopt_maybe_char (uv_udp_t *handle, int option4, int option6, int val)
 
int uv_udp_set_broadcast (uv_udp_t *handle, int on)
 
int uv_udp_set_ttl (uv_udp_t *handle, int ttl)
 
int uv_udp_set_multicast_ttl (uv_udp_t *handle, int ttl)
 
int uv_udp_set_multicast_loop (uv_udp_t *handle, int on)
 
int uv_udp_set_multicast_interface (uv_udp_t *handle, const char *interface_addr)
 
int uv_udp_getpeername (const uv_udp_t *handle, struct sockaddr *name, int *namelen)
 
int uv_udp_getsockname (const uv_udp_t *handle, struct sockaddr *name, int *namelen)
 
int uv__udp_recv_start (uv_udp_t *handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
 
int uv__udp_recv_stop (uv_udp_t *handle)
 

Macro Definition Documentation

◆ UV__UDP_DGRAM_MAXSIZE

#define UV__UDP_DGRAM_MAXSIZE   (64 * 1024)

Definition at line 35 of file udp.c.

Function Documentation

◆ uv__set_reuse()

static int uv__set_reuse ( int  fd)
static

Definition at line 480 of file udp.c.

480  {
481  int yes;
482  yes = 1;
483 
484 #if defined(SO_REUSEPORT) && defined(__MVS__)
485  struct sockaddr_in sockfd;
486  unsigned int sockfd_len = sizeof(sockfd);
487  if (getsockname(fd, (struct sockaddr*) &sockfd, &sockfd_len) == -1)
488  return UV__ERR(errno);
489  if (sockfd.sin_family == AF_UNIX) {
490  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
491  return UV__ERR(errno);
492  } else {
493  if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
494  return UV__ERR(errno);
495  }
496 #elif defined(SO_REUSEPORT) && !defined(__linux__)
497  if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
498  return UV__ERR(errno);
499 #else
500  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
501  return UV__ERR(errno);
502 #endif
503 
504  return 0;
505 }
#define UV__ERR(x)
Definition: errno.h:29
static sockfd
Definition: sfsocketcall.h:114
#define AF_UNIX
Definition: sftypes.h:285
#define SO_REUSEADDR
Definition: sftypes.h:430
#define SOL_SOCKET
Definition: sftypes.h:427
static const z80_opcode fd[]
Definition: z80_tab.h:997

References AF_UNIX, fd, SO_REUSEADDR, sockfd, SOL_SOCKET, and UV__ERR.

Referenced by uv__udp_bind(), and uv_udp_open().

◆ uv__setsockopt()

static int uv__setsockopt ( uv_udp_t handle,
int  option4,
int  option6,
const void *  val,
socklen_t  size 
)
static

Definition at line 1084 of file udp.c.

1088  {
1089  int r;
1090 
1091  if (handle->flags & UV_HANDLE_IPV6)
1092  r = setsockopt(handle->io_watcher.fd,
1093  IPPROTO_IPV6,
1094  option6,
1095  val,
1096  size);
1097  else
1098  r = setsockopt(handle->io_watcher.fd,
1099  IPPROTO_IP,
1100  option4,
1101  val,
1102  size);
1103  if (r)
1104  return UV__ERR(errno);
1105 
1106  return 0;
1107 }
ut16 val
Definition: armass64_const.h:6
static mcore_handle handle
Definition: asm_mcore.c:8
#define r
Definition: crypto_rc6.c:12
voidpf void uLong size
Definition: ioapi.h:138
@ UV_HANDLE_IPV6
Definition: uv-common.h:102

References handle, r, UV__ERR, UV_HANDLE_IPV6, and val.

Referenced by uv__setsockopt_maybe_char(), uv_udp_set_multicast_loop(), uv_udp_set_multicast_ttl(), and uv_udp_set_ttl().

◆ uv__setsockopt_maybe_char()

static int uv__setsockopt_maybe_char ( uv_udp_t handle,
int  option4,
int  option6,
int  val 
)
static

Definition at line 1109 of file udp.c.

1112  {
1113 #if defined(__sun) || defined(_AIX) || defined(__MVS__)
1114  char arg = val;
1115 #elif defined(__OpenBSD__)
1116  unsigned char arg = val;
1117 #else
1118  int arg = val;
1119 #endif
1120 
1121  if (val < 0 || val > 255)
1122  return UV_EINVAL;
1123 
1124  return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
1125 }
static int uv__setsockopt(uv_udp_t *handle, int option4, int option6, const void *val, socklen_t size)
Definition: udp.c:1084

References handle, uv__setsockopt(), and val.

Referenced by uv_udp_set_multicast_loop(), uv_udp_set_multicast_ttl(), and uv_udp_set_ttl().

◆ uv__udp_bind()

int uv__udp_bind ( uv_udp_t handle,
const struct sockaddr addr,
unsigned int  addrlen,
unsigned int  flags 
)

Definition at line 508 of file udp.c.

511  {
512  int err;
513  int yes;
514  int fd;
515 
516  /* Check for bad flags. */
518  return UV_EINVAL;
519 
520  /* Cannot set IPv6-only mode on non-IPv6 socket. */
521  if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6)
522  return UV_EINVAL;
523 
524  fd = handle->io_watcher.fd;
525  if (fd == -1) {
526  err = uv__socket(addr->sa_family, SOCK_DGRAM, 0);
527  if (err < 0)
528  return err;
529  fd = err;
530  handle->io_watcher.fd = fd;
531  }
532 
533  if (flags & UV_UDP_REUSEADDR) {
534  err = uv__set_reuse(fd);
535  if (err)
536  return err;
537  }
538 
539  if (flags & UV_UDP_IPV6ONLY) {
540 #ifdef IPV6_V6ONLY
541  yes = 1;
542  if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
543  err = UV__ERR(errno);
544  return err;
545  }
546 #else
547  err = UV_ENOTSUP;
548  return err;
549 #endif
550  }
551 
552  if (bind(fd, addr, addrlen)) {
553  err = UV__ERR(errno);
554  if (errno == EAFNOSUPPORT)
555  /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
556  * socket created with AF_INET to an AF_INET6 address or vice versa. */
557  err = UV_EINVAL;
558  return err;
559  }
560 
561  if (addr->sa_family == AF_INET6)
562  handle->flags |= UV_HANDLE_IPV6;
563 
564  handle->flags |= UV_HANDLE_BOUND;
565  return 0;
566 }
static bool err
Definition: armass.c:435
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset void static length char static len const struct iovec static count unsigned long static filedes static sched_yield static flags static oldfd static pause unsigned static seconds static protocol struct sockaddr addrlen
Definition: sflib.h:75
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
static bind
Definition: sfsocketcall.h:114
#define EAFNOSUPPORT
Definition: sftypes.h:157
@ SOCK_DGRAM
Definition: sftypes.h:227
#define AF_INET6
Definition: sftypes.h:295
int uv__socket(int domain, int type, int protocol)
Definition: core.c:436
static int uv__set_reuse(int fd)
Definition: udp.c:480
@ UV_HANDLE_BOUND
Definition: uv-common.h:91
@ UV_UDP_IPV6ONLY
Definition: uv.h:597
@ UV_UDP_REUSEADDR
Definition: uv.h:611
#define IPV6_V6ONLY
Definition: winsock.h:46
static int addr
Definition: z80asm.c:58

References addr, addrlen, AF_INET6, bind, EAFNOSUPPORT, err, fd, flags, handle, IPV6_V6ONLY, SOCK_DGRAM, UV__ERR, uv__set_reuse(), uv__socket(), UV_HANDLE_BOUND, UV_HANDLE_IPV6, UV_UDP_IPV6ONLY, and UV_UDP_REUSEADDR.

Referenced by uv__udp_maybe_deferred_bind(), and uv_udp_bind().

◆ uv__udp_close()

void uv__udp_close ( uv_udp_t handle)

Definition at line 90 of file udp.c.

90  {
91  uv__io_close(handle->loop, &handle->io_watcher);
93 
94  if (handle->io_watcher.fd != -1) {
95  uv__close(handle->io_watcher.fd);
96  handle->io_watcher.fd = -1;
97  }
98 }
void uv__io_close(uv_loop_t *loop, uv__io_t *w)
Definition: core.c:942
int uv__close(int fd)
Definition: core.c:569
#define uv__handle_stop(h)
Definition: uv-common.h:266

References handle, uv__close(), uv__handle_stop, and uv__io_close().

Referenced by uv_close().

◆ uv__udp_connect()

int uv__udp_connect ( uv_udp_t handle,
const struct sockaddr addr,
unsigned int  addrlen 
)

Definition at line 606 of file udp.c.

608  {
609  int err;
610 
611  err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
612  if (err)
613  return err;
614 
615  do {
616  errno = 0;
617  err = connect(handle->io_watcher.fd, addr, addrlen);
618  } while (err == -1 && errno == EINTR);
619 
620  if (err)
621  return UV__ERR(errno);
622 
624 
625  return 0;
626 }
#define EINTR
Definition: sftypes.h:114
static int uv__udp_maybe_deferred_bind(uv_udp_t *handle, int domain, unsigned int flags)
Definition: udp.c:569
@ UV_HANDLE_UDP_CONNECTED
Definition: uv-common.h:114

References addr, addrlen, EINTR, err, handle, UV__ERR, uv__udp_maybe_deferred_bind(), and UV_HANDLE_UDP_CONNECTED.

Referenced by uv_udp_connect().

◆ uv__udp_disconnect()

int uv__udp_disconnect ( uv_udp_t handle)

Definition at line 629 of file udp.c.

629  {
630  int r;
631  struct sockaddr addr;
632 
633  memset(&addr, 0, sizeof(addr));
634 
635  addr.sa_family = AF_UNSPEC;
636 
637  do {
638  errno = 0;
639  r = connect(handle->io_watcher.fd, &addr, sizeof(addr));
640  } while (r == -1 && errno == EINTR);
641 
642  if (r == -1 && errno != EAFNOSUPPORT)
643  return UV__ERR(errno);
644 
645  handle->flags &= ~UV_HANDLE_UDP_CONNECTED;
646  return 0;
647 }
return memset(p, 0, total)
#define AF_UNSPEC
Definition: sftypes.h:283

References addr, AF_UNSPEC, EAFNOSUPPORT, EINTR, handle, memset(), r, UV__ERR, and UV_HANDLE_UDP_CONNECTED.

Referenced by uv_udp_connect().

◆ uv__udp_finish_close()

void uv__udp_finish_close ( uv_udp_t handle)

Definition at line 101 of file udp.c.

101  {
103  QUEUE* q;
104 
105  assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
106  assert(handle->io_watcher.fd == -1);
107 
108  while (!QUEUE_EMPTY(&handle->write_queue)) {
109  q = QUEUE_HEAD(&handle->write_queue);
110  QUEUE_REMOVE(q);
111 
113  req->status = UV_ECANCELED;
114  QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
115  }
116 
118 
119  assert(handle->send_queue_size == 0);
120  assert(handle->send_queue_count == 0);
121 
122  /* Now tear down the handle. */
123  handle->recv_cb = NULL;
124  handle->alloc_cb = NULL;
125  /* but _do not_ touch close_cb */
126 }
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
assert(limit<=UINT32_MAX/2)
#define QUEUE_DATA(ptr, type, field)
Definition: queue.h:30
#define QUEUE_EMPTY(q)
Definition: queue.h:39
#define QUEUE_HEAD(q)
Definition: queue.h:42
#define QUEUE_INSERT_TAIL(h, q)
Definition: queue.h:92
void * QUEUE[2]
Definition: queue.h:21
#define QUEUE_REMOVE(q)
Definition: queue.h:101
int uv__io_active(const uv__io_t *w, unsigned int events)
Definition: core.c:958
static void uv__udp_run_completed(uv_udp_t *handle)
Definition: udp.c:129
uv_pipe_t queue
Definition: worker.c:9

References assert(), handle, NULL, queue, QUEUE_DATA, QUEUE_EMPTY, QUEUE_HEAD, QUEUE_INSERT_TAIL, QUEUE_REMOVE, req, uv__io_active(), and uv__udp_run_completed().

Referenced by uv__finish_close().

◆ uv__udp_init_ex()

int uv__udp_init_ex ( uv_loop_t loop,
uv_udp_t handle,
unsigned  flags,
int  domain 
)

Definition at line 954 of file udp.c.

957  {
958  int fd;
959 
960  fd = -1;
961  if (domain != AF_UNSPEC) {
963  if (fd < 0)
964  return fd;
965  }
966 
968  handle->alloc_cb = NULL;
969  handle->recv_cb = NULL;
970  handle->send_queue_size = 0;
971  handle->send_queue_count = 0;
972  uv__io_init(&handle->io_watcher, uv__udp_io, fd);
973  QUEUE_INIT(&handle->write_queue);
974  QUEUE_INIT(&handle->write_completed_queue);
975 
976  return 0;
977 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd domain
Definition: sflib.h:79
#define QUEUE_INIT(q)
Definition: queue.h:45
uv_loop_t * loop
Definition: main.c:7
void uv__io_init(uv__io_t *w, uv__io_cb cb, int fd)
Definition: core.c:865
static void uv__udp_io(uv_loop_t *loop, uv__io_t *w, unsigned int revents)
Definition: udp.c:173
#define uv__handle_init(loop_, h, type_)
Definition: uv-common.h:301

References AF_UNSPEC, domain, fd, handle, loop, NULL, QUEUE_INIT, SOCK_DGRAM, uv__handle_init, uv__io_init(), uv__socket(), and uv__udp_io().

Referenced by uv_udp_init_ex().

◆ uv__udp_io()

static void uv__udp_io ( uv_loop_t loop,
uv__io_t w,
unsigned int  revents 
)
static

Definition at line 173 of file udp.c.

173  {
174  uv_udp_t* handle;
175 
176  handle = container_of(w, uv_udp_t, io_watcher);
177  assert(handle->type == UV_UDP);
178 
179  if (revents & POLLIN)
181 
182  if (revents & POLLOUT) {
185  }
186 }
#define w
Definition: crypto_rc6.c:13
#define container_of(ptr, type, member)
Definition: rz_types.h:650
Definition: uv.h:638
static void uv__udp_sendmsg(uv_udp_t *handle)
Definition: udp.c:406
static void uv__udp_recvmsg(uv_udp_t *handle)
Definition: udp.c:247

References assert(), container_of, handle, uv__udp_recvmsg(), uv__udp_run_completed(), uv__udp_sendmsg(), and w.

Referenced by uv__udp_init_ex().

◆ uv__udp_maybe_deferred_bind()

static int uv__udp_maybe_deferred_bind ( uv_udp_t handle,
int  domain,
unsigned int  flags 
)
static

Definition at line 569 of file udp.c.

571  {
572  union uv__sockaddr taddr;
574 
575  if (handle->io_watcher.fd != -1)
576  return 0;
577 
578  switch (domain) {
579  case AF_INET:
580  {
581  struct sockaddr_in* addr = &taddr.in;
582  memset(addr, 0, sizeof *addr);
583  addr->sin_family = AF_INET;
584  addr->sin_addr.s_addr = INADDR_ANY;
585  addrlen = sizeof *addr;
586  break;
587  }
588  case AF_INET6:
589  {
590  struct sockaddr_in6* addr = &taddr.in6;
591  memset(addr, 0, sizeof *addr);
592  addr->sin6_family = AF_INET6;
593  addr->sin6_addr = in6addr_any;
594  addrlen = sizeof *addr;
595  break;
596  }
597  default:
598  assert(0 && "unsupported address family");
599  abort();
600  }
601 
602  return uv__udp_bind(handle, &taddr.addr, addrlen, flags);
603 }
unsigned int socklen_t
Definition: sftypes.h:219
#define AF_INET
Definition: sftypes.h:287
static const struct in6_addr in6addr_any
Definition: sftypes.h:368
int uv__udp_bind(uv_udp_t *handle, const struct sockaddr *addr, unsigned int addrlen, unsigned int flags)
Definition: udp.c:508

References addr, uv__sockaddr::addr, addrlen, AF_INET, AF_INET6, assert(), domain, flags, handle, uv__sockaddr::in, uv__sockaddr::in6, in6addr_any, memset(), and uv__udp_bind().

Referenced by uv__udp_connect(), uv__udp_recv_start(), uv__udp_send(), uv__udp_set_source_membership4(), uv__udp_set_source_membership6(), uv__udp_try_send(), and uv_udp_set_membership().

◆ uv__udp_recv_start()

int uv__udp_recv_start ( uv_udp_t handle,
uv_alloc_cb  alloc_cb,
uv_udp_recv_cb  recv_cb 
)

Definition at line 1297 of file udp.c.

1299  {
1300  int err;
1301 
1302  if (alloc_cb == NULL || recv_cb == NULL)
1303  return UV_EINVAL;
1304 
1305  if (uv__io_active(&handle->io_watcher, POLLIN))
1306  return UV_EALREADY; /* FIXME(bnoordhuis) Should be UV_EBUSY. */
1307 
1309  if (err)
1310  return err;
1311 
1312  handle->alloc_cb = alloc_cb;
1313  handle->recv_cb = recv_cb;
1314 
1315  uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
1317 
1318  return 0;
1319 }
void uv__io_start(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:882
#define uv__handle_start(h)
Definition: uv-common.h:258

References AF_INET, err, handle, NULL, uv__handle_start, uv__io_active(), uv__io_start(), and uv__udp_maybe_deferred_bind().

Referenced by uv_udp_recv_start().

◆ uv__udp_recv_stop()

int uv__udp_recv_stop ( uv_udp_t handle)

Definition at line 1322 of file udp.c.

1322  {
1323  uv__io_stop(handle->loop, &handle->io_watcher, POLLIN);
1324 
1325  if (!uv__io_active(&handle->io_watcher, POLLOUT))
1327 
1328  handle->alloc_cb = NULL;
1329  handle->recv_cb = NULL;
1330 
1331  return 0;
1332 }
void uv__io_stop(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:910

Referenced by uv_udp_recv_stop().

◆ uv__udp_recvmsg()

static void uv__udp_recvmsg ( uv_udp_t handle)
static

Definition at line 247 of file udp.c.

247  {
248  struct sockaddr_storage peer;
249  struct msghdr h;
250  ssize_t nread;
251  uv_buf_t buf;
252  int flags;
253  int count;
254 
255  assert(handle->recv_cb != NULL);
256  assert(handle->alloc_cb != NULL);
257 
258  /* Prevent loop starvation when the data comes in as fast as (or faster than)
259  * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
260  */
261  count = 32;
262 
263  do {
264  buf = uv_buf_init(NULL, 0);
266  if (buf.base == NULL || buf.len == 0) {
267  handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
268  return;
269  }
270  assert(buf.base != NULL);
271 
272 #if HAVE_MMSG
274  nread = uv__udp_recvmmsg(handle, &buf);
275  if (nread > 0)
276  count -= nread;
277  continue;
278  }
279 #endif
280 
281  memset(&h, 0, sizeof(h));
282  memset(&peer, 0, sizeof(peer));
283  h.msg_name = &peer;
284  h.msg_namelen = sizeof(peer);
285  h.msg_iov = (void*) &buf;
286  h.msg_iovlen = 1;
287 
288  do {
289  nread = recvmsg(handle->io_watcher.fd, &h, 0);
290  }
291  while (nread == -1 && errno == EINTR);
292 
293  if (nread == -1) {
294  if (errno == EAGAIN || errno == EWOULDBLOCK)
295  handle->recv_cb(handle, 0, &buf, NULL, 0);
296  else
297  handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
298  }
299  else {
300  flags = 0;
301  if (h.msg_flags & MSG_TRUNC)
303 
304  handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags);
305  }
306  count--;
307  }
308  /* recv_cb callback may decide to pause or close the handle */
309  while (nread != -1
310  && count > 0
311  && handle->io_watcher.fd != -1
312  && handle->recv_cb != NULL);
313 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
voidpf void * buf
Definition: ioapi.h:138
#define EAGAIN
Definition: sftypes.h:121
int ssize_t
Definition: sftypes.h:39
#define h(i)
Definition: sha256.c:48
Definition: unix.h:123
#define UV__UDP_DGRAM_MAXSIZE
Definition: udp.c:35
int uv_udp_using_recvmmsg(const uv_udp_t *handle)
Definition: udp.c:980
@ UV_UDP_PARTIAL
Definition: uv.h:602
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157

References assert(), count, EAGAIN, EINTR, flags, h, handle, memset(), NULL, UV__ERR, UV__UDP_DGRAM_MAXSIZE, uv_buf_init(), UV_UDP_PARTIAL, and uv_udp_using_recvmmsg().

Referenced by uv__udp_io().

◆ uv__udp_run_completed()

static void uv__udp_run_completed ( uv_udp_t handle)
static

Definition at line 129 of file udp.c.

129  {
131  QUEUE* q;
132 
135 
136  while (!QUEUE_EMPTY(&handle->write_completed_queue)) {
137  q = QUEUE_HEAD(&handle->write_completed_queue);
138  QUEUE_REMOVE(q);
139 
141  uv__req_unregister(handle->loop, req);
142 
143  handle->send_queue_size -= uv__count_bufs(req->bufs, req->nbufs);
144  handle->send_queue_count--;
145 
146  if (req->bufs != req->bufsml)
147  uv__free(req->bufs);
148  req->bufs = NULL;
149 
150  if (req->send_cb == NULL)
151  continue;
152 
153  /* req->status >= 0 == bytes written
154  * req->status < 0 == errno
155  */
156  if (req->status >= 0)
157  req->send_cb(req, 0);
158  else
159  req->send_cb(req, req->status);
160  }
161 
162  if (QUEUE_EMPTY(&handle->write_queue)) {
163  /* Pending queue and completion queue empty, stop watcher. */
164  uv__io_stop(handle->loop, &handle->io_watcher, POLLOUT);
165  if (!uv__io_active(&handle->io_watcher, POLLIN))
167  }
168 
169  handle->flags &= ~UV_HANDLE_UDP_PROCESSING;
170 }
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs)
Definition: uv-common.c:573
void uv__free(void *ptr)
Definition: uv-common.c:81
@ UV_HANDLE_UDP_PROCESSING
Definition: uv-common.h:113
#define uv__req_unregister(loop, req)
Definition: uv-common.h:230

References assert(), handle, NULL, queue, QUEUE_DATA, QUEUE_EMPTY, QUEUE_HEAD, QUEUE_REMOVE, req, uv__count_bufs(), uv__free(), uv__handle_stop, uv__io_active(), uv__io_stop(), uv__req_unregister, and UV_HANDLE_UDP_PROCESSING.

Referenced by uv__udp_finish_close(), and uv__udp_io().

◆ uv__udp_send()

int uv__udp_send ( uv_udp_send_t req,
uv_udp_t handle,
const uv_buf_t  bufs[],
unsigned int  nbufs,
const struct sockaddr addr,
unsigned int  addrlen,
uv_udp_send_cb  send_cb 
)

Definition at line 650 of file udp.c.

656  {
657  int err;
658  int empty_queue;
659 
660  assert(nbufs > 0);
661 
662  if (addr) {
663  err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
664  if (err)
665  return err;
666  }
667 
668  /* It's legal for send_queue_count > 0 even when the write_queue is empty;
669  * it means there are error-state requests in the write_completed_queue that
670  * will touch up send_queue_size/count later.
671  */
672  empty_queue = (handle->send_queue_count == 0);
673 
674  uv__req_init(handle->loop, req, UV_UDP_SEND);
675  assert(addrlen <= sizeof(req->addr));
676  if (addr == NULL)
677  req->addr.ss_family = AF_UNSPEC;
678  else
679  memcpy(&req->addr, addr, addrlen);
680  req->send_cb = send_cb;
681  req->handle = handle;
682  req->nbufs = nbufs;
683 
684  req->bufs = req->bufsml;
685  if (nbufs > ARRAY_SIZE(req->bufsml))
686  req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
687 
688  if (req->bufs == NULL) {
689  uv__req_unregister(handle->loop, req);
690  return UV_ENOMEM;
691  }
692 
693  memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
694  handle->send_queue_size += uv__count_bufs(req->bufs, req->nbufs);
695  handle->send_queue_count++;
696  QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue);
698 
699  if (empty_queue && !(handle->flags & UV_HANDLE_UDP_PROCESSING)) {
701 
702  /* `uv__udp_sendmsg` may not be able to do non-blocking write straight
703  * away. In such cases the `io_watcher` has to be queued for asynchronous
704  * write.
705  */
706  if (!QUEUE_EMPTY(&handle->write_queue))
707  uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
708  } else {
709  uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
710  }
711 
712  return 0;
713 }
#define ARRAY_SIZE(a)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static char bufs[4][128]
Buffers for uint64_to_str() and uint64_to_nicestr()
Definition: util.c:18
void * uv__malloc(size_t size)
Definition: uv-common.c:75
#define uv__req_init(loop, req, typ)
Definition: uv-common.h:329

References addr, addrlen, AF_UNSPEC, ARRAY_SIZE, assert(), bufs, err, handle, memcpy(), NULL, QUEUE_EMPTY, QUEUE_INSERT_TAIL, req, uv__count_bufs(), uv__handle_start, uv__io_start(), uv__malloc(), uv__req_init, uv__req_unregister, uv__udp_maybe_deferred_bind(), uv__udp_sendmsg(), and UV_HANDLE_UDP_PROCESSING.

Referenced by uv_udp_send().

◆ uv__udp_sendmsg()

static void uv__udp_sendmsg ( uv_udp_t handle)
static

Definition at line 406 of file udp.c.

406  {
408  struct msghdr h;
409  QUEUE* q;
410  ssize_t size;
411 
412 #if HAVE_MMSG
413  uv_once(&once, uv__udp_mmsg_init);
414  if (uv__sendmmsg_avail) {
415  uv__udp_sendmmsg(handle);
416  return;
417  }
418 #endif
419 
420  while (!QUEUE_EMPTY(&handle->write_queue)) {
421  q = QUEUE_HEAD(&handle->write_queue);
422  assert(q != NULL);
423 
425  assert(req != NULL);
426 
427  memset(&h, 0, sizeof h);
428  if (req->addr.ss_family == AF_UNSPEC) {
429  h.msg_name = NULL;
430  h.msg_namelen = 0;
431  } else {
432  h.msg_name = &req->addr;
433  if (req->addr.ss_family == AF_INET6)
434  h.msg_namelen = sizeof(struct sockaddr_in6);
435  else if (req->addr.ss_family == AF_INET)
436  h.msg_namelen = sizeof(struct sockaddr_in);
437  else if (req->addr.ss_family == AF_UNIX)
438  h.msg_namelen = sizeof(struct sockaddr_un);
439  else {
440  assert(0 && "unsupported address family");
441  abort();
442  }
443  }
444  h.msg_iov = (struct iovec*) req->bufs;
445  h.msg_iovlen = req->nbufs;
446 
447  do {
448  size = sendmsg(handle->io_watcher.fd, &h, 0);
449  } while (size == -1 && errno == EINTR);
450 
451  if (size == -1) {
452  if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
453  break;
454  }
455 
456  req->status = (size == -1 ? UV__ERR(errno) : size);
457 
458  /* Sending a datagram is an atomic operation: either all data
459  * is written or nothing is (and EMSGSIZE is raised). That is
460  * why we don't handle partial writes. Just pop the request
461  * off the write queue and onto the completed queue, done.
462  */
463  QUEUE_REMOVE(&req->queue);
464  QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
465  uv__io_feed(handle->loop, &handle->io_watcher);
466  }
467 }
#define ENOBUFS
Definition: sftypes.h:165
Definition: sftypes.h:73
void uv__io_feed(uv_loop_t *loop, uv__io_t *w)
Definition: core.c:952
static uv_once_t once
Definition: threadpool.c:32
UV_EXTERN void uv_once(uv_once_t *guard, void(*callback)(void))
Definition: thread.c:419

References AF_INET, AF_INET6, AF_UNIX, AF_UNSPEC, assert(), EAGAIN, EINTR, ENOBUFS, h, handle, memset(), NULL, once, queue, QUEUE_DATA, QUEUE_EMPTY, QUEUE_HEAD, QUEUE_INSERT_TAIL, QUEUE_REMOVE, req, UV__ERR, uv__io_feed(), and uv_once().

Referenced by uv__udp_io(), and uv__udp_send().

◆ uv__udp_set_membership4()

static int uv__udp_set_membership4 ( uv_udp_t handle,
const struct sockaddr_in multicast_addr,
const char *  interface_addr,
uv_membership  membership 
)
static

Definition at line 760 of file udp.c.

763  {
764  struct ip_mreq mreq;
765  int optname;
766  int err;
767 
768  memset(&mreq, 0, sizeof mreq);
769 
770  if (interface_addr) {
771  err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
772  if (err)
773  return err;
774  } else {
775  mreq.imr_interface.s_addr = htonl(INADDR_ANY);
776  }
777 
778  mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
779 
780  switch (membership) {
781  case UV_JOIN_GROUP:
782  optname = IP_ADD_MEMBERSHIP;
783  break;
784  case UV_LEAVE_GROUP:
785  optname = IP_DROP_MEMBERSHIP;
786  break;
787  default:
788  return UV_EINVAL;
789  }
790 
791  if (setsockopt(handle->io_watcher.fd,
792  IPPROTO_IP,
793  optname,
794  &mreq,
795  sizeof(mreq))) {
796 #if defined(__MVS__)
797  if (errno == ENXIO)
798  return UV_ENODEV;
799 #endif
800  return UV__ERR(errno);
801  }
802 
803  return 0;
804 }
#define ENXIO
Definition: sftypes.h:116
in_addr_t s_addr
Definition: sftypes.h:337
struct in_addr sin_addr
Definition: sftypes.h:344
@ UV_JOIN_GROUP
Definition: uv.h:384
@ UV_LEAVE_GROUP
Definition: uv.h:383
UV_EXTERN int uv_inet_pton(int af, const char *src, void *dst)
Definition: inet.c:150

References AF_INET, ENXIO, err, handle, memset(), in_addr::s_addr, sockaddr_in::sin_addr, UV__ERR, uv_inet_pton(), UV_JOIN_GROUP, and UV_LEAVE_GROUP.

Referenced by uv_udp_set_membership().

◆ uv__udp_set_membership6()

static int uv__udp_set_membership6 ( uv_udp_t handle,
const struct sockaddr_in6 multicast_addr,
const char *  interface_addr,
uv_membership  membership 
)
static

Definition at line 807 of file udp.c.

810  {
811  int optname;
812  struct ipv6_mreq mreq;
813  struct sockaddr_in6 addr6;
814 
815  memset(&mreq, 0, sizeof mreq);
816 
817  if (interface_addr) {
818  if (uv_ip6_addr(interface_addr, 0, &addr6))
819  return UV_EINVAL;
820  mreq.ipv6mr_interface = addr6.sin6_scope_id;
821  } else {
822  mreq.ipv6mr_interface = 0;
823  }
824 
825  mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr;
826 
827  switch (membership) {
828  case UV_JOIN_GROUP:
829  optname = IPV6_ADD_MEMBERSHIP;
830  break;
831  case UV_LEAVE_GROUP:
832  optname = IPV6_DROP_MEMBERSHIP;
833  break;
834  default:
835  return UV_EINVAL;
836  }
837 
838  if (setsockopt(handle->io_watcher.fd,
839  IPPROTO_IPV6,
840  optname,
841  &mreq,
842  sizeof(mreq))) {
843 #if defined(__MVS__)
844  if (errno == ENXIO)
845  return UV_ENODEV;
846 #endif
847  return UV__ERR(errno);
848  }
849 
850  return 0;
851 }
struct in6_addr sin6_addr
Definition: sftypes.h:375
UV_EXTERN int uv_ip6_addr(const char *ip, int port, struct sockaddr_in6 *addr)
Definition: uv-common.c:232

References ENXIO, handle, memset(), sockaddr_in6::sin6_addr, sockaddr_in6::sin6_scope_id, UV__ERR, uv_ip6_addr(), UV_JOIN_GROUP, and UV_LEAVE_GROUP.

Referenced by uv_udp_set_membership().

◆ uv__udp_set_source_membership4()

static int uv__udp_set_source_membership4 ( uv_udp_t handle,
const struct sockaddr_in multicast_addr,
const char *  interface_addr,
const struct sockaddr_in source_addr,
uv_membership  membership 
)
static

Definition at line 859 of file udp.c.

863  {
864  struct ip_mreq_source mreq;
865  int optname;
866  int err;
867 
869  if (err)
870  return err;
871 
872  memset(&mreq, 0, sizeof(mreq));
873 
874  if (interface_addr != NULL) {
875  err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
876  if (err)
877  return err;
878  } else {
879  mreq.imr_interface.s_addr = htonl(INADDR_ANY);
880  }
881 
882  mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
883  mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr;
884 
885  if (membership == UV_JOIN_GROUP)
886  optname = IP_ADD_SOURCE_MEMBERSHIP;
887  else if (membership == UV_LEAVE_GROUP)
888  optname = IP_DROP_SOURCE_MEMBERSHIP;
889  else
890  return UV_EINVAL;
891 
892  if (setsockopt(handle->io_watcher.fd,
893  IPPROTO_IP,
894  optname,
895  &mreq,
896  sizeof(mreq))) {
897  return UV__ERR(errno);
898  }
899 
900  return 0;
901 }

References AF_INET, err, handle, memset(), NULL, in_addr::s_addr, sockaddr_in::sin_addr, UV__ERR, uv__udp_maybe_deferred_bind(), uv_inet_pton(), UV_JOIN_GROUP, UV_LEAVE_GROUP, and UV_UDP_REUSEADDR.

Referenced by uv_udp_set_source_membership().

◆ uv__udp_set_source_membership6()

static int uv__udp_set_source_membership6 ( uv_udp_t handle,
const struct sockaddr_in6 multicast_addr,
const char *  interface_addr,
const struct sockaddr_in6 source_addr,
uv_membership  membership 
)
static

Definition at line 904 of file udp.c.

908  {
909  struct group_source_req mreq;
910  struct sockaddr_in6 addr6;
911  int optname;
912  int err;
913 
915  if (err)
916  return err;
917 
918  memset(&mreq, 0, sizeof(mreq));
919 
920  if (interface_addr != NULL) {
921  err = uv_ip6_addr(interface_addr, 0, &addr6);
922  if (err)
923  return err;
924  mreq.gsr_interface = addr6.sin6_scope_id;
925  } else {
926  mreq.gsr_interface = 0;
927  }
928 
929  STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
930  STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
931  memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr));
932  memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr));
933 
934  if (membership == UV_JOIN_GROUP)
935  optname = MCAST_JOIN_SOURCE_GROUP;
936  else if (membership == UV_LEAVE_GROUP)
937  optname = MCAST_LEAVE_SOURCE_GROUP;
938  else
939  return UV_EINVAL;
940 
941  if (setsockopt(handle->io_watcher.fd,
942  IPPROTO_IPV6,
943  optname,
944  &mreq,
945  sizeof(mreq))) {
946  return UV__ERR(errno);
947  }
948 
949  return 0;
950 }
#define STATIC_ASSERT(expr)
Definition: uv-common.h:60
#define MCAST_LEAVE_SOURCE_GROUP
Definition: winsock.h:62
#define MCAST_JOIN_SOURCE_GROUP
Definition: winsock.h:58

References AF_INET6, err, handle, MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP, memcpy(), memset(), NULL, sockaddr_in6::sin6_scope_id, STATIC_ASSERT, UV__ERR, uv__udp_maybe_deferred_bind(), uv_ip6_addr(), UV_JOIN_GROUP, UV_LEAVE_GROUP, and UV_UDP_REUSEADDR.

Referenced by uv_udp_set_source_membership().

◆ uv__udp_try_send()

int uv__udp_try_send ( uv_udp_t handle,
const uv_buf_t  bufs[],
unsigned int  nbufs,
const struct sockaddr addr,
unsigned int  addrlen 
)

Definition at line 716 of file udp.c.

720  {
721  int err;
722  struct msghdr h;
723  ssize_t size;
724 
725  assert(nbufs > 0);
726 
727  /* already sending a message */
728  if (handle->send_queue_count != 0)
729  return UV_EAGAIN;
730 
731  if (addr) {
732  err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
733  if (err)
734  return err;
735  } else {
737  }
738 
739  memset(&h, 0, sizeof h);
740  h.msg_name = (struct sockaddr*) addr;
741  h.msg_namelen = addrlen;
742  h.msg_iov = (struct iovec*) bufs;
743  h.msg_iovlen = nbufs;
744 
745  do {
746  size = sendmsg(handle->io_watcher.fd, &h, 0);
747  } while (size == -1 && errno == EINTR);
748 
749  if (size == -1) {
750  if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
751  return UV_EAGAIN;
752  else
753  return UV__ERR(errno);
754  }
755 
756  return size;
757 }

References addr, addrlen, assert(), bufs, EAGAIN, EINTR, ENOBUFS, err, h, handle, memset(), UV__ERR, uv__udp_maybe_deferred_bind(), and UV_HANDLE_UDP_CONNECTED.

Referenced by uv_udp_try_send().

◆ uv_udp_getpeername()

int uv_udp_getpeername ( const uv_udp_t handle,
struct sockaddr name,
int namelen 
)

Definition at line 1276 of file udp.c.

1278  {
1279 
1280  return uv__getsockpeername((const uv_handle_t*) handle,
1281  getpeername,
1282  name,
1283  namelen);
1284 }
Definition: z80asm.h:102
int uv__getsockpeername(const uv_handle_t *handle, uv__peersockfunc func, struct sockaddr *name, int *namelen)
Definition: core.c:1490

◆ uv_udp_getsockname()

int uv_udp_getsockname ( const uv_udp_t handle,
struct sockaddr name,
int namelen 
)

Definition at line 1286 of file udp.c.

1288  {
1289 
1290  return uv__getsockpeername((const uv_handle_t*) handle,
1291  getsockname,
1292  name,
1293  namelen);
1294 }

Referenced by uv__udp_is_bound().

◆ uv_udp_open()

int uv_udp_open ( uv_udp_t handle,
uv_os_sock_t  sock 
)

Definition at line 991 of file udp.c.

991  {
992  int err;
993 
994  /* Check for already active socket. */
995  if (handle->io_watcher.fd != -1)
996  return UV_EBUSY;
997 
998  if (uv__fd_exists(handle->loop, sock))
999  return UV_EEXIST;
1000 
1001  err = uv__nonblock(sock, 1);
1002  if (err)
1003  return err;
1004 
1005  err = uv__set_reuse(sock);
1006  if (err)
1007  return err;
1008 
1009  handle->io_watcher.fd = sock;
1011  handle->flags |= UV_HANDLE_UDP_CONNECTED;
1012 
1013  return 0;
1014 }
int uv__fd_exists(uv_loop_t *loop, int fd)
Definition: core.c:965
#define uv__nonblock
Definition: internal.h:170
int uv__udp_is_connected(uv_udp_t *handle)
Definition: uv-common.c:393

◆ uv_udp_set_broadcast()

int uv_udp_set_broadcast ( uv_udp_t handle,
int  on 
)

Definition at line 1128 of file udp.c.

1128  {
1129  if (setsockopt(handle->io_watcher.fd,
1130  SOL_SOCKET,
1131  SO_BROADCAST,
1132  &on,
1133  sizeof(on))) {
1134  return UV__ERR(errno);
1135  }
1136 
1137  return 0;
1138 }
#define SO_BROADCAST
Definition: sftypes.h:434

◆ uv_udp_set_membership()

int uv_udp_set_membership ( uv_udp_t handle,
const char *  multicast_addr,
const char *  interface_addr,
uv_membership  membership 
)

Definition at line 1017 of file udp.c.

1020  {
1021  int err;
1022  struct sockaddr_in addr4;
1023  struct sockaddr_in6 addr6;
1024 
1025  if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) {
1027  if (err)
1028  return err;
1029  return uv__udp_set_membership4(handle, &addr4, interface_addr, membership);
1030  } else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) {
1032  if (err)
1033  return err;
1034  return uv__udp_set_membership6(handle, &addr6, interface_addr, membership);
1035  } else {
1036  return UV_EINVAL;
1037  }
1038 }
static int uv__udp_set_membership4(uv_udp_t *handle, const struct sockaddr_in *multicast_addr, const char *interface_addr, uv_membership membership)
Definition: udp.c:760
static int uv__udp_set_membership6(uv_udp_t *handle, const struct sockaddr_in6 *multicast_addr, const char *interface_addr, uv_membership membership)
Definition: udp.c:807
UV_EXTERN int uv_ip4_addr(const char *ip, int port, struct sockaddr_in *addr)
Definition: uv-common.c:221

◆ uv_udp_set_multicast_interface()

int uv_udp_set_multicast_interface ( uv_udp_t handle,
const char *  interface_addr 
)

Definition at line 1227 of file udp.c.

1227  {
1228  struct sockaddr_storage addr_st;
1229  struct sockaddr_in* addr4;
1230  struct sockaddr_in6* addr6;
1231 
1232  addr4 = (struct sockaddr_in*) &addr_st;
1233  addr6 = (struct sockaddr_in6*) &addr_st;
1234 
1235  if (!interface_addr) {
1236  memset(&addr_st, 0, sizeof addr_st);
1237  if (handle->flags & UV_HANDLE_IPV6) {
1238  addr_st.ss_family = AF_INET6;
1239  addr6->sin6_scope_id = 0;
1240  } else {
1241  addr_st.ss_family = AF_INET;
1242  addr4->sin_addr.s_addr = htonl(INADDR_ANY);
1243  }
1244  } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) {
1245  /* nothing, address was parsed */
1246  } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) {
1247  /* nothing, address was parsed */
1248  } else {
1249  return UV_EINVAL;
1250  }
1251 
1252  if (addr_st.ss_family == AF_INET) {
1253  if (setsockopt(handle->io_watcher.fd,
1254  IPPROTO_IP,
1255  IP_MULTICAST_IF,
1256  (void*) &addr4->sin_addr,
1257  sizeof(addr4->sin_addr)) == -1) {
1258  return UV__ERR(errno);
1259  }
1260  } else if (addr_st.ss_family == AF_INET6) {
1261  if (setsockopt(handle->io_watcher.fd,
1262  IPPROTO_IPV6,
1263  IPV6_MULTICAST_IF,
1264  &addr6->sin6_scope_id,
1265  sizeof(addr6->sin6_scope_id)) == -1) {
1266  return UV__ERR(errno);
1267  }
1268  } else {
1269  assert(0 && "unexpected address family");
1270  abort();
1271  }
1272 
1273  return 0;
1274 }
uint32_t sin6_scope_id
Definition: sftypes.h:376

◆ uv_udp_set_multicast_loop()

int uv_udp_set_multicast_loop ( uv_udp_t handle,
int  on 
)

Definition at line 1203 of file udp.c.

1203  {
1204 /*
1205  * On Solaris and derivatives such as SmartOS, the length of socket options
1206  * is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for
1207  * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
1208  * and use the general uv__setsockopt_maybe_char call otherwise.
1209  */
1210 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
1211  defined(__MVS__) || defined(__QNX__)
1212  if (handle->flags & UV_HANDLE_IPV6)
1213  return uv__setsockopt(handle,
1214  IP_MULTICAST_LOOP,
1215  IPV6_MULTICAST_LOOP,
1216  &on,
1217  sizeof(on));
1218 #endif /* defined(__sun) || defined(_AIX) ||defined(__OpenBSD__) ||
1219  defined(__MVS__) || defined(__QNX__) */
1220 
1222  IP_MULTICAST_LOOP,
1223  IPV6_MULTICAST_LOOP,
1224  on);
1225 }
static int uv__setsockopt_maybe_char(uv_udp_t *handle, int option4, int option6, int val)
Definition: udp.c:1109

References handle, uv__setsockopt(), uv__setsockopt_maybe_char(), and UV_HANDLE_IPV6.

◆ uv_udp_set_multicast_ttl()

int uv_udp_set_multicast_ttl ( uv_udp_t handle,
int  ttl 
)

Definition at line 1178 of file udp.c.

1178  {
1179 /*
1180  * On Solaris and derivatives such as SmartOS, the length of socket options
1181  * is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for
1182  * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
1183  * and use the general uv__setsockopt_maybe_char call otherwise.
1184  */
1185 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
1186  defined(__MVS__) || defined(__QNX__)
1187  if (handle->flags & UV_HANDLE_IPV6)
1188  return uv__setsockopt(handle,
1189  IP_MULTICAST_TTL,
1190  IPV6_MULTICAST_HOPS,
1191  &ttl,
1192  sizeof(ttl));
1193 #endif /* defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
1194  defined(__MVS__) || defined(__QNX__) */
1195 
1197  IP_MULTICAST_TTL,
1198  IPV6_MULTICAST_HOPS,
1199  ttl);
1200 }

References handle, uv__setsockopt(), uv__setsockopt_maybe_char(), and UV_HANDLE_IPV6.

◆ uv_udp_set_source_membership()

int uv_udp_set_source_membership ( uv_udp_t handle,
const char *  multicast_addr,
const char *  interface_addr,
const char *  source_addr,
uv_membership  membership 
)

Definition at line 1041 of file udp.c.

1045  {
1046 #if !defined(__OpenBSD__) && \
1047  !defined(__NetBSD__) && \
1048  !defined(__ANDROID__) && \
1049  !defined(__DragonFly__) && \
1050  !defined(__QNX__)
1051  int err;
1052  union uv__sockaddr mcast_addr;
1053  union uv__sockaddr src_addr;
1054 
1055  err = uv_ip4_addr(multicast_addr, 0, &mcast_addr.in);
1056  if (err) {
1057  err = uv_ip6_addr(multicast_addr, 0, &mcast_addr.in6);
1058  if (err)
1059  return err;
1060  err = uv_ip6_addr(source_addr, 0, &src_addr.in6);
1061  if (err)
1062  return err;
1064  &mcast_addr.in6,
1065  interface_addr,
1066  &src_addr.in6,
1067  membership);
1068  }
1069 
1070  err = uv_ip4_addr(source_addr, 0, &src_addr.in);
1071  if (err)
1072  return err;
1074  &mcast_addr.in,
1075  interface_addr,
1076  &src_addr.in,
1077  membership);
1078 #else
1079  return UV_ENOSYS;
1080 #endif
1081 }
static int uv__udp_set_source_membership6(uv_udp_t *handle, const struct sockaddr_in6 *multicast_addr, const char *interface_addr, const struct sockaddr_in6 *source_addr, uv_membership membership)
Definition: udp.c:904
static int uv__udp_set_source_membership4(uv_udp_t *handle, const struct sockaddr_in *multicast_addr, const char *interface_addr, const struct sockaddr_in *source_addr, uv_membership membership)
Definition: udp.c:859

◆ uv_udp_set_ttl()

int uv_udp_set_ttl ( uv_udp_t handle,
int  ttl 
)

Definition at line 1141 of file udp.c.

1141  {
1142  if (ttl < 1 || ttl > 255)
1143  return UV_EINVAL;
1144 
1145 #if defined(__MVS__)
1146  if (!(handle->flags & UV_HANDLE_IPV6))
1147  return UV_ENOTSUP; /* zOS does not support setting ttl for IPv4 */
1148 #endif
1149 
1150 /*
1151  * On Solaris and derivatives such as SmartOS, the length of socket options
1152  * is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS,
1153  * so hardcode the size of these options on this platform,
1154  * and use the general uv__setsockopt_maybe_char call on other platforms.
1155  */
1156 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
1157  defined(__MVS__) || defined(__QNX__)
1158 
1159  return uv__setsockopt(handle,
1160  IP_TTL,
1161  IPV6_UNICAST_HOPS,
1162  &ttl,
1163  sizeof(ttl));
1164 
1165 #else /* !(defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
1166  defined(__MVS__) || defined(__QNX__)) */
1167 
1169  IP_TTL,
1170  IPV6_UNICAST_HOPS,
1171  ttl);
1172 
1173 #endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
1174  defined(__MVS__) || defined(__QNX__) */
1175 }

References handle, uv__setsockopt(), uv__setsockopt_maybe_char(), and UV_HANDLE_IPV6.

◆ uv_udp_using_recvmmsg()

int uv_udp_using_recvmmsg ( const uv_udp_t handle)

Definition at line 980 of file udp.c.

980  {
981 #if HAVE_MMSG
982  if (handle->flags & UV_HANDLE_UDP_RECVMMSG) {
983  uv_once(&once, uv__udp_mmsg_init);
984  return uv__recvmmsg_avail;
985  }
986 #endif
987  return 0;
988 }
@ UV_HANDLE_UDP_RECVMMSG
Definition: uv-common.h:115

Referenced by uv__udp_recvmsg().