Issue #422: Update server & client TFO

Seems to work for TLS now too.
At least on Linux.
Thanks Craig Andrews
This commit is contained in:
Willem Toorop 2019-03-15 12:13:38 +01:00
parent 74e584cd61
commit 7438de712a
4 changed files with 74 additions and 17 deletions

View File

@ -1,5 +1,8 @@
* 2019-??-??: Version 1.?.?
* Issue #422: Enable server side and update client side TCP Fast
Open implementation. Thanks Craig Andrews
* Issue #423: Fix insecure delegation detection while scheduling.
Thanks Charles Milette
* Issue #419: Escape backslashed when printing in JSON format.
Thanks boB Rudis
* DOA rr-type

View File

@ -302,13 +302,31 @@ if test "x$enable_tcp_fastopen" = xno; then
AC_MSG_WARN([TCP Fast Open is disabled])
else
case `uname` in
Linux) AC_CHECK_DECL([MSG_FASTOPEN], [AC_DEFINE_UNQUOTED([USE_TCP_FASTOPEN], [1], [Define this to enable TCP fast open.])],
[AC_MSG_WARN([TCP Fast Open is not available, continuing without])], [#include <sys/socket.h>])
;;
Darwin) AC_CHECK_DECL([CONNECT_RESUME_ON_READ_WRITE], [AC_DEFINE_UNQUOTED([USE_OSX_TCP_FASTOPEN], [1], [Define this to enable TCP fast open.])],
[AC_MSG_WARN([TCP Fast Open is not available, continuing without])], [#include <sys/socket.h>])
;;
*) AC_MSG_WARN([TCP Fast Open is not available, continuing without])
*)
AC_CHECK_HEADERS([sys/socket.h netinet/tcp.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECL([TCP_FASTOPEN], [
AC_DEFINE_UNQUOTED([USE_TCP_FASTOPEN], [1], [Define this to enable TCP fast open.])
AC_CHECK_DECLS([TCP_FASTOPEN,MSG_FASTOPEN,TCP_FASTOPEN_CONNECT], [], [], [AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_TCP_H
# include <netinet/tcp.h>
#endif
])
], [
AC_MSG_WARN([TCP Fast Open is not available, continuing without])
], [AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_TCP_H
# include <netinet/tcp.h>
#endif
])
;;
esac
fi
@ -1731,6 +1749,10 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

View File

@ -860,9 +860,15 @@ static getdns_return_t add_listeners(listen_set *set)
break;
if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEADDR,
&enable, sizeof(int)) < 0) {
&enable, sizeof(enable)) < 0) {
; /* Ignore */
}
#ifdef HAVE_DECL_TCP_FASTOPEN
if (setsockopt(l->fd, IPPROTO_TCP, TCP_FASTOPEN,
&enable, sizeof(enable)) < 0) {
; /* Ignore */
}
#endif
if (bind(l->fd, (struct sockaddr *)&l->addr,
l->addr_len) == -1)
/* IO error */

View File

@ -375,22 +375,23 @@ getdns_sock_nonblock(int sockfd)
static int
tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
{
#if defined(TCP_FASTOPEN) || defined(TCP_FASTOPEN_CONNECT)
# ifdef USE_WINSOCK
static const char enable = 1;
# else
static const int enable = 1;
# endif
#endif
int fd = -1;
DEBUG_STUB("%s %-35s: Creating TCP connection: %p\n", STUB_DEBUG_SETUP,
__FUNC__, (void*)upstream);
if ((fd = socket(upstream->addr.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
return -1;
getdns_sock_nonblock(fd);
/* Note that error detection is different with TFO. Since the handshake
doesn't start till the sendto() lack of connection is often delayed until
then or even the subsequent event depending on the error and platform.*/
#ifdef USE_TCP_FASTOPEN
/* Leave the connect to the later call to sendto() if using TCP*/
if (transport == GETDNS_TRANSPORT_TCP)
return fd;
#elif USE_OSX_TCP_FASTOPEN
(void)transport;
#ifdef USE_OSX_TCP_FASTOPEN
sa_endpoints_t endpoints;
endpoints.sae_srcif = 0;
endpoints.sae_srcaddr = NULL;
@ -405,9 +406,29 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
if (_getdns_socketerror() == _getdns_EINPROGRESS ||
_getdns_socketerror() == _getdns_EWOULDBLOCK)
return fd;
#else
(void)transport;
#endif
#else /* USE_OSX_TCP_FASTOPEN */
/* Note that error detection is different with TFO. Since the handshake
doesn't start till the sendto() lack of connection is often delayed until
then or even the subsequent event depending on the error and platform.*/
# ifdef HAVE_DECL_TCP_FASTOPEN_CONNECT
(void)setsockopt( fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT
, (void *)&enable, sizeof(enable));
# else /* HAVE_DECL_TCP_FASTOPEN_CONNECT */
# ifdef HAVE_DECL_TCP_FASTOPEN
(void)setsockopt( fd, IPPROTO_TCP, TCP_FASTOPEN
, (void *)&enable, sizeof(enable));
# endif/* HAVE_DECL_TCP_FASTOPEN*/
# endif /* HAVE_DECL_TCP_FASTOPEN_CONNECT */
# ifdef HAVE_DECL_MSG_FASTOPEN
/* Leave the connect to the later call to sendto() if using TCP*/
if (transport == GETDNS_TRANSPORT_TCP)
return fd;
# else /* HAVE_DECL_MSG_FASTOPEN */
(void)transport;
# endif /* HAVE_DECL_MSG_FASTOPEN */
#endif /* USE_OSX_TCP_FASTOPEN */
if (connect(fd, (struct sockaddr *)&upstream->addr,
upstream->addr_len) == -1) {
if (_getdns_socketerror() == _getdns_EINPROGRESS ||
@ -739,7 +760,12 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
/* We use sendto() here which will do both a connect and send */
#ifdef USE_TCP_FASTOPEN
written = sendto(fd, netreq->query - 2, pkt_len + 2,
MSG_FASTOPEN, (struct sockaddr *)&(netreq->upstream->addr),
# ifdef HAVE_DECL_MSG_FASTOPEN
MSG_FASTOPEN,
# else
0,
# endif
(struct sockaddr *)&(netreq->upstream->addr),
netreq->upstream->addr_len);
/* If pipelining we will find that the connection is already up so
just fall back to a 'normal' write. */