support for IP_RECVDSTADDR.

git-svn-id: file:///svn/unbound/trunk@874 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-01-18 08:51:19 +00:00
parent 95b0a129e2
commit 306db56f1f
5 changed files with 77 additions and 25 deletions

View 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.

View file

@ -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);
@ -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,7 +210,7 @@ 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
@ -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"

View 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 */

View 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);

View 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
}