My code passed #YC9 even if the answer section doesn’t contain proper response
package main
import (
"bytes"
"encoding/binary"
"fmt"
"net"
)
/*
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
* |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
*
* QR Query/Response Indicator, 1 bit
* OPCODE Operation Code, 4 bit
* AA Authoritative Answer, 1 bit
* TC Truncation, 1 bit
* RD Recursion Desired, 1 bit
* RA Recursion Available, 1 bit
* Z Reserved, 3 bit
* RCODE Response Code, 4 bit
*/
type DNSHeader struct {
ID uint16 // Packet Identifier (bytes 0-1)
FLAGS uint16 // Bits in the middle packed into a 2 byte flag (bytes 2-3)
QDCOUNT uint16 // Question Count (bytes 4-5)
ANCOUNT uint16 // Answer Record Count (bytes 6-7)
NSCOUNT uint16 // Authority Record Count (bytes 8-9)
ARCOUNT uint16 // Additional Record Count (bytes 10-11)
}
func (h *DNSHeader) ToBytes() []byte {
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, h)
return buf.Bytes()
}
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:2053")
if err != nil {
fmt.Println("Failed to resolve UDP address:", err)
return
}
udpConn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println("Failed to bind to address:", err)
return
}
defer udpConn.Close()
buf := make([]byte, 512)
for {
_, source, err := udpConn.ReadFromUDP(buf)
if err != nil {
fmt.Println("Error receiving data:", err)
break
}
header := buf[:12]
// Set QR bit to make it a response
header[2] |= 0x80 // 10000000 in binary
flags := binary.BigEndian.Uint16(header[2:4])
opcode := (flags >> 11) & 0x0F // 0x0F = 0b1111 in binary, can also (flags >> 11) & 15
if opcode != 0 {
// Clear the bottom 4 bits (RCODE) and set to 4
flags = (flags & 0xFFF0) | 4 // 0xFFF0 = 0b1111111111110000
binary.BigEndian.PutUint16(header[2:4], flags) // Write the updated flags back to the header
}
qdCount := binary.BigEndian.Uint16(header[4:6])
binary.BigEndian.PutUint16(header[6:8], qdCount) // Set ANCOUNT (bytes 6-7)
names, questionEnd := getQuestionEnd(buf, qdCount)
question := buf[12:questionEnd]
answer := []byte{}
for _, name := range names {
answer = append(answer, name...) // Copy name first
answer = binary.BigEndian.AppendUint16(answer, 1) // Type: 1 (A record)
answer = binary.BigEndian.AppendUint16(answer, 1) // Class: 1 (IN)
answer = binary.BigEndian.AppendUint32(answer, 60) // TTL: 60
answer = binary.BigEndian.AppendUint16(answer, 4) // RDLENGTH: 4 bytes
answer = append(answer, 8, 8, 8, 8) // RDATA: 8.8.8.8
}
response := bytes.Join([][]byte{header, question, answer}, nil)
_, err = udpConn.WriteToUDP(response, source)
if err != nil {
fmt.Println("Failed to send response:", err)
}
}
}
func getQuestionEnd(buf []byte, qdCount uint16) ([][]byte, int) {
pos := 12 // start after header
currQd := 0
names := [][]byte{}
nameMap := make(map[int][]byte)
// iterate through domain labels till we get a null terminator
for currQd != int(qdCount) {
// if 1st 2 bit of 1st byte is 11, then it is pointer, the next byte is label start pos
// if 1st 2 bit of 1st byte is 00, then treat it as length of label
start := pos
firstByte := buf[pos]
if firstByte == 0xc0 { // 0b1100_0000
pos += 1
names = append(names, nameMap[int(buf[pos])])
pos += 1
} else if firstByte != 0 {
for buf[pos] != 0 {
labelLen := int(buf[pos])
pos += labelLen + 1
}
pos += 1 // null terminator itself
nameMap[start] = buf[start:pos] // domain name with
fmt.Println("found name:", string(nameMap[start]))
names = append(names, nameMap[start])
}
currQd++
pos += 4 // QTYPE and QCLASS
}
return names, pos
}
[tester::#YC9] Querying the following in the same request (Messages with >> prefix are part of this log)
[tester::#YC9] >> ;abc.longassdomainname.com. IN A
[tester::#YC9] >> ;def.longassdomainname.com. IN A
[tester::#YC9] Sending Request: (Messages with >>> prefix are part of this log)
[tester::#YC9] >>> ;; opcode: QUERY, status: NOERROR, id: 28447
[tester::#YC9] >>> ;; flags: rd; QUERY: 2, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
[tester::#YC9] >>>
[tester::#YC9] >>> ;; QUESTION SECTION:
[tester::#YC9] >>> ;abc.longassdomainname.com. IN A
[tester::#YC9] >>> ;def.longassdomainname.com. IN A
[tester::#YC9] >>>
[your_program] found name: abclongassdomainnamecom
[your_program] found name: def�
[tester::#YC9] Received Response: (Messages with >>> prefix are part of this log)
[tester::#YC9] >>> ;; opcode: QUERY, status: NOERROR, id: 28447
[tester::#YC9] >>> ;; flags: qr rd; QUERY: 2, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
[tester::#YC9] >>>
[tester::#YC9] >>> ;; QUESTION SECTION:
[tester::#YC9] >>> ;abc.longassdomainname.com. IN A
[tester::#YC9] >>> ;def.longassdomainname.com. IN A
[tester::#YC9] >>>
[tester::#YC9] >>> ;; ANSWER SECTION:
[tester::#YC9] >>> . 0 CLASS0 TYPE0 # 0
[tester::#YC9] >>> . 0 CLASS0 TYPE0 # 0
[tester::#YC9] >>>
[tester::#YC9] Test passed.
[tester::#YC9] Terminating program
[tester::#YC9] Shutting down DNS resolver server…
[tester::#YC9] Program terminated successfully