github.com/igoogolx/clash@v1.19.8/constant/listener.go (about)

     1  package constant
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"net/url"
     7  	"strconv"
     8  )
     9  
    10  type Listener interface {
    11  	RawAddress() string
    12  	Address() string
    13  	Close() error
    14  }
    15  
    16  type InboundType string
    17  
    18  const (
    19  	InboundTypeSocks  InboundType = "socks"
    20  	InboundTypeRedir  InboundType = "redir"
    21  	InboundTypeTproxy InboundType = "tproxy"
    22  	InboundTypeHTTP   InboundType = "http"
    23  	InboundTypeMixed  InboundType = "mixed"
    24  )
    25  
    26  var supportInboundTypes = map[InboundType]bool{
    27  	InboundTypeSocks:  true,
    28  	InboundTypeRedir:  true,
    29  	InboundTypeTproxy: true,
    30  	InboundTypeHTTP:   true,
    31  	InboundTypeMixed:  true,
    32  }
    33  
    34  type inbound struct {
    35  	Type          InboundType `json:"type" yaml:"type"`
    36  	BindAddress   string      `json:"bind-address" yaml:"bind-address"`
    37  	IsFromPortCfg bool        `json:"-" yaml:"-"`
    38  }
    39  
    40  // Inbound
    41  type Inbound inbound
    42  
    43  // UnmarshalYAML implements yaml.Unmarshaler
    44  func (i *Inbound) UnmarshalYAML(unmarshal func(any) error) error {
    45  	var tp string
    46  	if err := unmarshal(&tp); err != nil {
    47  		var inner inbound
    48  		if err := unmarshal(&inner); err != nil {
    49  			return err
    50  		}
    51  
    52  		*i = Inbound(inner)
    53  	} else {
    54  		inner, err := parseInbound(tp)
    55  		if err != nil {
    56  			return err
    57  		}
    58  
    59  		*i = Inbound(*inner)
    60  	}
    61  
    62  	if !supportInboundTypes[i.Type] {
    63  		return fmt.Errorf("not support inbound type: %s", i.Type)
    64  	}
    65  	_, portStr, err := net.SplitHostPort(i.BindAddress)
    66  	if err != nil {
    67  		return fmt.Errorf("bind address parse error. addr: %s, err: %w", i.BindAddress, err)
    68  	}
    69  	port, err := strconv.ParseUint(portStr, 10, 16)
    70  	if err != nil || port == 0 {
    71  		return fmt.Errorf("invalid bind port. addr: %s", i.BindAddress)
    72  	}
    73  	return nil
    74  }
    75  
    76  func parseInbound(alias string) (*inbound, error) {
    77  	u, err := url.Parse(alias)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	listenerType := InboundType(u.Scheme)
    82  	return &inbound{
    83  		Type:        listenerType,
    84  		BindAddress: u.Host,
    85  	}, nil
    86  }
    87  
    88  func (i *Inbound) ToAlias() string {
    89  	return string(i.Type) + "://" + i.BindAddress
    90  }