Adding patches from upstream (by bnoordhuis) to solve an issue with dns/bind916).
See <https://github.com/libuv/libuv/issues/2791> and <https://github.com/libuv/libuv/pull/2792> PR: 245653 Reported by: lysfjord.daniel(at)smokepit.net and many
This commit is contained in:
parent
6281e3cb8d
commit
bd9cd48a9a
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=531835
@ -4,6 +4,7 @@
|
||||
PORTNAME= libuv
|
||||
PORTVERSION= 1.36.0
|
||||
DISTVERSIONPREFIX= v
|
||||
PORTREVISION= 1
|
||||
CATEGORIES= devel
|
||||
|
||||
MAINTAINER= thierry@FreeBSD.org
|
||||
|
51
devel/libuv/files/patch-docs_src_udp.rst
Normal file
51
devel/libuv/files/patch-docs_src_udp.rst
Normal file
@ -0,0 +1,51 @@
|
||||
--- docs/src/udp.rst.orig 2020-04-15 16:31:21 UTC
|
||||
+++ docs/src/udp.rst
|
||||
@@ -42,11 +42,6 @@ Data types
|
||||
* any traffic, in effect "stealing" the port from the previous listener.
|
||||
*/
|
||||
UV_UDP_REUSEADDR = 4
|
||||
- /*
|
||||
- * Indicates that the message was received by recvmmsg, so the buffer provided
|
||||
- * must not be freed by the recv_cb callback.
|
||||
- */
|
||||
- UV_UDP_MMSG_CHUNK = 8
|
||||
};
|
||||
|
||||
.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status)
|
||||
@@ -67,18 +62,13 @@ Data types
|
||||
* `buf`: :c:type:`uv_buf_t` with the received data.
|
||||
* `addr`: ``struct sockaddr*`` containing the address of the sender.
|
||||
Can be NULL. Valid for the duration of the callback only.
|
||||
- * `flags`: One or more or'ed UV_UDP_* constants.
|
||||
+ * `flags`: One or more or'ed UV_UDP_* constants. Right now only
|
||||
+ ``UV_UDP_PARTIAL`` is used.
|
||||
|
||||
The callee is responsible for freeing the buffer, libuv does not reuse it.
|
||||
The buffer may be a null buffer (where `buf->base` == NULL and `buf->len` == 0)
|
||||
on error.
|
||||
|
||||
- When using :man:`recvmmsg(2)`, chunks will have the `UV_UDP_MMSG_CHUNK` flag set,
|
||||
- those must not be freed. There will be a final callback with `nread` set to 0,
|
||||
- `addr` set to NULL and the buffer pointing at the initially allocated data with
|
||||
- the `UV_UDP_MMSG_CHUNK` flag cleared. This is a good chance for the callee to
|
||||
- free the provided buffer.
|
||||
-
|
||||
.. note::
|
||||
The receive callback will be called with `nread` == 0 and `addr` == NULL when there is
|
||||
nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is
|
||||
@@ -376,10 +366,6 @@ API
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
- .. versionchanged:: 1.35.0 added support for :man:`recvmmsg(2)` on supported platforms).
|
||||
- The use of this feature requires a buffer larger than
|
||||
- 2 * 64KB to be passed to `alloc_cb`.
|
||||
-
|
||||
.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle)
|
||||
|
||||
Stop listening for incoming datagrams.
|
||||
@@ -402,3 +388,4 @@ API
|
||||
.. versionadded:: 1.19.0
|
||||
|
||||
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
||||
+
|
23
devel/libuv/files/patch-include_uv.h
Normal file
23
devel/libuv/files/patch-include_uv.h
Normal file
@ -0,0 +1,23 @@
|
||||
--- include/uv.h.orig 2020-04-15 16:31:21 UTC
|
||||
+++ include/uv.h
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
+/* COPYRIGHT JOYENT, INC. AND OTHER NODE CONTRIBUTORS. ALL RIGHTS RESERVED.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
@@ -607,8 +607,7 @@ enum uv_udp_flags {
|
||||
*/
|
||||
UV_UDP_REUSEADDR = 4,
|
||||
/*
|
||||
- * Indicates that the message was received by recvmmsg, so the buffer provided
|
||||
- * must not be freed by the recv_cb callback.
|
||||
+ * Unused. Here for API/ABI compatibility.
|
||||
*/
|
||||
UV_UDP_MMSG_CHUNK = 8
|
||||
};
|
||||
@@ -1802,3 +1801,4 @@ UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data
|
||||
}
|
||||
#endif
|
||||
#endif /* UV_H */
|
||||
+
|
30
devel/libuv/files/patch-src_unix_freebsd.c
Normal file
30
devel/libuv/files/patch-src_unix_freebsd.c
Normal file
@ -0,0 +1,30 @@
|
||||
--- src/unix/freebsd.c.orig 2020-04-15 16:31:21 UTC
|
||||
+++ src/unix/freebsd.c
|
||||
@@ -289,27 +289,3 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-
|
||||
-int uv__sendmmsg(int fd,
|
||||
- struct uv__mmsghdr* mmsg,
|
||||
- unsigned int vlen,
|
||||
- unsigned int flags) {
|
||||
-#if __FreeBSD__ >= 11
|
||||
- return sendmmsg(fd, mmsg, vlen, flags);
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int uv__recvmmsg(int fd,
|
||||
- struct uv__mmsghdr* mmsg,
|
||||
- unsigned int vlen,
|
||||
- unsigned int flags,
|
||||
- struct timespec* timeout) {
|
||||
-#if __FreeBSD__ >= 11
|
||||
- return recvmmsg(fd, mmsg, vlen, flags, timeout);
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
39
devel/libuv/files/patch-src_unix_internal.h
Normal file
39
devel/libuv/files/patch-src_unix_internal.h
Normal file
@ -0,0 +1,39 @@
|
||||
--- src/unix/internal.h.orig 2020-04-15 16:31:21 UTC
|
||||
+++ src/unix/internal.h
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <fcntl.h> /* O_CLOEXEC and O_NONBLOCK, if supported. */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
-#include <sys/socket.h>
|
||||
|
||||
#if defined(__STRICT_ANSI__)
|
||||
# define inline __inline
|
||||
@@ -328,27 +327,5 @@ int uv__getsockpeername(const uv_handle_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen);
|
||||
|
||||
-#if defined(__linux__) || \
|
||||
- defined(__FreeBSD__) || \
|
||||
- defined(__FreeBSD_kernel__)
|
||||
-#define HAVE_MMSG 1
|
||||
-struct uv__mmsghdr {
|
||||
- struct msghdr msg_hdr;
|
||||
- unsigned int msg_len;
|
||||
-};
|
||||
-
|
||||
-int uv__recvmmsg(int fd,
|
||||
- struct uv__mmsghdr* mmsg,
|
||||
- unsigned int vlen,
|
||||
- unsigned int flags,
|
||||
- struct timespec* timeout);
|
||||
-int uv__sendmmsg(int fd,
|
||||
- struct uv__mmsghdr* mmsg,
|
||||
- unsigned int vlen,
|
||||
- unsigned int flags);
|
||||
-#else
|
||||
-#define HAVE_MMSG 0
|
||||
-#endif
|
||||
-
|
||||
-
|
||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||
+
|
242
devel/libuv/files/patch-src_unix_linux-syscalls.c
Normal file
242
devel/libuv/files/patch-src_unix_linux-syscalls.c
Normal file
@ -0,0 +1,242 @@
|
||||
--- src/unix/linux-syscalls.c.orig 2020-04-15 16:31:21 UTC
|
||||
+++ src/unix/linux-syscalls.c
|
||||
@@ -19,187 +19,71 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
-#include "linux-syscalls.h"
|
||||
-#include <unistd.h>
|
||||
+#ifndef UV_LINUX_SYSCALL_H_
|
||||
+#define UV_LINUX_SYSCALL_H_
|
||||
+
|
||||
+#undef _GNU_SOURCE
|
||||
+#define _GNU_SOURCE
|
||||
+
|
||||
+#include <stdint.h>
|
||||
#include <signal.h>
|
||||
-#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
-#include <errno.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <sys/socket.h>
|
||||
|
||||
-#if defined(__arm__)
|
||||
-# if defined(__thumb__) || defined(__ARM_EABI__)
|
||||
-# define UV_SYSCALL_BASE 0
|
||||
-# else
|
||||
-# define UV_SYSCALL_BASE 0x900000
|
||||
-# endif
|
||||
-#endif /* __arm__ */
|
||||
+struct uv__statx_timestamp {
|
||||
+ int64_t tv_sec;
|
||||
+ uint32_t tv_nsec;
|
||||
+ int32_t unused0;
|
||||
+};
|
||||
|
||||
-#ifndef __NR_recvmmsg
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_recvmmsg 299
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_recvmmsg 337
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
|
||||
-# endif
|
||||
-#endif /* __NR_recvmsg */
|
||||
+struct uv__statx {
|
||||
+ uint32_t stx_mask;
|
||||
+ uint32_t stx_blksize;
|
||||
+ uint64_t stx_attributes;
|
||||
+ uint32_t stx_nlink;
|
||||
+ uint32_t stx_uid;
|
||||
+ uint32_t stx_gid;
|
||||
+ uint16_t stx_mode;
|
||||
+ uint16_t unused0;
|
||||
+ uint64_t stx_ino;
|
||||
+ uint64_t stx_size;
|
||||
+ uint64_t stx_blocks;
|
||||
+ uint64_t stx_attributes_mask;
|
||||
+ struct uv__statx_timestamp stx_atime;
|
||||
+ struct uv__statx_timestamp stx_btime;
|
||||
+ struct uv__statx_timestamp stx_ctime;
|
||||
+ struct uv__statx_timestamp stx_mtime;
|
||||
+ uint32_t stx_rdev_major;
|
||||
+ uint32_t stx_rdev_minor;
|
||||
+ uint32_t stx_dev_major;
|
||||
+ uint32_t stx_dev_minor;
|
||||
+ uint64_t unused1[14];
|
||||
+};
|
||||
|
||||
-#ifndef __NR_sendmmsg
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_sendmmsg 307
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_sendmmsg 345
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
|
||||
-# endif
|
||||
-#endif /* __NR_sendmmsg */
|
||||
+struct uv__mmsghdr {
|
||||
+ struct msghdr msg_hdr;
|
||||
+ unsigned int msg_len;
|
||||
+};
|
||||
|
||||
-#ifndef __NR_utimensat
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_utimensat 280
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_utimensat 320
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_utimensat (UV_SYSCALL_BASE + 348)
|
||||
-# endif
|
||||
-#endif /* __NR_utimensat */
|
||||
-
|
||||
-#ifndef __NR_preadv
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_preadv 295
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_preadv 333
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_preadv (UV_SYSCALL_BASE + 361)
|
||||
-# endif
|
||||
-#endif /* __NR_preadv */
|
||||
-
|
||||
-#ifndef __NR_pwritev
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_pwritev 296
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_pwritev 334
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_pwritev (UV_SYSCALL_BASE + 362)
|
||||
-# endif
|
||||
-#endif /* __NR_pwritev */
|
||||
-
|
||||
-#ifndef __NR_dup3
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_dup3 292
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_dup3 330
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_dup3 (UV_SYSCALL_BASE + 358)
|
||||
-# endif
|
||||
-#endif /* __NR_pwritev */
|
||||
-
|
||||
-#ifndef __NR_statx
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_statx 332
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_statx 383
|
||||
-# elif defined(__aarch64__)
|
||||
-# define __NR_statx 397
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_statx (UV_SYSCALL_BASE + 397)
|
||||
-# elif defined(__ppc__)
|
||||
-# define __NR_statx 383
|
||||
-# elif defined(__s390__)
|
||||
-# define __NR_statx 379
|
||||
-# endif
|
||||
-#endif /* __NR_statx */
|
||||
-
|
||||
-#ifndef __NR_getrandom
|
||||
-# if defined(__x86_64__)
|
||||
-# define __NR_getrandom 318
|
||||
-# elif defined(__i386__)
|
||||
-# define __NR_getrandom 355
|
||||
-# elif defined(__aarch64__)
|
||||
-# define __NR_getrandom 384
|
||||
-# elif defined(__arm__)
|
||||
-# define __NR_getrandom (UV_SYSCALL_BASE + 384)
|
||||
-# elif defined(__ppc__)
|
||||
-# define __NR_getrandom 359
|
||||
-# elif defined(__s390__)
|
||||
-# define __NR_getrandom 349
|
||||
-# endif
|
||||
-#endif /* __NR_getrandom */
|
||||
-
|
||||
-struct uv__mmsghdr;
|
||||
-
|
||||
-int uv__sendmmsg(int fd,
|
||||
- struct uv__mmsghdr* mmsg,
|
||||
- unsigned int vlen,
|
||||
- unsigned int flags) {
|
||||
-#if defined(__NR_sendmmsg)
|
||||
- return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-
|
||||
int uv__recvmmsg(int fd,
|
||||
struct uv__mmsghdr* mmsg,
|
||||
unsigned int vlen,
|
||||
unsigned int flags,
|
||||
- struct timespec* timeout) {
|
||||
-#if defined(__NR_recvmmsg)
|
||||
- return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-
|
||||
-ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
|
||||
-#if defined(__NR_preadv)
|
||||
- return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-
|
||||
-ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
|
||||
-#if defined(__NR_pwritev)
|
||||
- return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int uv__dup3(int oldfd, int newfd, int flags) {
|
||||
-#if defined(__NR_dup3)
|
||||
- return syscall(__NR_dup3, oldfd, newfd, flags);
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-
|
||||
+ struct timespec* timeout);
|
||||
+int uv__sendmmsg(int fd,
|
||||
+ struct uv__mmsghdr* mmsg,
|
||||
+ unsigned int vlen,
|
||||
+ unsigned int flags);
|
||||
+ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
|
||||
+ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
|
||||
+int uv__dup3(int oldfd, int newfd, int flags);
|
||||
int uv__statx(int dirfd,
|
||||
const char* path,
|
||||
int flags,
|
||||
unsigned int mask,
|
||||
- struct uv__statx* statxbuf) {
|
||||
- /* __NR_statx make Android box killed by SIGSYS.
|
||||
- * That looks like a seccomp2 sandbox filter rejecting the system call.
|
||||
- */
|
||||
-#if defined(__NR_statx) && !defined(__ANDROID__)
|
||||
- return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
||||
+ struct uv__statx* statxbuf);
|
||||
+ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags);
|
||||
|
||||
+#endif /* UV_LINUX_SYSCALL_H_ */
|
||||
|
||||
-ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) {
|
||||
-#if defined(__NR_getrandom)
|
||||
- return syscall(__NR_getrandom, buf, buflen, flags);
|
||||
-#else
|
||||
- return errno = ENOSYS, -1;
|
||||
-#endif
|
||||
-}
|
28
devel/libuv/files/patch-src_unix_linux-syscalls.h
Normal file
28
devel/libuv/files/patch-src_unix_linux-syscalls.h
Normal file
@ -0,0 +1,28 @@
|
||||
--- src/unix/linux-syscalls.h.orig 2020-04-15 16:31:21 UTC
|
||||
+++ src/unix/linux-syscalls.h
|
||||
@@ -61,6 +61,20 @@ struct uv__statx {
|
||||
uint64_t unused1[14];
|
||||
};
|
||||
|
||||
+struct uv__mmsghdr {
|
||||
+ struct msghdr msg_hdr;
|
||||
+ unsigned int msg_len;
|
||||
+};
|
||||
+
|
||||
+int uv__recvmmsg(int fd,
|
||||
+ struct uv__mmsghdr* mmsg,
|
||||
+ unsigned int vlen,
|
||||
+ unsigned int flags,
|
||||
+ struct timespec* timeout);
|
||||
+int uv__sendmmsg(int fd,
|
||||
+ struct uv__mmsghdr* mmsg,
|
||||
+ unsigned int vlen,
|
||||
+ unsigned int flags);
|
||||
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
|
||||
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
|
||||
int uv__dup3(int oldfd, int newfd, int flags);
|
||||
@@ -72,3 +86,4 @@ int uv__statx(int dirfd,
|
||||
ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags);
|
||||
|
||||
#endif /* UV_LINUX_SYSCALL_H_ */
|
||||
+
|
277
devel/libuv/files/patch-src_unix_udp.c
Normal file
277
devel/libuv/files/patch-src_unix_udp.c
Normal file
@ -0,0 +1,277 @@
|
||||
--- src/unix/udp.c.orig 2020-04-15 16:31:21 UTC
|
||||
+++ src/unix/udp.c
|
||||
@@ -32,8 +32,6 @@
|
||||
#endif
|
||||
#include <sys/un.h>
|
||||
|
||||
-#define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
|
||||
-
|
||||
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
|
||||
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#endif
|
||||
@@ -51,37 +49,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handl
|
||||
int domain,
|
||||
unsigned int flags);
|
||||
|
||||
-#if HAVE_MMSG
|
||||
|
||||
-#define UV__MMSG_MAXWIDTH 20
|
||||
-
|
||||
-static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf);
|
||||
-static void uv__udp_sendmmsg(uv_udp_t* handle);
|
||||
-
|
||||
-static int uv__recvmmsg_avail;
|
||||
-static int uv__sendmmsg_avail;
|
||||
-static uv_once_t once = UV_ONCE_INIT;
|
||||
-
|
||||
-static void uv__udp_mmsg_init(void) {
|
||||
- int ret;
|
||||
- int s;
|
||||
- s = uv__socket(AF_INET, SOCK_DGRAM, 0);
|
||||
- if (s < 0)
|
||||
- return;
|
||||
- ret = uv__sendmmsg(s, NULL, 0, 0);
|
||||
- if (ret == 0 || errno != ENOSYS) {
|
||||
- uv__sendmmsg_avail = 1;
|
||||
- uv__recvmmsg_avail = 1;
|
||||
- } else {
|
||||
- ret = uv__recvmmsg(s, NULL, 0, 0, NULL);
|
||||
- if (ret == 0 || errno != ENOSYS)
|
||||
- uv__recvmmsg_avail = 1;
|
||||
- }
|
||||
- uv__close(s);
|
||||
-}
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
void uv__udp_close(uv_udp_t* handle) {
|
||||
uv__io_close(handle->loop, &handle->io_watcher);
|
||||
uv__handle_stop(handle);
|
||||
@@ -180,62 +148,7 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, u
|
||||
}
|
||||
}
|
||||
|
||||
-#if HAVE_MMSG
|
||||
-static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
- struct sockaddr_in6 peers[UV__MMSG_MAXWIDTH];
|
||||
- struct iovec iov[UV__MMSG_MAXWIDTH];
|
||||
- struct uv__mmsghdr msgs[UV__MMSG_MAXWIDTH];
|
||||
- ssize_t nread;
|
||||
- uv_buf_t chunk_buf;
|
||||
- size_t chunks;
|
||||
- int flags;
|
||||
- size_t k;
|
||||
|
||||
- /* prepare structures for recvmmsg */
|
||||
- chunks = buf->len / UV__UDP_DGRAM_MAXSIZE;
|
||||
- if (chunks > ARRAY_SIZE(iov))
|
||||
- chunks = ARRAY_SIZE(iov);
|
||||
- for (k = 0; k < chunks; ++k) {
|
||||
- iov[k].iov_base = buf->base + k * UV__UDP_DGRAM_MAXSIZE;
|
||||
- iov[k].iov_len = UV__UDP_DGRAM_MAXSIZE;
|
||||
- msgs[k].msg_hdr.msg_iov = iov + k;
|
||||
- msgs[k].msg_hdr.msg_iovlen = 1;
|
||||
- msgs[k].msg_hdr.msg_name = peers + k;
|
||||
- msgs[k].msg_hdr.msg_namelen = sizeof(peers[0]);
|
||||
- }
|
||||
-
|
||||
- do
|
||||
- nread = uv__recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL);
|
||||
- while (nread == -1 && errno == EINTR);
|
||||
-
|
||||
- if (nread < 1) {
|
||||
- if (nread == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
- handle->recv_cb(handle, 0, buf, NULL, 0);
|
||||
- else
|
||||
- handle->recv_cb(handle, UV__ERR(errno), buf, NULL, 0);
|
||||
- } else {
|
||||
- /* pass each chunk to the application */
|
||||
- for (k = 0; k < (size_t) nread && handle->recv_cb != NULL; k++) {
|
||||
- flags = UV_UDP_MMSG_CHUNK;
|
||||
- if (msgs[k].msg_hdr.msg_flags & MSG_TRUNC)
|
||||
- flags |= UV_UDP_PARTIAL;
|
||||
-
|
||||
- chunk_buf = uv_buf_init(iov[k].iov_base, iov[k].iov_len);
|
||||
- handle->recv_cb(handle,
|
||||
- msgs[k].msg_len,
|
||||
- &chunk_buf,
|
||||
- msgs[k].msg_hdr.msg_name,
|
||||
- flags);
|
||||
- }
|
||||
-
|
||||
- /* one last callback so the original buffer is freed */
|
||||
- if (handle->recv_cb != NULL)
|
||||
- handle->recv_cb(handle, 0, buf, NULL, 0);
|
||||
- }
|
||||
- return nread;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static void uv__udp_recvmsg(uv_udp_t* handle) {
|
||||
struct sockaddr_storage peer;
|
||||
struct msghdr h;
|
||||
@@ -254,27 +167,13 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
||||
|
||||
do {
|
||||
buf = uv_buf_init(NULL, 0);
|
||||
- handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf);
|
||||
+ handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf);
|
||||
if (buf.base == NULL || buf.len == 0) {
|
||||
handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
|
||||
return;
|
||||
}
|
||||
assert(buf.base != NULL);
|
||||
|
||||
-#if HAVE_MMSG
|
||||
- uv_once(&once, uv__udp_mmsg_init);
|
||||
- if (uv__recvmmsg_avail) {
|
||||
- /* Returned space for more than 1 datagram, use it to receive
|
||||
- * multiple datagrams. */
|
||||
- if (buf.len >= 2 * UV__UDP_DGRAM_MAXSIZE) {
|
||||
- nread = uv__udp_recvmmsg(handle, &buf);
|
||||
- if (nread > 0)
|
||||
- count -= nread;
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
memset(&h, 0, sizeof(h));
|
||||
memset(&peer, 0, sizeof(peer));
|
||||
h.msg_name = &peer;
|
||||
@@ -300,120 +199,21 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
||||
|
||||
handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags);
|
||||
}
|
||||
- count--;
|
||||
}
|
||||
/* recv_cb callback may decide to pause or close the handle */
|
||||
while (nread != -1
|
||||
- && count > 0
|
||||
+ && count-- > 0
|
||||
&& handle->io_watcher.fd != -1
|
||||
&& handle->recv_cb != NULL);
|
||||
}
|
||||
|
||||
-#if HAVE_MMSG
|
||||
-static void uv__udp_sendmmsg(uv_udp_t* handle) {
|
||||
- uv_udp_send_t* req;
|
||||
- struct uv__mmsghdr h[UV__MMSG_MAXWIDTH];
|
||||
- struct uv__mmsghdr *p;
|
||||
- QUEUE* q;
|
||||
- ssize_t npkts;
|
||||
- size_t pkts;
|
||||
- size_t i;
|
||||
|
||||
- if (QUEUE_EMPTY(&handle->write_queue))
|
||||
- return;
|
||||
-
|
||||
-write_queue_drain:
|
||||
- for (pkts = 0, q = QUEUE_HEAD(&handle->write_queue);
|
||||
- pkts < UV__MMSG_MAXWIDTH && q != &handle->write_queue;
|
||||
- ++pkts, q = QUEUE_HEAD(q)) {
|
||||
- assert(q != NULL);
|
||||
- req = QUEUE_DATA(q, uv_udp_send_t, queue);
|
||||
- assert(req != NULL);
|
||||
-
|
||||
- p = &h[pkts];
|
||||
- memset(p, 0, sizeof(*p));
|
||||
- if (req->addr.ss_family == AF_UNSPEC) {
|
||||
- p->msg_hdr.msg_name = NULL;
|
||||
- p->msg_hdr.msg_namelen = 0;
|
||||
- } else {
|
||||
- p->msg_hdr.msg_name = &req->addr;
|
||||
- if (req->addr.ss_family == AF_INET6)
|
||||
- p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in6);
|
||||
- else if (req->addr.ss_family == AF_INET)
|
||||
- p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in);
|
||||
- else if (req->addr.ss_family == AF_UNIX)
|
||||
- p->msg_hdr.msg_namelen = sizeof(struct sockaddr_un);
|
||||
- else {
|
||||
- assert(0 && "unsupported address family");
|
||||
- abort();
|
||||
- }
|
||||
- }
|
||||
- h[pkts].msg_hdr.msg_iov = (struct iovec*) req->bufs;
|
||||
- h[pkts].msg_hdr.msg_iovlen = req->nbufs;
|
||||
- }
|
||||
-
|
||||
- do
|
||||
- npkts = uv__sendmmsg(handle->io_watcher.fd, h, pkts, 0);
|
||||
- while (npkts == -1 && errno == EINTR);
|
||||
-
|
||||
- if (npkts < 1) {
|
||||
- if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
- return;
|
||||
- for (i = 0, q = QUEUE_HEAD(&handle->write_queue);
|
||||
- i < pkts && q != &handle->write_queue;
|
||||
- ++i, q = QUEUE_HEAD(q)) {
|
||||
- assert(q != NULL);
|
||||
- req = QUEUE_DATA(q, uv_udp_send_t, queue);
|
||||
- assert(req != NULL);
|
||||
-
|
||||
- req->status = UV__ERR(errno);
|
||||
- QUEUE_REMOVE(&req->queue);
|
||||
- QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
|
||||
- }
|
||||
- uv__io_feed(handle->loop, &handle->io_watcher);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- for (i = 0, q = QUEUE_HEAD(&handle->write_queue);
|
||||
- i < pkts && q != &handle->write_queue;
|
||||
- ++i, q = QUEUE_HEAD(&handle->write_queue)) {
|
||||
- assert(q != NULL);
|
||||
- req = QUEUE_DATA(q, uv_udp_send_t, queue);
|
||||
- assert(req != NULL);
|
||||
-
|
||||
- req->status = req->bufs[0].len;
|
||||
-
|
||||
- /* Sending a datagram is an atomic operation: either all data
|
||||
- * is written or nothing is (and EMSGSIZE is raised). That is
|
||||
- * why we don't handle partial writes. Just pop the request
|
||||
- * off the write queue and onto the completed queue, done.
|
||||
- */
|
||||
- QUEUE_REMOVE(&req->queue);
|
||||
- QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
|
||||
- }
|
||||
-
|
||||
- /* couldn't batch everything, continue sending (jump to avoid stack growth) */
|
||||
- if (!QUEUE_EMPTY(&handle->write_queue))
|
||||
- goto write_queue_drain;
|
||||
- uv__io_feed(handle->loop, &handle->io_watcher);
|
||||
- return;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static void uv__udp_sendmsg(uv_udp_t* handle) {
|
||||
uv_udp_send_t* req;
|
||||
- struct msghdr h;
|
||||
QUEUE* q;
|
||||
+ struct msghdr h;
|
||||
ssize_t size;
|
||||
|
||||
-#if HAVE_MMSG
|
||||
- uv_once(&once, uv__udp_mmsg_init);
|
||||
- if (uv__sendmmsg_avail) {
|
||||
- uv__udp_sendmmsg(handle);
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
while (!QUEUE_EMPTY(&handle->write_queue)) {
|
||||
q = QUEUE_HEAD(&handle->write_queue);
|
||||
assert(q != NULL);
|
||||
@@ -463,6 +263,7 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
|
||||
}
|
||||
}
|
||||
|
||||
+
|
||||
/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional
|
||||
* refinements for programs that use multicast.
|
||||
*
|
||||
@@ -1333,3 +1134,4 @@ int uv__udp_recv_stop(uv_udp_t* handle) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
Loading…
Reference in New Issue
Block a user