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,
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;
}
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,
}
}
+/** 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)
* 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);
comm_point_callback_type* ATTR_UNUSED(callback),
void* ATTR_UNUSED(callback_arg))
{
- /* could create a test framework; and intercept eg. authzone probes */
return NULL;
}
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;
}