Go to the documentation of this file.
35 #define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
37 #if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
38 # define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
41 #if defined(IPV6_LEAVE_GROUP) && !defined(IPV6_DROP_MEMBERSHIP)
42 # define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
56 #define UV__MMSG_MAXWIDTH 20
61 static int uv__recvmmsg_avail;
62 static int uv__sendmmsg_avail;
65 static void uv__udp_mmsg_init(
void) {
72 if (
ret == 0 || errno != ENOSYS) {
73 uv__sendmmsg_avail = 1;
74 uv__recvmmsg_avail = 1;
77 if (
ret == 0 || errno != ENOSYS)
78 uv__recvmmsg_avail = 1;
89 if (
handle->io_watcher.fd != -1) {
91 handle->io_watcher.fd = -1;
101 assert(
handle->io_watcher.fd == -1);
108 req->status = UV_ECANCELED;
114 assert(
handle->send_queue_size == 0);
115 assert(
handle->send_queue_count == 0);
139 handle->send_queue_count--;
141 if (
req->bufs !=
req->bufsml)
145 if (
req->send_cb == NULL)
151 if (
req->status >= 0)
172 assert(
handle->type == UV_UDP);
174 if (revents & POLLIN)
177 if (revents & POLLOUT) {
186 struct iovec iov[UV__MMSG_MAXWIDTH];
187 struct uv__mmsghdr msgs[UV__MMSG_MAXWIDTH];
198 for (
k = 0;
k < chunks; ++
k) {
201 msgs[
k].msg_hdr.msg_iov =
iov +
k;
202 msgs[
k].msg_hdr.msg_iovlen = 1;
203 msgs[
k].msg_hdr.msg_name = peers +
k;
204 msgs[
k].msg_hdr.msg_namelen =
sizeof(peers[0]);
209 while (nread == -1 && errno == EINTR);
212 if (nread == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
218 for (
k = 0;
k < (size_t) nread &&
handle->recv_cb != NULL;
k++) {
220 if (msgs[
k].msg_hdr.msg_flags & MSG_TRUNC)
227 msgs[
k].msg_hdr.msg_name,
232 if (
handle->recv_cb != NULL)
240 struct sockaddr_storage peer;
247 assert(
handle->recv_cb != NULL);
248 assert(
handle->alloc_cb != NULL);
258 if (
buf.base == NULL ||
buf.len == 0) {
262 assert(
buf.base != NULL);
267 if (uv__recvmmsg_avail) {
277 memset(&peer, 0,
sizeof(peer));
279 h.msg_namelen =
sizeof(peer);
280 h.msg_iov = (
void*) &
buf;
284 nread = recvmsg(
handle->io_watcher.fd, &h, 0);
286 while (nread == -1 && errno == EINTR);
289 if (errno == EAGAIN || errno == EWOULDBLOCK)
296 if (h.msg_flags & MSG_TRUNC)
306 &&
handle->io_watcher.fd != -1
307 &&
handle->recv_cb != NULL);
313 struct uv__mmsghdr
h[UV__MMSG_MAXWIDTH];
314 struct uv__mmsghdr *
p;
325 pkts < UV__MMSG_MAXWIDTH && q != &handle->write_queue;
333 if (
req->addr.ss_family == AF_UNSPEC) {
334 p->msg_hdr.msg_name = NULL;
335 p->msg_hdr.msg_namelen = 0;
337 p->msg_hdr.msg_name = &
req->addr;
340 else if (
req->addr.ss_family == AF_INET)
341 p->msg_hdr.msg_namelen =
sizeof(
struct sockaddr_in);
342 else if (
req->addr.ss_family == AF_UNIX)
343 p->msg_hdr.msg_namelen =
sizeof(
struct sockaddr_un);
345 assert(0 &&
"unsupported address family");
349 h[pkts].msg_hdr.msg_iov = (
struct iovec*)
req->bufs;
350 h[pkts].msg_hdr.msg_iovlen =
req->nbufs;
355 while (npkts == -1 && errno == EINTR);
358 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
361 i < pkts && q != &handle->write_queue;
376 i < pkts && q != &handle->write_queue;
382 req->status =
req->bufs[0].len;
395 goto write_queue_drain;
409 if (uv__sendmmsg_avail) {
423 if (
req->addr.ss_family == AF_UNSPEC) {
427 h.msg_name = &
req->addr;
430 else if (
req->addr.ss_family == AF_INET)
431 h.msg_namelen =
sizeof(
struct sockaddr_in);
432 else if (
req->addr.ss_family == AF_UNIX)
433 h.msg_namelen =
sizeof(
struct sockaddr_un);
435 assert(0 &&
"unsupported address family");
439 h.msg_iov = (
struct iovec*)
req->bufs;
440 h.msg_iovlen =
req->nbufs;
444 }
while (
size == -1 && errno == EINTR);
447 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
479 #if defined(SO_REUSEPORT) && defined(__MVS__)
480 struct sockaddr_in sockfd;
481 unsigned int sockfd_len =
sizeof(sockfd);
482 if (getsockname(fd, (
struct sockaddr*) &sockfd, &sockfd_len) == -1)
484 if (sockfd.sin_family == AF_UNIX) {
485 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)))
488 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes,
sizeof(yes)))
491 #elif defined(SO_REUSEPORT) && !defined(__linux__)
492 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes,
sizeof(yes)))
495 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)))
504 const struct sockaddr*
addr,
505 unsigned int addrlen,
506 unsigned int flags) {
519 fd =
handle->io_watcher.fd;
525 handle->io_watcher.fd = fd;
537 if (setsockopt(fd, IPPROTO_IPV6,
IPV6_V6ONLY, &yes,
sizeof yes) == -1) {
547 if (bind(fd,
addr, addrlen)) {
549 if (errno == EAFNOSUPPORT)
566 unsigned int flags) {
569 struct sockaddr_in
in;
570 struct sockaddr
addr;
574 if (
handle->io_watcher.fd != -1)
580 struct sockaddr_in*
addr = &taddr.in;
582 addr->sin_family = AF_INET;
583 addr->sin_addr.s_addr = INADDR_ANY;
584 addrlen =
sizeof *
addr;
592 addr->sin6_addr = in6addr_any;
593 addrlen =
sizeof *
addr;
597 assert(0 &&
"unsupported address family");
606 const struct sockaddr*
addr,
607 unsigned int addrlen) {
617 }
while (
err == -1 && errno == EINTR);
630 struct sockaddr
addr;
634 addr.sa_family = AF_UNSPEC;
639 }
while (
r == -1 && errno == EINTR);
641 if (
r == -1 && errno != EAFNOSUPPORT)
653 const struct sockaddr*
addr,
654 unsigned int addrlen,
671 empty_queue = (
handle->send_queue_count == 0);
674 assert(addrlen <=
sizeof(
req->addr));
676 req->addr.ss_family = AF_UNSPEC;
687 if (
req->bufs == NULL) {
694 handle->send_queue_count++;
718 const struct sockaddr*
addr,
719 unsigned int addrlen) {
727 if (
handle->send_queue_count != 0)
739 h.msg_name = (
struct sockaddr*)
addr;
740 h.msg_namelen = addrlen;
742 h.msg_iovlen = nbufs;
746 }
while (
size == -1 && errno == EINTR);
749 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
760 const struct sockaddr_in* multicast_addr,
761 const char* interface_addr,
767 memset(&mreq, 0,
sizeof mreq);
769 if (interface_addr) {
770 err =
uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
774 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
777 mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
779 switch (membership) {
781 optname = IP_ADD_MEMBERSHIP;
784 optname = IP_DROP_MEMBERSHIP;
790 if (setsockopt(
handle->io_watcher.fd,
808 const char* interface_addr,
811 struct ipv6_mreq mreq;
814 memset(&mreq, 0,
sizeof mreq);
816 if (interface_addr) {
821 mreq.ipv6mr_interface = 0;
824 mreq.ipv6mr_multiaddr = multicast_addr->
sin6_addr;
826 switch (membership) {
828 optname = IPV6_ADD_MEMBERSHIP;
831 optname = IPV6_DROP_MEMBERSHIP;
837 if (setsockopt(
handle->io_watcher.fd,
853 #if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__)
855 const struct sockaddr_in* multicast_addr,
856 const char* interface_addr,
857 const struct sockaddr_in* source_addr,
859 struct ip_mreq_source mreq;
867 memset(&mreq, 0,
sizeof(mreq));
869 if (interface_addr != NULL) {
870 err =
uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
874 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
877 mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
878 mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr;
881 optname = IP_ADD_SOURCE_MEMBERSHIP;
883 optname = IP_DROP_SOURCE_MEMBERSHIP;
887 if (setsockopt(
handle->io_watcher.fd,
901 const char* interface_addr,
904 struct group_source_req mreq;
913 memset(&mreq, 0,
sizeof(mreq));
915 if (interface_addr != NULL) {
921 mreq.gsr_interface = 0;
924 memcpy(&mreq.gsr_group, multicast_addr,
sizeof(mreq.gsr_group));
925 memcpy(&mreq.gsr_source, source_addr,
sizeof(mreq.gsr_source));
934 if (setsockopt(
handle->io_watcher.fd,
954 domain =
flags & 0xFF;
955 if (domain != AF_INET && domain !=
AF_INET6 && domain != AF_UNSPEC)
959 extra_flags =
flags & ~0xFF;
963 if (domain != AF_UNSPEC) {
975 handle->send_queue_size = 0;
976 handle->send_queue_count = 0;
997 if (
handle->io_watcher.fd != -1)
1011 handle->io_watcher.fd = sock;
1020 const char* multicast_addr,
1021 const char* interface_addr,
1024 struct sockaddr_in
addr4;
1044 const char* multicast_addr,
1045 const char* interface_addr,
1046 const char* source_addr,
1048 #if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__)
1050 struct sockaddr_storage mcast_addr;
1051 struct sockaddr_in* mcast_addr4;
1053 struct sockaddr_storage src_addr;
1054 struct sockaddr_in* src_addr4;
1057 mcast_addr4 = (
struct sockaddr_in*)&mcast_addr;
1059 src_addr4 = (
struct sockaddr_in*)&src_addr;
1099 r = setsockopt(
handle->io_watcher.fd,
1105 r = setsockopt(
handle->io_watcher.fd,
1120 #if defined(__sun) || defined(_AIX) || defined(__MVS__)
1122 #elif defined(__OpenBSD__)
1123 unsigned char arg = val;
1128 if (val < 0 || val > 255)
1136 if (setsockopt(
handle->io_watcher.fd,
1149 if (ttl < 1 || ttl > 255)
1152 #if defined(__MVS__)
1163 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
1192 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
1197 IPV6_MULTICAST_HOPS,
1205 IPV6_MULTICAST_HOPS,
1217 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
1222 IPV6_MULTICAST_LOOP,
1230 IPV6_MULTICAST_LOOP,
1235 struct sockaddr_storage addr_st;
1236 struct sockaddr_in*
addr4;
1239 addr4 = (
struct sockaddr_in*) &addr_st;
1242 if (!interface_addr) {
1243 memset(&addr_st, 0,
sizeof addr_st);
1248 addr_st.ss_family = AF_INET;
1249 addr4->sin_addr.s_addr = htonl(INADDR_ANY);
1259 if (addr_st.ss_family == AF_INET) {
1260 if (setsockopt(
handle->io_watcher.fd,
1263 (
void*) &
addr4->sin_addr,
1264 sizeof(
addr4->sin_addr)) == -1) {
1267 }
else if (addr_st.ss_family ==
AF_INET6) {
1268 if (setsockopt(
handle->io_watcher.fd,
1276 assert(0 &&
"unexpected address family");
1284 struct sockaddr*
name,
1294 struct sockaddr*
name,
int uv_udp_set_multicast_interface(uv_udp_t *handle, const char *interface_addr)
UV_EXTERN int uv_ip6_addr(const char *ip, int port, struct sockaddr_in6 *addr)
UV_EXTERN int uv_inet_pton(int af, const char *src, void *dst)
static int uv__setsockopt_maybe_char(uv_udp_t *handle, int option4, int option6, int val)
int uv_udp_getpeername(const uv_udp_t *handle, struct sockaddr *name, int *namelen)
int uv_udp_open(uv_udp_t *handle, uv_os_sock_t sock)
#define ARRAY_SIZE(array)
int uv__udp_is_connected(uv_udp_t *handle)
return memset(p, 0, total)
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)
int uv__socket(int domain, int type, int protocol)
#define uv__req_init(loop, req, typ)
void uv__udp_finish_close(uv_udp_t *handle)
void * uv__malloc(size_t size)
static int uv__setsockopt(uv_udp_t *handle, int option4, int option6, const void *val, socklen_t size)
#define MCAST_LEAVE_SOURCE_GROUP
@ UV_HANDLE_UDP_CONNECTED
#define UV__UDP_DGRAM_MAXSIZE
int uv_udp_set_ttl(uv_udp_t *handle, int ttl)
static void alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
static void send_cb(uv_udp_send_t *req, int status)
int uv__udp_recv_stop(uv_udp_t *handle)
void uv__io_init(uv__io_t *w, uv__io_cb cb, int fd)
#define QUEUE_DATA(ptr, type, field)
#define container_of(ptr, type, member)
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)
void(* uv_alloc_cb)(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
UV_EXTERN int uv_ip4_addr(const char *ip, int port, struct sockaddr_in *addr)
static void uv__udp_recvmsg(uv_udp_t *handle)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int uv__udp_bind(uv_udp_t *handle, const struct sockaddr *addr, unsigned int addrlen, unsigned int flags)
@ UV_HANDLE_UDP_PROCESSING
UV_EXTERN void uv_once(uv_once_t *guard, void(*callback)(void))
int uv__udp_disconnect(uv_udp_t *handle)
int uv_udp_set_broadcast(uv_udp_t *handle, int on)
int uv__fd_exists(uv_loop_t *loop, int fd)
int uv__io_active(const uv__io_t *w, unsigned int events)
void uv__io_start(uv_loop_t *loop, uv__io_t *w, unsigned int events)
int uv__getsockpeername(const uv_handle_t *handle, uv__peersockfunc func, struct sockaddr *name, int *namelen)
static int uv__set_reuse(int fd)
static struct sockaddr_in6 addr6
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_connect(uv_udp_t *handle, const struct sockaddr *addr, unsigned int addrlen)
void(* uv_udp_send_cb)(uv_udp_send_t *req, int status)
static int uv__udp_set_membership6(uv_udp_t *handle, const struct sockaddr_in6 *multicast_addr, const char *interface_addr, uv_membership membership)
static void recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
void(* uv_udp_recv_cb)(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
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_set_membership(uv_udp_t *handle, const char *multicast_addr, const char *interface_addr, uv_membership membership)
#define uv__handle_init(loop_, h, type_)
static int uv__udp_set_membership4(uv_udp_t *handle, const struct sockaddr_in *multicast_addr, const char *interface_addr, uv_membership membership)
void uv__udp_close(uv_udp_t *handle)
static struct sockaddr_in addr4
int uv__recvmmsg(int fd, struct uv__mmsghdr *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout)
static void uv__udp_io(uv_loop_t *loop, uv__io_t *w, unsigned int revents)
void uv__io_feed(uv_loop_t *loop, uv__io_t *w)
#define MCAST_JOIN_SOURCE_GROUP
int uv__udp_recv_start(uv_udp_t *handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_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)
int uv_udp_init_ex(uv_loop_t *loop, uv_udp_t *handle, unsigned int flags)
void uv__io_close(uv_loop_t *loop, uv__io_t *w)
UniquePtr< SSL_SESSION > ret
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
static int uv__udp_maybe_deferred_bind(uv_udp_t *handle, int domain, unsigned int flags)
void uv__io_stop(uv_loop_t *loop, uv__io_t *w, unsigned int events)
struct ares_in6_addr sin6_addr
int uv_udp_getsockname(const uv_udp_t *handle, struct sockaddr *name, int *namelen)
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs)
#define uv__handle_start(h)
static void uv__udp_sendmsg(uv_udp_t *handle)
static void uv__udp_run_completed(uv_udp_t *handle)
#define uv__handle_stop(h)
#define QUEUE_INSERT_TAIL(h, q)
int uv_udp_init(uv_loop_t *loop, uv_udp_t *handle)
int uv_udp_set_multicast_loop(uv_udp_t *handle, int on)
unsigned int sin6_scope_id
#define uv__req_unregister(loop, req)
int uv_udp_set_multicast_ttl(uv_udp_t *handle, int ttl)
int uv__sendmmsg(int fd, struct uv__mmsghdr *mmsg, unsigned int vlen, unsigned int flags)
grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:43