#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
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) {
/*
* 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) {
}
}
- 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];
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));
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;
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;
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)");
}
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];
query = reqev->ev_arg;
- response = NULL;
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
result = dns_request_getresponse(reqev->request, response,
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;
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));
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;
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);
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,
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);
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;
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));
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);
#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);
query = reqev->ev_arg;
- response = NULL;
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
result = dns_request_getresponse(reqev->request, response,
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);
}
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);
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;
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));
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);
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());
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,
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;
}
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;
}
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;
}
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 */
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;
#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;
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.
*/
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
* 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 */
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;
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', ' ')
#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 */
+
+/*%
+ * 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).
+ */
+#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 */
/*%
- * 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.
+ * 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.
*/
-#define PORTBUFLOCK(mgr) \
- if ((mgr)->qid != NULL) \
- LOCK(&((mgr)->qid->lock))
-#define PORTBUFUNLOCK(mgr) \
- if ((mgr)->qid != NULL) \
- UNLOCK((&(mgr)->qid->lock))
+#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.
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)
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]);
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) {
}
}
-/*%
- * 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.
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);
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;
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;
* 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)];
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];
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;
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.
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);
}
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.
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 {
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);
}
REQUIRE(VALID_DISPATCH(disp));
- qid = disp->qid;
+ qid = disp->mgr->qid;
LOCK(&disp->lock);
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;
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);
} 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));
}
mgr->v6ports = v6ports;
mgr->nv6ports = nv6ports;
- PORTBUFUNLOCK(mgr);
return (ISC_R_SUCCESS);
}
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);
isc_portset_destroy(mctx, &v4portset);
isc_portset_destroy(mctx, &v6portset);
+ qid_allocate(mgr, &mgr->qid);
mgr->magic = DNS_DISPATCHMGR_MAGIC;
*mgrp = mgr;
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;
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
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));
}
* 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));
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);
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;
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 =
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;
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.
*/
return (ISC_R_SUCCESS);
-kill_socket:
+cleanup:
isc_socket_detach(&disp->socket);
-deallocate_dispatch:
dispatch_free(&disp);
UNLOCK(&mgr->lock);
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;
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;
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;
/*
* 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);
}
}
}
- 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];
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;
/*
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)
{
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.
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);
disp->requests--;
dec_stats(disp->mgr,
- (qid == disp->mgr->qid)
+ (disp->socktype == isc_sockettype_udp)
? dns_resstatscounter_disprequdp
: dns_resstatscounter_dispreqtcp);
REQUIRE(VALID_DISPATCH(disp));
mgr = disp->mgr;
REQUIRE(VALID_DISPATCHMGR(mgr));
-
- qid = DNS_QID(disp);
+ qid = mgr->qid;
if (sockevent != NULL) {
REQUIRE(*sockevent != NULL);
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);
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.
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;
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.
*
*\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.
*
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.
*
*\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.
*
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
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
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);
}
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) {
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)) {
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
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);
}
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));
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
- sock = req_getsocket(request);
+ sock = dns_dispatch_getentrysocket(request->dispentry);
INSIST(sock != NULL);
message->id = id;
/***
*** 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;
*/
} 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:
}
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;
}
bool retry = false;
isc_interval_t interval;
isc_result_t result;
- unsigned int attrs;
fetchctx_t *fctx;
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
isc_socket_detach(&query->tcpsocket);
resquery_destroy(&query);
} else {
+ int attrs = 0;
+
switch (sevent->result) {
case ISC_R_SUCCESS:
* 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()
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);
}
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);
}
uint16_t id;
struct in_addr ina;
unsigned char message[12];
- unsigned int attrs;
unsigned char rbuf[12];
UNUSED(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);
/*
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);
*\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);
/*%<
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
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
sock->fd = -1;
sock->threadid = -1;
sock->dscp = 0; /* TOS/TCLASS is zero until set. */
- sock->dupped = 0;
sock->statsindex = NULL;
sock->active = 0;
}
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";
#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;
-
- /*
- * 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;
+ 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;
}
-#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;
}
}
- if (dup_socket != NULL) {
- goto setup_done;
- }
-
result = make_nonblock(sock->fd);
if (result != ISC_R_SUCCESS) {
(void)close(sock->fd);
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]);
}
/*
- * 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;
sock->pf = pf;
- result = opensocket(manager, sock, dup_socket);
+ result = opensocket(manager, sock);
if (result != ISC_R_SUCCESS) {
free_socket(&sock);
return (result);
#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);
}
* 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
REQUIRE(sock->fd == -1);
REQUIRE(sock->threadid == -1);
- result = opensocket(sock->manager, sock, NULL);
+ result = opensocket(sock->manager, sock);
UNLOCK(&sock->lock);
sock->fd = -1;
sock->threadid = -1;
- sock->dupped = 0;
memset(sock->name, 0, sizeof(sock->name));
sock->tag = NULL;
sock->listener = 0;
LOCK(&sock->lock);
INSIST(!sock->bound);
- INSIST(!sock->dupped);
if (sock->pf != sockaddr->type.sa.sa_family) {
UNLOCK(&sock->lock);
#endif /* if defined(IPV6_V6ONLY) */
REQUIRE(VALID_SOCKET(sock));
- INSIST(!sock->dupped);
#ifdef IPV6_V6ONLY
if (sock->pf == AF_INET6) {
}
#endif /* if !defined(IP_TOS) && !defined(IPV6_TCLASS) */
-#ifdef notyet
- REQUIRE(!sock->dupped);
-#endif /* ifdef notyet */
-
setdscp(sock, dscp);
}
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__))
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) {
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,