mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
support for IP_RECVDSTADDR.
git-svn-id: file:///svn/unbound/trunk@874 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
95b0a129e2
commit
306db56f1f
5 changed files with 77 additions and 25 deletions
|
|
@ -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
|
17 January 2008: Wouter
|
||||||
- fixup configure in case -lldns is installed.
|
- fixup configure in case -lldns is installed.
|
||||||
- fixup a couple of doxygen warnings, about enum variables.
|
- fixup a couple of doxygen warnings, about enum variables.
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,14 @@
|
||||||
\fBub_val_ctx_add_ta\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR ta);
|
\fBub_val_ctx_add_ta\fR(\fIstruct ub_val_ctx*\fR ctx, \fIchar*\fR ta);
|
||||||
.LP
|
.LP
|
||||||
\fIint\fR
|
\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
|
.LP
|
||||||
\fIint\fR
|
\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
|
.LP
|
||||||
\fIint\fR
|
\fIint\fR
|
||||||
\fBub_val_ctx_debuglevel\fR(\fIstruct ub_val_ctx*\fR ctx, \fIint\fR d);
|
\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
|
.TP
|
||||||
.B ub_val_ctx_async
|
.B ub_val_ctx_async
|
||||||
Set a context behaviour for asynchronous action.
|
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.
|
creates a thread to handle work in the background.
|
||||||
If false, a process is forked 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
|
Changes to this setting after
|
||||||
no effect (delete and re\-create the context to change).
|
.B ub_val_resolve_async
|
||||||
|
calls have been made have no effect (delete and re\-create the context
|
||||||
|
to change).
|
||||||
.TP
|
.TP
|
||||||
.B ub_val_ctx_poll
|
.B ub_val_ctx_poll
|
||||||
Poll a context to see if it has any new results.
|
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.
|
and then check, or wait using the wait routine.
|
||||||
Returns 0 if nothing to read, or nonzero if a result is available.
|
Returns 0 if nothing to read, or nonzero if a result is available.
|
||||||
If nonzero, call
|
If nonzero, call
|
||||||
.B ctx_process
|
.B ub_val_ctx_process
|
||||||
to do callbacks.
|
to do callbacks.
|
||||||
.TP
|
.TP
|
||||||
.B ub_val_ctx_wait
|
.B ub_val_ctx_wait
|
||||||
Wait for a context to finish with results. Calls
|
Wait for a context to finish with results. Calls
|
||||||
.B ub_val_ctx_process after
|
.B ub_val_ctx_process
|
||||||
the wait for you. After the wait, there are no more outstanding asynchronous
|
after the wait for you. After the wait, there are no more outstanding
|
||||||
queries.
|
asynchronous queries.
|
||||||
.TP
|
.TP
|
||||||
.B ub_val_ctx_fd
|
.B ub_val_ctx_fd
|
||||||
Get file descriptor. Wait for it to become readable, at this point
|
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.
|
Perform asynchronous resolution and validation of the target name.
|
||||||
Arguments mean the same as for \fBub_val_resolve\fR except no
|
Arguments mean the same as for \fBub_val_resolve\fR except no
|
||||||
data is returned immediately, instead a callback is called later.
|
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
|
information to the callback. The callback type is a function pointer to
|
||||||
a function declared as
|
a function declared as
|
||||||
.IP
|
.IP
|
||||||
|
|
@ -239,8 +246,8 @@ The result of the DNS resolution and validation is returned as
|
||||||
int* len; /* array with lengths of rdata items */
|
int* len; /* array with lengths of rdata items */
|
||||||
char* canonname; /* canonical name of result */
|
char* canonname; /* canonical name of result */
|
||||||
int rcode; /* additional error code in case of error */
|
int rcode; /* additional error code in case of error */
|
||||||
int nxdomain; /* if nodata because no domain */
|
int nxdomain; /* true if nodata because no domain */
|
||||||
int bogus; /* if not secure due to security failure */
|
int bogus; /* true if there was a security failure */
|
||||||
};
|
};
|
||||||
.fi
|
.fi
|
||||||
.SH "RETURN VALUES"
|
.SH "RETURN VALUES"
|
||||||
|
|
|
||||||
|
|
@ -264,14 +264,20 @@ set_ip6_recvpktinfo(int s)
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* defined IPV6_RECVPKTINFO */
|
#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,
|
if(setsockopt(s, IPPROTO_IP, IP_PKTINFO,
|
||||||
&on, (socklen_t)sizeof(on)) < 0) {
|
&on, (socklen_t)sizeof(on)) < 0) {
|
||||||
log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s",
|
log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
log_err("no IP_PKTINFO option, please disable "
|
log_err("no IP_RECVDSTADDR or IP_PKTINFO option, please disable "
|
||||||
"interface-automatic in config");
|
"interface-automatic in config");
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* IP_PKTINFO */
|
#endif /* IP_PKTINFO */
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ comm_point_send_udp_msg(struct comm_point *c, ldns_buffer* packet,
|
||||||
/** print debug ancillary info */
|
/** print debug ancillary info */
|
||||||
void p_ancil(const char* str, struct comm_reply* r)
|
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) {
|
if(r->srctype != 4 && r->srctype != 6) {
|
||||||
log_info("%s: unknown srctype %d", str, r->srctype);
|
log_info("%s: unknown srctype %d", str, r->srctype);
|
||||||
return;
|
return;
|
||||||
|
|
@ -195,6 +195,15 @@ void p_ancil(const char* str, struct comm_reply* r)
|
||||||
buf[sizeof(buf)-1]=0;
|
buf[sizeof(buf)-1]=0;
|
||||||
log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex);
|
log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex);
|
||||||
} else if(r->srctype == 4) {
|
} 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];
|
char buf1[1024], buf2[1024];
|
||||||
if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_addr,
|
if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_addr,
|
||||||
buf1, (socklen_t)sizeof(buf1)) == 0) {
|
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;
|
buf2[sizeof(buf2)-1]=0;
|
||||||
log_info("%s: %d %s %s", str, r->pktinfo.v4info.ipi_ifindex,
|
log_info("%s: %d %s %s", str, r->pktinfo.v4info.ipi_ifindex,
|
||||||
buf1, buf2);
|
buf1, buf2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -217,7 +227,7 @@ int
|
||||||
comm_point_send_udp_msg_if(struct comm_point *c, ldns_buffer* packet,
|
comm_point_send_udp_msg_if(struct comm_point *c, ldns_buffer* packet,
|
||||||
struct sockaddr* addr, socklen_t addrlen, struct comm_reply* r)
|
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;
|
ssize_t sent;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov[1];
|
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
|
#ifndef S_SPLINT_S
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
if(r->srctype == 4) {
|
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_level = IPPROTO_IP;
|
||||||
cmsg->cmsg_type = IP_PKTINFO;
|
cmsg->cmsg_type = IP_PKTINFO;
|
||||||
memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info,
|
memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info,
|
||||||
sizeof(struct in_pktinfo));
|
sizeof(struct in_pktinfo));
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
||||||
|
#endif
|
||||||
} else if(r->srctype == 6) {
|
} else if(r->srctype == 6) {
|
||||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||||
cmsg->cmsg_type = IPV6_PKTINFO;
|
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||||
|
|
@ -286,7 +304,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, ldns_buffer* packet,
|
||||||
void
|
void
|
||||||
comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
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 comm_reply rep;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov[1];
|
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)",
|
log_info("looking at hdr %d %d (need %d %d or %d %d)",
|
||||||
cmsg->cmsg_level, cmsg->cmsg_type,
|
cmsg->cmsg_level, cmsg->cmsg_type,
|
||||||
IPPROTO_IPV6, IPV6_PKTINFO,
|
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 &&
|
if( cmsg->cmsg_level == IPPROTO_IPV6 &&
|
||||||
cmsg->cmsg_type == IPV6_PKTINFO) {
|
cmsg->cmsg_type == IPV6_PKTINFO) {
|
||||||
rep.srctype = 6;
|
rep.srctype = 6;
|
||||||
memmove(&rep.pktinfo.v6info, CMSG_DATA(cmsg),
|
memmove(&rep.pktinfo.v6info, CMSG_DATA(cmsg),
|
||||||
sizeof(struct in6_pktinfo));
|
sizeof(struct in6_pktinfo));
|
||||||
break;
|
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 &&
|
} else if( cmsg->cmsg_level == IPPROTO_IP &&
|
||||||
cmsg->cmsg_type == IP_PKTINFO) {
|
cmsg->cmsg_type == IP_PKTINFO) {
|
||||||
rep.srctype = 4;
|
rep.srctype = 4;
|
||||||
memmove(&rep.pktinfo.v4info, CMSG_DATA(cmsg),
|
memmove(&rep.pktinfo.v4info, CMSG_DATA(cmsg),
|
||||||
sizeof(struct in_pktinfo));
|
sizeof(struct in_pktinfo));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p_ancil("receive_udp on interface", &rep);
|
p_ancil("receive_udp on interface", &rep);
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,9 @@ struct comm_reply {
|
||||||
#ifdef IPV6_PKTINFO
|
#ifdef IPV6_PKTINFO
|
||||||
struct in6_pktinfo v6info;
|
struct in6_pktinfo v6info;
|
||||||
#endif
|
#endif
|
||||||
#ifdef IP_PKTINFO
|
#ifdef IP_RECVDSTADDR
|
||||||
|
struct in_addr v4addr;
|
||||||
|
#elif defined(IP_PKTINFO)
|
||||||
struct in_pktinfo v4info;
|
struct in_pktinfo v4info;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue