refactor: engine/tcp/worker perf improvements
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package engine
|
||||
|
||||
import "net"
|
||||
|
||||
type L3Info struct {
|
||||
Version uint8
|
||||
Protocol uint8
|
||||
IHL uint8
|
||||
SrcIP [4]byte
|
||||
DstIP [4]byte
|
||||
Length uint16
|
||||
}
|
||||
|
||||
func (i L3Info) SrcIPAddr() net.IP { return net.IP(i.SrcIP[:]) }
|
||||
func (i L3Info) DstIPAddr() net.IP { return net.IP(i.DstIP[:]) }
|
||||
|
||||
type TCPInfo struct {
|
||||
SrcPort uint16
|
||||
DstPort uint16
|
||||
Seq uint32
|
||||
Ack uint32
|
||||
HdrLen uint8
|
||||
SYN bool
|
||||
FIN bool
|
||||
RST bool
|
||||
ACK bool
|
||||
}
|
||||
|
||||
type UDPInfo struct {
|
||||
SrcPort uint16
|
||||
DstPort uint16
|
||||
}
|
||||
|
||||
func ParseL3(data []byte) (l3 L3Info, transport []byte, ok bool) {
|
||||
if len(data) < 20 {
|
||||
return
|
||||
}
|
||||
version := data[0] >> 4
|
||||
if version != 4 {
|
||||
return
|
||||
}
|
||||
ihl := data[0] & 0x0F
|
||||
if ihl < 5 || len(data) < int(ihl)*4 {
|
||||
return
|
||||
}
|
||||
totalLen := int(uint16(data[2])<<8 | uint16(data[3]))
|
||||
if totalLen < int(ihl)*4 || totalLen > len(data) {
|
||||
totalLen = len(data)
|
||||
}
|
||||
return L3Info{
|
||||
Version: 4,
|
||||
Protocol: data[9],
|
||||
IHL: ihl,
|
||||
Length: uint16(totalLen),
|
||||
SrcIP: [4]byte{data[12], data[13], data[14], data[15]},
|
||||
DstIP: [4]byte{data[16], data[17], data[18], data[19]},
|
||||
}, data[ihl*4:totalLen], true
|
||||
}
|
||||
|
||||
func ParseTCP(transport []byte) (TCPInfo, []byte, bool) {
|
||||
if len(transport) < 20 {
|
||||
return TCPInfo{}, nil, false
|
||||
}
|
||||
dataOff := uint8(transport[12]>>4) * 4
|
||||
if dataOff < 20 || len(transport) < int(dataOff) {
|
||||
return TCPInfo{}, nil, false
|
||||
}
|
||||
flags := transport[13]
|
||||
payloadLen := len(transport) - int(dataOff)
|
||||
return TCPInfo{
|
||||
SrcPort: uint16(transport[0])<<8 | uint16(transport[1]),
|
||||
DstPort: uint16(transport[2])<<8 | uint16(transport[3]),
|
||||
Seq: uint32(transport[4])<<24 | uint32(transport[5])<<16 | uint32(transport[6])<<8 | uint32(transport[7]),
|
||||
Ack: uint32(transport[8])<<24 | uint32(transport[9])<<16 | uint32(transport[10])<<8 | uint32(transport[11]),
|
||||
HdrLen: dataOff,
|
||||
SYN: flags&0x02 != 0,
|
||||
FIN: flags&0x01 != 0,
|
||||
RST: flags&0x04 != 0,
|
||||
ACK: flags&0x10 != 0,
|
||||
}, transport[dataOff : dataOff+uint8(payloadLen)], true
|
||||
}
|
||||
|
||||
func ParseUDP(transport []byte) (UDPInfo, []byte, bool) {
|
||||
if len(transport) < 8 {
|
||||
return UDPInfo{}, nil, false
|
||||
}
|
||||
return UDPInfo{
|
||||
SrcPort: uint16(transport[0])<<8 | uint16(transport[1]),
|
||||
DstPort: uint16(transport[2])<<8 | uint16(transport[3]),
|
||||
}, transport[8:], true
|
||||
}
|
||||
Reference in New Issue
Block a user