diff --git a/bin/named/server.c b/bin/named/server.c index 57930b5040..e70cba3662 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -160,10 +160,8 @@ #ifdef TUNE_LARGE #define RESOLVER_NTASKS_PERCPU 32 -#define UDPBUFFERS 32768 #else #define RESOLVER_NTASKS_PERCPU 8 -#define UDPBUFFERS 4096 #endif /* TUNE_LARGE */ /* RFC7828 defines timeout as 16-bit value specified in units of 100 @@ -1260,9 +1258,8 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, isc_result_t result = ISC_R_FAILURE; dns_dispatch_t *disp = NULL; isc_sockaddr_t sa; - unsigned int attrs; + unsigned int attrs = 0; const cfg_obj_t *obj = NULL; - unsigned int maxdispatchbuffers = UDPBUFFERS; isc_dscp_t dscp = -1; switch (af) { @@ -1308,15 +1305,6 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, /* * Try to find a dispatcher that we can share. */ - attrs = DNS_DISPATCHATTR_UDP; - switch (af) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - } if (isc_sockaddr_getport(&sa) != 0) { INSIST(obj != NULL); if (is_firstview) { @@ -1327,9 +1315,8 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af, } } - result = dns_dispatch_createudp( - named_g_dispatchmgr, named_g_socketmgr, named_g_taskmgr, &sa, - maxdispatchbuffers, 32768, 16411, 16433, attrs, &disp); + result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_socketmgr, + named_g_taskmgr, &sa, attrs, &disp); if (result != ISC_R_SUCCESS) { isc_sockaddr_t any; char buf[ISC_SOCKADDR_FORMATSIZE]; @@ -10343,7 +10330,7 @@ named_add_reserved_dispatch(named_server_t *server, in_port_t port; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_result_t result; - unsigned int attrs; + unsigned int attrs = 0; REQUIRE(NAMED_SERVER_VALID(server)); @@ -10370,22 +10357,8 @@ named_add_reserved_dispatch(named_server_t *server, dispatch->dispatchgen = server->dispatchgen; dispatch->dispatch = NULL; - attrs = DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(addr)) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup; - } - result = dns_dispatch_createudp(named_g_dispatchmgr, named_g_socketmgr, - named_g_taskmgr, &dispatch->addr, - UDPBUFFERS, 32768, 16411, 16433, attrs, + named_g_taskmgr, &dispatch->addr, attrs, &dispatch->dispatch); if (result != ISC_R_SUCCESS) { goto cleanup; diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index d0a2895d01..be39164216 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -801,7 +801,6 @@ static void setup_system(void) { isc_result_t result; isc_sockaddr_t bind_any, bind_any6; - unsigned int attrs; isc_sockaddrlist_t *nslist; isc_logconfig_t *logconfig = NULL; irs_resconf_t *resconf = NULL; @@ -937,20 +936,16 @@ setup_system(void) { set_source_ports(dispatchmgr); if (have_ipv6) { - attrs = (DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_IPV6); isc_sockaddr_any6(&bind_any6); result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, - &bind_any6, 4, 2, 3, 5, attrs, - &dispatchv6); + &bind_any6, 0, &dispatchv6); check_result(result, "dns_dispatch_createudp (v6)"); } if (have_ipv4) { - attrs = (DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_IPV4); isc_sockaddr_any(&bind_any); result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, - &bind_any, 4, 2, 3, 5, attrs, - &dispatchv4); + &bind_any, 0, &dispatchv4); check_result(result, "dns_dispatch_createudp (v4)"); } diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index 0adf5036ff..6466771ff2 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -70,7 +70,7 @@ static void recvresponse(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = (dns_requestevent_t *)event; isc_result_t result; - dns_message_t *query, *response; + dns_message_t *query = NULL, *response = NULL; isc_buffer_t outbuf; char output[1024]; @@ -86,7 +86,6 @@ recvresponse(isc_task_t *task, isc_event_t *event) { query = reqev->ev_arg; - response = NULL; dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); result = dns_request_getresponse(reqev->request, response, @@ -207,7 +206,6 @@ main(int argc, char *argv[]) { isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; dns_dispatchmgr_t *dispatchmgr = NULL; - unsigned int attrs; dns_dispatch_t *dispatchv4 = NULL; dns_view_t *view = NULL; uint16_t port = PORT; @@ -275,10 +273,9 @@ main(int argc, char *argv[]) { RUNCHECK(isc_task_create(taskmgr, 0, &task)); RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr)); - attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_IPV4; RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, - have_src ? &srcaddr : &bind_any, 4, 2, - 3, 5, attrs, &dispatchv4)); + have_src ? &srcaddr : &bind_any, 0, + &dispatchv4)); RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c index b5ca6fdb48..6904c1998a 100644 --- a/bin/tests/system/tkey/keycreate.c +++ b/bin/tests/system/tkey/keycreate.c @@ -56,20 +56,20 @@ static char *ip_address = NULL; static int port = 0; -static dst_key_t *ourkey; -static isc_mem_t *mctx; -static dns_tsigkey_t *tsigkey, *initialkey; -static dns_tsig_keyring_t *ring; +static dst_key_t *ourkey = NULL; +static isc_mem_t *mctx = NULL; +static dns_tsigkey_t *tsigkey = NULL, *initialkey = NULL; +static dns_tsig_keyring_t *ring = NULL; static unsigned char noncedata[16]; static isc_buffer_t nonce; -static dns_requestmgr_t *requestmgr; +static dns_requestmgr_t *requestmgr = NULL; static const char *ownername_str = "."; static void recvquery(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = (dns_requestevent_t *)event; isc_result_t result; - dns_message_t *query, *response; + dns_message_t *query = NULL, *response = NULL; char keyname[256]; isc_buffer_t keynamebuf; int type; @@ -134,8 +134,8 @@ sendquery(isc_task_t *task, isc_event_t *event) { dns_fixedname_t ownername; isc_buffer_t namestr, keybuf; unsigned char keydata[9]; - dns_message_t *query; - dns_request_t *request; + dns_message_t *query = NULL; + dns_request_t *request = NULL; static char keystr[] = "0123456789ab"; isc_event_free(&event); @@ -166,14 +166,12 @@ sendquery(isc_task_t *task, isc_event_t *event) { isc_buffer_usedregion(&keybuf, &r); - initialkey = NULL; result = dns_tsigkey_create( dns_fixedname_name(&keyname), DNS_TSIG_HMACMD5_NAME, isc_buffer_base(&keybuf), isc_buffer_usedlength(&keybuf), false, NULL, 0, 0, mctx, ring, &initialkey); CHECK("dns_tsigkey_create", result); - query = NULL; dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query); result = dns_tkey_builddhquery(query, ourkey, @@ -181,7 +179,6 @@ sendquery(isc_task_t *task, isc_event_t *event) { DNS_TSIG_HMACMD5_NAME, &nonce, 3600); CHECK("dns_tkey_builddhquery", result); - request = NULL; result = dns_request_create(requestmgr, query, &address, DNS_REQUESTOPT_TCP, initialkey, TIMEOUT, task, recvquery, query, &request); @@ -196,7 +193,6 @@ main(int argc, char *argv[]) { isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_socket_t *sock = NULL; - unsigned int attrs; isc_sockaddr_t bind_any; dns_dispatchmgr_t *dispatchmgr = NULL; dns_dispatch_t *dispatchv4 = NULL; @@ -224,12 +220,9 @@ main(int argc, char *argv[]) { dns_result_register(); - mctx = NULL; isc_mem_debugging = ISC_MEM_DEBUGRECORD; isc_mem_create(&mctx); - log = NULL; - logconfig = NULL; isc_log_create(mctx, &log, &logconfig); RUNCHECK(dst_lib_init(mctx, NULL)); @@ -241,32 +234,24 @@ main(int argc, char *argv[]) { RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr)); isc_sockaddr_any(&bind_any); - attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_IPV4; RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, - &bind_any, 4, 2, 3, 5, attrs, - &dispatchv4)); - requestmgr = NULL; + &bind_any, 0, &dispatchv4)); RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); - ring = NULL; RUNCHECK(dns_tsigkeyring_create(mctx, &ring)); - tctx = NULL; RUNCHECK(dns_tkeyctx_create(mctx, &tctx)); - view = NULL; RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); dns_view_setkeyring(view, ring); dns_tsigkeyring_detach(&ring); - sock = NULL; RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &sock)); RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL)); - ourkey = NULL; type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY; result = dst_key_fromnamedfile(ourkeyname, NULL, type, mctx, &ourkey); CHECK("dst_key_fromnamedfile", result); diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c index d4caf2940d..1b8d3dc336 100644 --- a/bin/tests/system/tkey/keydelete.c +++ b/bin/tests/system/tkey/keydelete.c @@ -53,18 +53,18 @@ #define TIMEOUT 30 -static char *ip_address; +static char *ip_address = NULL; static int port; -static isc_mem_t *mctx; -static dns_tsigkey_t *tsigkey; -static dns_tsig_keyring_t *ring; -static dns_requestmgr_t *requestmgr; +static isc_mem_t *mctx = NULL; +static dns_tsigkey_t *tsigkey = NULL; +static dns_tsig_keyring_t *ring = NULL; +static dns_requestmgr_t *requestmgr = NULL; static void recvquery(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = (dns_requestevent_t *)event; isc_result_t result; - dns_message_t *query, *response; + dns_message_t *query = NULL, *response = NULL; UNUSED(task); @@ -78,7 +78,6 @@ recvquery(isc_task_t *task, isc_event_t *event) { query = reqev->ev_arg; - response = NULL; dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); result = dns_request_getresponse(reqev->request, response, @@ -108,8 +107,8 @@ sendquery(isc_task_t *task, isc_event_t *event) { struct in_addr inaddr; isc_sockaddr_t address; isc_result_t result; - dns_message_t *query; - dns_request_t *request; + dns_message_t *query = NULL; + dns_request_t *request = NULL; isc_event_free(&event); @@ -119,13 +118,11 @@ sendquery(isc_task_t *task, isc_event_t *event) { } isc_sockaddr_fromin(&address, &inaddr, port); - query = NULL; dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query); result = dns_tkey_builddeletequery(query, tsigkey); CHECK("dns_tkey_builddeletequery", result); - request = NULL; result = dns_request_create(requestmgr, query, &address, DNS_REQUESTOPT_TCP, tsigkey, TIMEOUT, task, recvquery, query, &request); @@ -140,7 +137,6 @@ main(int argc, char **argv) { isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_socket_t *sock = NULL; - unsigned int attrs; isc_sockaddr_t bind_any; dns_dispatchmgr_t *dispatchmgr = NULL; dns_dispatch_t *dispatchv4 = NULL; @@ -169,11 +165,8 @@ main(int argc, char **argv) { dns_result_register(); - mctx = NULL; isc_mem_create(&mctx); - log = NULL; - logconfig = NULL; isc_log_create(mctx, &log, &logconfig); RUNCHECK(dst_lib_init(mctx, NULL)); @@ -184,31 +177,23 @@ main(int argc, char **argv) { RUNCHECK(isc_task_create(taskmgr, 0, &task)); RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr)); isc_sockaddr_any(&bind_any); - attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_IPV4; RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, - &bind_any, 4, 2, 3, 5, attrs, - &dispatchv4)); - requestmgr = NULL; + &bind_any, 0, &dispatchv4)); RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); - ring = NULL; RUNCHECK(dns_tsigkeyring_create(mctx, &ring)); - tctx = NULL; RUNCHECK(dns_tkeyctx_create(mctx, &tctx)); - view = NULL; RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); dns_view_setkeyring(view, ring); - sock = NULL; RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &sock)); RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL)); - dstkey = NULL; type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY; result = dst_key_fromnamedfile(keyname, NULL, type, mctx, &dstkey); CHECK("dst_key_fromnamedfile", result); diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index 4578fd9472..9c58a337cd 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -2073,7 +2073,7 @@ main(int argc, char *argv[]) { dns_dispatchmgr_t *dispatchmgr = NULL; dns_dispatch_t *dispatchvx = NULL; dns_view_t *view = NULL; - unsigned int attrs, i; + unsigned int i; int ns; RUNCHECK(isc_app_start()); @@ -2128,17 +2128,14 @@ main(int argc, char *argv[]) { RUNCHECK(isc_task_create(taskmgr, 0, &task)); RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr)); - attrs = DNS_DISPATCHATTR_UDP; if (have_ipv4) { isc_sockaddr_any(&bind_any); - attrs |= DNS_DISPATCHATTR_IPV4; } else { isc_sockaddr_any6(&bind_any); - attrs |= DNS_DISPATCHATTR_IPV6; } RUNCHECK(dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, - have_src ? &srcaddr : &bind_any, 100, - 100, 17, 19, attrs, &dispatchvx)); + have_src ? &srcaddr : &bind_any, 0, + &dispatchvx)); RUNCHECK(dns_requestmgr_create( mctx, timermgr, socketmgr, taskmgr, dispatchmgr, diff --git a/lib/dns/client.c b/lib/dns/client.c index 3547d3cc81..1d113972b8 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -203,40 +203,18 @@ cleanup: static isc_result_t getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr, isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr, - bool is_shared, dns_dispatch_t **dispp, - const isc_sockaddr_t *localaddr) { - unsigned int attrs; + dns_dispatch_t **dispp, const isc_sockaddr_t *localaddr) { dns_dispatch_t *disp = NULL; - unsigned maxbuffers, maxrequests, buckets, increment; isc_result_t result; isc_sockaddr_t anyaddr; - attrs = DNS_DISPATCHATTR_UDP; - switch (family) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - default: - INSIST(0); - ISC_UNREACHABLE(); - } - if (localaddr == NULL) { isc_sockaddr_anyofpf(&anyaddr, family); localaddr = &anyaddr; } - maxbuffers = is_shared ? 1000 : 8; - maxrequests = 32768; - buckets = is_shared ? 16411 : 3; - increment = is_shared ? 16433 : 5; - result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, - localaddr, maxbuffers, maxrequests, - buckets, increment, attrs, &disp); + localaddr, 0, &disp); if (result == ISC_R_SUCCESS) { *dispp = disp; } @@ -334,7 +312,7 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, client->dispatchv4 = NULL; if (localaddr4 != NULL || localaddr6 == NULL) { result = getudpdispatch(AF_INET, dispatchmgr, socketmgr, - taskmgr, true, &dispatchv4, localaddr4); + taskmgr, &dispatchv4, localaddr4); if (result == ISC_R_SUCCESS) { client->dispatchv4 = dispatchv4; } @@ -343,7 +321,7 @@ dns_client_create(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, client->dispatchv6 = NULL; if (localaddr6 != NULL || localaddr4 == NULL) { result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr, - taskmgr, true, &dispatchv6, localaddr6); + taskmgr, &dispatchv6, localaddr6); if (result == ISC_R_SUCCESS) { client->dispatchv6 = dispatchv6; } diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 5a3bbad899..cbb84220ee 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -43,9 +43,6 @@ typedef ISC_LIST(dns_dispentry_t) dns_displist_t; typedef struct dispsocket dispsocket_t; typedef ISC_LIST(dispsocket_t) dispsocketlist_t; -typedef struct dispportentry dispportentry_t; -typedef ISC_LIST(dispportentry_t) dispportlist_t; - typedef struct dns_qid { unsigned int magic; unsigned int qid_nbuckets; /*%< hash table size */ @@ -72,7 +69,6 @@ struct dns_dispatchmgr { isc_mutex_t buffer_lock; unsigned int buffers; /*%< allocated buffers */ unsigned int buffersize; /*%< size of each buffer */ - unsigned int maxbuffers; /*%< max buffers */ isc_refcount_t irefs; @@ -101,8 +97,6 @@ struct dns_dispatchmgr { #define MGR_SHUTTINGDOWN 0x00000001U #define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0) -#define IS_PRIVATE(d) (((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0) - struct dns_dispentry { unsigned int magic; dns_dispatch_t *disp; @@ -119,27 +113,6 @@ struct dns_dispentry { ISC_LINK(dns_dispentry_t) link; }; -/*% - * Maximum number of dispatch sockets that can be pooled for reuse. The - * appropriate value may vary, but experiments have shown a busy caching server - * may need more than 1000 sockets concurrently opened. The maximum allowable - * number of dispatch sockets (per manager) will be set to the double of this - * value. - */ -#ifndef DNS_DISPATCH_POOLSOCKS -#define DNS_DISPATCH_POOLSOCKS 2048 -#endif /* ifndef DNS_DISPATCH_POOLSOCKS */ - -/*% - * Quota to control the number of dispatch sockets. If a dispatch has more - * than the quota of sockets, new queries will purge oldest ones, so that - * a massive number of outstanding queries won't prevent subsequent queries - * (especially if the older ones take longer time and result in timeout). - */ -#ifndef DNS_DISPATCH_SOCKSQUOTA -#define DNS_DISPATCH_SOCKSQUOTA 3072 -#endif /* ifndef DNS_DISPATCH_SOCKSQUOTA */ - /*% * Fixed UDP buffer size. */ @@ -152,31 +125,14 @@ struct dispsocket { isc_socket_t *socket; dns_dispatch_t *disp; isc_sockaddr_t host; - dispportentry_t *portentry; dns_dispentry_t *resp; isc_task_t *task; + in_port_t port; ISC_LINK(dispsocket_t) link; unsigned int bucket; ISC_LINK(dispsocket_t) blink; }; -/*% - * A port table entry. We remember every port we first open in a table with a - * reference counter so that we can 'reuse' the same port (with different - * destination addresses) using the SO_REUSEADDR socket option. - */ -struct dispportentry { - in_port_t port; - isc_refcount_t refs; - ISC_LINK(struct dispportentry) link; -}; - -#ifndef DNS_DISPATCH_PORTTABLESIZE -#define DNS_DISPATCH_PORTTABLESIZE 1024 -#endif /* ifndef DNS_DISPATCH_PORTTABLESIZE */ - -#define INVALID_BUCKET (0xffffdead) - /*% * Number of tasks for each dispatch that use separate sockets for different * transactions. This must be a power of 2 as it will divide 32 bit numbers @@ -195,11 +151,10 @@ struct dns_dispatch { * 1st task (task[0]) for internal control events. */ isc_task_t *task[MAX_INTERNAL_TASKS]; - isc_socket_t *socket; /*%< isc socket attached to */ - isc_sockaddr_t local; /*%< local address */ - in_port_t localport; /*%< local UDP port */ - isc_sockaddr_t peer; /*%< peer address (TCP) */ - unsigned int maxrequests; /*%< max requests */ + isc_socket_t *socket; /*%< isc socket attached to */ + isc_sockaddr_t local; /*%< local address */ + in_port_t localport; /*%< local UDP port */ + isc_sockaddr_t peer; /*%< peer address (TCP) */ isc_event_t *ctlevent; isc_mem_t *sepool; /*%< pool for socket events */ @@ -214,8 +169,7 @@ struct dns_dispatch { isc_refcount_t refcount; dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */ unsigned int shutting_down : 1, shutdown_out : 1, connected : 1, - tcpmsg_valid : 1, recv_pending : 1; /*%< is a recv() pending? * - */ + tcpmsg_valid : 1, recv_pending : 1; isc_result_t shutdown_why; ISC_LIST(dispsocket_t) activesockets; ISC_LIST(dispsocket_t) inactivesockets; @@ -223,8 +177,6 @@ struct dns_dispatch { unsigned int requests; /*%< how many requests we have */ unsigned int tcpbuffers; /*%< allocated buffers */ dns_tcpmsg_t tcpmsg; /*%< for tcp streams */ - dns_qid_t *qid; - dispportlist_t *port_table; /*%< hold ports 'owned' by us */ }; #define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ') @@ -242,23 +194,65 @@ struct dns_dispatch { #define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r') #define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC) -#define DNS_QID(disp) \ - ((disp)->socktype == isc_sockettype_tcp) ? (disp)->qid \ - : (disp)->mgr->qid +/*% + * Maximum number of dispatch sockets that can be pooled for reuse. The + * appropriate value may vary, but experiments have shown a busy caching server + * may need more than 1000 sockets concurrently opened. The maximum allowable + * number of dispatch sockets (per manager) will be set to the double of this + * value. + */ +#ifndef DNS_DISPATCH_POOLSOCKS +#define DNS_DISPATCH_POOLSOCKS 2048 +#endif /* ifndef DNS_DISPATCH_POOLSOCKS */ /*% - * Locking a query port buffer is a bit tricky. We access the buffer without - * locking until qid is created. Technically, there is a possibility of race - * between the creation of qid and access to the port buffer; in practice, - * however, this should be safe because qid isn't created until the first - * dispatch is created and there should be no contending situation until then. + * Quota to control the number of UDP dispatch sockets. If a dispatch has + * more than the quota of sockets, new queries will purge oldest ones, so + * that a massive number of outstanding queries won't prevent subsequent + * queries (especially if the older ones take longer time and result in + * timeout). */ -#define PORTBUFLOCK(mgr) \ - if ((mgr)->qid != NULL) \ - LOCK(&((mgr)->qid->lock)) -#define PORTBUFUNLOCK(mgr) \ - if ((mgr)->qid != NULL) \ - UNLOCK((&(mgr)->qid->lock)) +#ifndef DNS_DISPATCH_SOCKSQUOTA +#define DNS_DISPATCH_SOCKSQUOTA 3072 +#endif /* ifndef DNS_DISPATCH_SOCKSQUOTA */ + +/*% + * Number of buffers available for all dispatches in the buffery memory + * pool. + */ +#ifndef DNS_DISPATCH_MAXBUFFERS +#define DNS_DISPATCH_MAXBUFFERS 32768 +#endif /* ifndef DNS_DISPATCH_MAXBUFFERS */ + +/*% + * Number of dispatch sockets available for all dispatches in the + * socket memory pool. + */ +#ifndef DNS_DISPATCH_MAXSOCKETS +#define DNS_DISPATCH_MAXSOCKETS 32768 +#endif /* ifndef DNS_DISPATCH_MAXSOCKETS */ + +/*% + * Quota to control the number of concurrent requests that can be handled + * by each TCP dispatch. (UDP dispatches do not currently support socket + * sharing.) + */ +#ifndef DNS_DISPATCH_MAXREQUESTS +#define DNS_DISPATCH_MAXREQUESTS 32768 +#endif /* ifndef DNS_DISPATCH_MAXREQUESTS */ + +/*% + * Number of buckets in the QID hash table, and the value to + * increment the QID by when attempting to avoid collisions. + * The number of buckets should be prime, and the increment + * should be the next higher prime number. + */ +#ifndef DNS_QID_BUCKETS +#define DNS_QID_BUCKETS 16411 +#endif /* ifndef DNS_QID_BUCKETS */ +#ifndef DNS_QID_INCREMENT +#define DNS_QID_INCREMENT 16433 +#endif /* ifndef DNS_QID_INCREMENT */ /* * Statics. @@ -301,21 +295,18 @@ dispatch_free(dns_dispatch_t **dispp); static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - unsigned int maxrequests, unsigned int attributes, - dns_dispatch_t **dispp); + unsigned int attributes, dns_dispatch_t **dispp); static bool destroy_mgr_ok(dns_dispatchmgr_t *mgr); static void destroy_mgr(dns_dispatchmgr_t **mgrp); -static isc_result_t -qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, - unsigned int increment, dns_qid_t **qidp, bool needaddrtable); +static void +qid_allocate(dns_dispatchmgr_t *mgr, dns_qid_t **qidp); static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp); static isc_result_t open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local, - unsigned int options, isc_socket_t **sockp, - isc_socket_t *dup_socket); + unsigned int options, isc_socket_t **sockp); #define LVL(x) ISC_LOG_DEBUG(x) @@ -433,9 +424,7 @@ dns_hash(dns_qid_t *qid, const isc_sockaddr_t *dest, dns_messageid_t id, static dns_dispentry_t * linear_first(dns_qid_t *qid) { dns_dispentry_t *ret = NULL; - unsigned int bucket; - - bucket = 0; + unsigned int bucket = 0; while (bucket < qid->qid_nbuckets) { ret = ISC_LIST_HEAD(qid->qid_table[bucket]); @@ -462,8 +451,7 @@ linear_next(dns_qid_t *qid, dns_dispentry_t *resp) { return (ret); } - bucket = resp->bucket; - bucket++; + bucket = resp->bucket + 1; while (bucket < qid->qid_nbuckets) { ret = ISC_LIST_HEAD(qid->qid_table[bucket]); if (ret != NULL) { @@ -551,67 +539,6 @@ destroy_disp(isc_task_t *task, isc_event_t *event) { } } -/*% - * Manipulate port table per dispatch: find an entry for a given port number, - * create a new entry, and decrement a given entry with possible clean-up. - */ -static dispportentry_t * -port_search(dns_dispatch_t *disp, in_port_t port) { - dispportentry_t *portentry = NULL; - - REQUIRE(disp->port_table != NULL); - - portentry = ISC_LIST_HEAD( - disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE]); - while (portentry != NULL) { - if (portentry->port == port) { - return (portentry); - } - portentry = ISC_LIST_NEXT(portentry, link); - } - - return (NULL); -} - -static dispportentry_t * -new_portentry(dns_dispatch_t *disp, in_port_t port) { - dispportentry_t *portentry = NULL; - dns_qid_t *qid = NULL; - - REQUIRE(disp->port_table != NULL); - - portentry = isc_mem_get(disp->mgr->mctx, sizeof(*portentry)); - portentry->port = port; - isc_refcount_init(&portentry->refs, 1); - ISC_LINK_INIT(portentry, link); - qid = DNS_QID(disp); - LOCK(&qid->lock); - ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE], - portentry, link); - UNLOCK(&qid->lock); - - return (portentry); -} - -/*% - * The caller must hold the qid->lock. - */ -static void -deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { - dispportentry_t *portentry = *portentryp; - *portentryp = NULL; - - REQUIRE(disp->port_table != NULL); - REQUIRE(portentry != NULL); - - if (isc_refcount_decrement(&portentry->refs) == 1) { - ISC_LIST_UNLINK(disp->port_table[portentry->port % - DNS_DISPATCH_PORTTABLESIZE], - portentry, link); - isc_mem_put(disp->mgr->mctx, portentry, sizeof(*portentry)); - } -} - /*% * Find a dispsocket for socket address 'dest', and port number 'port'. * Return NULL if no such entry exists. Requires qid->lock to be held. @@ -627,10 +554,8 @@ socket_search(dns_qid_t *qid, const isc_sockaddr_t *dest, in_port_t port, dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]); while (dispsock != NULL) { - if (dispsock->portentry != NULL && - dispsock->portentry->port == port && - isc_sockaddr_equal(dest, &dispsock->host)) - { + if (dispsock->port == port && + isc_sockaddr_equal(dest, &dispsock->host)) { return (dispsock); } dispsock = ISC_LIST_NEXT(dispsock, blink); @@ -649,6 +574,7 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest, in_port_t *portp) { int i; dns_dispatchmgr_t *mgr = disp->mgr; + dns_qid_t *qid = mgr->qid; isc_socket_t *sock = NULL; isc_result_t result = ISC_R_FAILURE; in_port_t port; @@ -657,9 +583,6 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest, dispsocket_t *dispsock = NULL; unsigned int nports; in_port_t *ports = NULL; - isc_socket_options_t bindoptions; - dispportentry_t *portentry = NULL; - dns_qid_t *qid = NULL; if (isc_sockaddr_pf(&disp->local) == AF_INET) { nports = mgr->nv4ports; @@ -696,7 +619,6 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest, * very likely to fail in bind(2) or connect(2). */ localaddr = disp->local; - qid = DNS_QID(disp); for (i = 0; i < 64; i++) { port = ports[isc_random_uniform(nports)]; @@ -709,20 +631,9 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest, continue; } UNLOCK(&qid->lock); - bindoptions = 0; - portentry = port_search(disp, port); - - if (portentry != NULL) { - bindoptions |= ISC_SOCKET_REUSEADDRESS; - } - result = open_socket(sockmgr, &localaddr, bindoptions, &sock, - NULL); + result = open_socket(sockmgr, &localaddr, + ISC_SOCKET_REUSEADDRESS, &sock); if (result == ISC_R_SUCCESS) { - if (portentry == NULL) { - portentry = new_portentry(disp, port); - } else { - isc_refcount_increment(&portentry->refs); - } break; } else if (result == ISC_R_NOPERM) { char buf[ISC_SOCKADDR_FORMATSIZE]; @@ -746,8 +657,9 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest, dispsock->socket = sock; dispsock->host = *dest; dispsock->bucket = bucket; + dispsock->port = port; + LOCK(&qid->lock); - dispsock->portentry = portentry; ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink); UNLOCK(&qid->lock); *dispsockp = dispsock; @@ -762,7 +674,7 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest, static void destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) { dispsocket_t *dispsock = NULL; - dns_qid_t *qid = DNS_QID(disp); + dns_qid_t *qid = disp->mgr->qid; /* * The dispatch must be locked. @@ -775,11 +687,6 @@ destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) { disp->nsockets--; dispsock->magic = 0; - if (dispsock->portentry != NULL) { - LOCK(&qid->lock); - deref_portentry(disp, &dispsock->portentry); - UNLOCK(&qid->lock); - } if (dispsock->socket != NULL) { isc_socket_detach(&dispsock->socket); } @@ -802,7 +709,7 @@ destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) { static void deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) { isc_result_t result; - dns_qid_t *qid = DNS_QID(disp); + dns_qid_t *qid = disp->mgr->qid; /* * The dispatch must be locked. @@ -813,12 +720,6 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) { dispsock->resp->dispsocket = NULL; } - INSIST(dispsock->portentry != NULL); - - LOCK(&qid->lock); - deref_portentry(disp, &dispsock->portentry); - UNLOCK(&qid->lock); - if (disp->nsockets > DNS_DISPATCH_POOLSOCKS) { destroy_dispsocket(disp, &dispsock); } else { @@ -896,7 +797,7 @@ free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) { static void * allocate_udp_buffer(dns_dispatch_t *disp) { LOCK(&disp->mgr->buffer_lock); - if (disp->mgr->buffers >= disp->mgr->maxbuffers) { + if (disp->mgr->buffers >= DNS_DISPATCH_MAXBUFFERS) { UNLOCK(&disp->mgr->buffer_lock); return (NULL); } @@ -1238,7 +1139,7 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) { REQUIRE(VALID_DISPATCH(disp)); - qid = disp->qid; + qid = disp->mgr->qid; LOCK(&disp->lock); @@ -1512,8 +1413,7 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) { static isc_result_t open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local, - unsigned int options, isc_socket_t **sockp, - isc_socket_t *dup_socket) { + unsigned int options, isc_socket_t **sockp) { isc_socket_t *sock = NULL; isc_result_t result; @@ -1523,15 +1423,6 @@ open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local, if (result != ISC_R_SUCCESS) { return (result); } - } else if (dup_socket != NULL && !isc_socket_hasreuseport()) { - result = isc_socket_dup(dup_socket, &sock); - if (result != ISC_R_SUCCESS) { - return (result); - } - - isc_socket_setname(sock, "dispatcher", NULL); - *sockp = sock; - return (ISC_R_SUCCESS); } else { result = isc_socket_create(mgr, isc_sockaddr_pf(local), isc_sockettype_udp, &sock); @@ -1601,7 +1492,6 @@ setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, } while (p++ < 65535); INSIST(i4 == nv4ports && i6 == nv6ports); - PORTBUFLOCK(mgr); if (mgr->v4ports != NULL) { isc_mem_put(mgr->mctx, mgr->v4ports, mgr->nv4ports * sizeof(in_port_t)); @@ -1615,7 +1505,6 @@ setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, } mgr->v6ports = v6ports; mgr->nv6ports = nv6ports; - PORTBUFUNLOCK(mgr); return (ISC_R_SUCCESS); } @@ -1634,7 +1523,7 @@ dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp) { REQUIRE(mgrp != NULL && *mgrp == NULL); mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t)); - *mgr = (dns_dispatchmgr_t){ .maxbuffers = 20000 }; + *mgr = (dns_dispatchmgr_t){ 0 }; isc_mem_attach(mctx, &mgr->mctx); @@ -1653,6 +1542,7 @@ dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp) { isc_portset_destroy(mctx, &v4portset); isc_portset_destroy(mctx, &v6portset); + qid_allocate(mgr, &mgr->qid); mgr->magic = DNS_DISPATCHMGR_MAGIC; *mgrp = mgr; @@ -1681,60 +1571,6 @@ dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, return (setavailports(mgr, v4portset, v6portset)); } -static isc_result_t -dispatchmgr_setudp(dns_dispatchmgr_t *mgr, unsigned int maxbuffers, - unsigned int maxrequests, unsigned int buckets, - unsigned int increment) { - isc_result_t result; - - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(maxbuffers > 0); - REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ - REQUIRE(increment > buckets); - UNUSED(maxrequests); - - /* - * Keep some number of items around. This should be a config - * option. For now, keep 8, but later keep at least two even - * if the caller wants less. This allows us to ensure certain - * things, like an event can be "freed" and the next allocation - * will always succeed. - * - * Note that if limits are placed on anything here, we use one - * event internally, so the actual limit should be "wanted + 1." - * - * XXXMLG - */ - - if (maxbuffers < 8) { - maxbuffers = 8; - } - - /* Adjust buffer pool if needed - * - * We only increase maxbuffers to avoid accidental buffer - * shortage. Ideally we'd separate the manager-wide maximum - * from per-dispatch limits and respect the latter within the - * global limit. But at this moment that's deemed to be - * overkilling and isn't worth additional implementation - * complexity. - */ - LOCK(&mgr->buffer_lock); - if (maxbuffers > mgr->maxbuffers) { - mgr->maxbuffers = maxbuffers; - } - UNLOCK(&mgr->buffer_lock); - - if (mgr->qid == NULL) { - result = qid_allocate(mgr, buckets, increment, &mgr->qid, true); - if (result != ISC_R_SUCCESS) { - return (result); - } - } - - return (ISC_R_SUCCESS); -} - void dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) { dns_dispatchmgr_t *mgr = NULL; @@ -1767,42 +1603,31 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) { isc_stats_attach(stats, &mgr->stats); } -static isc_result_t -qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, - unsigned int increment, dns_qid_t **qidp, bool needsocktable) { +static void +qid_allocate(dns_dispatchmgr_t *mgr, dns_qid_t **qidp) { dns_qid_t *qid = NULL; unsigned int i; - REQUIRE(VALID_DISPATCHMGR(mgr)); - REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ - REQUIRE(increment > buckets); REQUIRE(qidp != NULL && *qidp == NULL); qid = isc_mem_get(mgr->mctx, sizeof(*qid)); + *qid = (dns_qid_t){ .qid_nbuckets = DNS_QID_BUCKETS, + .qid_increment = DNS_QID_INCREMENT }; qid->qid_table = isc_mem_get(mgr->mctx, - buckets * sizeof(dns_displist_t)); - - qid->sock_table = NULL; - if (needsocktable) { - qid->sock_table = isc_mem_get( - mgr->mctx, buckets * sizeof(dispsocketlist_t)); - } + DNS_QID_BUCKETS * sizeof(dns_displist_t)); + qid->sock_table = isc_mem_get( + mgr->mctx, DNS_QID_BUCKETS * sizeof(dispsocketlist_t)); isc_mutex_init(&qid->lock); - for (i = 0; i < buckets; i++) { + for (i = 0; i < qid->qid_nbuckets; i++) { ISC_LIST_INIT(qid->qid_table[i]); - if (qid->sock_table != NULL) { - ISC_LIST_INIT(qid->sock_table[i]); - } + ISC_LIST_INIT(qid->sock_table[i]); } - qid->qid_nbuckets = buckets; - qid->qid_increment = increment; qid->magic = QID_MAGIC; *qidp = qid; - return (ISC_R_SUCCESS); } static void @@ -1818,10 +1643,8 @@ qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) { qid->magic = 0; isc_mem_put(mctx, qid->qid_table, qid->qid_nbuckets * sizeof(dns_displist_t)); - if (qid->sock_table != NULL) { - isc_mem_put(mctx, qid->sock_table, - qid->qid_nbuckets * sizeof(dispsocketlist_t)); - } + isc_mem_put(mctx, qid->sock_table, + qid->qid_nbuckets * sizeof(dispsocketlist_t)); isc_mutex_destroy(&qid->lock); isc_mem_put(mctx, qid, sizeof(*qid)); } @@ -1830,8 +1653,7 @@ qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) { * Allocate and set important limits. */ static isc_result_t -dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, - dns_dispatch_t **dispp) { +dispatch_allocate(dns_dispatchmgr_t *mgr, dns_dispatch_t **dispp) { dns_dispatch_t *disp = NULL; REQUIRE(VALID_DISPATCHMGR(mgr)); @@ -1846,7 +1668,6 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, isc_refcount_increment0(&mgr->irefs); *disp = (dns_dispatch_t){ .mgr = mgr, - .maxrequests = maxrequests, .shutdown_why = ISC_R_UNEXPECTED }; isc_refcount_init(&disp->refcount, 1); ISC_LINK_INIT(disp, link); @@ -1891,19 +1712,6 @@ dispatch_free(dns_dispatch_t **dispp) { isc_mem_put(mgr->mctx, disp->failsafe_ev, sizeof(*disp->failsafe_ev)); disp->failsafe_ev = NULL; - if (disp->qid != NULL) { - qid_destroy(mgr->mctx, &disp->qid); - } - - if (disp->port_table != NULL) { - for (int i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) { - INSIST(ISC_LIST_EMPTY(disp->port_table[i])); - } - isc_mem_put(mgr->mctx, disp->port_table, - sizeof(disp->port_table[0]) * - DNS_DISPATCH_PORTTABLESIZE); - } - disp->mgr = NULL; isc_mutex_destroy(&disp->lock); disp->magic = 0; @@ -1914,52 +1722,34 @@ dispatch_free(dns_dispatch_t **dispp) { isc_result_t dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - const isc_sockaddr_t *destaddr, unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp) { + const isc_sockaddr_t *destaddr, unsigned int attributes, + dns_dispatch_t **dispp) { isc_result_t result; dns_dispatch_t *disp = NULL; - - UNUSED(maxbuffers); - UNUSED(buffersize); + int pf; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp); - REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0); - REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0); - if (destaddr == NULL) { - attributes |= DNS_DISPATCHATTR_PRIVATE; /* XXXMLG */ - } + attributes |= DNS_DISPATCHATTR_TCP; + attributes &= ~DNS_DISPATCHATTR_UDP; LOCK(&mgr->lock); - /* - * dispatch_allocate() checks mgr for us. - * qid_allocate() checks buckets and increment for us. - */ - disp = NULL; - result = dispatch_allocate(mgr, maxrequests, &disp); + result = dispatch_allocate(mgr, &disp); if (result != ISC_R_SUCCESS) { UNLOCK(&mgr->lock); return (result); } - result = qid_allocate(mgr, buckets, increment, &disp->qid, false); - if (result != ISC_R_SUCCESS) { - goto deallocate_dispatch; - } - disp->socktype = isc_sockettype_tcp; - disp->socket = NULL; isc_socket_attach(sock, &disp->socket); disp->ntasks = 1; disp->task[0] = NULL; result = isc_task_create(taskmgr, 50, &disp->task[0]); if (result != ISC_R_SUCCESS) { - goto kill_socket; + goto cleanup; } disp->ctlevent = @@ -1971,17 +1761,18 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg); disp->tcpmsg_valid = 1; - disp->attributes = attributes; - if (destaddr == NULL) { (void)isc_socket_getpeername(sock, &disp->peer); + attributes |= DNS_DISPATCHATTR_PRIVATE; } else { disp->peer = *destaddr; } + pf = isc_sockaddr_pf(&disp->peer); + if (localaddr == NULL) { if (destaddr != NULL) { - switch (isc_sockaddr_pf(destaddr)) { + switch (pf) { case AF_INET: isc_sockaddr_any(&disp->local); break; @@ -1996,6 +1787,22 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, disp->local = *localaddr; } + switch (pf) { + case PF_INET: + attributes |= DNS_DISPATCHATTR_IPV4; + break; + + case PF_INET6: + attributes |= DNS_DISPATCHATTR_IPV6; + break; + + default: + result = ISC_R_NOTIMPLEMENTED; + goto cleanup; + } + + disp->attributes = attributes; + /* * Append it to the dispatcher list. */ @@ -2012,9 +1819,8 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, return (ISC_R_SUCCESS); -kill_socket: +cleanup: isc_socket_detach(&disp->socket); -deallocate_dispatch: dispatch_free(&disp); UNLOCK(&mgr->lock); @@ -2108,8 +1914,6 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, isc_result_t dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, unsigned int attributes, dns_dispatch_t **dispp) { isc_result_t result; dns_dispatch_t *disp = NULL; @@ -2118,21 +1922,14 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, REQUIRE(sockmgr != NULL); REQUIRE(localaddr != NULL); REQUIRE(taskmgr != NULL); - REQUIRE(maxbuffers > 0); - REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ - REQUIRE(increment > buckets); REQUIRE(dispp != NULL && *dispp == NULL); - REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0); - result = dispatchmgr_setudp(mgr, maxbuffers, maxrequests, buckets, - increment); - if (result != ISC_R_SUCCESS) { - return (result); - } + attributes |= DNS_DISPATCHATTR_UDP; + attributes &= ~DNS_DISPATCHATTR_TCP; LOCK(&mgr->lock); result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr, - maxrequests, attributes, &disp); + attributes, &disp); if (result == ISC_R_SUCCESS) { *dispp = disp; @@ -2145,23 +1942,24 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - unsigned int maxrequests, unsigned int attributes, - dns_dispatch_t **dispp) { + unsigned int attributes, dns_dispatch_t **dispp) { isc_result_t result; dns_dispatch_t *disp = NULL; isc_socket_t *sock = NULL; isc_sockaddr_t sa_any; - int i = 0; + int pf, i = 0; /* * dispatch_allocate() checks mgr for us. */ disp = NULL; - result = dispatch_allocate(mgr, maxrequests, &disp); + result = dispatch_allocate(mgr, &disp); if (result != ISC_R_SUCCESS) { return (result); } + pf = isc_sockaddr_pf(localaddr); + disp->socktype = isc_sockettype_udp; /* @@ -2170,9 +1968,9 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, * but we don't keep it open; sockets used for sending requests * will be created later on demand. */ - isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr)); + isc_sockaddr_anyofpf(&sa_any, pf); if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) { - result = open_socket(sockmgr, localaddr, 0, &sock, NULL); + result = open_socket(sockmgr, localaddr, 0, &sock); if (sock != NULL) { isc_socket_detach(&sock); } @@ -2181,13 +1979,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, } } - disp->port_table = isc_mem_get(mgr->mctx, - sizeof(disp->port_table[0]) * - DNS_DISPATCH_PORTTABLESIZE); - for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) { - ISC_LIST_INIT(disp->port_table[i]); - } - if (isc_log_wouldlog(dns_lctx, 90)) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; @@ -2225,6 +2016,21 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, attributes &= ~DNS_DISPATCHATTR_TCP; attributes |= DNS_DISPATCHATTR_UDP; + + switch (pf) { + case PF_INET: + attributes |= DNS_DISPATCHATTR_IPV4; + break; + + case PF_INET6: + attributes |= DNS_DISPATCHATTR_IPV6; + break; + + default: + result = ISC_R_NOTIMPLEMENTED; + goto kill_socket; + } + disp->attributes = attributes; /* @@ -2330,11 +2136,13 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, return (ISC_R_SHUTTINGDOWN); } - if (disp->requests >= disp->maxrequests) { + if (disp->requests >= DNS_DISPATCH_MAXREQUESTS) { UNLOCK(&disp->lock); return (ISC_R_QUOTA); } + qid = disp->mgr->qid; + if (disp->socktype == isc_sockettype_udp && disp->nsockets > DNS_DISPATCH_SOCKSQUOTA) { @@ -2369,8 +2177,6 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, ISC_LIST_APPEND(disp->activesockets, oldestsocket, link); } - qid = DNS_QID(disp); - if (disp->socktype == isc_sockettype_udp) { /* * Get a separate UDP socket with a random port number. @@ -2440,7 +2246,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, ISC_LIST_APPEND(qid->qid_table[bucket], res, link); UNLOCK(&qid->lock); - inc_stats(disp->mgr, (qid == disp->mgr->qid) + inc_stats(disp->mgr, (disp->socktype == isc_sockettype_udp) ? dns_resstatscounter_disprequdp : dns_resstatscounter_dispreqtcp); @@ -2463,7 +2269,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options, disp->requests--; dec_stats(disp->mgr, - (qid == disp->mgr->qid) + (disp->socktype == isc_sockettype_udp) ? dns_resstatscounter_disprequdp : dns_resstatscounter_dispreqtcp); @@ -2570,8 +2376,7 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp, REQUIRE(VALID_DISPATCH(disp)); mgr = disp->mgr; REQUIRE(VALID_DISPATCHMGR(mgr)); - - qid = DNS_QID(disp); + qid = mgr->qid; if (sockevent != NULL) { REQUIRE(*sockevent != NULL); @@ -2585,7 +2390,7 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp, INSIST(disp->requests > 0); disp->requests--; - dec_stats(disp->mgr, (qid == disp->mgr->qid) + dec_stats(disp->mgr, (disp->socktype == isc_sockettype_udp) ? dns_resstatscounter_disprequdp : dns_resstatscounter_dispreqtcp); @@ -2677,14 +2482,12 @@ static void do_cancel(dns_dispatch_t *disp) { dns_dispatchevent_t *ev = NULL; dns_dispentry_t *resp = NULL; - dns_qid_t *qid = NULL; + dns_qid_t *qid = disp->mgr->qid; if (disp->shutdown_out == 1) { return; } - qid = DNS_QID(disp); - /* * Search for the first response handler without packets outstanding * unless a specific handler is given. @@ -2827,8 +2630,7 @@ dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, for (i = 1; i < n; i++) { dset->dispatches[i] = NULL; result = dispatch_createudp(mgr, sockmgr, taskmgr, - &source->local, source->maxrequests, - source->attributes, + &source->local, source->attributes, &dset->dispatches[i]); if (result != ISC_R_SUCCESS) { goto fail; diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h index dfae6ff87e..c9bdc42954 100644 --- a/lib/dns/include/dns/dispatch.h +++ b/lib/dns/include/dns/dispatch.h @@ -207,8 +207,6 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats); isc_result_t dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, unsigned int attributes, dns_dispatch_t **dispp); /*%< * Create a new UDP dispatch. @@ -218,16 +216,6 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, * *\li dispp != NULL && *disp == NULL * - *\li 512 <= buffersize <= 64k - * - *\li maxbuffers > 0 - * - *\li buckets < 2097169 - * - *\li increment > buckets - * - *\li (attributes & DNS_DISPATCHATTR_TCP) == 0 - * * Returns: *\li ISC_R_SUCCESS -- success. * @@ -237,25 +225,11 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_result_t dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_taskmgr_t *taskmgr, const isc_sockaddr_t *localaddr, - const isc_sockaddr_t *destaddr, unsigned int buffersize, - unsigned int maxbuffers, unsigned int maxrequests, - unsigned int buckets, unsigned int increment, - unsigned int attributes, dns_dispatch_t **dispp); + const isc_sockaddr_t *destaddr, unsigned int attributes, + dns_dispatch_t **dispp); /*%< * Create a new dns_dispatch and attach it to the provided isc_socket_t. * - * For all dispatches, "buffersize" is the maximum packet size we will - * accept. - * - * "maxbuffers" and "maxrequests" control the number of buffers in the - * overall system and the number of buffers which can be allocated to - * requests. - * - * "buckets" is the number of buckets to use, and should be prime. - * - * "increment" is used in a collision avoidance function, and needs to be - * a prime > buckets, and not 2. - * * Requires: * *\li mgr is a valid dispatch manager. @@ -264,19 +238,6 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, * *\li task is a valid task that can be used internally to this dispatcher. * - * \li 512 <= buffersize <= 64k - * - *\li maxbuffers > 0. - * - *\li maxrequests <= maxbuffers. - * - *\li buckets < 2097169 (the next prime after 65536 * 32) - * - *\li increment > buckets (and prime). - * - *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include - * #DNS_DISPATCHATTR_UDP. - * * Returns: *\li ISC_R_SUCCESS -- success. * diff --git a/lib/dns/request.c b/lib/dns/request.c index c9256377d3..fed16798ee 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -119,8 +119,6 @@ static void req_response(isc_task_t *task, isc_event_t *event); static void req_timeout(isc_task_t *task, isc_event_t *event); -static isc_socket_t * -req_getsocket(dns_request_t *request); static void req_connected(isc_task_t *task, isc_event_t *event); static void @@ -423,8 +421,9 @@ req_send(dns_request_t *request, isc_task_t *task, REQUIRE(VALID_REQUEST(request)); - sock = req_getsocket(request); + sock = dns_dispatch_getentrysocket(request->dispentry); isc_buffer_usedregion(request->query, &r); + /* * We could connect the socket when we are using an exclusive dispatch * as we do in resolver.c, but we prefer implementation simplicity @@ -456,29 +455,11 @@ new_request(isc_mem_t *mctx, dns_request_t **requestp) { dns_request_t *request; request = isc_mem_get(mctx, sizeof(*request)); - - /* - * Zero structure. - */ - request->magic = 0; - request->mctx = NULL; - request->flags = 0; + *request = (dns_request_t){ .dscp = -1 }; ISC_LINK_INIT(request, link); - request->query = NULL; - request->answer = NULL; - request->event = NULL; - request->dispatch = NULL; - request->dispentry = NULL; - request->timer = NULL; - request->requestmgr = NULL; - request->tsig = NULL; - request->tsigkey = NULL; - request->dscp = -1; ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL, DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL, NULL, NULL); - request->canceling = false; - request->udpcount = 0; isc_mem_attach(mctx, &request->mctx); @@ -513,14 +494,12 @@ isblackholed(dns_dispatchmgr_t *dispatchmgr, const isc_sockaddr_t *destaddr) { } static isc_result_t -create_tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr, - const isc_sockaddr_t *srcaddr, - const isc_sockaddr_t *destaddr, isc_dscp_t dscp, - bool *connected, dns_dispatch_t **dispatchp) { +tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr, + const isc_sockaddr_t *srcaddr, const isc_sockaddr_t *destaddr, + isc_dscp_t dscp, bool *connected, dns_dispatch_t **dispatchp) { isc_result_t result; isc_socket_t *sock = NULL; isc_sockaddr_t src; - unsigned int attrs; isc_sockaddr_t bind_any; if (!newtcp) { @@ -556,27 +535,20 @@ create_tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr, goto cleanup; } - attrs = DNS_DISPATCHATTR_TCP; - if (isc_sockaddr_pf(destaddr) == AF_INET) { - attrs |= DNS_DISPATCHATTR_IPV4; - } else { - attrs |= DNS_DISPATCHATTR_IPV6; - } - isc_socket_dscp(sock, dscp); - result = dns_dispatch_createtcp( - requestmgr->dispatchmgr, sock, requestmgr->taskmgr, srcaddr, - destaddr, 4096, 32768, 32768, 16411, 16433, attrs, dispatchp); + result = dns_dispatch_createtcp(requestmgr->dispatchmgr, sock, + requestmgr->taskmgr, srcaddr, destaddr, + 0, dispatchp); + cleanup: isc_socket_detach(&sock); return (result); } static isc_result_t -find_udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, - const isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp) { +udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, + const isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp) { dns_dispatch_t *disp = NULL; - unsigned int attrs; if (srcaddr == NULL) { switch (isc_sockaddr_pf(destaddr)) { @@ -597,24 +569,10 @@ find_udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, dns_dispatch_attach(disp, dispatchp); return (ISC_R_SUCCESS); } - attrs = DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(srcaddr)) { - case PF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case PF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - - default: - return (ISC_R_NOTIMPLEMENTED); - } - - return (dns_dispatch_createudp(requestmgr->dispatchmgr, - requestmgr->socketmgr, - requestmgr->taskmgr, srcaddr, 32768, - 32768, 16411, 16433, attrs, dispatchp)); + return (dns_dispatch_createudp( + requestmgr->dispatchmgr, requestmgr->socketmgr, + requestmgr->taskmgr, srcaddr, 0, dispatchp)); } static isc_result_t @@ -624,12 +582,10 @@ get_dispatch(bool tcp, bool newtcp, dns_requestmgr_t *requestmgr, isc_result_t result; if (tcp) { - result = create_tcp_dispatch(newtcp, requestmgr, srcaddr, - destaddr, dscp, connected, - dispatchp); + result = tcp_dispatch(newtcp, requestmgr, srcaddr, destaddr, + dscp, connected, dispatchp); } else { - result = find_udp_dispatch(requestmgr, srcaddr, destaddr, - dispatchp); + result = udp_dispatch(requestmgr, srcaddr, destaddr, dispatchp); } return (result); } @@ -760,7 +716,7 @@ again: goto cleanup; } - sock = req_getsocket(request); + sock = dns_dispatch_getentrysocket(request->dispentry); INSIST(sock != NULL); isc_buffer_allocate(mctx, &request->query, r.length + (tcp ? 2 : 0)); @@ -931,7 +887,7 @@ use_tcp: if (result != ISC_R_SUCCESS) { goto cleanup; } - sock = req_getsocket(request); + sock = dns_dispatch_getentrysocket(request->dispentry); INSIST(sock != NULL); message->id = id; @@ -1240,12 +1196,6 @@ dns_request_destroy(dns_request_t **requestp) { /*** *** Private: request. ***/ - -static isc_socket_t * -req_getsocket(dns_request_t *request) { - return (dns_dispatch_getentrysocket(request->dispentry)); -} - static void req_connected(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 14f82f3a73..9a39175319 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2140,15 +2140,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, */ } else { if (have_addr) { - unsigned int attrs; - attrs = DNS_DISPATCHATTR_UDP; switch (isc_sockaddr_pf(&addr)) { case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; dscp = dns_resolver_getquerydscp4(fctx->res); break; case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; dscp = dns_resolver_getquerydscp6(fctx->res); break; default: @@ -2157,8 +2153,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, } result = dns_dispatch_createudp( res->dispatchmgr, res->socketmgr, res->taskmgr, - &addr, 20000, 32768, 16411, 16433, attrs, - &query->dispatch); + &addr, 0, &query->dispatch); if (result != ISC_R_SUCCESS) { goto cleanup_query; } @@ -2941,7 +2936,6 @@ resquery_connected(isc_task_t *task, isc_event_t *event) { bool retry = false; isc_interval_t interval; isc_result_t result; - unsigned int attrs; fetchctx_t *fctx; REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); @@ -2970,6 +2964,8 @@ resquery_connected(isc_task_t *task, isc_event_t *event) { isc_socket_detach(&query->tcpsocket); resquery_destroy(&query); } else { + int attrs = 0; + switch (sevent->result) { case ISC_R_SUCCESS: @@ -2997,20 +2993,11 @@ resquery_connected(isc_task_t *task, isc_event_t *event) { * We are connected. Create a dispatcher and * send the query. */ - attrs = DNS_DISPATCHATTR_TCP | - DNS_DISPATCHATTR_PRIVATE | - DNS_DISPATCHATTR_CONNECTED; - if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == - AF_INET) { - attrs |= DNS_DISPATCHATTR_IPV4; - } else { - attrs |= DNS_DISPATCHATTR_IPV6; - } - + attrs = DNS_DISPATCHATTR_CONNECTED; result = dns_dispatch_createtcp( query->dispatchmgr, query->tcpsocket, - query->fctx->res->taskmgr, NULL, NULL, 4096, 2, - 1, 1, 3, attrs, &query->dispatch); + query->fctx->res->taskmgr, NULL, NULL, attrs, + &query->dispatch); /* * Regardless of whether dns_dispatch_create() diff --git a/lib/dns/tests/dispatch_test.c b/lib/dns/tests/dispatch_test.c index fb79fcf40b..aa92f4ed87 100644 --- a/lib/dns/tests/dispatch_test.c +++ b/lib/dns/tests/dispatch_test.c @@ -66,7 +66,6 @@ static isc_result_t make_dispatchset(unsigned int ndisps) { isc_result_t result; isc_sockaddr_t any; - unsigned int attrs; dns_dispatch_t *disp = NULL; result = dns_dispatchmgr_create(dt_mctx, &dispatchmgr); @@ -75,9 +74,8 @@ make_dispatchset(unsigned int ndisps) { } isc_sockaddr_any(&any); - attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &any, - 6, 1024, 17, 19, attrs, &disp); + 0, &disp); if (result != ISC_R_SUCCESS) { return (result); } @@ -258,7 +256,6 @@ dispatch_getnext(void **state) { uint16_t id; struct in_addr ina; unsigned char message[12]; - unsigned int attrs; unsigned char rbuf[12]; UNUSED(state); @@ -273,9 +270,8 @@ dispatch_getnext(void **state) { ina.s_addr = htonl(INADDR_LOOPBACK); isc_sockaddr_fromin(&local, &ina, 0); - attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &local, - 6, 1024, 17, 19, attrs, &dispatch); + 0, &dispatch); assert_int_equal(result, ISC_R_SUCCESS); /* diff --git a/lib/dns/tests/resolver_test.c b/lib/dns/tests/resolver_test.c index 5b4b7e8b81..1a6e0f6143 100644 --- a/lib/dns/tests/resolver_test.c +++ b/lib/dns/tests/resolver_test.c @@ -58,7 +58,7 @@ _setup(void **state) { isc_sockaddr_any(&local); result = dns_dispatch_createudp(dispatchmgr, socketmgr, taskmgr, &local, - 100, 100, 100, 500, 0, &dispatch); + 0, &dispatch); assert_int_equal(result, ISC_R_SUCCESS); return (0); diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index ad6cf29603..23630bdaa5 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -225,12 +225,6 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, *\li #ISC_R_UNEXPECTED */ -isc_result_t -isc_socket_dup(isc_socket_t *sock0, isc_socket_t **socketp); -/*%< - * Duplicate an existing socket, reusing its file descriptor. - */ - void isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how); /*%< diff --git a/lib/isc/socket.c b/lib/isc/socket.c index 12d8c71550..c28b32165c 100644 --- a/lib/isc/socket.c +++ b/lib/isc/socket.c @@ -350,8 +350,8 @@ struct isc_socket { unsigned int listener : 1, /* listener socket */ connected : 1, connecting : 1, /* connect pending * */ - bound : 1, /* bound to local addr */ - dupped : 1, active : 1, /* currently active */ + bound : 1, /* bound to local addr */ + active : 1, /* currently active */ pktdscp : 1; /* per packet dscp */ #ifdef ISC_PLATFORM_RECVOVERFLOW @@ -434,7 +434,7 @@ struct isc__socketthread { static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, - isc_socket_t **socketp, isc_socket_t *dup_socket); + isc_socket_t **socketp); static void send_recvdone_event(isc_socket_t *, isc_socketevent_t **); static void @@ -1881,7 +1881,6 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, sock->fd = -1; sock->threadid = -1; sock->dscp = 0; /* TOS/TCLASS is zero until set. */ - sock->dupped = 0; sock->statsindex = NULL; sock->active = 0; @@ -2123,8 +2122,7 @@ set_ip_disable_pmtud(isc_socket_t *sock) { } static isc_result_t -opensocket(isc_socketmgr_t *manager, isc_socket_t *sock, - isc_socket_t *dup_socket) { +opensocket(isc_socketmgr_t *manager, isc_socket_t *sock) { isc_result_t result; char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; @@ -2138,60 +2136,52 @@ opensocket(isc_socketmgr_t *manager, isc_socket_t *sock, #endif again: - if (dup_socket == NULL) { - switch (sock->type) { - case isc_sockettype_udp: - sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP); - break; - case isc_sockettype_tcp: - sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); - break; - case isc_sockettype_unix: - sock->fd = socket(sock->pf, SOCK_STREAM, 0); - break; - case isc_sockettype_raw: - errno = EPFNOSUPPORT; - /* - * PF_ROUTE is a alias for PF_NETLINK on linux. - */ + switch (sock->type) { + case isc_sockettype_udp: + sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP); + break; + case isc_sockettype_tcp: + sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); + break; + case isc_sockettype_unix: + sock->fd = socket(sock->pf, SOCK_STREAM, 0); + break; + case isc_sockettype_raw: + errno = EPFNOSUPPORT; + /* + * PF_ROUTE is a alias for PF_NETLINK on linux. + */ #if defined(PF_ROUTE) - if (sock->fd == -1 && sock->pf == PF_ROUTE) { + if (sock->fd == -1 && sock->pf == PF_ROUTE) { #ifdef NETLINK_ROUTE - sock->fd = socket(sock->pf, SOCK_RAW, - NETLINK_ROUTE); + sock->fd = socket(sock->pf, SOCK_RAW, NETLINK_ROUTE); #else /* ifdef NETLINK_ROUTE */ - sock->fd = socket(sock->pf, SOCK_RAW, 0); + sock->fd = socket(sock->pf, SOCK_RAW, 0); #endif /* ifdef NETLINK_ROUTE */ - if (sock->fd != -1) { + if (sock->fd != -1) { #ifdef NETLINK_ROUTE - struct sockaddr_nl sa; - int n; + struct sockaddr_nl sa; + int n; - /* - * Do an implicit bind. - */ - memset(&sa, 0, sizeof(sa)); - sa.nl_family = AF_NETLINK; - sa.nl_groups = RTMGRP_IPV4_IFADDR | - RTMGRP_IPV6_IFADDR; - n = bind(sock->fd, - (struct sockaddr *)&sa, - sizeof(sa)); - if (n < 0) { - close(sock->fd); - sock->fd = -1; - } -#endif /* ifdef NETLINK_ROUTE */ - sock->bound = 1; + /* + * Do an implicit bind. + */ + memset(&sa, 0, sizeof(sa)); + sa.nl_family = AF_NETLINK; + sa.nl_groups = RTMGRP_IPV4_IFADDR | + RTMGRP_IPV6_IFADDR; + n = bind(sock->fd, (struct sockaddr *)&sa, + sizeof(sa)); + if (n < 0) { + close(sock->fd); + sock->fd = -1; } +#endif /* ifdef NETLINK_ROUTE */ + sock->bound = 1; } -#endif /* if defined(PF_ROUTE) */ - break; } - } else { - sock->fd = dup(dup_socket->fd); - sock->dupped = 1; - sock->bound = dup_socket->bound; +#endif /* if defined(PF_ROUTE) */ + break; } if (sock->fd == -1 && errno == EINTR && tries++ < 42) { goto again; @@ -2268,10 +2258,6 @@ again: } } - if (dup_socket != NULL) { - goto setup_done; - } - result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { (void)close(sock->fd); @@ -2410,7 +2396,6 @@ again: set_ip_disable_pmtud(sock); -setup_done: inc_stats(manager->stats, sock->statsindex[STATID_OPEN]); if (sock->active == 0) { inc_stats(manager->stats, sock->statsindex[STATID_ACTIVE]); @@ -2421,14 +2406,13 @@ setup_done: } /* - * Create a 'type' socket or duplicate an existing socket, managed - * by 'manager'. Events will be posted to 'task' and when dispatched - * 'action' will be called with 'arg' as the arg value. The new - * socket is returned in 'socketp'. + * Create a 'type' socket, managed by 'manager'. Events will be posted to + * 'task' and when dispatched 'action' will be called with 'arg' as the arg + * value. The new socket is returned in 'socketp'. */ static isc_result_t socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, - isc_socket_t **socketp, isc_socket_t *dup_socket) { + isc_socket_t **socketp) { isc_socket_t *sock = NULL; isc__socketthread_t *thread; isc_result_t result; @@ -2466,7 +2450,7 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, sock->pf = pf; - result = opensocket(manager, sock, dup_socket); + result = opensocket(manager, sock); if (result != ISC_R_SUCCESS) { free_socket(&sock); return (result); @@ -2507,8 +2491,7 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, #endif /* ifdef USE_SELECT */ UNLOCK(&manager->lock); - socket_log(sock, NULL, CREATION, - dup_socket != NULL ? "dupped" : "created"); + socket_log(sock, NULL, CREATION, "created"); return (ISC_R_SUCCESS); } @@ -2520,22 +2503,9 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, * in 'socketp'. */ isc_result_t -isc_socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, +isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp) { - return (socket_create(manager0, pf, type, socketp, NULL)); -} - -/*% - * Duplicate an existing socket. The new socket is returned - * in 'socketp'. - */ -isc_result_t -isc_socket_dup(isc_socket_t *sock, isc_socket_t **socketp) { - REQUIRE(VALID_SOCKET(sock)); - REQUIRE(socketp != NULL && *socketp == NULL); - - return (socket_create(sock->manager, sock->pf, sock->type, socketp, - sock)); + return (socket_create(manager, pf, type, socketp)); } isc_result_t @@ -2551,7 +2521,7 @@ isc_socket_open(isc_socket_t *sock) { REQUIRE(sock->fd == -1); REQUIRE(sock->threadid == -1); - result = opensocket(sock->manager, sock, NULL); + result = opensocket(sock->manager, sock); UNLOCK(&sock->lock); @@ -2642,7 +2612,6 @@ isc_socket_close(isc_socket_t *sock) { sock->fd = -1; sock->threadid = -1; - sock->dupped = 0; memset(sock->name, 0, sizeof(sock->name)); sock->tag = NULL; sock->listener = 0; @@ -4334,7 +4303,6 @@ isc_socket_bind(isc_socket_t *sock, const isc_sockaddr_t *sockaddr, LOCK(&sock->lock); INSIST(!sock->bound); - INSIST(!sock->dupped); if (sock->pf != sockaddr->type.sa.sa_family) { UNLOCK(&sock->lock); @@ -5078,7 +5046,6 @@ isc_socket_ipv6only(isc_socket_t *sock, bool yes) { #endif /* if defined(IPV6_V6ONLY) */ REQUIRE(VALID_SOCKET(sock)); - INSIST(!sock->dupped); #ifdef IPV6_V6ONLY if (sock->pf == AF_INET6) { @@ -5151,10 +5118,6 @@ isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp) { } #endif /* if !defined(IP_TOS) && !defined(IPV6_TCLASS) */ -#ifdef notyet - REQUIRE(!sock->dupped); -#endif /* ifdef notyet */ - setdscp(sock, dscp); } @@ -5200,8 +5163,7 @@ static void init_hasreuseport(void) { /* * SO_REUSEPORT works very differently on *BSD and on Linux (because why not). - * We only want to use it on Linux, if it's available. On BSD we want to dup() - * sockets instead of re-binding them. + * We only want to use it on Linux, if it's available. */ #if (defined(SO_REUSEPORT) && defined(__linux__)) || \ (defined(SO_REUSEPORT_LB) && defined(__FreeBSD_kernel__)) diff --git a/lib/isc/tests/socket_test.c b/lib/isc/tests/socket_test.c index 285e3c86ab..a98fc11906 100644 --- a/lib/isc/tests/socket_test.c +++ b/lib/isc/tests/socket_test.c @@ -218,89 +218,6 @@ udp_sendto_test(void **state) { assert_string_equal(recvbuf, "Hello"); } -/* Test UDP sendto/recv with duplicated socket */ -static void -udp_dup_test(void **state) { - isc_result_t result; - isc_sockaddr_t addr1, addr2; - struct in_addr in; - char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; - completion_t completion; - isc_region_t r; - - UNUSED(state); - - in.s_addr = inet_addr("127.0.0.1"); - isc_sockaddr_fromin(&addr1, &in, 0); - isc_sockaddr_fromin(&addr2, &in, 0); - - result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1); - assert_int_equal(result, ISC_R_SUCCESS); - result = isc_socket_bind(s1, &addr1, 0); - assert_int_equal(result, ISC_R_SUCCESS); - result = isc_socket_getsockname(s1, &addr1); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(isc_sockaddr_getport(&addr1) != 0); - - result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2); - assert_int_equal(result, ISC_R_SUCCESS); - result = isc_socket_bind(s2, &addr2, 0); - assert_int_equal(result, ISC_R_SUCCESS); - result = isc_socket_getsockname(s2, &addr2); - assert_int_equal(result, ISC_R_SUCCESS); - assert_true(isc_sockaddr_getport(&addr2) != 0); - - result = isc_socket_dup(s2, &s3); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_task_create(taskmgr, 0, &test_task); - assert_int_equal(result, ISC_R_SUCCESS); - - snprintf(sendbuf, sizeof(sendbuf), "Hello"); - r.base = (void *)sendbuf; - r.length = strlen(sendbuf) + 1; - - completion_init(&completion); - result = isc_socket_sendto(s1, &r, test_task, event_done, &completion, - &addr2, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - waitfor(&completion); - assert_true(atomic_load(&completion.done)); - assert_int_equal(completion.result, ISC_R_SUCCESS); - - snprintf(sendbuf, sizeof(sendbuf), "World"); - r.base = (void *)sendbuf; - r.length = strlen(sendbuf) + 1; - - completion_init(&completion); - result = isc_socket_sendto(s1, &r, test_task, event_done, &completion, - &addr2, NULL); - assert_int_equal(result, ISC_R_SUCCESS); - waitfor(&completion); - assert_true(atomic_load(&completion.done)); - assert_int_equal(completion.result, ISC_R_SUCCESS); - - r.base = (void *)recvbuf; - r.length = BUFSIZ; - completion_init(&completion); - result = isc_socket_recv(s2, &r, 1, test_task, event_done, &completion); - assert_int_equal(result, ISC_R_SUCCESS); - waitfor(&completion); - assert_true(atomic_load(&completion.done)); - assert_int_equal(completion.result, ISC_R_SUCCESS); - assert_string_equal(recvbuf, "Hello"); - - r.base = (void *)recvbuf; - r.length = BUFSIZ; - completion_init(&completion); - result = isc_socket_recv(s3, &r, 1, test_task, event_done, &completion); - assert_int_equal(result, ISC_R_SUCCESS); - waitfor(&completion); - assert_true(atomic_load(&completion.done)); - assert_int_equal(completion.result, ISC_R_SUCCESS); - assert_string_equal(recvbuf, "World"); -} - /* Test UDP sendto/recv (IPv4) */ static void udp_dscp_v4_test(void **state) { @@ -787,8 +704,6 @@ main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(udp_sendto_test, _setup, _teardown), - cmocka_unit_test_setup_teardown(udp_dup_test, _setup, - _teardown), cmocka_unit_test_setup_teardown(tcp_dscp_v4_test, _setup, _teardown), cmocka_unit_test_setup_teardown(tcp_dscp_v6_test, _setup,