diff options
Diffstat (limited to 'services/outside_network.c')
| -rw-r--r-- | services/outside_network.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/services/outside_network.c b/services/outside_network.c index 5700ef8a95e5..87c88349b3f8 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -48,6 +48,7 @@ #include "services/outside_network.h" #include "services/listen_dnsport.h" #include "services/cache/infra.h" +#include "iterator/iterator.h" #include "util/data/msgparse.h" #include "util/data/msgreply.h" #include "util/data/msgencode.h" @@ -1036,6 +1037,8 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen, int freebind = 0; struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr; sa.sin6_port = (in_port_t)htons((uint16_t)port); + sa.sin6_flowinfo = 0; + sa.sin6_scope_id = 0; if(pfxlen != 0) { freebind = 1; sai6_putrandom(&sa, pfxlen, rnd); @@ -1882,7 +1885,7 @@ serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff) sq->last_sent_time = *sq->outnet->now_tv; if(sq->tcp_upstream || sq->ssl_upstream) { timeout = rtt; - if(rtt >= 376 && rtt < TCP_AUTH_QUERY_TIMEOUT) + if(rtt >= UNKNOWN_SERVER_NICENESS && rtt < TCP_AUTH_QUERY_TIMEOUT) timeout = TCP_AUTH_QUERY_TIMEOUT; } else { timeout = TCP_AUTH_QUERY_TIMEOUT; @@ -2190,39 +2193,48 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr, { struct sockaddr_storage* addr; socklen_t addrlen; - int i; - int try; - - /* select interface */ - if(addr_is_ip6(to_addr, to_addrlen)) { - if(outnet->num_ip6 == 0) { - char to[64]; - addr_to_str(to_addr, to_addrlen, to, sizeof(to)); - verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to); - return -1; - } - i = ub_random_max(outnet->rnd, outnet->num_ip6); - addr = &outnet->ip6_ifs[i].addr; - addrlen = outnet->ip6_ifs[i].addrlen; - } else { - if(outnet->num_ip4 == 0) { - char to[64]; - addr_to_str(to_addr, to_addrlen, to, sizeof(to)); - verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to); - return -1; - } - i = ub_random_max(outnet->rnd, outnet->num_ip4); - addr = &outnet->ip4_ifs[i].addr; - addrlen = outnet->ip4_ifs[i].addrlen; - } + int i, try, pnum; + struct port_if* pif; /* create fd */ for(try = 0; try<1000; try++) { + int port = 0; int freebind = 0; int noproto = 0; int inuse = 0; - int port = ub_random(outnet->rnd)&0xffff; int fd = -1; + + /* select interface */ + if(addr_is_ip6(to_addr, to_addrlen)) { + if(outnet->num_ip6 == 0) { + char to[64]; + addr_to_str(to_addr, to_addrlen, to, sizeof(to)); + verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to); + return -1; + } + i = ub_random_max(outnet->rnd, outnet->num_ip6); + pif = &outnet->ip6_ifs[i]; + } else { + if(outnet->num_ip4 == 0) { + char to[64]; + addr_to_str(to_addr, to_addrlen, to, sizeof(to)); + verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to); + return -1; + } + i = ub_random_max(outnet->rnd, outnet->num_ip4); + pif = &outnet->ip4_ifs[i]; + } + addr = &pif->addr; + addrlen = pif->addrlen; + pnum = ub_random_max(outnet->rnd, pif->avail_total); + if(pnum < pif->inuse) { + /* port already open */ + port = pif->out[pnum]->number; + } else { + /* unused ports in start part of array */ + port = pif->avail_ports[pnum - pif->inuse]; + } + if(addr_is_ip6(to_addr, to_addrlen)) { struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr; sa.sin6_port = (in_port_t)htons((uint16_t)port); |
