dns: listen on ipv6

This commit is contained in:
Pavel Vasin 2014-07-21 15:26:21 +04:00
parent 34fd2888bb
commit bb53306a2e

40
dns.c
View file

@ -18,18 +18,18 @@
#if defined IP_RECVDSTADDR #if defined IP_RECVDSTADDR
# define DSTADDR_SOCKOPT IP_RECVDSTADDR # define DSTADDR_SOCKOPT IP_RECVDSTADDR
# define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in_addr))) # define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in6_addr)))
# define dstaddr(x) (CMSG_DATA(x)) # define dstaddr(x) (CMSG_DATA(x))
#elif defined IP_PKTINFO #elif defined IPV6_PKTINFO
struct in_pktinfo { struct in6_pktinfo
unsigned int ipi_ifindex; /* Interface index */ {
struct in_addr ipi_spec_dst; /* Local address */ struct in6_addr ipi6_addr; /* src/dst IPv6 address */
struct in_addr ipi_addr; /* Header Destination address */ unsigned int ipi6_ifindex; /* send/recv interface index */
}; };
# define DSTADDR_SOCKOPT IP_PKTINFO # define DSTADDR_SOCKOPT IPV6_PKTINFO
# define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in_pktinfo))) # define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in6_pktinfo)))
# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr)) # define dstaddr(x) (&(((struct in6_pktinfo *)(CMSG_DATA(x)))->ipi6_addr))
#else #else
# error "can't determine socket option" # error "can't determine socket option"
#endif #endif
@ -366,31 +366,31 @@ error:
static int listenSocket = -1; static int listenSocket = -1;
int dnsserver(dns_opt_t *opt) { int dnsserver(dns_opt_t *opt) {
struct sockaddr_in si_other; struct sockaddr_in6 si_other;
int senderSocket = -1; int senderSocket = -1;
senderSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); senderSocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (senderSocket == -1) if (senderSocket == -1)
return -3; return -3;
int replySocket; int replySocket;
if (listenSocket == -1) { if (listenSocket == -1) {
struct sockaddr_in si_me; struct sockaddr_in6 si_me;
if ((listenSocket=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) { if ((listenSocket=socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP))==-1) {
listenSocket = -1; listenSocket = -1;
return -1; return -1;
} }
replySocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); replySocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (replySocket == -1) if (replySocket == -1)
{ {
close(listenSocket); close(listenSocket);
return -1; return -1;
} }
int sockopt = 1; int sockopt = 1;
setsockopt(listenSocket, IPPROTO_IP, DSTADDR_SOCKOPT, &sockopt, sizeof sockopt); setsockopt(listenSocket, IPPROTO_IPV6, DSTADDR_SOCKOPT, &sockopt, sizeof sockopt);
memset((char *) &si_me, 0, sizeof(si_me)); memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET; si_me.sin6_family = AF_INET6;
si_me.sin_port = htons(opt->port); si_me.sin6_port = htons(opt->port);
si_me.sin_addr.s_addr = INADDR_ANY; si_me.sin6_addr = in6addr_any;
if (bind(listenSocket, (struct sockaddr*)&si_me, sizeof(si_me))==-1) if (bind(listenSocket, (struct sockaddr*)&si_me, sizeof(si_me))==-1)
return -2; return -2;
} }
@ -414,7 +414,7 @@ int dnsserver(dns_opt_t *opt) {
for (; 1; ++(opt->nRequests)) for (; 1; ++(opt->nRequests))
{ {
ssize_t insize = recvmsg(listenSocket, &msg, 0); ssize_t insize = recvmsg(listenSocket, &msg, 0);
unsigned char *addr = (unsigned char*)&si_other.sin_addr.s_addr; // unsigned char *addr = (unsigned char*)&si_other.sin_addr.s_addr;
// printf("DNS: Request %llu from %i.%i.%i.%i:%i of %i bytes\n", (unsigned long long)(opt->nRequests), addr[0], addr[1], addr[2], addr[3], ntohs(si_other.sin_port), (int)insize); // printf("DNS: Request %llu from %i.%i.%i.%i:%i of %i bytes\n", (unsigned long long)(opt->nRequests), addr[0], addr[1], addr[2], addr[3], ntohs(si_other.sin_port), (int)insize);
if (insize <= 0) if (insize <= 0)
continue; continue;