github.com/sagernet/sing-tun@v0.3.0-beta.5/stack.go (about) 1 package tun 2 3 import ( 4 "context" 5 "encoding/binary" 6 "net" 7 "net/netip" 8 9 "github.com/sagernet/sing/common/control" 10 E "github.com/sagernet/sing/common/exceptions" 11 "github.com/sagernet/sing/common/logger" 12 ) 13 14 type Stack interface { 15 Start() error 16 Close() error 17 } 18 19 type StackOptions struct { 20 Context context.Context 21 Tun Tun 22 TunOptions Options 23 EndpointIndependentNat bool 24 UDPTimeout int64 25 Handler Handler 26 Logger logger.Logger 27 ForwarderBindInterface bool 28 IncludeAllNetworks bool 29 InterfaceFinder control.InterfaceFinder 30 } 31 32 func NewStack( 33 stack string, 34 options StackOptions, 35 ) (Stack, error) { 36 switch stack { 37 case "": 38 if options.IncludeAllNetworks { 39 return NewGVisor(options) 40 } else if WithGVisor && !options.TunOptions.GSO { 41 return NewMixed(options) 42 } else { 43 return NewSystem(options) 44 } 45 case "gvisor": 46 return NewGVisor(options) 47 case "mixed": 48 if options.IncludeAllNetworks { 49 return nil, ErrIncludeAllNetworks 50 } 51 return NewMixed(options) 52 case "system": 53 if options.IncludeAllNetworks { 54 return nil, ErrIncludeAllNetworks 55 } 56 return NewSystem(options) 57 default: 58 return nil, E.New("unknown stack: ", stack) 59 } 60 } 61 62 func BroadcastAddr(inet4Address []netip.Prefix) netip.Addr { 63 if len(inet4Address) == 0 { 64 return netip.Addr{} 65 } 66 prefix := inet4Address[0] 67 var broadcastAddr [4]byte 68 binary.BigEndian.PutUint32(broadcastAddr[:], binary.BigEndian.Uint32(prefix.Masked().Addr().AsSlice())|^binary.BigEndian.Uint32(net.CIDRMask(prefix.Bits(), 32))) 69 return netip.AddrFrom4(broadcastAddr) 70 }