MCPcopy Create free account
hub / github.com/SamNet-dev/snix / recvLoop

Method recvLoop

platform/windows/backend.go:105–163  ·  view source on GitHub ↗

recvLoop reads WinDivert packets and forwards them on b.packets. The caller's Verdict decides whether the packet is reinjected (Accept), dropped (Drop), or reinjected-modified (AcceptModified — caller must have handed us the mutated bytes elsewhere; today the engine uses Inject() instead, so we just

(ctx context.Context)

Source from the content-addressed store, hash-verified

103// handed us the mutated bytes elsewhere; today the engine uses Inject()
104// instead, so we just treat all non-Drop verdicts as Accept).
105func (b *Backend) recvLoop(ctx context.Context) {
106 defer b.reader.Done()
107 defer close(b.packets)
108
109 buf := make([]byte, b.cfg.ReadBufferSize)
110 for {
111 n, addr, err := Recv(b.handle, buf)
112 if err != nil {
113 // ERROR_NO_DATA (232) is the graceful signal that Close() tore
114 // the handle down mid-Recv; exit silently. Anything else gets
115 // printed once so users notice unexpected errors.
116 if IsHandleClosed(err) {
117 return
118 }
119 select {
120 case <-b.closed:
121 return
122 default:
123 }
124 fmt.Printf("snix/windows: recv error: %v\n", err)
125 return
126 }
127 // Copy payload so the caller can keep it past next Recv.
128 pkt := make([]byte, n)
129 copy(pkt, buf[:n])
130 // Copy address too (80 bytes) so the verdict closure can reinject.
131 addrCopy := addr
132 dir := snixplatform.DirInbound
133 if addr.Outbound() {
134 dir = snixplatform.DirOutbound
135 // Stash last outbound address for Inject() to reuse.
136 b.mu.Lock()
137 a := addr
138 b.outboundAddr = &a
139 b.mu.Unlock()
140 }
141
142 verdict := func(k snixplatform.VerdictKind) {
143 switch k {
144 case snixplatform.Drop:
145 return // don't reinject; packet is dropped by not calling Send.
146 default:
147 // Reinject the original packet via WinDivertSend.
148 _, _ = Send(b.handle, pkt, &addrCopy)
149 }
150 }
151
152 select {
153 case b.packets <- snixplatform.Packet{Dir: dir, Raw: pkt, Verdict: verdict}:
154 case <-b.closed:
155 // Shutting down: reinject so the stack keeps flowing.
156 _, _ = Send(b.handle, pkt, &addrCopy)
157 return
158 case <-ctx.Done():
159 _, _ = Send(b.handle, pkt, &addrCopy)
160 return
161 }
162 }

Callers 1

OpenMethod · 0.95

Implementers 3

fakeBackendcore/engine/engine_test.go
Backendplatform/windows/backend.go
Backendplatform/linux/nfqueue.go

Calls 5

closeFunction · 0.85
RecvFunction · 0.85
IsHandleClosedFunction · 0.85
SendFunction · 0.85
OutboundMethod · 0.80

Tested by

no test coverage detected