-
Notifications
You must be signed in to change notification settings - Fork 2
/
handler.go
99 lines (82 loc) · 2.18 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package netstackgo
import (
"net"
"net/netip"
"github.com/josexy/netstackgo/tun/core/adapter"
"gvisor.dev/gvisor/pkg/tcpip/stack"
)
type ConnHandler interface {
HandleTCPConn(ConnTuple, net.Conn)
HandleUDPConn(ConnTuple, net.PacketConn)
}
type ConnTuple struct {
SrcAddr netip.AddrPort
DstAddr netip.AddrPort
}
func newConnTuple(id *stack.TransportEndpointID) ConnTuple {
srcIP, _ := netip.AddrFromSlice(id.RemoteAddress.AsSlice())
dstIP, _ := netip.AddrFromSlice(id.LocalAddress.AsSlice())
return ConnTuple{
SrcAddr: netip.AddrPortFrom(srcIP, id.RemotePort),
DstAddr: netip.AddrPortFrom(dstIP, id.LocalPort),
}
}
func (t *ConnTuple) Src() string {
return t.SrcAddr.String()
}
func (t *ConnTuple) Dst() string {
return t.DstAddr.String()
}
type tunTransportHandler struct {
tcpQueue chan adapter.TCPConn
udpQueue chan adapter.UDPConn
closeCh chan struct{}
adapter.TransportHandler
connHandler ConnHandler
}
func newTunTransportHandler() *tunTransportHandler {
handler := &tunTransportHandler{
tcpQueue: make(chan adapter.TCPConn, 128),
udpQueue: make(chan adapter.UDPConn, 128),
closeCh: make(chan struct{}, 1),
}
handler.TransportHandler = handler
return handler
}
func (h *tunTransportHandler) registerConnHandler(handler ConnHandler) {
h.connHandler = handler
}
func (h *tunTransportHandler) run() {
go func() {
defer func() { recover() }()
for {
select {
case conn := <-h.tcpQueue:
go h.handleTCPConn(conn)
case conn := <-h.udpQueue:
go h.handleUDPConn(conn)
case <-h.closeCh:
return
}
}
}()
}
func (h *tunTransportHandler) finish() {
h.closeCh <- struct{}{}
}
func (h *tunTransportHandler) HandleTCP(conn adapter.TCPConn) { h.tcpQueue <- conn }
func (h *tunTransportHandler) HandleUDP(conn adapter.UDPConn) { h.udpQueue <- conn }
func (h *tunTransportHandler) handleTCPConn(conn adapter.TCPConn) {
defer conn.Close()
connTuple := newConnTuple(conn.ID())
if h.connHandler != nil {
h.connHandler.HandleTCPConn(connTuple, conn)
}
}
func (h *tunTransportHandler) handleUDPConn(conn adapter.UDPConn) {
defer conn.Close()
connTuple := newConnTuple(conn.ID())
if h.connHandler != nil {
h.connHandler.HandleUDPConn(connTuple, conn)
}
}