isc_refcount_t irefs;
- /*%
- * Locked by qid->lock if qid exists; otherwise, can be used without
- * being locked.
- *
- * Memory footprint considerations: this is a simple implementation of
- * available ports, i.e., an ordered array of the actual port numbers.
- * This will require about 256KB of memory in the worst case (128KB for
- * each of IPv4 and IPv6). We could reduce it by representing it as a
- * more sophisticated way such as a list (or array) of ranges that are
- * searched to identify a specific port. Our decision here is the saved
- * memory isn't worth the implementation complexity, considering the
- * fact that the whole BIND9 process (which is mainly named) already
- * requires a pretty large memory footprint. We may, however, have to
- * revisit the decision when we want to use it as a separate module for
- * an environment where memory requirement is severer.
- */
in_port_t *v4ports; /*%< available ports for IPv4 */
unsigned int nv4ports; /*%< # of available ports for IPv4 */
in_port_t *v6ports; /*%< available ports for IPv4 */
}
}
+isc_result_t
+dns_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp,
+ isc_task_t *task, isc_taskaction_t action, void *arg) {
+ isc_socket_t *sock = NULL;
+ isc_sockaddr_t *address = NULL;
+
+ if (resp != NULL) {
+ REQUIRE(VALID_RESPONSE(resp));
+ sock = resp->dispsocket->socket;
+ address = &resp->host;
+ } else if (disp != NULL) {
+ REQUIRE(VALID_DISPATCH(disp));
+ sock = disp->socket;
+ address = &disp->peer;
+ } else {
+ INSIST(0);
+ ISC_UNREACHABLE();
+ }
+
+ return (isc_socket_connect(sock, address, task, action, arg));
+}
+
/*
* disp must be locked.
*/
*\li dispp != NULL and *dispp be a valid dispatch.
*/
+isc_result_t
+dns_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp,
+ isc_task_t *task, isc_taskaction_t action, void *arg);
+/*%<
+ * Connect the UDP socket in 'resp' or the TCP socket in 'disp' to the
+ * remote server, and run the specified callback.
+ *
+ * Requires:
+ *\li 'resp' is NULL and 'disp' is valid, or
+ *\li 'disp' is NULL and 'resp' is valid.
+ */
+
void
dns_dispatch_starttcp(dns_dispatch_t *disp);
/*%<
request->destaddr = *destaddr;
if (tcp && !connected) {
- result = isc_socket_connect(sock, destaddr, task, req_connected,
- request);
+ result = dns_dispatch_connect(request->dispatch, NULL, task,
+ req_connected, request);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
request->destaddr = *destaddr;
if (tcp && !connected) {
- result = isc_socket_connect(sock, destaddr, task, req_connected,
- request);
+ result = dns_dispatch_connect(request->dispatch, NULL, task,
+ req_connected, request);
if (result != ISC_R_SUCCESS) {
goto unlink;
}
query->magic = QUERY_MAGIC;
if ((query->options & DNS_FETCHOPT_TCP) != 0) {
- isc_socket_t *sock = NULL;
-
/*
* Connect to the remote server.
*/
- sock = dns_dispatch_getsocket(query->dispatch);
- result = isc_socket_connect(sock, &addrinfo->sockaddr, task,
- resquery_connected, query);
+ result = dns_dispatch_connect(query->dispatch, NULL, task,
+ resquery_connected, query);
if (result != ISC_R_SUCCESS) {
goto cleanup_dispatch;
}
return (0);
}
-static inline isc_socket_t *
-query2sock(const resquery_t *query) {
- return (dns_dispatch_getentrysocket(query->dispentry));
-}
-
static inline size_t
add_serveraddr(uint8_t *buf, const size_t bufsize, const resquery_t *query) {
return (addr2buf(buf, bufsize, &query->addrinfo->sockaddr));
static isc_result_t
resquery_send(resquery_t *query) {
- fetchctx_t *fctx;
+ fetchctx_t *fctx = NULL;
isc_result_t result;
dns_name_t *qname = NULL;
dns_rdataset_t *qrdataset = NULL;
isc_region_t r;
- dns_resolver_t *res;
+ dns_resolver_t *res = NULL;
isc_task_t *task;
isc_socket_t *sock;
isc_buffer_t tcpbuffer;
- isc_sockaddr_t *address;
- isc_buffer_t *buffer;
+ isc_sockaddr_t *address = NULL;
+ isc_buffer_t *buffer = NULL;
isc_netaddr_t ipaddr;
dns_tsigkey_t *tsigkey = NULL;
dns_peer_t *peer = NULL;
res = fctx->res;
task = res->buckets[fctx->bucketnum].task;
- address = NULL;
if (tcp) {
/*
*/
dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
- sock = query2sock(query);
-
- /*
- * Send the query!
- */
if (!tcp) {
- address = &query->addrinfo->sockaddr;
- result = isc_socket_connect(sock, address, task,
- resquery_udpconnected, query);
+ /* Connect the UDP socket */
+ result = dns_dispatch_connect(NULL, query->dispentry, task,
+ resquery_udpconnected, query);
if (result != ISC_R_SUCCESS) {
goto cleanup_message;
}
query->connects++;
}
+
isc_buffer_usedregion(buffer, &r);
+ sock = dns_dispatch_getentrysocket(query->dispentry);
+
/*
* XXXRTH Make sure we don't send to ourselves! We should probably
* prune out these addresses when we get them from the ADB.
}
}
+ address = tcp ? NULL : &query->addrinfo->sockaddr;
result = isc_socket_sendto2(sock, &r, task, address, NULL,
&query->sendevent, 0);
INSIST(result == ISC_R_SUCCESS);
dtmsgtype = DNS_DTTYPE_RR;
}
- sock = query2sock(rctx->query);
-
+ sock = dns_dispatch_getentrysocket(rctx->query);
if (sock != NULL) {
result = isc_socket_getsockname(sock, &localaddr);
if (result == ISC_R_SUCCESS) {
ISC_UNREACHABLE();
}
- /* TODO isc_socket_dscp(xfr->socket, xfr->dscp); */
return (ISC_R_SUCCESS);
failure:
xfr->handle = handle;
sockaddr = isc_nmhandle_peeraddr(handle);
isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext));
+ /* TODO set DSCP */
if (xfr->tsigkey != NULL && xfr->tsigkey->key != NULL) {
dns_name_format(dst_key_name(xfr->tsigkey->key), signerbuf,