a go dns packet parser

increase performance of encode domain

Before
```
goos: darwin
goarch: arm64
pkg: tangled.sh/seiso.moe/magna
cpu: Apple M2
BenchmarkDecodeDomainSimple-8 15712374 77.80 ns/op
BenchmarkDecodeDomainCompressed-8 13250395 90.30 ns/op
BenchmarkEncodeDomainSimple-8 11716813 102.7 ns/op
BenchmarkEncodeDomainWithCompression-8 6848320 174.9 ns/op
PASS
ok tangled.sh/seiso.moe/magna 6.471s
```

After
```
goos: darwin
goarch: arm64
pkg: tangled.sh/seiso.moe/magna
cpu: Apple M2
BenchmarkDecodeDomainSimple-8 15675970 77.08 ns/op
BenchmarkDecodeDomainCompressed-8 13399174 89.80 ns/op
BenchmarkEncodeDomainSimple-8 16123866 72.83 ns/op
BenchmarkEncodeDomainWithCompression-8 11180266 107.2 ns/op
PASS
ok tangled.sh/seiso.moe/magna 6.341s
```

Changed files
+29 -17
+29 -17
domain_name.go
···
return append(bytes, 0)
}
-
labelIndices := []int{0}
-
for i, r := range domain_name {
-
if r == '.' {
-
labelIndices = append(labelIndices, i+1)
-
}
}
-
for i := 0; i < len(labelIndices); i++ {
-
suffix := domain_name[labelIndices[i]:]
if offset, found := (*offsets)[suffix]; found {
-
pointer := 0xC000 | offset
-
return binary.BigEndian.AppendUint16(bytes, pointer)
}
currentPos := uint16(len(bytes))
···
(*offsets)[suffix] = currentPos
}
-
start := labelIndices[i]
-
end := len(domain_name)
-
if i+1 < len(labelIndices) {
-
end = labelIndices[i+1] - 1
}
-
labelBytes := []byte(domain_name[start:end])
-
if len(labelBytes) == 0 {
-
continue
-
}
if len(labelBytes) > 63 {
labelBytes = labelBytes[:63]
}
···
return append(bytes, 0)
}
+
clean_domain := strings.TrimSuffix(domain_name, ".")
+
if clean_domain == "" {
+
return append(bytes, 0)
}
+
start := 0
+
for start < len(clean_domain) {
+
suffix := clean_domain[start:]
if offset, found := (*offsets)[suffix]; found {
+
if offset > 0x3FFF {
+
end := strings.IndexByte(suffix, '.')
+
if end == -1 {
+
end = len(suffix)
+
}
+
} else {
+
pointer := 0xC000 | offset
+
return binary.BigEndian.AppendUint16(bytes, pointer)
+
}
}
currentPos := uint16(len(bytes))
···
(*offsets)[suffix] = currentPos
}
+
end := strings.IndexByte(suffix, '.')
+
var label string
+
nextStart := len(clean_domain)
+
+
if end == -1 {
+
label = suffix
+
start = nextStart
+
} else {
+
label = suffix[:end]
+
nextStart = start + end + 1
+
start = nextStart
}
+
+
labelBytes := []byte(label)
if len(labelBytes) > 63 {
+
// XXX: maybe should return an error
labelBytes = labelBytes[:63]
}