github.com/metacubex/sing-tun@v0.2.7-0.20240512075008-89e7c6208eec/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 InterfaceFinder control.InterfaceFinder 29 EnforceBindInterface bool 30 } 31 32 func NewStack( 33 stack string, 34 options StackOptions, 35 ) (Stack, error) { 36 switch stack { 37 case "": 38 if WithGVisor && !options.TunOptions.GSO { 39 return NewMixed(options) 40 } else { 41 return NewSystem(options) 42 } 43 case "gvisor": 44 return NewGVisor(options) 45 case "mixed": 46 return NewMixed(options) 47 case "system": 48 return NewSystem(options) 49 default: 50 return nil, E.New("unknown stack: ", stack) 51 } 52 } 53 54 func BroadcastAddr(inet4Address []netip.Prefix) netip.Addr { 55 if len(inet4Address) == 0 { 56 return netip.Addr{} 57 } 58 prefix := inet4Address[0] 59 var broadcastAddr [4]byte 60 binary.BigEndian.PutUint32(broadcastAddr[:], binary.BigEndian.Uint32(prefix.Masked().Addr().AsSlice())|^binary.BigEndian.Uint32(net.CIDRMask(prefix.Bits(), 32))) 61 return netip.AddrFrom4(broadcastAddr) 62 }