From: Wouter Wijngaards Date: Fri, 18 Jan 2008 08:51:19 +0000 (+0000) Subject: support for IP_RECVDSTADDR. X-Git-Tag: release-0.9~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=306db56f1f4abb586aa2e7ae8e6db31baa0f0720;p=thirdparty%2Funbound.git support for IP_RECVDSTADDR. git-svn-id: file:///svn/unbound/trunk@874 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 812489901..8a338e506 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +18 January 2008: Wouter + - touch up of manpage for libunbound. + - support for IP_RECVDSTADDR (for *BSD ip4). + 17 January 2008: Wouter - fixup configure in case -lldns is installed. - fixup a couple of doxygen warnings, about enum variables. diff --git a/doc/libunbound.3 b/doc/libunbound.3 index e147d83bb..a49e8b16d 100644 --- a/doc/libunbound.3 +++ b/doc/libunbound.3 @@ -49,10 +49,14 @@ \fBub_val_ctx_add_ta\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR ta); .LP \fIint\fR -\fBub_val_ctx_add_ta_file\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR fname); +\fBub_val_ctx_add_ta_file\fR(\fIstruct ub_val_ctx*\fR ctx, +.br + \fIchar*\fR fname); .LP \fIint\fR -\fBub_val_ctx_trustedkeys\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR fname); +\fBub_val_ctx_trustedkeys\fR(\fIstruct ub_val_ctx*\fR ctx, +.br + \fIchar*\fR fname); .LP \fIint\fR \fBub_val_ctx_debuglevel\fR(\fIstruct ub_val_ctx*\fR ctx, \fIint\fR d); @@ -75,16 +79,16 @@ \fIint\fR \fBub_val_resolve\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR name, .br - \fIint\fR rrtype, \fIint\fR rrclass, \fIint*\fR secure, + \fIint\fR rrtype, \fIint\fR rrclass, \fIint*\fR secure, .br - \fIint*\fR data, \fIstruct ub_val_result**\fR result); + \fIint*\fR data, \fIstruct ub_val_result**\fR result); .LP \fIint\fR \fBub_val_resolve_async\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR name, .br - \fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata, + \fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata, .br - \fIub_val_callback_t\fR callback, \fIint*\fR async_id); + \fIub_val_callback_t\fR callback, \fIint*\fR async_id); .LP \fIint\fR \fBub_val_cancel\fR(\fIstruct ub_val_ctx*\fR ctx, \fIint\fR async_id); @@ -160,11 +164,14 @@ Higher debug level gives more output. .TP .B ub_val_ctx_async Set a context behaviour for asynchronous action. -if set to true, enables threading and a call to resolve_async() +if set to true, enables threading and a call to +.B ub_val_resolve_async creates a thread to handle work in the background. If false, a process is forked to handle work in the background. -Changes to this setting after async() calls have been made have -no effect (delete and re\-create the context to change). +Changes to this setting after +.B ub_val_resolve_async +calls have been made have no effect (delete and re\-create the context +to change). .TP .B ub_val_ctx_poll Poll a context to see if it has any new results. @@ -172,14 +179,14 @@ Do not poll in a loop, instead extract the fd below to poll for readiness, and then check, or wait using the wait routine. Returns 0 if nothing to read, or nonzero if a result is available. If nonzero, call -.B ctx_process +.B ub_val_ctx_process to do callbacks. .TP .B ub_val_ctx_wait Wait for a context to finish with results. Calls -.B ub_val_ctx_process after -the wait for you. After the wait, there are no more outstanding asynchronous -queries. +.B ub_val_ctx_process +after the wait for you. After the wait, there are no more outstanding +asynchronous queries. .TP .B ub_val_ctx_fd Get file descriptor. Wait for it to become readable, at this point @@ -203,15 +210,15 @@ The result structure is newly allocated with the resulting data. Perform asynchronous resolution and validation of the target name. Arguments mean the same as for \fBub_val_resolve\fR except no data is returned immediately, instead a callback is called later. -The callback receives a copy of the mydata point, that you can use to pass +The callback receives a copy of the mydata pointer, that you can use to pass information to the callback. The callback type is a function pointer to a function declared as .IP void my_callback_function(void* my_arg, int err, .br - int secure, int havedata, + int secure, int havedata, .br - struct ub_val_result* result); + struct ub_val_result* result); .IP The async_id is returned so you can (at your option) decide to track it and cancel the request if needed. @@ -239,8 +246,8 @@ The result of the DNS resolution and validation is returned as int* len; /* array with lengths of rdata items */ char* canonname; /* canonical name of result */ int rcode; /* additional error code in case of error */ - int nxdomain; /* if nodata because no domain */ - int bogus; /* if not secure due to security failure */ + int nxdomain; /* true if nodata because no domain */ + int bogus; /* true if there was a security failure */ }; .fi .SH "RETURN VALUES" diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 6cd65c4de..22e3dad8f 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -264,14 +264,20 @@ set_ip6_recvpktinfo(int s) return 0; #endif /* defined IPV6_RECVPKTINFO */ -#ifdef IP_PKTINFO +#ifdef IP_RECVDSTADDR + if(setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, + &on, (socklen_t)sizeof(on)) < 0) { + log_err("setsockopt(..., IP_RECVDSTADDR, ...) failed: %s", + strerror(errno)); + } +#elif defined(IP_PKTINFO) if(setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, (socklen_t)sizeof(on)) < 0) { log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s", strerror(errno)); } #else - log_err("no IP_PKTINFO option, please disable " + log_err("no IP_RECVDSTADDR or IP_PKTINFO option, please disable " "interface-automatic in config"); return 0; #endif /* IP_PKTINFO */ diff --git a/util/netevent.c b/util/netevent.c index 43bd1917f..7f43b7715 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -181,7 +181,7 @@ comm_point_send_udp_msg(struct comm_point *c, ldns_buffer* packet, /** print debug ancillary info */ void p_ancil(const char* str, struct comm_reply* r) { -#if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(IP_PKTINFO) +#if defined(AF_INET6) && defined(IPV6_PKTINFO) if(r->srctype != 4 && r->srctype != 6) { log_info("%s: unknown srctype %d", str, r->srctype); return; @@ -195,6 +195,15 @@ void p_ancil(const char* str, struct comm_reply* r) buf[sizeof(buf)-1]=0; log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex); } else if(r->srctype == 4) { +#ifdef IP_RECVDSTADDR + char buf1[1024]; + if(inet_ntop(AF_INET, &r->pktinfo.v4addr, + buf1, (socklen_t)sizeof(buf1)) == 0) { + strncpy(buf1, "(inet_ntop error)", sizeof(buf1)); + } + buf1[sizeof(buf1)-1]=0; + log_info("%s: %s", str, buf1); +#elif defined(IP_PKTINFO) char buf1[1024], buf2[1024]; if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_addr, buf1, (socklen_t)sizeof(buf1)) == 0) { @@ -208,6 +217,7 @@ void p_ancil(const char* str, struct comm_reply* r) buf2[sizeof(buf2)-1]=0; log_info("%s: %d %s %s", str, r->pktinfo.v4info.ipi_ifindex, buf1, buf2); +#endif } #endif } @@ -217,7 +227,7 @@ int comm_point_send_udp_msg_if(struct comm_point *c, ldns_buffer* packet, struct sockaddr* addr, socklen_t addrlen, struct comm_reply* r) { -#if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(IP_PKTINFO) +#if defined(AF_INET6) && defined(IPV6_PKTINFO) ssize_t sent; struct msghdr msg; struct iovec iov[1]; @@ -245,11 +255,19 @@ comm_point_send_udp_msg_if(struct comm_point *c, ldns_buffer* packet, #ifndef S_SPLINT_S cmsg = CMSG_FIRSTHDR(&msg); if(r->srctype == 4) { +#ifdef IP_RECVDSTADDR + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_RECVDSTADDR; + memmove(CMSG_DATA(cmsg), &r->pktinfo.v4addr, + sizeof(struct in_addr)); + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); +#elif defined(IP_PKTINFO) cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_PKTINFO; memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info, sizeof(struct in_pktinfo)); cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); +#endif } else if(r->srctype == 6) { cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; @@ -286,7 +304,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, ldns_buffer* packet, void comm_point_udp_ancil_callback(int fd, short event, void* arg) { -#if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(IP_PKTINFO) +#if defined(AF_INET6) && defined(IPV6_PKTINFO) struct comm_reply rep; struct msghdr msg; struct iovec iov[1]; @@ -334,19 +352,34 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) log_info("looking at hdr %d %d (need %d %d or %d %d)", cmsg->cmsg_level, cmsg->cmsg_type, IPPROTO_IPV6, IPV6_PKTINFO, - IPPROTO_IP, IP_PKTINFO); + IPPROTO_IP, +#ifdef IP_RECVDSTADDR + IP_RECVDSTADDR +#elif defined(IP_PKTINFO) + IP_PKTINFO +#endif + ); if( cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { rep.srctype = 6; memmove(&rep.pktinfo.v6info, CMSG_DATA(cmsg), sizeof(struct in6_pktinfo)); break; +#ifdef IP_RECVDSTADDR + } else if( cmsg->cmsg_level == IPPROTO_IP && + cmsg->cmsg_type == IP_RECVDSTADDR) { + rep.srctype = 4; + memmove(&rep.v4addr, CMSG_DATA(cmsg), + sizeof(struct in_addr)); + break; +#elif defined(IP_PKTINFO) } else if( cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { rep.srctype = 4; memmove(&rep.pktinfo.v4info, CMSG_DATA(cmsg), sizeof(struct in_pktinfo)); break; +#endif } } p_ancil("receive_udp on interface", &rep); diff --git a/util/netevent.h b/util/netevent.h index bff08ebd7..6a5a22f6c 100644 --- a/util/netevent.h +++ b/util/netevent.h @@ -105,7 +105,9 @@ struct comm_reply { #ifdef IPV6_PKTINFO struct in6_pktinfo v6info; #endif -#ifdef IP_PKTINFO +#ifdef IP_RECVDSTADDR + struct in_addr v4addr; +#elif defined(IP_PKTINFO) struct in_pktinfo v4info; #endif }