mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-06 01:07:03 +08:00
Chore: move stack & device to core
This commit is contained in:
91
core/stack/tcp.go
Executable file
91
core/stack/tcp.go
Executable file
@@ -0,0 +1,91 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/xjasonlyu/tun2socks/common/adapter"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
const (
|
||||
// defaultWndSize if set to zero, the default
|
||||
// receive window buffer size is used instead.
|
||||
defaultWndSize = 0
|
||||
|
||||
// maxConnAttempts specifies the maximum number
|
||||
// of in-flight tcp connection attempts.
|
||||
maxConnAttempts = 2 << 10
|
||||
|
||||
// tcpKeepaliveIdle specifies the time a connection
|
||||
// must remain idle before the first TCP keepalive
|
||||
// packet is sent. Once this time is reached,
|
||||
// tcpKeepaliveInterval option is used instead.
|
||||
tcpKeepaliveIdle = 60 * time.Second
|
||||
|
||||
// tcpKeepaliveInterval specifies the interval
|
||||
// time between sending TCP keepalive packets.
|
||||
tcpKeepaliveInterval = 30 * time.Second
|
||||
)
|
||||
|
||||
func withTCPHandler() Option {
|
||||
return func(s *Stack) error {
|
||||
tcpForwarder := tcp.NewForwarder(s.Stack, defaultWndSize, maxConnAttempts, func(r *tcp.ForwarderRequest) {
|
||||
var wq waiter.Queue
|
||||
id := r.ID()
|
||||
ep, err := r.CreateEndpoint(&wq)
|
||||
if err != nil {
|
||||
// prevent potential half-open TCP connection leak.
|
||||
r.Complete(true)
|
||||
return
|
||||
}
|
||||
r.Complete(false)
|
||||
|
||||
setKeepalive(ep)
|
||||
|
||||
conn := &tcpConn{
|
||||
Conn: gonet.NewTCPConn(&wq, ep),
|
||||
metadata: &adapter.Metadata{
|
||||
Net: adapter.TCP,
|
||||
SrcIP: net.IP(id.RemoteAddress),
|
||||
SrcPort: id.RemotePort,
|
||||
DstIP: net.IP(id.LocalAddress),
|
||||
DstPort: id.LocalPort,
|
||||
},
|
||||
}
|
||||
|
||||
s.handler.Add(conn)
|
||||
})
|
||||
s.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func setKeepalive(ep tcpip.Endpoint) error {
|
||||
ep.SocketOptions().SetKeepAlive(true)
|
||||
|
||||
idle := tcpip.KeepaliveIdleOption(tcpKeepaliveIdle)
|
||||
if err := ep.SetSockOpt(&idle); err != nil {
|
||||
return fmt.Errorf("set keepalive idle: %s", err)
|
||||
}
|
||||
|
||||
interval := tcpip.KeepaliveIntervalOption(tcpKeepaliveInterval)
|
||||
if err := ep.SetSockOpt(&interval); err != nil {
|
||||
return fmt.Errorf("set keepalive interval: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type tcpConn struct {
|
||||
net.Conn
|
||||
metadata *adapter.Metadata
|
||||
}
|
||||
|
||||
func (c *tcpConn) Metadata() *adapter.Metadata {
|
||||
return c.metadata
|
||||
}
|
Reference in New Issue
Block a user