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  }