I’m stuck on Stage #hd8 (actually I’m not stuck, details follow).
I’ve tried … adding a lot of debug info to my server and running codecrafters tests 3 times.
Here are my logs:
remote: [tester::#HD8] Connecting to 127.0.0.1:2053 using UDP
remote: [your_program] Received 33bytes
remote: [your_program] Received packet with ID 1172
remote: [your_program] Received packet with flags 0100
remote: [your_program] Received packet with QDCOUNT 1
remote: [your_program] Received packet with ANCOUNT 0
remote: [tester::#HD8] Querying: ;star-mini.c10r.facebook.com. IN A
remote: [tester::#HD8] Sending Request: (Messages with >>> prefix are part of this log)
remote: [tester::#HD8] >>> ;; opcode: QUERY, status: NOERROR, id: 48947
remote: [tester::#HD8] >>> ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
remote: [tester::#HD8] >>>
remote: [tester::#HD8] >>> ;; QUESTION SECTION:
remote: [tester::#HD8] >>> ;star-mini.c10r.facebook.com. IN A
remote: [tester::#HD8] >>>
remote: [your_program] Received packet with NSCOUNT 0
remote: [your_program] Received packet with ARCOUNT 0
remote: [your_program] Received 1 questions
remote: [your_program] Question 0: FQDN codecrafters.io TYPE 1 CLASS 1
remote: [your_program] Adding codecrafters.io TYPE 1 CLASS 1 TTL 60 DATA 8.8.8.8
remote: [your_program] Sending 64 bytes
remote: [your_program] 04 94 81 00 00 01 00 01 00 00 00 00 0c 63 6f 64 65 63 72 61 66 74 65 72 73 02 69 6f 00 00 01 00 01 0c 63 6f 64 65 63 72 61 66 74 65 72 73 02 69 6f 00 00 01 00 01 00 00 00 3c 00 04 08 08 08 08
remote: [your_program] Received 33bytes
remote: [your_program] Received packet with ID 48947
remote: [your_program] Received packet with flags 0100
remote: [your_program] Received packet with QDCOUNT 1
remote: [your_program] Received packet with ANCOUNT 0
remote: [your_program] Received packet with NSCOUNT 0
remote: [your_program] terminate called after throwing an instance of 'std::invalid_argument'
remote: [your_program] Received packet with ARCOUNT 0
remote: [your_program] Received 1 questions
remote: [your_program] Question 0: FQDN star-mini.c10r.facebaceb[tester::#HD8] DNS query failed: read udp 127.0.0.1:41369->127.0.0.1:2053: i/o timeout.
And here’s a snippet of my code:
std::vector<uint8_t> encodeRdata(RECORD_TYPE type, const std::string &data)
{
std::vector<uint8_t> buf;
switch (type)
{
case RECORD_TYPE::A:
{
uint8_t addr[4];
if (inet_pton(AF_INET, data.c_str(), addr) != 1)
throw std::invalid_argument("Invalid IPv4 address: " + data);
buf.insert(buf.end(), addr, addr + 4);
break;
}
case RECORD_TYPE::CNAME:
case RECORD_TYPE::NS:
case RECORD_TYPE::PTR:
{
encodeLabels(data, buf);
break;
}
case RECORD_TYPE::MX:
{
std::istringstream in{data};
uint16_t pref;
std::string target;
in >> pref >> target;
append_u16_be(buf, pref);
encodeLabels(target, buf);
break;
}
case RECORD_TYPE::TXT:
{
std::istringstream in{data};
std::string chunk;
while (std::getline(in, chunk, ' '))
{
if (chunk.size() > 255)
throw std::length_error("TXT chunk too big");
buf.push_back(static_cast<uint8_t>(chunk.size()));
buf.insert(buf.end(), chunk.begin(), chunk.end());
}
break;
}
default:
std::string msg = "Unsupported RDATA type: " + to_hex16(type);
throw std::invalid_argument(msg);
}
return buf;
}
So the tests were passed on my 3rd try. Second try is after I added the debug logging you see there, but the tester terminated the process early so there are some output missing.
The exception is thrown when record type is invalid. Testing it locally works well with that domain name. Also I am not hardcoding the record type, I copy it over from the client’s question section to the response’s question section.
Without changing any logic, just making my debug logging better, the third time ran it. It worked but in the 3rd run I’m unable to see that “star-mini.c10r.facebaceb” dns request in the log.
The first failed run had the domain name alt1.aspmx.l.google. com. I tried running my local test with this fqdn request and no issue.
PS: the test from this stage are weird: in my third run I only see one request for github.com the rest are all for codecrafters. io I assume there is some randomness in the FQDN requested
