]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
support for IP_RECVDSTADDR.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 18 Jan 2008 08:51:19 +0000 (08:51 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 18 Jan 2008 08:51:19 +0000 (08:51 +0000)
git-svn-id: file:///svn/unbound/trunk@874 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
doc/libunbound.3
services/listen_dnsport.c
util/netevent.c
util/netevent.h

index 8124899019a6b0ad70e8202236f70ad8f1f1c198..8a338e5067ea94688b0235a5684d927eaa403214 100644 (file)
@@ -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.
index e147d83bb9b6d9d97602f0e34b4016b45be90329..a49e8b16dcd64bad88513307a04725438237dc4f 100644 (file)
 \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);
 \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"
index 6cd65c4de31308ca2d1e1640620ee86d4cee5669..22e3dad8f692a86a99b441678b63f5957822b168 100644 (file)
@@ -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 */
index 43bd1917f31e18a0b1f480c81110316ad4c4e830..7f43b7715905f3203b91b7defc88e1371e4722c7 100644 (file)
@@ -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);
index bff08ebd7d632b912735d378208536fb996ee399..6a5a22f6c1f8f23f3cac97a5bf235d2f272663a2 100644 (file)
@@ -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
        }