Convert dns.c to C++
This commit is contained in:
parent
d098ad9a1f
commit
529a667f30
4 changed files with 107 additions and 93 deletions
7
Makefile
7
Makefile
|
@ -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
|
|
||||||
|
|
181
dns.c → dns.cpp
181
dns.c → dns.cpp
|
@ -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
10
dns.h
|
@ -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
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -163,9 +163,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
}
|
|
||||||
|
|
||||||
CAddrDb db;
|
CAddrDb db;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue