mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-18 23:06:06 -05:00
- Use TCP_NODELAY on TLS sockets to speed up the TLS handshake.
This commit is contained in:
parent
ded4c82ced
commit
7559d26c93
6 changed files with 63 additions and 30 deletions
|
|
@ -703,7 +703,10 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
|||
{
|
||||
int s = -1;
|
||||
char* err;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) \
|
||||
|| defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) \
|
||||
|| defined(IP_BINDANY) || defined(IP_FREEBIND) \
|
||||
|| defined(SO_BINDANY) || defined(TCP_NODELAY)
|
||||
int on = 1;
|
||||
#endif
|
||||
#ifdef HAVE_SYSTEMD
|
||||
|
|
@ -1237,26 +1240,6 @@ set_recvpktinfo(int s, int family)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** see if interface is ssl, its port number == the ssl port number */
|
||||
static int
|
||||
if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
||||
struct config_strlist* tls_additional_port)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
char* p = strchr(ifname, '@');
|
||||
if(!p && atoi(port) == ssl_port)
|
||||
return 1;
|
||||
if(p && atoi(p+1) == ssl_port)
|
||||
return 1;
|
||||
for(s = tls_additional_port; s; s = s->next) {
|
||||
if(p && atoi(p+1) == atoi(s->str))
|
||||
return 1;
|
||||
if(!p && atoi(port) == atoi(s->str))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for ports_open. Creates one interface (or NULL for default).
|
||||
* @param ifname: The interface ip address.
|
||||
|
|
@ -1300,10 +1283,16 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
int quic_port, int http_notls_downstream, int sock_queue_timeout)
|
||||
{
|
||||
int s, noip6=0;
|
||||
int is_ssl = if_is_ssl(ifname, port, ssl_port, tls_additional_port);
|
||||
int is_https = if_is_https(ifname, port, https_port);
|
||||
int is_dnscrypt = if_is_dnscrypt(ifname, port, dnscrypt_port);
|
||||
int is_pp2 = if_is_pp2(ifname, port, proxy_protocol_port);
|
||||
int nodelay = is_https && http2_nodelay;
|
||||
/* Always set TCP_NODELAY on TLS connection as it speeds up the TLS
|
||||
* handshake. DoH had already such option so we respect it.
|
||||
* Otherwise the server waits before sending more handshake data for
|
||||
* the client ACK (Nagle's algorithm), which is delayed because the
|
||||
* client waits for more data before ACKing (delayed ACK). */
|
||||
int nodelay = is_https?http2_nodelay:is_ssl;
|
||||
struct unbound_socket* ub_sock;
|
||||
int is_doq = if_is_quic(ifname, port, quic_port);
|
||||
const char* add = NULL;
|
||||
|
|
|
|||
|
|
@ -262,12 +262,14 @@ pick_outgoing_tcp(struct pending_tcp* pend, struct waiting_tcp* w, int s)
|
|||
/** get TCP file descriptor for address, returns -1 on failure,
|
||||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||
int
|
||||
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp)
|
||||
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int tcp_mss, int dscp, int nodelay)
|
||||
{
|
||||
int s;
|
||||
int af;
|
||||
char* err;
|
||||
#if defined(SO_REUSEADDR) || defined(IP_BIND_ADDRESS_NO_PORT)
|
||||
#if defined(SO_REUSEADDR) || defined(IP_BIND_ADDRESS_NO_PORT) \
|
||||
|| defined(TCP_NODELAY)
|
||||
int on = 1;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
|
|
@ -320,6 +322,18 @@ outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss,
|
|||
" setsockopt(.. IP_BIND_ADDRESS_NO_PORT ..) failed");
|
||||
}
|
||||
#endif /* IP_BIND_ADDRESS_NO_PORT */
|
||||
if(nodelay) {
|
||||
#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
|
||||
if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
verbose(VERB_ALGO, "outgoing tcp:"
|
||||
" setsockopt(.. TCP_NODELAY ..) failed");
|
||||
}
|
||||
#else
|
||||
verbose(VERB_ALGO, "outgoing tcp:"
|
||||
" setsockopt(.. TCP_NODELAY ..) unsupported");
|
||||
#endif /* defined(IPPROTO_TCP) && defined(TCP_NODELAY) */
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -649,7 +663,8 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
|
|||
}
|
||||
|
||||
/* open socket */
|
||||
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss, w->outnet->ip_dscp);
|
||||
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss,
|
||||
w->outnet->ip_dscp, w->ssl_upstream);
|
||||
|
||||
if(s == -1)
|
||||
return 0;
|
||||
|
|
@ -3718,7 +3733,8 @@ outnet_comm_point_for_tcp(struct outside_network* outnet,
|
|||
sldns_buffer* query, int timeout, int ssl, char* host)
|
||||
{
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss,
|
||||
outnet->ip_dscp, ssl);
|
||||
if(fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3793,7 +3809,8 @@ outnet_comm_point_for_http(struct outside_network* outnet,
|
|||
{
|
||||
/* cp calls cb with err=NETEVENT_DONE when transfer is done */
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss,
|
||||
outnet->ip_dscp, ssl);
|
||||
if(fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -743,9 +743,11 @@ void reuse_write_wait_remove(struct reuse_tcp* reuse, struct waiting_tcp* w);
|
|||
void reuse_write_wait_push_back(struct reuse_tcp* reuse, struct waiting_tcp* w);
|
||||
|
||||
/** get TCP file descriptor for address, returns -1 on failure,
|
||||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||
* tcp_mss is 0 or maxseg size to set for TCP packets,
|
||||
* nodelay (TCP_NODELAY) should be set for TLS connections to speed up the TLS
|
||||
* handshake.*/
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int tcp_mss, int dscp);
|
||||
int tcp_mss, int dscp, int nodelay);
|
||||
|
||||
/**
|
||||
* Create udp commpoint suitable for sending packets to the destination.
|
||||
|
|
|
|||
|
|
@ -1938,7 +1938,8 @@ int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
|||
}
|
||||
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss), int ATTR_UNUSED(dscp))
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss),
|
||||
int ATTR_UNUSED(dscp), int ATTR_UNUSED(nodelay))
|
||||
{
|
||||
log_assert(0);
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -2796,6 +2796,26 @@ int cfg_has_https(struct config_file* cfg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** see if interface is ssl, its port number == the ssl port number */
|
||||
int
|
||||
if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
||||
struct config_strlist* tls_additional_port)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
char* p = strchr(ifname, '@');
|
||||
if(!p && atoi(port) == ssl_port)
|
||||
return 1;
|
||||
if(p && atoi(p+1) == ssl_port)
|
||||
return 1;
|
||||
for(s = tls_additional_port; s; s = s->next) {
|
||||
if(p && atoi(p+1) == atoi(s->str))
|
||||
return 1;
|
||||
if(!p && atoi(port) == atoi(s->str))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** see if interface is PROXYv2, its port number == the proxy port number */
|
||||
int
|
||||
if_is_pp2(const char* ifname, const char* port,
|
||||
|
|
|
|||
|
|
@ -1405,6 +1405,10 @@ int if_is_https(const char* ifname, const char* port, int https_port);
|
|||
*/
|
||||
int cfg_has_https(struct config_file* cfg);
|
||||
|
||||
/** see if interface is ssl, its port number == the ssl port number */
|
||||
int if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
||||
struct config_strlist* tls_additional_port);
|
||||
|
||||
/** see if interface is PROXYv2, its port number == the proxy port number */
|
||||
int if_is_pp2(const char* ifname, const char* port,
|
||||
struct config_strlist* proxy_protocol_port);
|
||||
|
|
|
|||
Loading…
Reference in a new issue