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  }