diff --git a/src/seeder/dns.h b/src/seeder/dns.h --- a/src/seeder/dns.h +++ b/src/seeder/dns.h @@ -8,6 +8,10 @@ #include #include +// Total number of bytes in the DNS counts sections +// 4 sections each 2 bytes long +static const int DNS_HEADER_COUNTS_SIZE = 8; + struct addr_t { int v; union { diff --git a/src/seeder/dns.cpp b/src/seeder/dns.cpp --- a/src/seeder/dns.cpp +++ b/src/seeder/dns.cpp @@ -163,11 +163,13 @@ int ret = write_name(outpos, outend, name, offset); if (ret) { error = ret; - goto error; + *outpos = oldpos; + return error; } if (outend - *outpos < 8) { error = -4; - goto error; + *outpos = oldpos; + return error; } // type *((*outpos)++) = typ >> 8; @@ -181,9 +183,6 @@ *((*outpos)++) = (ttl >> 8) & 0xFF; *((*outpos)++) = ttl & 0xFF; return 0; -error: - *outpos = oldpos; - return error; } static int write_record_a(uint8_t **outpos, const uint8_t *outend, @@ -200,7 +199,8 @@ } if (outend - *outpos < 6) { error = -5; - goto error; + *outpos = oldpos; + return error; } // rdlength *((*outpos)++) = 0; @@ -210,9 +210,6 @@ *((*outpos)++) = ip->data.v4[i]; } return 0; -error: - *outpos = oldpos; - return error; } static int write_record_aaaa(uint8_t **outpos, const uint8_t *outend, @@ -229,7 +226,8 @@ } if (outend - *outpos < 6) { error = -5; - goto error; + *outpos = oldpos; + return error; } // rdlength *((*outpos)++) = 0; @@ -239,9 +237,6 @@ *((*outpos)++) = ip->data.v6[i]; } return 0; -error: - *outpos = oldpos; - return error; } static int write_record_ns(uint8_t **outpos, const uint8_t *outend, @@ -259,7 +254,8 @@ int error = 0; if (outend - *outpos < 2) { error = -5; - goto error; + *outpos = oldpos; + return error; } (*outpos) += 2; @@ -267,16 +263,13 @@ ret = write_name(outpos, outend, ns, -1); if (ret) { error = ret; - goto error; + *outpos = oldpos; + return error; } curpos[-2] = (*outpos - curpos) >> 8; curpos[-1] = (*outpos - curpos) & 0xFF; return 0; - -error: - *outpos = oldpos; - return error; } static int write_record_soa(uint8_t **outpos, const uint8_t *outend, @@ -296,7 +289,8 @@ int error = 0; if (outend - *outpos < 2) { error = -5; - goto error; + *outpos = oldpos; + return error; } (*outpos) += 2; @@ -304,18 +298,21 @@ ret = write_name(outpos, outend, mname, -1); if (ret) { error = ret; - goto error; + *outpos = oldpos; + return error; } ret = write_name(outpos, outend, rname, -1); if (ret) { error = ret; - goto error; + *outpos = oldpos; + return error; } if (outend - *outpos < 20) { error = -5; - goto error; + *outpos = oldpos; + return error; } *((*outpos)++) = (serial >> 24) & 0xFF; @@ -341,10 +338,13 @@ curpos[-2] = (*outpos - curpos) >> 8; curpos[-1] = (*outpos - curpos) & 0xFF; return 0; +} -error: - *outpos = oldpos; - return error; +static void setErrorAndZeroCounts(int error, uint8_t *sendMessage) { + // set error + sendMessage[3] |= error & 0xF; + // set counts + memset(sendMessage, 0, DNS_HEADER_COUNTS_SIZE); } static ssize_t dnshandle(dns_opt_t *opt, const uint8_t *inbuf, size_t insize, @@ -372,14 +372,16 @@ if (inbuf[2] & 128) { /* fprintf(stdout, "Got response?\n"); */ error = 1; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } // check opcode if (((inbuf[2] & 120) >> 3) != 0) { /* fprintf(stdout, "Opcode nonzero?\n"); */ error = 4; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } // unset TC @@ -391,13 +393,15 @@ if (nquestion == 0) { /* fprintf(stdout, "No questions?\n"); */ error = 0; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } if (nquestion > 1) { /* fprintf(stdout, "Multiple questions %i?\n", nquestion); */ error = 4; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } { @@ -408,12 +412,14 @@ int ret = parse_name(&inpos, inend, inbuf, name, 256); if (ret == -1) { error = 1; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } if (ret == -2) { error = 5; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } int namel = strlen(name), hostl = strlen(opt->host); @@ -421,12 +427,14 @@ (namel < hostl + 2 || name[namel - hostl - 1] != '.' || strcasecmp(name + namel - hostl, opt->host))) { error = 5; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } if (inend - inpos < 4) { error = 1; - goto error; + setErrorAndZeroCounts(error, outbuf); + return 12; } // copy question to output @@ -557,20 +565,6 @@ 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;