Add and improve InfoOnly and ExpectInfo packet flags
This commit is contained in:
@@ -173,9 +173,13 @@ func interceptionStart() error {
|
||||
getConfig()
|
||||
startAPIAuth()
|
||||
|
||||
interceptionModule.StartServiceWorker("stat logger", 0, statLogger)
|
||||
interceptionModule.StartServiceWorker("packet handler", 0, packetHandler)
|
||||
|
||||
// Start stat logger if logging is set to trace.
|
||||
if log.GetLogLevel() == log.TraceLevel {
|
||||
interceptionModule.StartServiceWorker("stat logger", 0, statLogger)
|
||||
}
|
||||
|
||||
return interception.Start()
|
||||
}
|
||||
|
||||
@@ -543,6 +547,11 @@ func inspectAndVerdictHandler(conn *network.Connection, pkt packet.Packet) {
|
||||
}
|
||||
|
||||
func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.Verdict, allowPermanent bool) {
|
||||
// Check if packed was already fast-tracked by the OS integration.
|
||||
if pkt.FastTrackedByIntegration() {
|
||||
return
|
||||
}
|
||||
|
||||
// enable permanent verdict
|
||||
if allowPermanent && !conn.VerdictPermanent {
|
||||
conn.VerdictPermanent = permanentVerdicts()
|
||||
|
||||
@@ -13,6 +13,12 @@ type infoPacket struct {
|
||||
pmpacket.Base
|
||||
}
|
||||
|
||||
// InfoOnly returns whether the packet is informational only and does not
|
||||
// represent an actual packet.
|
||||
func (pkt *infoPacket) InfoOnly() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// LoadPacketData does nothing on Linux, as data is always fully parsed.
|
||||
func (pkt *infoPacket) LoadPacketData() error {
|
||||
return fmt.Errorf("can't load data in info only packet")
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package windowskext
|
||||
|
||||
// This file contains example code how to read bandwidth stats from the kext. Its not ment to be used in production.
|
||||
|
||||
@@ -30,6 +30,11 @@ const (
|
||||
// connection that was intercepted on an ALE layer instead of in the network
|
||||
// stack itself. Thus, no packet data is available.
|
||||
VerdictRequestFlagSocketAuth = 2
|
||||
|
||||
// VerdictRequestFlagExpectSocketAuth indicates that the next verdict
|
||||
// requests is expected to be an informational socket auth request from
|
||||
// the ALE layer.
|
||||
VerdictRequestFlagExpectSocketAuth = 4
|
||||
)
|
||||
|
||||
// Do not change the order of the members! The structure is used to communicate with the kernel extension.
|
||||
|
||||
@@ -127,8 +127,10 @@ func RecvVerdictRequest() (*VerdictRequest, error) {
|
||||
return nil, ErrKextNotReady
|
||||
}
|
||||
|
||||
timestamp := time.Now()
|
||||
defer log.Tracef("winkext: getting verdict request took %s", time.Since(timestamp))
|
||||
// DEBUG:
|
||||
// timestamp := time.Now()
|
||||
// defer log.Tracef("winkext: getting verdict request took %s", time.Since(timestamp))
|
||||
|
||||
// Initialize struct for the output data
|
||||
var new VerdictRequest
|
||||
|
||||
|
||||
@@ -24,16 +24,21 @@ type Packet struct {
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// FastTrackedByIntegration returns whether the packet has been fast-track
|
||||
// accepted by the OS integration.
|
||||
func (pkt *Packet) FastTrackedByIntegration() bool {
|
||||
return pkt.verdictRequest.flags&VerdictRequestFlagFastTrackPermitted > 0
|
||||
}
|
||||
|
||||
// InfoOnly returns whether the packet is informational only and does not
|
||||
// represent an actual packet.
|
||||
func (pkt *Packet) InfoOnly() bool {
|
||||
return pkt.verdictRequest.flags&VerdictRequestFlagSocketAuth > 0
|
||||
}
|
||||
|
||||
// FastTrackedByIntegration returns whether the packet has been fast-track
|
||||
// accepted by the OS integration.
|
||||
func (pkt *Packet) FastTrackedByIntegration() bool {
|
||||
return pkt.verdictRequest.flags&VerdictRequestFlagFastTrackPermitted > 0
|
||||
// ExpectInfo returns whether the next packet is expected to be informational only.
|
||||
func (pkt *Packet) ExpectInfo() bool {
|
||||
return pkt.verdictRequest.flags&VerdictRequestFlagExpectSocketAuth > 0
|
||||
}
|
||||
|
||||
// GetPayload returns the full raw packet.
|
||||
|
||||
@@ -760,12 +760,46 @@ func (conn *Connection) packetHandlerWorker(ctx context.Context) error {
|
||||
pktQueue = conn.pktQueue
|
||||
}()
|
||||
|
||||
// pktSeq counts the seen packets.
|
||||
var pktSeq int
|
||||
|
||||
for {
|
||||
select {
|
||||
case pkt := <-pktQueue:
|
||||
if pkt == nil {
|
||||
return nil
|
||||
}
|
||||
pktSeq++
|
||||
|
||||
// Check if we should expect an(other) info only packet.
|
||||
// Only wait if this is the first packet and is not an info packet itself.
|
||||
if pktSeq == 1 && pkt.ExpectInfo() && !pkt.InfoOnly() {
|
||||
// Debug: FIXME
|
||||
// log.Debugf("filter: waiting for info only packet in order to pull forward: %s", pkt)
|
||||
select {
|
||||
case infoPkt := <-pktQueue:
|
||||
if infoPkt != nil {
|
||||
// Debug: FIXME
|
||||
// log.Debugf("filter: packet #%d [pulled forward] info=%v PID=%d packet: %s", pktSeq, pkt.InfoOnly(), pkt.Info().PID, pkt)
|
||||
packetHandlerHandleConn(ctx, conn, pkt)
|
||||
pktSeq++
|
||||
}
|
||||
case <-time.After(5 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
// Debug: FIXME
|
||||
// switch {
|
||||
// case pkt.Info().Inbound:
|
||||
// log.Debugf("filter: packet #%d info=%v PID=%d packet: %s", pktSeq, pkt.InfoOnly(), pkt.Info().PID, pkt)
|
||||
// case pktSeq == 1 && !pkt.InfoOnly():
|
||||
// log.Warningf("filter: packet #%d [should be info only!] info=%v PID=%d packet: %s", pktSeq, pkt.InfoOnly(), pkt.Info().PID, pkt)
|
||||
// case pktSeq >= 2 && pkt.InfoOnly():
|
||||
// log.Errorf("filter: packet #%d [should not be info only!] info=%v PID=%d packet: %s", pktSeq, pkt.InfoOnly(), pkt.Info().PID, pkt)
|
||||
// default:
|
||||
// log.Debugf("filter: packet #%d info=%v PID=%d packet: %s", pktSeq, pkt.InfoOnly(), pkt.Info().PID, pkt)
|
||||
// }
|
||||
|
||||
packetHandlerHandleConn(ctx, conn, pkt)
|
||||
|
||||
case <-ctx.Done():
|
||||
@@ -802,7 +836,7 @@ func packetHandlerHandleConn(ctx context.Context, conn *Connection, pkt packet.P
|
||||
case conn.DataIsComplete():
|
||||
tracer.Infof("filter: connection %s %s: %s", conn, conn.VerdictVerb(), conn.Reason.Msg)
|
||||
case conn.Verdict.Firewall != VerdictUndecided:
|
||||
tracer.Debugf("filter: connection %s fast-tracked", conn)
|
||||
tracer.Debugf("filter: connection %s fast-tracked", pkt)
|
||||
default:
|
||||
tracer.Infof("filter: gathered data on connection %s", conn)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,11 @@ func (pkt *Base) InfoOnly() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ExpectInfo returns whether the next packet is expected to be informational only.
|
||||
func (pkt *Base) ExpectInfo() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SetCtx sets the packet context.
|
||||
func (pkt *Base) SetCtx(ctx context.Context) {
|
||||
pkt.ctx = ctx
|
||||
@@ -244,6 +249,7 @@ type Packet interface {
|
||||
RerouteToTunnel() error
|
||||
FastTrackedByIntegration() bool
|
||||
InfoOnly() bool
|
||||
ExpectInfo() bool
|
||||
|
||||
// Info.
|
||||
SetCtx(context.Context)
|
||||
|
||||
Reference in New Issue
Block a user