12 December 2017: Ralph
- Fix qname-minimisation documentation (A QTYPE, not NS)
+12 December 2017: Wouter
+ - authzone work, transfer connect.
+
7 December 2017: Ralph
- Check whether --with-libunbound-only is set when using --with-nettle
or --with-nss.
}
}
- /* always new cp? TODO */
- /* TODO: set REUSEADDR and tcp nonblock, and call connect on fd */
+ /* remove previous TCP connection (if any) */
+ if(xfr->task_transfer->cp) {
+ comm_point_delete(xfr->task_transfer->cp);
+ xfr->task_transfer->cp = NULL;
+ }
+
+ /* connect on fd */
if(!xfr->task_transfer->cp) {
- int fd = xfr_fd_for_master(env, &addr, addrlen, master->host);
+ int fd = outnet_get_tcp_fd(&addr, addrlen, env->cfg->tcp_mss);
if(fd == -1) {
char zname[255+1];
dname_str(xfr->name, zname);
"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);
/* set timeout on TCP connection */
comm_point_start_listening(xfr->task_transfer->cp, fd,
AUTH_TRANSFER_TIMEOUT);
- } else {
- comm_point_start_listening(xfr->task_transfer->cp, -1,
- AUTH_TRANSFER_TIMEOUT);
}
/* set the packet to be written */
struct module_env* env;
log_assert(xfr->task_probe);
env = xfr->task_probe->env;
-
- /* TODO */
- (void)xfr;
- (void)env;
(void)repinfo;
- (void)c;
- (void)err;
+
+ if(err != NETEVENT_NOERROR) {
+ /* connection failed, closed, or timeout */
+ /* stop this transfer, cleanup
+ * and continue task_transfer*/
+ verbose(VERB_ALGO, "xfr stopped, connection lost to %s",
+ xfr->task_transfer->master->host);
+ comm_point_close(c);
+ xfr_transfer_nexttarget_or_end(xfr, env);
+ return 0;
+ }
+
+ /* TODO: handle returned packet */
+ /* if it fails, cleanup and end this transfer */
+ /* if it needs to fallback from IXFR to AXFR, do that */
+ /* if it is good, link it into the list of data */
+
+ /* if we want to read more messages, setup the commpoint to read
+ * a DNS packet, and the timeout */
+ c->tcp_is_reading = 1;
+ comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT);
return 0;
}
return 1;
}
-/** use next free buffer to service a tcp query */
-static int
-outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
+/** get TCP file descriptor for address, returns -1 on failure,
+ * 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)
{
- struct pending_tcp* pend = w->outnet->tcp_free;
int s;
#ifdef SO_REUSEADDR
int on = 1;
#endif
- log_assert(pend);
- log_assert(pkt);
- log_assert(w->addrlen > 0);
- /* open socket */
#ifdef INET6
- if(addr_is_ip6(&w->addr, w->addrlen))
+ if(addr_is_ip6(addr, addrlen))
s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
else
#endif
if(s == -1) {
#ifndef USE_WINSOCK
log_err_addr("outgoing tcp: socket", strerror(errno),
- &w->addr, w->addrlen);
+ addr, addrlen);
#else
log_err_addr("outgoing tcp: socket",
- wsa_strerror(WSAGetLastError()), &w->addr, w->addrlen);
+ wsa_strerror(WSAGetLastError()), addr, addrlen);
#endif
- return 0;
+ return -1;
}
#ifdef SO_REUSEADDR
" setsockopt(.. SO_REUSEADDR ..) failed");
}
#endif
- if (w->outnet->tcp_mss > 0) {
+
+ if(tcp_mss > 0) {
#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
- (void*)&w->outnet->tcp_mss,
- (socklen_t)sizeof(w->outnet->tcp_mss)) < 0) {
+ (void*)&tcp_mss, (socklen_t)sizeof(tcp_mss)) < 0) {
verbose(VERB_ALGO, "outgoing tcp:"
" setsockopt(.. TCP_MAXSEG ..) failed");
}
#endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */
}
+ return s;
+}
+
+/** connect tcp connection to addr, 0 on failure */
+int
+outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen)
+{
+ if(connect(s, (struct sockaddr*)addr, addrlen) == -1) {
+#ifndef USE_WINSOCK
+#ifdef EINPROGRESS
+ if(errno != EINPROGRESS) {
+#endif
+ if(tcp_connect_errno_needs_log(
+ (struct sockaddr*)addr, addrlen))
+ log_err_addr("outgoing tcp: connect",
+ strerror(errno), addr, addrlen);
+ close(s);
+#ifdef EINPROGRESS
+ }
+#endif
+#else /* USE_WINSOCK */
+ if(WSAGetLastError() != WSAEINPROGRESS &&
+ WSAGetLastError() != WSAEWOULDBLOCK) {
+ closesocket(s);
+ }
+#endif
+ return 0;
+ }
+ return 1;
+}
+
+/** use next free buffer to service a tcp query */
+static int
+outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
+{
+ struct pending_tcp* pend = w->outnet->tcp_free;
+ int s;
+ log_assert(pend);
+ log_assert(pkt);
+ log_assert(w->addrlen > 0);
+ /* open socket */
+ s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss);
+
if(!pick_outgoing_tcp(w, s))
return 0;
*/
size_t serviced_get_mem(struct serviced_query* sq);
+/** get TCP file descriptor for address, returns -1 on failure,
+ * 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);
+
+/** connect tcp connection to addr, 0 on failure */
+int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
+
/** callback for incoming udp answers from the network */
int outnet_udp_cb(struct comm_point* c, void* arg, int error,
struct comm_reply *reply_info);
return 0;
}
+int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr),
+ socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss))
+{
+ return -1;
+}
+
+int outnet_tcp_connect(int ATTR_UNUSED(s), struct sockaddr_storage* ATTR_UNUSED(addr),
+ socklen_t ATTR_UNUSED(addrlen))
+{
+ return 0;
+}
+
/*********** End of Dummy routines ***********/