mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-09 16:22:55 -05:00
auth zone move file descriptor functionality to outside network
for the unit test git-svn-id: file:///svn/unbound/trunk@4482 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
c1047e6a6c
commit
84e819dc31
4 changed files with 197 additions and 109 deletions
|
|
@ -3399,67 +3399,6 @@ xfr_probe_nextmaster(struct auth_xfer* xfr)
|
|||
return;
|
||||
}
|
||||
|
||||
/** create fd to send to this master */
|
||||
static int
|
||||
xfr_fd_for_master(struct module_env* env, struct sockaddr_storage* to_addr,
|
||||
socklen_t to_addrlen, char* host)
|
||||
{
|
||||
struct sockaddr_storage* addr;
|
||||
socklen_t addrlen;
|
||||
int i;
|
||||
int try;
|
||||
|
||||
/* select interface */
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
if(env->outnet->num_ip6 == 0) {
|
||||
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", host);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(env->rnd, env->outnet->num_ip6);
|
||||
addr = &env->outnet->ip6_ifs[i].addr;
|
||||
addrlen = env->outnet->ip6_ifs[i].addrlen;
|
||||
} else {
|
||||
if(env->outnet->num_ip4 == 0) {
|
||||
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", host);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(env->rnd, env->outnet->num_ip4);
|
||||
addr = &env->outnet->ip4_ifs[i].addr;
|
||||
addrlen = env->outnet->ip4_ifs[i].addrlen;
|
||||
}
|
||||
|
||||
/* create fd */
|
||||
for(try = 0; try<1000; try++) {
|
||||
int freebind = 0;
|
||||
int noproto = 0;
|
||||
int inuse = 0;
|
||||
int port = ub_random(env->rnd)&0xffff;
|
||||
int fd = -1;
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
|
||||
sa.sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
|
||||
(struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
|
||||
(struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
}
|
||||
if(fd != -1) {
|
||||
return fd;
|
||||
}
|
||||
if(!inuse) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* too many tries */
|
||||
log_err("cannot send probe, ports are in use");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** create SOA probe packet for xfr */
|
||||
static void
|
||||
xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf,
|
||||
|
|
@ -4103,47 +4042,23 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
|||
xfr->task_transfer->cp = NULL;
|
||||
}
|
||||
|
||||
/* connect on fd */
|
||||
if(!xfr->task_transfer->cp) {
|
||||
int fd = outnet_get_tcp_fd(&addr, addrlen, env->cfg->tcp_mss);
|
||||
if(fd == -1) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "cannot create fd for "
|
||||
"xfr %s to %s", zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
fd_set_nonblock(fd);
|
||||
if(!outnet_tcp_connect(fd, &addr, addrlen)) {
|
||||
/* outnet_tcp_connect has closed fd on error for us */
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "cannot tcp connect() for"
|
||||
"xfr %s to %s", zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xfr->task_transfer->cp = comm_point_create_tcp_out(
|
||||
env->worker_base, 65552,
|
||||
auth_xfer_transfer_tcp_callback, xfr);
|
||||
if(!xfr->task_transfer->cp) {
|
||||
close(fd);
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
xfr->task_transfer->cp->repinfo.addrlen = addrlen;
|
||||
memcpy(&xfr->task_transfer->cp->repinfo.addr, &addr, addrlen);
|
||||
/* set timeout on TCP connection */
|
||||
comm_point_start_listening(xfr->task_transfer->cp, fd,
|
||||
AUTH_TRANSFER_TIMEOUT);
|
||||
}
|
||||
|
||||
/* set the packet to be written */
|
||||
/* create new ID */
|
||||
xfr->task_transfer->id = (uint16_t)(ub_random(env->rnd)&0xffff);
|
||||
xfr_create_ixfr_packet(xfr, xfr->task_transfer->cp->buffer,
|
||||
xfr_create_ixfr_packet(xfr, env->scratch_buffer,
|
||||
xfr->task_transfer->id);
|
||||
|
||||
/* connect on fd */
|
||||
xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
|
||||
auth_xfer_transfer_tcp_callback, xfr, &addr, addrlen,
|
||||
env->scratch_buffer, AUTH_TRANSFER_TIMEOUT);
|
||||
if(!xfr->task_transfer->cp) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "cannot create tcp cp connection for "
|
||||
"xfr %s to %s", zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -4750,22 +4665,15 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
|||
xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
|
||||
xfr->task_probe->id);
|
||||
if(!xfr->task_probe->cp) {
|
||||
int fd = xfr_fd_for_master(env, &addr, addrlen, master->host);
|
||||
if(fd == -1) {
|
||||
xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
|
||||
auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
|
||||
if(!xfr->task_probe->cp) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "cannot create fd for "
|
||||
verbose(VERB_ALGO, "cannot create udp cp for "
|
||||
"probe %s to %s", zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
xfr->task_probe->cp = comm_point_create_udp(env->worker_base,
|
||||
fd, env->outnet->udp_buff, auth_xfer_probe_udp_callback,
|
||||
xfr);
|
||||
if(!xfr->task_probe->cp) {
|
||||
close(fd);
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(!xfr->task_probe->timer) {
|
||||
xfr->task_probe->timer = comm_timer_create(env->worker_base,
|
||||
|
|
|
|||
|
|
@ -2140,6 +2140,122 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
|
|||
}
|
||||
}
|
||||
|
||||
/** create fd to send to this destination */
|
||||
static int
|
||||
fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
socklen_t to_addrlen)
|
||||
{
|
||||
struct sockaddr_storage* addr;
|
||||
socklen_t addrlen;
|
||||
int i;
|
||||
int try;
|
||||
|
||||
/* select interface */
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
if(outnet->num_ip6 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip6);
|
||||
addr = &outnet->ip6_ifs[i].addr;
|
||||
addrlen = outnet->ip6_ifs[i].addrlen;
|
||||
} else {
|
||||
if(outnet->num_ip4 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip4);
|
||||
addr = &outnet->ip4_ifs[i].addr;
|
||||
addrlen = outnet->ip4_ifs[i].addrlen;
|
||||
}
|
||||
|
||||
/* create fd */
|
||||
for(try = 0; try<1000; try++) {
|
||||
int freebind = 0;
|
||||
int noproto = 0;
|
||||
int inuse = 0;
|
||||
int port = ub_random(outnet->rnd)&0xffff;
|
||||
int fd = -1;
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
|
||||
sa.sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
|
||||
(struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
|
||||
(struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
}
|
||||
if(fd != -1) {
|
||||
return fd;
|
||||
}
|
||||
if(!inuse) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* too many tries */
|
||||
log_err("cannot send probe, ports are in use");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct comm_point*
|
||||
outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen)
|
||||
{
|
||||
struct comm_point* cp;
|
||||
int fd = fd_for_dest(outnet, to_addr, to_addrlen);
|
||||
if(fd == -1) {
|
||||
return NULL;
|
||||
}
|
||||
cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
|
||||
cb, cb_arg);
|
||||
if(!cp) {
|
||||
log_err("malloc failure");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
struct comm_point*
|
||||
outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
sldns_buffer* query, int timeout)
|
||||
{
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
|
||||
if(fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
fd_set_nonblock(fd);
|
||||
if(!outnet_tcp_connect(fd, to_addr, to_addrlen)) {
|
||||
/* outnet_tcp_connect has closed fd on error for us */
|
||||
return 0;
|
||||
}
|
||||
cp = comm_point_create_tcp_out(outnet->base, 65552, cb, cb_arg);
|
||||
if(!cp) {
|
||||
log_err("malloc failure");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
cp->repinfo.addrlen = to_addrlen;
|
||||
memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
|
||||
/* set timeout on TCP connection */
|
||||
comm_point_start_listening(cp, fd, timeout);
|
||||
/* copy scratch buffer to cp->buffer */
|
||||
sldns_buffer_copy(cp->buffer, query);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/** get memory used by waiting tcp entry (in use or not) */
|
||||
static size_t
|
||||
waiting_tcp_get_mem(struct waiting_tcp* w)
|
||||
|
|
|
|||
|
|
@ -537,6 +537,41 @@ size_t serviced_get_mem(struct serviced_query* sq);
|
|||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss);
|
||||
|
||||
/**
|
||||
* Create udp commpoint suitable for sending packets to the destination.
|
||||
* @param outnet: outside_network with the comm_base it is attached to,
|
||||
* with the outgoing interfaces chosen from, and rnd gen for random.
|
||||
* @param cb: callback function for the commpoint.
|
||||
* @param cb_arg: callback argument for cb.
|
||||
* @param to_addr: intended destination.
|
||||
* @param to_addrlen: length of to_addr.
|
||||
* @return commpoint that you can comm_point_send_udp_msg with, or NULL.
|
||||
*/
|
||||
struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen);
|
||||
|
||||
/**
|
||||
* Create tcp commpoint suitable for communication to the destination.
|
||||
* It also performs connect() to the to_addr.
|
||||
* @param outnet: outside_network with the comm_base it is attached to,
|
||||
* and the tcp_mss.
|
||||
* @param cb: callback function for the commpoint.
|
||||
* @param cb_arg: callback argument for cb.
|
||||
* @param to_addr: intended destination.
|
||||
* @param to_addrlen: length of to_addr.
|
||||
* @param query: initial packet to send writing, in buffer. It is copied
|
||||
* to the commpoint buffer that is created.
|
||||
* @param timeout: timeout for the TCP connection.
|
||||
* timeout in milliseconds, or -1 for no (change to the) timeout.
|
||||
* So seconds*1000.
|
||||
* @return commpoint that you can comm_point_send_udp_msg with, or NULL.
|
||||
*/
|
||||
struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
struct sldns_buffer* query, int timeout);
|
||||
|
||||
/** connect tcp connection to addr, 0 on failure */
|
||||
int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
|
|
|
|||
|
|
@ -1437,7 +1437,6 @@ struct comm_point* comm_point_create_udp(struct comm_base *ATTR_UNUSED(base),
|
|||
comm_point_callback_type* ATTR_UNUSED(callback),
|
||||
void* ATTR_UNUSED(callback_arg))
|
||||
{
|
||||
/* could create a test framework; and intercept eg. authzone probes */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1445,8 +1444,38 @@ struct comm_point* comm_point_create_tcp_out(struct comm_base*
|
|||
ATTR_UNUSED(base), size_t ATTR_UNUSED(bufsize),
|
||||
comm_point_callback_type* ATTR_UNUSED(callback),
|
||||
void* ATTR_UNUSED(callback_arg))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen)
|
||||
{
|
||||
/* used by authzone transfers */
|
||||
(void)outnet;
|
||||
(void)cb;
|
||||
(void)cb_arg;
|
||||
(void)to_addr;
|
||||
(void)to_addrlen;
|
||||
/* TODO */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
struct sldns_buffer* query, int timeout)
|
||||
{
|
||||
/* used by authzone transfers */
|
||||
(void)outnet;
|
||||
(void)cb;
|
||||
(void)cb_arg;
|
||||
(void)to_addr;
|
||||
(void)to_addrlen;
|
||||
(void)query;
|
||||
(void)timeout;
|
||||
/* TODO */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue