Skip to content

Commit

Permalink
Refactor(core): with error callback
Browse files Browse the repository at this point in the history
  • Loading branch information
xjasonlyu committed Mar 29, 2022
1 parent 0a9f7f1 commit 3999c5d
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 19 deletions.
8 changes: 1 addition & 7 deletions core/adapter/handler.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package adapter

// TransportHandler is a TCP/UDP connection handler that implements
// HandleTCPConn and HandleUDPConn methods.
// HandleTCP and HandleUDP methods.
type TransportHandler interface {
HandleTCP(TCPConn)
HandleUDP(UDPConn)
}

// TCPHandleFunc handles incoming TCP connection.
type TCPHandleFunc func(TCPConn)

// UDPHandleFunc handles incoming UDP connection.
type UDPHandleFunc func(UDPConn)
37 changes: 33 additions & 4 deletions core/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,36 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
)

// CreateStackWithOptions creates *stack.Stack with given options.
func CreateStackWithOptions(linkEP stack.LinkEndpoint, handler adapter.TransportHandler, opts ...option.Option) (*stack.Stack, error) {
// Config is the configuration to create *stack.Stack.
type Config struct {
// LinkEndpoints is the interface implemented by
// data link layer protocols.
LinkEndpoint stack.LinkEndpoint

// TransportHandler is the handler used by internal
// stack to set transport handlers.
TransportHandler adapter.TransportHandler

// ErrorFunc is the function that will be called
// when internal stack encounters errors.
ErrorFunc func(tcpip.Error)

// Options are supplement options to apply settings
// for the internal stack.
Options []option.Option
}

// CreateStack creates *stack.Stack with given config.
func CreateStack(cfg *Config) (*stack.Stack, error) {
if cfg.ErrorFunc == nil {
cfg.ErrorFunc = func(tcpip.Error) {}
}

opts := cfg.Options
if len(opts) == 0 {
opts = []option.Option{option.WithDefault()}
}

s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{
ipv4.NewProtocol,
Expand All @@ -33,7 +61,7 @@ func CreateStackWithOptions(linkEP stack.LinkEndpoint, handler adapter.Transport

opts = append(opts,
// Create stack NIC and then bind link endpoint to it.
withCreatingNIC(nicID, linkEP),
withCreatingNIC(nicID, cfg.LinkEndpoint),

// In the past we did s.AddAddressRange to assign 0.0.0.0/0
// onto the interface. We need that to be able to terminate
Expand Down Expand Up @@ -63,7 +91,8 @@ func CreateStackWithOptions(linkEP stack.LinkEndpoint, handler adapter.Transport
withRouteTable(nicID),

// Initiate transport protocol (TCP/UDP) with given handler.
withTCPHandler(handler.HandleTCP), withUDPHandler(handler.HandleUDP),
withTCPHandler(cfg.TransportHandler.HandleTCP, cfg.ErrorFunc),
withUDPHandler(cfg.TransportHandler.HandleUDP, cfg.ErrorFunc),
)

for _, opt := range opts {
Expand Down
20 changes: 16 additions & 4 deletions core/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,31 @@ const (
tcpKeepaliveInterval = 30 * time.Second
)

func withTCPHandler(handle adapter.TCPHandleFunc) option.Option {
func withTCPHandler(handle func(adapter.TCPConn), callback func(tcpip.Error)) option.Option {
return func(s *stack.Stack) error {
tcpForwarder := tcp.NewForwarder(s, defaultWndSize, maxConnAttempts, func(r *tcp.ForwarderRequest) {
var wq waiter.Queue
ep, err := r.CreateEndpoint(&wq)
var (
wq waiter.Queue
ep tcpip.Endpoint
err tcpip.Error
)

defer func() {
if err != nil {
callback(err)
}
}()

ep, err = r.CreateEndpoint(&wq)
if err != nil {
// RST: prevent potential half-open TCP connection leak.
r.Complete(true)
return
}
defer r.Complete(false)

setKeepalive(ep)
// TCP Keepalive
err = setKeepalive(ep)

conn := &tcpConn{
TCPConn: gonet.NewTCPConn(&wq, ep),
Expand Down
5 changes: 3 additions & 2 deletions core/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ import (
"github.com/xjasonlyu/tun2socks/v2/core/adapter"
"github.com/xjasonlyu/tun2socks/v2/core/option"

"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
"gvisor.dev/gvisor/pkg/waiter"
)

func withUDPHandler(handle adapter.UDPHandleFunc) option.Option {
func withUDPHandler(handle func(adapter.UDPConn), callback func(tcpip.Error)) option.Option {
return func(s *stack.Stack) error {
udpForwarder := udp.NewForwarder(s, func(r *udp.ForwarderRequest) {
var wq waiter.Queue
ep, err := r.CreateEndpoint(&wq)
if err != nil {
// TODO: handler errors in the future.
callback(err)
return
}

Expand Down
10 changes: 8 additions & 2 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"github.com/xjasonlyu/tun2socks/v2/component/dialer"
"github.com/xjasonlyu/tun2socks/v2/core"
"github.com/xjasonlyu/tun2socks/v2/core/device"
"github.com/xjasonlyu/tun2socks/v2/core/option"
_ "github.com/xjasonlyu/tun2socks/v2/dns"
"github.com/xjasonlyu/tun2socks/v2/log"
"github.com/xjasonlyu/tun2socks/v2/proxy"
"github.com/xjasonlyu/tun2socks/v2/stats"
"github.com/xjasonlyu/tun2socks/v2/tunnel"

"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/stack"
)

Expand Down Expand Up @@ -169,6 +169,12 @@ func (e *engine) applyStack() (err error) {
}
}()

e.stack, err = core.CreateStackWithOptions(e.device, &fakeTunnel{}, option.WithDefault())
e.stack, err = core.CreateStack(&core.Config{
LinkEndpoint: e.device,
TransportHandler: &fakeTunnel{},
ErrorFunc: func(err tcpip.Error) {
log.Warnf("[STACK] %s", err)
},
})
return
}

0 comments on commit 3999c5d

Please sign in to comment.