Convert dns.c to C++

This commit is contained in:
Pieter Wuille 2019-12-02 15:16:26 -08:00
parent d098ad9a1f
commit 529a667f30
4 changed files with 107 additions and 93 deletions

View file

@ -4,10 +4,5 @@ LDFLAGS = $(CXXFLAGS)
dnsseed: dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o dnsseed: dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o
g++ -pthread $(LDFLAGS) -o dnsseed dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o -lcrypto g++ -pthread $(LDFLAGS) -o dnsseed dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o -lcrypto
%.o: %.cpp bitcoin.h netbase.h protocol.h db.h serialize.h uint256.h util.h %.o: %.cpp *.h
g++ -std=c++11 -pthread $(CXXFLAGS) -Wall -Wno-unused -Wno-sign-compare -Wno-reorder -Wno-comment -c -o $@ $< g++ -std=c++11 -pthread $(CXXFLAGS) -Wall -Wno-unused -Wno-sign-compare -Wno-reorder -Wno-comment -c -o $@ $<
dns.o: dns.c
gcc -pthread -std=c99 $(CXXFLAGS) dns.c -Wall -c -o dns.o
%.o: %.cpp

View file

@ -16,17 +16,11 @@
#define BUFLEN 512 #define BUFLEN 512
#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 in6_addr))) # define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in6_addr)))
# define dstaddr(x) (CMSG_DATA(x)) # define dstaddr(x) (CMSG_DATA(x))
#elif defined IPV6_PKTINFO #elif defined(IPV6_PKTINFO)
struct in6_pktinfo
{
struct in6_addr ipi6_addr; /* src/dst IPv6 address */
unsigned int ipi6_ifindex; /* send/recv interface index */
};
# define DSTADDR_SOCKOPT IPV6_PKTINFO # define DSTADDR_SOCKOPT IPV6_PKTINFO
# define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in6_pktinfo))) # define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in6_pktinfo)))
# define dstaddr(x) (&(((struct in6_pktinfo *)(CMSG_DATA(x)))->ipi6_addr)) # define dstaddr(x) (&(((struct in6_pktinfo *)(CMSG_DATA(x)))->ipi6_addr))
@ -109,7 +103,7 @@ int static parse_name(const unsigned char **inpos, const unsigned char *inend, c
// -3: two subsequent dots // -3: two subsequent dots
int static write_name(unsigned char** outpos, const unsigned char *outend, const char *name, int offset) { int static write_name(unsigned char** outpos, const unsigned char *outend, const char *name, int offset) {
while (*name != 0) { while (*name != 0) {
char *dot = strchr(name, '.'); const char *dot = strchr(name, '.');
const char *fin = dot; const char *fin = dot;
if (!dot) fin = name + strlen(name); if (!dot) fin = name + strlen(name);
if (fin - name > 63) return -1; if (fin - name > 63) return -1;
@ -138,16 +132,21 @@ int static write_record(unsigned char** outpos, const unsigned char *outend, con
int error = 0; int error = 0;
// name // name
int ret = write_name(outpos, outend, name, offset); int ret = write_name(outpos, outend, name, offset);
if (ret) { error = ret; goto error; } if (ret) {
if (outend - *outpos < 8) { error = -4; goto error; } error = ret;
// type } else {
*((*outpos)++) = typ >> 8; *((*outpos)++) = typ & 0xFF; if (outend - *outpos < 8) {
// class error = -4;
*((*outpos)++) = cls >> 8; *((*outpos)++) = cls & 0xFF; } else {
// ttl // type
*((*outpos)++) = (ttl >> 24) & 0xFF; *((*outpos)++) = (ttl >> 16) & 0xFF; *((*outpos)++) = (ttl >> 8) & 0xFF; *((*outpos)++) = ttl & 0xFF; *((*outpos)++) = typ >> 8; *((*outpos)++) = typ & 0xFF;
return 0; // class
error: *((*outpos)++) = cls >> 8; *((*outpos)++) = cls & 0xFF;
// ttl
*((*outpos)++) = (ttl >> 24) & 0xFF; *((*outpos)++) = (ttl >> 16) & 0xFF; *((*outpos)++) = (ttl >> 8) & 0xFF; *((*outpos)++) = ttl & 0xFF;
return 0;
}
}
*outpos = oldpos; *outpos = oldpos;
return error; return error;
} }
@ -160,14 +159,16 @@ int static write_record_a(unsigned char** outpos, const unsigned char *outend, c
int error = 0; int error = 0;
int ret = write_record(outpos, outend, name, offset, TYPE_A, cls, ttl); int ret = write_record(outpos, outend, name, offset, TYPE_A, cls, ttl);
if (ret) return ret; if (ret) return ret;
if (outend - *outpos < 6) { error = -5; goto error; } if (outend - *outpos < 6) {
// rdlength error = -5;
*((*outpos)++) = 0; *((*outpos)++) = 4; } else {
// rdata // rdlength
for (int i=0; i<4; i++) *((*outpos)++) = 0; *((*outpos)++) = 4;
*((*outpos)++) = ip->data.v4[i]; // rdata
return 0; for (int i=0; i<4; i++)
error: *((*outpos)++) = ip->data.v4[i];
return 0;
}
*outpos = oldpos; *outpos = oldpos;
return error; return error;
} }
@ -179,63 +180,92 @@ int static write_record_aaaa(unsigned char** outpos, const unsigned char *outend
int error = 0; int error = 0;
int ret = write_record(outpos, outend, name, offset, TYPE_AAAA, cls, ttl); int ret = write_record(outpos, outend, name, offset, TYPE_AAAA, cls, ttl);
if (ret) return ret; if (ret) return ret;
if (outend - *outpos < 6) { error = -5; goto error; } if (outend - *outpos < 6) {
// rdlength error = -5;
*((*outpos)++) = 0; *((*outpos)++) = 16; } else {
// rdata // rdlength
for (int i=0; i<16; i++) *((*outpos)++) = 0; *((*outpos)++) = 16;
*((*outpos)++) = ip->data.v6[i]; // rdata
return 0; for (int i=0; i<16; i++)
error: *((*outpos)++) = ip->data.v6[i];
return 0;
}
*outpos = oldpos; *outpos = oldpos;
return error; return error;
} }
int static write_record_ns(unsigned char** outpos, const unsigned char *outend, char *name, int offset, dns_class cls, int ttl, const char *ns) { int static write_record_ns(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const char *ns) {
unsigned char *oldpos = *outpos; unsigned char *oldpos = *outpos;
int ret = write_record(outpos, outend, name, offset, TYPE_NS, cls, ttl); int ret = write_record(outpos, outend, name, offset, TYPE_NS, cls, ttl);
if (ret) return ret; if (ret) return ret;
int error = 0; int error = 0;
if (outend - *outpos < 2) { error = -5; goto error; } if (outend - *outpos < 2) {
(*outpos) += 2; error = -5;
unsigned char *curpos = *outpos; } else {
ret = write_name(outpos, outend, ns, -1); (*outpos) += 2;
if (ret) { error = ret; goto error; } unsigned char *curpos = *outpos;
curpos[-2] = (*outpos - curpos) >> 8; ret = write_name(outpos, outend, ns, -1);
curpos[-1] = (*outpos - curpos) & 0xFF; if (ret) {
return 0; error = ret;
error: } else {
curpos[-2] = (*outpos - curpos) >> 8;
curpos[-1] = (*outpos - curpos) & 0xFF;
return 0;
}
}
*outpos = oldpos; *outpos = oldpos;
return error; return error;
} }
int static write_record_soa(unsigned char** outpos, const unsigned char *outend, char *name, int offset, dns_class cls, int ttl, const char* mname, const char *rname, int static write_record_soa(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const char* mname, const char *rname,
uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum) { uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum) {
unsigned char *oldpos = *outpos; unsigned char *oldpos = *outpos;
int ret = write_record(outpos, outend, name, offset, TYPE_SOA, cls, ttl); int ret = write_record(outpos, outend, name, offset, TYPE_SOA, cls, ttl);
if (ret) return ret; if (ret) return ret;
int error = 0; int error = 0;
if (outend - *outpos < 2) { error = -5; goto error; } if (outend - *outpos < 2) {
(*outpos) += 2; error = -5;
unsigned char *curpos = *outpos; } else {
ret = write_name(outpos, outend, mname, -1); (*outpos) += 2;
if (ret) { error = ret; goto error; } unsigned char *curpos = *outpos;
ret = write_name(outpos, outend, rname, -1); ret = write_name(outpos, outend, mname, -1);
if (ret) { error = ret; goto error; } if (ret) {
if (outend - *outpos < 20) { error = -5; goto error; } error = ret;
*((*outpos)++) = (serial >> 24) & 0xFF; *((*outpos)++) = (serial >> 16) & 0xFF; *((*outpos)++) = (serial >> 8) & 0xFF; *((*outpos)++) = serial & 0xFF; } else {
*((*outpos)++) = (refresh >> 24) & 0xFF; *((*outpos)++) = (refresh >> 16) & 0xFF; *((*outpos)++) = (refresh >> 8) & 0xFF; *((*outpos)++) = refresh & 0xFF; ret = write_name(outpos, outend, rname, -1);
*((*outpos)++) = (retry >> 24) & 0xFF; *((*outpos)++) = (retry >> 16) & 0xFF; *((*outpos)++) = (retry >> 8) & 0xFF; *((*outpos)++) = retry & 0xFF; if (ret) {
*((*outpos)++) = (expire >> 24) & 0xFF; *((*outpos)++) = (expire >> 16) & 0xFF; *((*outpos)++) = (expire >> 8) & 0xFF; *((*outpos)++) = expire & 0xFF; error = ret;
*((*outpos)++) = (minimum >> 24) & 0xFF; *((*outpos)++) = (minimum >> 16) & 0xFF; *((*outpos)++) = (minimum >> 8) & 0xFF; *((*outpos)++) = minimum & 0xFF; } else {
curpos[-2] = (*outpos - curpos) >> 8; if (outend - *outpos < 20) {
curpos[-1] = (*outpos - curpos) & 0xFF; error = -5;
return 0; } else {
error: *((*outpos)++) = (serial >> 24) & 0xFF; *((*outpos)++) = (serial >> 16) & 0xFF; *((*outpos)++) = (serial >> 8) & 0xFF; *((*outpos)++) = serial & 0xFF;
*((*outpos)++) = (refresh >> 24) & 0xFF; *((*outpos)++) = (refresh >> 16) & 0xFF; *((*outpos)++) = (refresh >> 8) & 0xFF; *((*outpos)++) = refresh & 0xFF;
*((*outpos)++) = (retry >> 24) & 0xFF; *((*outpos)++) = (retry >> 16) & 0xFF; *((*outpos)++) = (retry >> 8) & 0xFF; *((*outpos)++) = retry & 0xFF;
*((*outpos)++) = (expire >> 24) & 0xFF; *((*outpos)++) = (expire >> 16) & 0xFF; *((*outpos)++) = (expire >> 8) & 0xFF; *((*outpos)++) = expire & 0xFF;
*((*outpos)++) = (minimum >> 24) & 0xFF; *((*outpos)++) = (minimum >> 16) & 0xFF; *((*outpos)++) = (minimum >> 8) & 0xFF; *((*outpos)++) = minimum & 0xFF;
curpos[-2] = (*outpos - curpos) >> 8;
curpos[-1] = (*outpos - curpos) & 0xFF;
return 0;
}
}
}
}
*outpos = oldpos; *outpos = oldpos;
return error; return error;
} }
static ssize_t set_error(unsigned char* outbuf, int error) {
// set error
outbuf[3] |= error & 0xF;
// set counts
outbuf[4] = 0; outbuf[5] = 0;
outbuf[6] = 0; outbuf[7] = 0;
outbuf[8] = 0; outbuf[9] = 0;
outbuf[10] = 0; outbuf[11] = 0;
return 12;
}
ssize_t static dnshandle(dns_opt_t *opt, const unsigned char *inbuf, size_t insize, unsigned char* outbuf) { ssize_t static dnshandle(dns_opt_t *opt, const unsigned char *inbuf, size_t insize, unsigned char* outbuf) {
int error = 0; int error = 0;
if (insize < 12) // DNS header if (insize < 12) // DNS header
@ -249,27 +279,27 @@ ssize_t static dnshandle(dns_opt_t *opt, const unsigned char *inbuf, size_t insi
// clear error // clear error
outbuf[3] &= ~15; outbuf[3] &= ~15;
// check qr // check qr
if (inbuf[2] & 128) { /* printf("Got response?\n"); */ error = 1; goto error; } if (inbuf[2] & 128) return set_error(outbuf, 1); /* printf("Got response?\n"); */
// check opcode // check opcode
if (((inbuf[2] & 120) >> 3) != 0) { /* printf("Opcode nonzero?\n"); */ error = 4; goto error; } if (((inbuf[2] & 120) >> 3) != 0) return set_error(outbuf, 1); /* printf("Opcode nonzero?\n"); */
// unset TC // unset TC
outbuf[2] &= ~2; outbuf[2] &= ~2;
// unset RA // unset RA
outbuf[3] &= ~128; outbuf[3] &= ~128;
// check questions // check questions
int nquestion = (inbuf[4] << 8) + inbuf[5]; int nquestion = (inbuf[4] << 8) + inbuf[5];
if (nquestion == 0) { /* printf("No questions?\n"); */ error = 0; goto error; } if (nquestion == 0) return set_error(outbuf, 0); /* printf("No questions?\n"); */
if (nquestion > 1) { /* printf("Multiple questions %i?\n", nquestion); */ error = 4; goto error; } if (nquestion > 1) return set_error(outbuf, 4); /* printf("Multiple questions %i?\n", nquestion); */
const unsigned char *inpos = inbuf + 12; const unsigned char *inpos = inbuf + 12;
const unsigned char *inend = inbuf + insize; const unsigned char *inend = inbuf + insize;
char name[256]; char name[256];
int offset = inpos - inbuf; int offset = inpos - inbuf;
int ret = parse_name(&inpos, inend, inbuf, name, 256); int ret = parse_name(&inpos, inend, inbuf, name, 256);
if (ret == -1) { error = 1; goto error; } if (ret == -1) return set_error(outbuf, 1);
if (ret == -2) { error = 5; goto error; } if (ret == -2) return set_error(outbuf, 5);
int namel = strlen(name), hostl = strlen(opt->host); int namel = strlen(name), hostl = strlen(opt->host);
if (strcasecmp(name, opt->host) && (namel<hostl+2 || name[namel-hostl-1]!='.' || strcasecmp(name+namel-hostl,opt->host))) { error = 5; goto error; } if (strcasecmp(name, opt->host) && (namel<hostl+2 || name[namel-hostl-1]!='.' || strcasecmp(name+namel-hostl,opt->host))) return set_error(outbuf, 5);
if (inend - inpos < 4) { error = 1; goto error; } if (inend - inpos < 4) return set_error(outbuf, 1);
// copy question to output // copy question to output
memcpy(outbuf+12, inbuf+12, inpos+4 - (inbuf+12)); memcpy(outbuf+12, inbuf+12, inpos+4 - (inbuf+12));
// set counts // set counts
@ -366,15 +396,6 @@ ssize_t static dnshandle(dns_opt_t *opt, const unsigned char *inbuf, size_t insi
outbuf[2] |= 4; outbuf[2] |= 4;
return outpos - outbuf; return outpos - outbuf;
error:
// set error
outbuf[3] |= error & 0xF;
// set counts
outbuf[4] = 0; outbuf[5] = 0;
outbuf[6] = 0; outbuf[7] = 0;
outbuf[8] = 0; outbuf[9] = 0;
outbuf[10] = 0; outbuf[11] = 0;
return 12;
} }
static int listenSocket = -1; static int listenSocket = -1;

10
dns.h
View file

@ -3,15 +3,15 @@
#include <stdint.h> #include <stdint.h>
typedef struct { struct addr_t {
int v; int v;
union { union {
unsigned char v4[4]; unsigned char v4[4];
unsigned char v6[16]; unsigned char v6[16];
} data; } data;
} addr_t; };
typedef struct { struct dns_opt_t {
int port; int port;
int datattl; int datattl;
int nsttl; int nsttl;
@ -21,8 +21,8 @@ typedef struct {
int (*cb)(void *opt, char *requested_hostname, addr_t *addr, int max, int ipv4, int ipv6); int (*cb)(void *opt, char *requested_hostname, addr_t *addr, int max, int ipv4, int ipv6);
// stats // stats
uint64_t nRequests; uint64_t nRequests;
} dns_opt_t; };
extern int dnsserver(dns_opt_t *opt); int dnsserver(dns_opt_t *opt);
#endif #endif

View file

@ -163,9 +163,7 @@ public:
} }
}; };
extern "C" {
#include "dns.h" #include "dns.h"
}
CAddrDb db; CAddrDb db;