github.com/sagernet/sing-box@v1.9.0-rc.20/adapter/inbound.go (about)

     1  package adapter
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"net/netip"
     7  
     8  	"github.com/sagernet/sing-box/common/process"
     9  	"github.com/sagernet/sing-box/option"
    10  	M "github.com/sagernet/sing/common/metadata"
    11  	N "github.com/sagernet/sing/common/network"
    12  )
    13  
    14  type Inbound interface {
    15  	Service
    16  	Type() string
    17  	Tag() string
    18  }
    19  
    20  type InjectableInbound interface {
    21  	Inbound
    22  	Network() []string
    23  	NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
    24  	NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
    25  }
    26  
    27  type InboundContext struct {
    28  	Inbound     string
    29  	InboundType string
    30  	IPVersion   uint8
    31  	Network     string
    32  	Source      M.Socksaddr
    33  	Destination M.Socksaddr
    34  	Domain      string
    35  	Protocol    string
    36  	User        string
    37  	Outbound    string
    38  
    39  	// cache
    40  
    41  	InboundDetour        string
    42  	LastInbound          string
    43  	OriginDestination    M.Socksaddr
    44  	InboundOptions       option.InboundOptions
    45  	DestinationAddresses []netip.Addr
    46  	SourceGeoIPCode      string
    47  	GeoIPCode            string
    48  	ProcessInfo          *process.Info
    49  	QueryType            uint16
    50  	FakeIP               bool
    51  
    52  	// rule cache
    53  
    54  	IPCIDRMatchSource            bool
    55  	SourceAddressMatch           bool
    56  	SourcePortMatch              bool
    57  	DestinationAddressMatch      bool
    58  	DestinationPortMatch         bool
    59  	DidMatch                     bool
    60  	IgnoreDestinationIPCIDRMatch bool
    61  }
    62  
    63  func (c *InboundContext) ResetRuleCache() {
    64  	c.IPCIDRMatchSource = false
    65  	c.SourceAddressMatch = false
    66  	c.SourcePortMatch = false
    67  	c.DestinationAddressMatch = false
    68  	c.DestinationPortMatch = false
    69  	c.DidMatch = false
    70  }
    71  
    72  type inboundContextKey struct{}
    73  
    74  func WithContext(ctx context.Context, inboundContext *InboundContext) context.Context {
    75  	return context.WithValue(ctx, (*inboundContextKey)(nil), inboundContext)
    76  }
    77  
    78  func ContextFrom(ctx context.Context) *InboundContext {
    79  	metadata := ctx.Value((*inboundContextKey)(nil))
    80  	if metadata == nil {
    81  		return nil
    82  	}
    83  	return metadata.(*InboundContext)
    84  }
    85  
    86  func AppendContext(ctx context.Context) (context.Context, *InboundContext) {
    87  	metadata := ContextFrom(ctx)
    88  	if metadata != nil {
    89  		return ctx, metadata
    90  	}
    91  	metadata = new(InboundContext)
    92  	return WithContext(ctx, metadata), metadata
    93  }
    94  
    95  func ExtendContext(ctx context.Context) (context.Context, *InboundContext) {
    96  	var newMetadata InboundContext
    97  	if metadata := ContextFrom(ctx); metadata != nil {
    98  		newMetadata = *metadata
    99  	}
   100  	return WithContext(ctx, &newMetadata), &newMetadata
   101  }
   102  
   103  func OverrideContext(ctx context.Context) context.Context {
   104  	if metadata := ContextFrom(ctx); metadata != nil {
   105  		var newMetadata InboundContext
   106  		newMetadata = *metadata
   107  		return WithContext(ctx, &newMetadata)
   108  	}
   109  	return ctx
   110  }