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
|
#endif
|
||||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
|
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)
|
if(bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
|
||||||
err(1, "bind");
|
err(1, "bind");
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,14 @@
|
||||||
|
|
||||||
#define QUERY_NAME_SIZE 256
|
#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
|
struct packet
|
||||||
{
|
{
|
||||||
int len; /* Total packet length */
|
int len; /* Total packet length */
|
||||||
|
@ -42,6 +50,7 @@ struct query {
|
||||||
char name[QUERY_NAME_SIZE];
|
char name[QUERY_NAME_SIZE];
|
||||||
short type;
|
short type;
|
||||||
short id;
|
short id;
|
||||||
|
struct in_addr destination;
|
||||||
struct sockaddr from;
|
struct sockaddr from;
|
||||||
int fromlen;
|
int fromlen;
|
||||||
};
|
};
|
||||||
|
|
|
@ -510,17 +510,39 @@ static int
|
||||||
read_dns(int fd, struct query *q)
|
read_dns(int fd, struct query *q)
|
||||||
{
|
{
|
||||||
struct sockaddr_in from;
|
struct sockaddr_in from;
|
||||||
char packet[64*1024];
|
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
char packet[64*1024];
|
||||||
|
char address[96];
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
addrlen = sizeof(struct sockaddr);
|
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) {
|
if (r > 0) {
|
||||||
dns_decode(NULL, 0, q, QR_QUERY, packet, r);
|
dns_decode(NULL, 0, q, QR_QUERY, packet, r);
|
||||||
memcpy((struct sockaddr*)&q->from, (struct sockaddr*)&from, addrlen);
|
memcpy((struct sockaddr*)&q->from, (struct sockaddr*)&from, addrlen);
|
||||||
q->fromlen = 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);
|
return strlen(q->name);
|
||||||
} else if (r < 0) {
|
} else if (r < 0) {
|
||||||
|
|
Loading…
Reference in New Issue