FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add UDP.go · celzero/firestack@a896c72 · GitHub

Commit a896c72

Browse files
Add UDP.go
1 parent 41ec060 commit a896c72

7 files changed

Lines changed: 175 additions & 11 deletions

File tree

‎intra/netstack/netstack.go‎

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,32 @@ import (
1515
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
1616
)
1717

18+
type GConnHandler interface {
19+
TCP() GTCPConnHandler
20+
UDP() GUDPConnHandler
21+
}
22+
23+
type gconnhandler struct {
24+
GConnHandler
25+
tcp GTCPConnHandler
26+
udp GUDPConnHandler
27+
}
28+
29+
func NewGConnHandler(tcp GTCPConnHandler, udp GUDPConnHandler) GConnHandler {
30+
return &gconnhandler{
31+
tcp: tcp,
32+
udp: udp,
33+
}
34+
}
35+
36+
func (g *gconnhandler) TCP() GTCPConnHandler {
37+
return g.tcp
38+
}
39+
40+
func (g *gconnhandler) UDP() GUDPConnHandler {
41+
return g.udp
42+
}
43+
1844
func NewEndpoint(dev int, mtu uint32) (stack.LinkEndpoint, error) {
1945
var endpoint stack.LinkEndpoint
2046
var fd_array []int
@@ -29,7 +55,7 @@ func NewEndpoint(dev int, mtu uint32) (stack.LinkEndpoint, error) {
2955

3056
const nic tcpip.NICID = 0x01
3157

32-
func NewStack(handler GTCPConnHandler, endpoint stack.LinkEndpoint) (*stack.Stack, error) {
58+
func NewStack(handler GConnHandler, endpoint stack.LinkEndpoint) (*stack.Stack, error) {
3359
var o stack.Options
3460
o = stack.Options{
3561
NetworkProtocols: []stack.NetworkProtocolFactory{
@@ -60,8 +86,9 @@ func NewStack(handler GTCPConnHandler, endpoint stack.LinkEndpoint) (*stack.Stac
6086
assertNoErr(s.SetSpoofing(nic, true))
6187
// allow all packets sent to our fake nic through to netstack
6288
assertNoErr(s.SetPromiscuousMode(nic, true))
63-
setupTcpHandler(s, handler)
64-
// setupUdpHandler(s, handler)
89+
setupTcpHandler(s, handler.TCP())
90+
setupUdpHandler(s, handler.UDP())
91+
//setupUdpHandler(s, handler)
6592
// setupIcmpHandler(s, endpoint, handler)
6693

6794
return s, nil

‎intra/netstack/tcp.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
)
1919

2020
type GTCPConnHandler interface {
21-
NewConnection(conn GTCPConn, src, dst net.TCPAddr)
21+
NewTCPConnection(conn GTCPConn, src, dst net.TCPAddr)
2222
}
2323

2424
func setupTcpHandler(s *stack.Stack, handler GTCPConnHandler) {
@@ -43,7 +43,7 @@ func setupTcpHandler(s *stack.Stack, handler GTCPConnHandler) {
4343
Port: int(id.LocalPort),
4444
}
4545

46-
go handler.NewConnection(GTCPConn{endpoint, gonet.NewTCPConn(waitQueue, endpoint)}, src, dst)
46+
go handler.NewTCPConnection(GTCPConn{endpoint, gonet.NewTCPConn(waitQueue, endpoint)}, src, dst)
4747
})
4848
s.SetTransportProtocolHandler(tcp.ProtocolNumber, forwarder.HandlePacket)
4949
}

‎intra/netstack/udp.go‎

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package netstack
2+
3+
import (
4+
"net"
5+
"strconv"
6+
"time"
7+
8+
// "github.com/v2fly/v2ray-core/v5/common/buf"
9+
// v2rayNet "github.com/v2fly/v2ray-core/v5/common/net"
10+
"github.com/eycorsican/go-tun2socks/core"
11+
"gvisor.dev/gvisor/pkg/tcpip"
12+
13+
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
14+
15+
"gvisor.dev/gvisor/pkg/tcpip/stack"
16+
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
17+
"gvisor.dev/gvisor/pkg/waiter"
18+
// "libcore/tun"
19+
)
20+
21+
var _ core.UDPConn = (*GUDPConn)(nil)
22+
23+
type GUDPConnHandler interface {
24+
NewUDPConnection(conn *GUDPConn, src, dst *net.UDPAddr) bool
25+
HandleData(conn *GUDPConn, data []byte, addr *net.UDPAddr) error
26+
}
27+
type GUDPConn struct {
28+
core.UDPConn
29+
ep tcpip.Endpoint
30+
gudp *gonet.UDPConn
31+
}
32+
33+
func setupUdpHandler(s *stack.Stack, handler GUDPConnHandler) {
34+
forwarder := udp.NewForwarder(s, func(request *udp.ForwarderRequest) {
35+
id := request.ID()
36+
waitQueue := new(waiter.Queue)
37+
endpoint, errT := request.CreateEndpoint(waitQueue)
38+
if errT != nil {
39+
40+
return
41+
}
42+
43+
src := &net.UDPAddr{
44+
IP: net.IP(id.RemoteAddress),
45+
Port: int(id.RemotePort),
46+
}
47+
48+
dst := &net.UDPAddr{
49+
IP: net.IP(id.LocalAddress),
50+
Port: int(id.LocalPort),
51+
}
52+
53+
gc := &GUDPConn{
54+
ep: endpoint,
55+
gudp: gonet.NewUDPConn(s, waitQueue, endpoint),
56+
}
57+
58+
go func() {
59+
ok := handler.NewUDPConnection(gc, src, dst)
60+
61+
if !ok {
62+
gc.gudp.Close()
63+
return
64+
}
65+
const maxUDPReqSize = 1600 // FIXME: MTU
66+
const readDeadline = 30 * time.Second // FIXME: Udp.Timeout
67+
q := make([]byte, maxUDPReqSize)
68+
for {
69+
gc.gudp.SetReadDeadline(time.Now().Add(readDeadline))
70+
if n, addr, err := gc.gudp.ReadFrom(q); err == nil {
71+
ipstr, portstr, _ := net.SplitHostPort(addr.String())
72+
port, _ := strconv.Atoi(portstr)
73+
udpaddr := &net.UDPAddr{
74+
IP: net.ParseIP(ipstr),
75+
Port: port,
76+
}
77+
handler.HandleData(gc, q[:n], udpaddr)
78+
} else {
79+
break
80+
}
81+
}
82+
}()
83+
})
84+
s.SetTransportProtocolHandler(udp.ProtocolNumber, forwarder.HandlePacket)
85+
}
86+
87+
func (g *GUDPConn) LocalAddr() *net.UDPAddr {
88+
return g.gudp.LocalAddr().(*net.UDPAddr)
89+
}
90+
91+
// ReceiveTo will be called when data arrives from TUN, and the received
92+
// data should be sent to addr.
93+
func (g *GUDPConn) ReceiveTo(_ []byte, _ *net.UDPAddr) error {
94+
return nil
95+
// no-op; forwarder.HandlePacket takes care of this
96+
}
97+
98+
// WriteFrom writes data to TUN, addr will be set as source address of
99+
// UDP packets that output to TUN.
100+
func (g *GUDPConn) WriteFrom(data []byte, addr *net.UDPAddr) (int, error) {
101+
// nb: write-deadlines set by intra.udp
102+
return g.gudp.WriteTo(data, addr)
103+
}
104+
105+
// Close closes the connection.
106+
func (g *GUDPConn) Close() error {
107+
return g.gudp.Close()
108+
}

‎intra/tcp.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func (h *tcpHandler) onConn(localConn net.Conn, target *net.TCPAddr) (netid stri
238238
return
239239
}
240240

241-
func (h *tcpHandler) NewConnection(conn netstack.GTCPConn, src, dst net.TCPAddr) {
241+
func (h *tcpHandler) NewTCPConnection(conn netstack.GTCPConn, src, dst net.TCPAddr) {
242242
/*gconn := GTCPConn{C: conn}
243243
newConn:= gconn.(net.Conn)*/
244244
if err := h.Handle(conn, &dst); err != nil {

‎intra/tunnel.go‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,17 @@ func NewGTunnel(fakedns string, dohdns doh.Transport, fd int, mtu uint32, dialer
125125

126126
tunmode := settings.DefaultTunMode()
127127

128+
// RFC 4787 REQ-5 requires a timeout no shorter than 5 minutes.
129+
udptimeout, _ := time.ParseDuration("5m")
130+
131+
udpfakedns, err := net.ResolveUDPAddr("udp", fakedns)
132+
if err != nil {
133+
return nil, err
134+
}
135+
128136
tcph := NewTCPHandler(fakednsaddr, dialer, flow, tunmode, listener)
129-
t, err := tunnel.NewGTunnel(fd, mtu, tcph)
137+
udph := NewUDPHandler(*udpfakedns, udptimeout, flow, tunmode, config, listener)
138+
t, err := tunnel.NewGTunnel(fd, mtu, tcph, udph)
130139

131140
if err != nil {
132141
return nil, err

‎intra/udp.go‎

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ import (
4444
"github.com/celzero/firestack/intra/doh"
4545
"github.com/celzero/firestack/intra/protect"
4646
"github.com/celzero/firestack/intra/settings"
47+
48+
"github.com/celzero/firestack/intra/netstack"
4749
)
4850

4951
// UDPSocketSummary describes a non-DNS UDP association, reported when it is discarded.
@@ -73,6 +75,8 @@ func makeTracker(conn interface{}) *tracker {
7375
// UDPHandler adds DOH support to the base UDPConnHandler interface.
7476
type UDPHandler interface {
7577
core.UDPConnHandler
78+
netstack.GUDPConnHandler
79+
7680
SetDNS(dns doh.Transport)
7781
onConn(localudp core.UDPConn, target *net.UDPAddr) string
7882
SetDNSCryptProxy(*dnscrypt.Proxy)
@@ -97,7 +101,7 @@ type udpHandler struct {
97101
proxies map[string]*proxy.Dialer
98102
}
99103

100-
// NewUDPHandler makes a UDP handler with Intra-style DNS redirection:
104+
// NewUDPHandler makes a UDP handler with Intra-style DNS redirection:udpHandler
101105
// All packets are routed directly to their destination, except packets whose
102106
// destination is `fakedns`. Those packets are redirected to DOH.
103107
// `timeout` controls the effective NAT mapping lifetime.
@@ -176,8 +180,10 @@ func (h *udpHandler) onConn(localudp core.UDPConn, target *net.UDPAddr) (netid s
176180
if h.tunMode.BlockMode == settings.BlockModeNone {
177181
return protect.NetIdActive
178182
}
183+
// localudp is either core.UDPConn or gonet.UDPConn wrapped in GUDPConn
184+
uconn := localudp.LocalAddr()
179185
// Next-up If: BlockModeFilter or BlockModeFilterProc
180-
return h.onNewConn(localudp.LocalAddr(), target)
186+
return h.onNewConn(uconn, target)
181187
}
182188

183189
func (h *udpHandler) onNewConn(source *net.UDPAddr, target *net.UDPAddr) (netid string) {
@@ -199,6 +205,15 @@ func (h *udpHandler) onNewConn(source *net.UDPAddr, target *net.UDPAddr) (netid
199205
return
200206
}
201207

208+
func (h *udpHandler) NewUDPConnection(conn *netstack.GUDPConn, _, dst *net.UDPAddr) bool {
209+
/*gconn := GTCPConn{C: conn}
210+
newConn:= gconn.(net.Conn)*/
211+
if err := h.Connect(conn, dst); err != nil {
212+
return false
213+
}
214+
return true
215+
}
216+
202217
// Connect connects the proxy server. Note that target can be nil.
203218
func (h *udpHandler) Connect(conn core.UDPConn, target *net.UDPAddr) error {
204219
netid := h.onConn(conn, target)
@@ -361,6 +376,10 @@ func (h *udpHandler) dnsOverride(nat *tracker, conn core.UDPConn, addr *net.UDPA
361376
return false
362377
}
363378

379+
func (h *udpHandler) HandleData(conn *netstack.GUDPConn, data []byte, addr *net.UDPAddr) error {
380+
return h.ReceiveTo(conn, data, addr)
381+
}
382+
364383
// ReceiveTo is called when data arrives from conn (tun).
365384
func (h *udpHandler) ReceiveTo(conn core.UDPConn, data []byte, addr *net.UDPAddr) (err error) {
366385
h.RLock()

‎tunnel/tunnel.go‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,13 @@ func (t *tunnel) Write(data []byte) (int, error) {
8787
return t.lwipStack.Write(data)
8888
}
8989

90-
func NewGTunnel(fd int, mtu uint32, tcphdl netstack.GTCPConnHandler) (Tunnel, error) {
90+
func NewGTunnel(fd int, mtu uint32, tcph netstack.GTCPConnHandler, udph netstack.GUDPConnHandler) (Tunnel, error) {
9191
endpoint, err := netstack.NewEndpoint(fd, mtu)
9292
if err != nil {
9393
return nil, err
9494
}
95-
stack, err := netstack.NewStack(tcphdl, endpoint)
95+
ghdl := netstack.NewGConnHandler(tcph, udph)
96+
stack, err := netstack.NewStack(ghdl, endpoint)
9697
if err != nil {
9798
return nil, err
9899
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL