Don't check for unnecessary flags, fix potential bottleneck

This commit is contained in:
Kioubit 2021-12-28 12:48:52 -05:00
parent b7c5e6afba
commit 1da76a4547
4 changed files with 23 additions and 45 deletions

View File

@ -13,7 +13,7 @@ type ndpRequest struct {
answeringForIP []byte
dstIP []byte
sourceIface string
rawPacket []byte
payload []byte
}
type ndpQuestion struct {

View File

@ -75,8 +75,8 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
bpf.LoadAbsolute{Off: 54, Size: 1},
// Jump to the drop packet instruction if Type is not Neighbor Solicitation / Advertisement.
bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: protocolNo, SkipTrue: 1},
// Verdict is: send up to 4096 bytes of the packet to userspace.
bpf.RetConstant{Val: 4096},
// Verdict is: send up to 86 bytes of the packet to userspace.
bpf.RetConstant{Val: 86},
// Verdict is: "ignore packet."
bpf.RetConstant{Val: 0},
}
@ -87,12 +87,12 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
}
for {
buf := make([]byte, 4096)
buf := make([]byte, 86)
numRead, err := syscall.Read(fd, buf)
if err != nil {
panic(err)
}
if numRead < 86 {
if numRead < 78 {
if GlobalDebug {
fmt.Println("Dropping packet since it does not meet the minimum length requirement")
fmt.Printf("% X\n", buf[:numRead])
@ -115,8 +115,6 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
fmt.Println("NDP Flags")
fmt.Printf("% X\n", buf[58])
}
fmt.Println("NDP MAC:")
fmt.Printf("% X\n", buf[80:86])
fmt.Println()
}
@ -127,13 +125,22 @@ func listen(iface string, responder chan *ndpRequest, requestType ndpType, stopW
continue
}
if requestType == ndp_ADV {
if buf[58] == 0x0 {
if GlobalDebug {
fmt.Println("Dropping Advertisement packet without any NDP flags set")
}
continue
}
}
responder <- &ndpRequest{
requestType: requestType,
srcIP: buf[22:38],
dstIP: buf[38:54],
answeringForIP: buf[62:78],
payload: buf[54:],
sourceIface: iface,
rawPacket: buf[:numRead],
}
}
}

View File

@ -135,7 +135,7 @@ func checksumAddition(b []byte) uint32 {
for i := 0; i < len(b); i++ {
if i%2 == 0 {
if len(b)-1 == i {
sum += uint32(uint16(b[i])<<8 | uint16(0x0))
sum += uint32(uint16(b[i])<<8 | uint16(0x00))
} else {
sum += uint32(uint16(b[i])<<8 | uint16(b[i+1]))
}

View File

@ -84,36 +84,11 @@ func respond(iface string, requests chan *ndpRequest, respondType ndpType, ndpQu
continue
}
if req.requestType == ndp_ADV {
if (req.rawPacket[78] != 0x02) || (req.rawPacket[79] != 0x01) {
if GlobalDebug {
fmt.Println("Dropping Advertisement packet without target Source address set")
}
continue
}
if req.rawPacket[58] == 0x0 {
if GlobalDebug {
fmt.Println("Dropping Advertisement packet without any NDP flags set")
}
continue
}
} else {
if (req.rawPacket[78] != 0x01) || (req.rawPacket[79] != 0x01) {
if GlobalDebug {
fmt.Println("Dropping Solicitation packet without Source address set")
}
continue
}
}
v6Header, err := newIpv6Header(req.srcIP, req.dstIP)
if err != nil {
continue
}
if !checkPacketChecksum(v6Header, req.rawPacket[54:]) {
if GlobalDebug {
fmt.Println("Dropping packet because of invalid checksum")
}
if !checkPacketChecksum(v6Header, req.payload) {
continue
}
@ -216,23 +191,19 @@ func getAddressFromQuestionListRetry(targetIP []byte, ndpQuestionChan chan *ndpQ
return result, true
}
hasBuffered := true
gotBuffered := false
for hasBuffered {
select {
case q := <-ndpQuestionChan:
ndpQuestionsList = append(ndpQuestionsList, q)
gotBuffered = true
default:
hasBuffered = false
}
select {
case q := <-ndpQuestionChan:
ndpQuestionsList = append(ndpQuestionsList, q)
gotBuffered = true
default:
}
if gotBuffered {
result, success = getAddressFromQuestionList(targetIP, ndpQuestionsList)
}
return result, success
return nil, false
}
func getAddressFromQuestionList(targetIP []byte, ndpQuestionsList []*ndpQuestion) ([]byte, bool) {