DNS resolution working butter smooth

This commit is contained in:
soypat
2025-07-12 12:54:34 -03:00
parent 68c4d1ea71
commit 698610242e
5 changed files with 66 additions and 18 deletions
+6 -6
View File
@@ -65,12 +65,12 @@ func (c *Client) Encapsulate(carrierData []byte, frameOffset int) (int, error) {
}
c.state = dnsAwaitResponse
// Unset don't frag since DNS requests go through LOTS of nodes.
if frameOffset >= 28 {
version := carrierData[0] >> 4
if version == 4 {
carrierData[6], carrierData[7] = 0, 0 // unset IP Flags.
}
}
// if frameOffset >= 28 {
// version := carrierData[0] >> 4
// if version == 4 {
// carrierData[6], carrierData[7] = 0, 0 // unset IP Flags.
// }
// }
return len(data), nil
}
+2 -2
View File
@@ -626,10 +626,10 @@ func (dst *Message) CopyFrom(m Message) {
for i := range dst.Answers {
dst.Answers[i].CopyFrom(m.Answers[i])
}
for i := range dst.Answers {
for i := range dst.Authorities {
dst.Authorities[i].CopyFrom(m.Authorities[i])
}
for i := range dst.Answers {
for i := range dst.Additionals {
dst.Additionals[i].CopyFrom(m.Additionals[i])
}
}
+15
View File
@@ -221,3 +221,18 @@ func (m *Message) String() string {
}
return s
}
func TestDecodeMessage(t *testing.T) {
var data = []byte{
0x84, 0x05, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x77, 0x68, 0x69,
0x74, 0x74, 0x69, 0x6c, 0x65, 0x61, 0x6b, 0x73, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1e, 0xaf, 0x00, 0x04, 0xc6, 0x31, 0x17,
0x91, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
var msg Message
msg.LimitResourceDecoding(5, 5, 5, 5)
off, incomplete, err := msg.Decode(data)
if incomplete || err != nil {
t.Fatal(incomplete, err, off)
}
}
+8 -6
View File
@@ -137,10 +137,12 @@ func run() (err error) {
}
case stateDNS:
addrs, err := stack.ResultLookupIP()
addrs, done, err := stack.ResultLookupIP()
if err == nil {
fmt.Println(flagHostToResolve, "resolved to", addrs)
return nil
} else if done {
return err
}
}
@@ -197,7 +199,7 @@ func (s *Stack) Demux(b []byte, _ int) (err error) {
s.aux, err = s.shark.CaptureEthernet(s.aux[:0], b, 0)
topFrame := s.aux[len(s.aux)-1]
isOK := topFrame.Protocol == "DHCPv4" || // Allow DHCP responses.
(topFrame.Protocol == lneto.IPProtoUDP && getField(topFrame, b, pcap.FieldClassSrc) == 53) || // Allow DNS responses.
topFrame.Protocol == "DNS" ||
topFrame.Protocol == ethernet.TypeARP // Allow ARP responses.
if !isOK {
return nil
@@ -308,12 +310,12 @@ func (s *Stack) StartLookupIP(host string) error {
return nil
}
func (s *Stack) ResultLookupIP() ([]netip.Addr, error) {
func (s *Stack) ResultLookupIP() ([]netip.Addr, bool, error) {
done, err := s.dns.MessageCopyTo(&s.lookup)
if err != nil {
return nil, err
return nil, done, err
} else if !done {
return nil, errors.New("DNS not done")
return nil, done, errors.New("DNS not done")
}
var addrs []netip.Addr
ans := s.lookup.Answers
@@ -325,7 +327,7 @@ func (s *Stack) ResultLookupIP() ([]netip.Addr, error) {
addrs = append(addrs, netip.AddrFrom16([16]byte(data)))
}
}
return addrs, nil
return addrs, done, nil
}
func (s *Stack) BeginDHCPRequest(request [4]byte) error {
+35 -4
View File
@@ -10,6 +10,7 @@ import (
"github.com/soypat/lneto"
"github.com/soypat/lneto/arp"
"github.com/soypat/lneto/dhcpv4"
"github.com/soypat/lneto/dns"
"github.com/soypat/lneto/ethernet"
"github.com/soypat/lneto/http/httpraw"
"github.com/soypat/lneto/ipv4"
@@ -21,8 +22,9 @@ import (
const unknownPayloadProto = "payload?"
type PacketBreakdown struct {
hdr httpraw.Header
vld lneto.Validator
hdr httpraw.Header
dmsg dns.Message
vld lneto.Validator
}
func (pc *PacketBreakdown) CaptureEthernet(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) {
@@ -323,13 +325,42 @@ func (pc *PacketBreakdown) CaptureUDP(dst []Frame, pkt []byte, bitOffset int) ([
end := bitOffset + 8*octet
payload := ufrm.Payload()
if dhcpv4.PayloadIsDHCPv4(payload) {
return pc.CaptureDHCPv4(dst, pkt, end)
} else {
dst, err = pc.CaptureDHCPv4(dst, pkt, end)
} else if ufrm.DestinationPort() == 53 || ufrm.SourcePort() == 53 {
dst, err = pc.CaptureDNS(dst, pkt, end)
}
if err != nil {
dst = append(dst, remainingFrameInfo(unknownPayloadProto, FieldClassPayload, end, octet*len(pkt)))
}
return dst, nil
}
func (pc *PacketBreakdown) CaptureDNS(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) {
if bitOffset%8 != 0 {
return nil, errors.New("DNS must be parsed at byte boundary")
}
dnsData := pkt[bitOffset/8:]
pc.dmsg.LimitResourceDecoding(20, 20, 20, 20)
off, incomplete, err := pc.dmsg.Decode(dnsData)
if err != nil && !incomplete {
return dst, err
}
finfo := Frame{
Protocol: "DNS",
PacketBitOffset: bitOffset,
}
if incomplete {
finfo.Errors = append(finfo.Errors, errors.New("pcap: could not parse all DNS resources; add higher limit"))
}
finfo.Fields = append(finfo.Fields, FrameField{
Name: "Data",
FrameBitOffset: 0,
BitLength: int(off) * octet,
})
dst = append(dst, finfo)
return dst, nil
}
func (pc *PacketBreakdown) CaptureDHCPv4(dst []Frame, pkt []byte, bitOffset int) ([]Frame, error) {
if bitOffset%8 != 0 {
return nil, errors.New("DHCP must be parsed at byte boundary")