mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- Fix to wait for blocked write on UDP sockets, with a timeout if it
takes too long the packet is dropped.
This commit is contained in:
parent
10a5a5880a
commit
ec5812a748
@ -457,6 +457,12 @@
|
||||
/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */
|
||||
#undef HAVE_OSSL_PARAM_BLD_NEW
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#undef HAVE_POLL_H
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
#undef HAVE_PTHREAD
|
||||
|
||||
|
4
configure
vendored
4
configure
vendored
@ -14772,7 +14772,7 @@ fi
|
||||
fi
|
||||
|
||||
# Checks for header files.
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
@ -20591,7 +20591,7 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
|
@ -397,7 +397,7 @@ PKG_PROG_PKG_CONFIG
|
||||
fi
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT])
|
||||
# net/if.h portability for Darwin see:
|
||||
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
|
||||
AC_CHECK_HEADERS([net/if.h],,, [
|
||||
@ -1644,7 +1644,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
- Patch from Vadim Fedorenko that adds MSG_DONTWAIT to receive
|
||||
operations, so that instruction reordering does not cause mistakenly
|
||||
blocking socket operations.
|
||||
- Fix to wait for blocked write on UDP sockets, with a timeout if it
|
||||
takes too long the packet is dropped.
|
||||
|
||||
22 August 2022: Wouter
|
||||
- Fix #741: systemd socket activation fails on IPv6.
|
||||
|
@ -60,6 +60,9 @@
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
@ -107,6 +110,9 @@
|
||||
#define NUM_UDP_PER_SELECT 1
|
||||
#endif
|
||||
|
||||
/** timeout in millisec to wait for write to unblock, packets dropped after.*/
|
||||
#define SEND_BLOCKED_WAIT_TIMEOUT 200
|
||||
|
||||
/**
|
||||
* The internal event structure for keeping ub_event info for the event.
|
||||
* Possibly other structures (list, tree) this is part of.
|
||||
@ -369,13 +375,14 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
||||
* we want to send the answer, and we will wait for
|
||||
* the ethernet interface buffer to have space. */
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN ||
|
||||
if(errno == EAGAIN || errno == EINTR ||
|
||||
# ifdef EWOULDBLOCK
|
||||
errno == EWOULDBLOCK ||
|
||||
# endif
|
||||
errno == ENOBUFS) {
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEINTR ||
|
||||
WSAGetLastError() == WSAENOBUFS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK) {
|
||||
#endif
|
||||
@ -383,17 +390,54 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
||||
* have a blocking fd that they operate on */
|
||||
while(
|
||||
#ifndef USE_WINSOCK
|
||||
errno == EAGAIN ||
|
||||
errno == EAGAIN || errno == EINTR ||
|
||||
# ifdef EWOULDBLOCK
|
||||
errno == EWOULDBLOCK ||
|
||||
# endif
|
||||
errno == ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEINTR ||
|
||||
WSAGetLastError() == WSAENOBUFS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK
|
||||
#endif
|
||||
) {
|
||||
#if defined(HAVE_POLL) || defined(USE_WINSOCK)
|
||||
struct pollfd p;
|
||||
int pret;
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.fd = c->fd;
|
||||
p.events = POLLOUT | POLLERR | POLLHUP;
|
||||
# ifndef USE_WINSOCK
|
||||
pret = poll(&p, 1, SEND_BLOCKED_WAIT_TIMEOUT);
|
||||
# else
|
||||
pret = WSAPoll(&p, 1,
|
||||
SEND_BLOCKED_WAIT_TIMEOUT);
|
||||
# endif
|
||||
if(pret == 0) {
|
||||
/* timer expired */
|
||||
verbose(VERB_OPS, "send udp blocked "
|
||||
"for long, dropping packet.");
|
||||
return 0;
|
||||
} else if(pret < 0 &&
|
||||
#ifndef USE_WINSOCK
|
||||
errno != EAGAIN && errno != EINTR &&
|
||||
# ifdef EWOULDBLOCK
|
||||
errno != EWOULDBLOCK &&
|
||||
# endif
|
||||
errno != ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEINTR &&
|
||||
WSAGetLastError() != WSAENOBUFS &&
|
||||
WSAGetLastError() != WSAEWOULDBLOCK
|
||||
#endif
|
||||
) {
|
||||
log_err("poll udp out failed: %s",
|
||||
sock_strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_POLL) || defined(USE_WINSOCK) */
|
||||
if (!is_connected) {
|
||||
sent = sendto(c->fd, (void*)sldns_buffer_begin(packet),
|
||||
sldns_buffer_remaining(packet), 0,
|
||||
@ -569,29 +613,67 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
||||
* we want to send the answer, and we will wait for
|
||||
* the ethernet interface buffer to have space. */
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN ||
|
||||
if(errno == EAGAIN || errno == EINTR ||
|
||||
# ifdef EWOULDBLOCK
|
||||
errno == EWOULDBLOCK ||
|
||||
# endif
|
||||
errno == ENOBUFS) {
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEINTR ||
|
||||
WSAGetLastError() == WSAENOBUFS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK) {
|
||||
#endif
|
||||
while(
|
||||
#ifndef USE_WINSOCK
|
||||
errno == EAGAIN ||
|
||||
errno == EAGAIN || errno == EINTR ||
|
||||
# ifdef EWOULDBLOCK
|
||||
errno == EWOULDBLOCK ||
|
||||
# endif
|
||||
errno == ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEINTR ||
|
||||
WSAGetLastError() == WSAENOBUFS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK
|
||||
#endif
|
||||
) {
|
||||
#if defined(HAVE_POLL) || defined(USE_WINSOCK)
|
||||
struct pollfd p;
|
||||
int pret;
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.fd = c->fd;
|
||||
p.events = POLLOUT | POLLERR | POLLHUP;
|
||||
# ifndef USE_WINSOCK
|
||||
pret = poll(&p, 1, SEND_BLOCKED_WAIT_TIMEOUT);
|
||||
# else
|
||||
pret = WSAPoll(&p, 1,
|
||||
SEND_BLOCKED_WAIT_TIMEOUT);
|
||||
# endif
|
||||
if(pret == 0) {
|
||||
/* timer expired */
|
||||
verbose(VERB_OPS, "send udp blocked "
|
||||
"for long, dropping packet.");
|
||||
return 0;
|
||||
} else if(pret < 0 &&
|
||||
#ifndef USE_WINSOCK
|
||||
errno != EAGAIN && errno != EINTR &&
|
||||
# ifdef EWOULDBLOCK
|
||||
errno != EWOULDBLOCK &&
|
||||
# endif
|
||||
errno != ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEINTR &&
|
||||
WSAGetLastError() != WSAENOBUFS &&
|
||||
WSAGetLastError() != WSAEWOULDBLOCK
|
||||
#endif
|
||||
) {
|
||||
log_err("poll udp out failed: %s",
|
||||
sock_strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_POLL) || defined(USE_WINSOCK) */
|
||||
sent = sendmsg(c->fd, &msg, 0);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user