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 @@ -158,16 +158,15 @@ const char *name, int offset, dns_type typ, dns_class cls, int ttl) { uint8_t *oldpos = *outpos; - int error = 0; // name - int ret = write_name(outpos, outend, name, offset); - if (ret) { - error = ret; - goto error; + int writeError = write_name(outpos, outend, name, offset); + if (writeError) { + *outpos = oldpos; + return writeError; } if (outend - *outpos < 8) { - error = -4; - goto error; + *outpos = oldpos; + return -4; } // type *((*outpos)++) = typ >> 8; @@ -181,9 +180,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, @@ -193,14 +189,14 @@ return -6; } uint8_t *oldpos = *outpos; - int error = 0; - int ret = write_record(outpos, outend, name, offset, TYPE_A, cls, ttl); - if (ret) { - return ret; + int writeError = + write_record(outpos, outend, name, offset, TYPE_A, cls, ttl); + if (writeError) { + return writeError; } if (outend - *outpos < 6) { - error = -5; - goto error; + *outpos = oldpos; + return -5; } // rdlength *((*outpos)++) = 0; @@ -210,9 +206,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, @@ -222,14 +215,14 @@ return -6; } uint8_t *oldpos = *outpos; - int error = 0; - int ret = write_record(outpos, outend, name, offset, TYPE_AAAA, cls, ttl); - if (ret) { - return ret; + int writeError = + write_record(outpos, outend, name, offset, TYPE_AAAA, cls, ttl); + if (writeError) { + return writeError; } if (outend - *outpos < 6) { - error = -5; - goto error; + *outpos = oldpos; + return -5; } // rdlength *((*outpos)++) = 0; @@ -239,44 +232,37 @@ *((*outpos)++) = ip->data.v6[i]; } return 0; -error: - *outpos = oldpos; - return error; } static int write_record_ns(uint8_t **outpos, const uint8_t *outend, const char *name, int offset, dns_class cls, int ttl, const char *ns) { uint8_t *oldpos = *outpos; - int ret = write_record(outpos, outend, name, offset, TYPE_NS, cls, ttl); - if (ret) { - return ret; + int writeError = + write_record(outpos, outend, name, offset, TYPE_NS, cls, ttl); + if (writeError) { + return writeError; } // Predeclare to avoid jumping over declaration. uint8_t *curpos; - int error = 0; if (outend - *outpos < 2) { - error = -5; - goto error; + *outpos = oldpos; + return -5; } (*outpos) += 2; curpos = *outpos; - ret = write_name(outpos, outend, ns, -1); - if (ret) { - error = ret; - goto error; + writeError = write_name(outpos, outend, ns, -1); + if (writeError) { + *outpos = oldpos; + return writeError; } 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, @@ -285,37 +271,37 @@ uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum) { uint8_t *oldpos = *outpos; - int ret = write_record(outpos, outend, name, offset, TYPE_SOA, cls, ttl); - if (ret) { - return ret; + int writeError = + write_record(outpos, outend, name, offset, TYPE_SOA, cls, ttl); + if (writeError) { + return writeError; } // Predeclare variable to not jump over declarations. uint8_t *curpos; - int error = 0; if (outend - *outpos < 2) { - error = -5; - goto error; + *outpos = oldpos; + return -5; } (*outpos) += 2; curpos = *outpos; - ret = write_name(outpos, outend, mname, -1); - if (ret) { - error = ret; - goto error; + writeError = write_name(outpos, outend, mname, -1); + if (writeError) { + *outpos = oldpos; + return writeError; } - ret = write_name(outpos, outend, rname, -1); - if (ret) { - error = ret; - goto error; + writeError = write_name(outpos, outend, rname, -1); + if (writeError) { + *outpos = oldpos; + return writeError; } if (outend - *outpos < 20) { - error = -5; - goto error; + *outpos = oldpos; + return -5; } *((*outpos)++) = (serial >> 24) & 0xFF; @@ -341,15 +327,18 @@ curpos[-2] = (*outpos - curpos) >> 8; curpos[-1] = (*outpos - curpos) & 0xFF; return 0; +} -error: - *outpos = oldpos; - return error; +static int setErrorAndZeroCounts(int error, uint8_t *sendMessage) { + // set error + sendMessage[3] |= error & 0xF; + // set counts + memset(sendMessage + 4, 0, DNS_HEADER_COUNTS_SIZE); + return 12; } static ssize_t dnshandle(dns_opt_t *opt, const uint8_t *inbuf, size_t insize, uint8_t *outbuf) { - int error = 0; if (insize < 12) { // DNS header return -1; @@ -371,15 +360,13 @@ // check qr if (inbuf[2] & 128) { /* fprintf(stdout, "Got response?\n"); */ - error = 1; - goto error; + return setErrorAndZeroCounts(1, outbuf); } // check opcode if (((inbuf[2] & 120) >> 3) != 0) { /* fprintf(stdout, "Opcode nonzero?\n"); */ - error = 4; - goto error; + return setErrorAndZeroCounts(4, outbuf); } // unset TC @@ -390,14 +377,12 @@ nquestion = (inbuf[4] << 8) + inbuf[5]; if (nquestion == 0) { /* fprintf(stdout, "No questions?\n"); */ - error = 0; - goto error; + return setErrorAndZeroCounts(0, outbuf); } if (nquestion > 1) { /* fprintf(stdout, "Multiple questions %i?\n", nquestion); */ - error = 4; - goto error; + return setErrorAndZeroCounts(4, outbuf); } { @@ -407,26 +392,22 @@ int offset = inpos - inbuf; int ret = parse_name(&inpos, inend, inbuf, name, 256); if (ret == -1) { - error = 1; - goto error; + return setErrorAndZeroCounts(1, outbuf); } if (ret == -2) { - error = 5; - goto error; + return setErrorAndZeroCounts(5, outbuf); } 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; + return setErrorAndZeroCounts(5, outbuf); } if (inend - inpos < 4) { - error = 1; - goto error; + return setErrorAndZeroCounts(1, outbuf); } // copy question to output @@ -557,20 +538,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;