Merge pull request #278 from safing/fix/netenv

Fix and improve netenv for Windows and Linux
This commit is contained in:
Daniel
2021-04-03 16:06:35 +02:00
committed by GitHub
21 changed files with 861 additions and 304 deletions

View File

@@ -139,15 +139,37 @@ func fastTrackedPermit(pkt packet.Packet) (handled bool) {
switch meta.Protocol {
case packet.ICMP:
// Submit to ICMP listener.
submitted := netenv.SubmitPacketToICMPListener(pkt)
// Always permit ICMP.
log.Debugf("filter: fast-track accepting ICMP: %s", pkt)
_ = pkt.PermanentAccept()
// If the packet was submitted to the listener, we must not do a
// permanent accept, because then we won't see any future packets of that
// connection and thus cannot continue to submit them.
if submitted {
_ = pkt.Accept()
} else {
_ = pkt.PermanentAccept()
}
return true
case packet.ICMPv6:
// Submit to ICMP listener.
submitted := netenv.SubmitPacketToICMPListener(pkt)
// Always permit ICMPv6.
log.Debugf("filter: fast-track accepting ICMPv6: %s", pkt)
_ = pkt.PermanentAccept()
// If the packet was submitted to the listener, we must not do a
// permanent accept, because then we won't see any future packets of that
// connection and thus cannot continue to submit them.
if submitted {
_ = pkt.Accept()
} else {
_ = pkt.PermanentAccept()
}
return true
case packet.UDP, packet.TCP:

View File

@@ -179,11 +179,13 @@ func (q *Queue) packetHandler(ctx context.Context) func(nfqueue.Attribute) int {
verdictPending: abool.New(),
}
if attrs.Payload != nil {
pkt.Payload = *attrs.Payload
if attrs.Payload == nil {
// There is not payload.
log.Warningf("nfqueue: packet #%s has no payload", pkt.pktID)
return 0
}
if err := pmpacket.Parse(pkt.Payload, pkt.Info()); err != nil {
if err := pmpacket.Parse(*attrs.Payload, &pkt.Base); err != nil {
log.Warningf("nfqueue: failed to parse payload: %s", err)
_ = pkt.Drop()
return 0

View File

@@ -65,6 +65,11 @@ func (pkt *packet) ID() string {
return fmt.Sprintf("pkt:%d qid:%d", pkt.pktID, pkt.queue.id)
}
// LoadPacketData does nothing on Linux, as data is always fully parsed.
func (pkt *packet) LoadPacketData() error {
return nil
}
// TODO(ppacher): revisit the following behavior:
// The legacy implementation of nfqueue (and the interception) module
// always accept a packet but may mark it so that a subsequent rule in

View File

@@ -230,6 +230,7 @@ func GetPayload(packetID uint32, packetSize uint32) ([]byte, error) {
if packetSize < uint32(len(buf)) {
return buf[:packetSize], nil
}
return buf, nil
}

View File

@@ -24,7 +24,7 @@ type Packet struct {
}
// GetPayload returns the full raw packet.
func (pkt *Packet) GetPayload() ([]byte, error) {
func (pkt *Packet) LoadPacketData() error {
pkt.lock.Lock()
defer pkt.lock.Unlock()
@@ -33,17 +33,21 @@ func (pkt *Packet) GetPayload() ([]byte, error) {
payload, err := GetPayload(pkt.verdictRequest.id, pkt.verdictRequest.packetSize)
if err != nil {
log.Tracer(pkt.Ctx()).Warningf("windowskext: failed to load payload %s", err)
log.Errorf("windowskext: failed to load payload %s", err)
return nil, packet.ErrFailedToLoadPayload
log.Tracer(pkt.Ctx()).Warningf("windowskext: failed to load payload: %s", err)
return packet.ErrFailedToLoadPayload
}
err = packet.Parse(payload, &pkt.Base)
if err != nil {
log.Tracer(pkt.Ctx()).Warningf("windowskext: failed to parse payload: %s", err)
return packet.ErrFailedToLoadPayload
}
pkt.Payload = payload
}
if len(pkt.Payload) == 0 {
return nil, packet.ErrFailedToLoadPayload
if len(pkt.Raw()) == 0 {
return packet.ErrFailedToLoadPayload
}
return pkt.Payload, nil
return nil
}
// Accept accepts the packet.