Now fetches destination address from udp packets
This commit is contained in:
parent
02d40c1a7b
commit
35a8ffe46d
|
@ -104,6 +104,9 @@ open_dns(int localport, in_addr_t listen_ip)
|
|||
#endif
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
|
||||
|
||||
/* To get destination address from each UDP datagram, see iodined.c:read_dns() */
|
||||
setsockopt(fd, IPPROTO_IP, DSTADDR_SOCKOPT, &flag, sizeof(flag));
|
||||
|
||||
if(bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
|
||||
err(1, "bind");
|
||||
|
||||
|
|
|
@ -30,6 +30,14 @@
|
|||
|
||||
#define QUERY_NAME_SIZE 256
|
||||
|
||||
#if defined IP_RECVDSTADDR
|
||||
# define DSTADDR_SOCKOPT IP_RECVDSTADDR
|
||||
# define dstaddr(x) (CMSG_DATA(x))
|
||||
#elif defined IP_PKTINFO
|
||||
# define DSTADDR_SOCKOPT IP_PKTINFO
|
||||
# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr))
|
||||
#endif
|
||||
|
||||
struct packet
|
||||
{
|
||||
int len; /* Total packet length */
|
||||
|
@ -42,6 +50,7 @@ struct query {
|
|||
char name[QUERY_NAME_SIZE];
|
||||
short type;
|
||||
short id;
|
||||
struct in_addr destination;
|
||||
struct sockaddr from;
|
||||
int fromlen;
|
||||
};
|
||||
|
|
|
@ -510,18 +510,40 @@ static int
|
|||
read_dns(int fd, struct query *q)
|
||||
{
|
||||
struct sockaddr_in from;
|
||||
char packet[64*1024];
|
||||
socklen_t addrlen;
|
||||
char packet[64*1024];
|
||||
char address[96];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
struct cmsghdr *cmsg;
|
||||
int r;
|
||||
|
||||
addrlen = sizeof(struct sockaddr);
|
||||
r = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr*)&from, &addrlen);
|
||||
iov.iov_base = packet;
|
||||
iov.iov_len = sizeof(packet);
|
||||
|
||||
msg.msg_name = (caddr_t) &from;
|
||||
msg.msg_namelen = (unsigned) addrlen;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = address;
|
||||
msg.msg_controllen = sizeof(address);
|
||||
msg.msg_flags = 0;
|
||||
|
||||
r = recvmsg(fd, &msg, 0);
|
||||
|
||||
if (r > 0) {
|
||||
dns_decode(NULL, 0, q, QR_QUERY, packet, r);
|
||||
memcpy((struct sockaddr*)&q->from, (struct sockaddr*)&from, addrlen);
|
||||
q->fromlen = addrlen;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == DSTADDR_SOCKOPT) {
|
||||
q->destination = *dstaddr(cmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return strlen(q->name);
|
||||
} else if (r < 0) {
|
||||
/* Error */
|
||||
|
|
Loading…
Reference in New Issue