github.com/metacubex/mihomo@v1.18.5/listener/inbound/socks.go (about)

     1  package inbound
     2  
     3  import (
     4  	"fmt"
     5  	C "github.com/metacubex/mihomo/constant"
     6  	"github.com/metacubex/mihomo/listener/socks"
     7  	"github.com/metacubex/mihomo/log"
     8  )
     9  
    10  type SocksOption struct {
    11  	BaseOption
    12  	UDP bool `inbound:"udp,omitempty"`
    13  }
    14  
    15  func (o SocksOption) Equal(config C.InboundConfig) bool {
    16  	return optionToString(o) == optionToString(config)
    17  }
    18  
    19  type Socks struct {
    20  	*Base
    21  	config *SocksOption
    22  	udp    bool
    23  	stl    *socks.Listener
    24  	sul    *socks.UDPListener
    25  }
    26  
    27  func NewSocks(options *SocksOption) (*Socks, error) {
    28  	base, err := NewBase(&options.BaseOption)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	return &Socks{
    33  		Base:   base,
    34  		config: options,
    35  		udp:    options.UDP,
    36  	}, nil
    37  }
    38  
    39  // Config implements constant.InboundListener
    40  func (s *Socks) Config() C.InboundConfig {
    41  	return s.config
    42  }
    43  
    44  // Close implements constant.InboundListener
    45  func (s *Socks) Close() error {
    46  	var err error
    47  	if s.stl != nil {
    48  		if tcpErr := s.stl.Close(); tcpErr != nil {
    49  			err = tcpErr
    50  		}
    51  	}
    52  	if s.udp && s.sul != nil {
    53  		if udpErr := s.sul.Close(); udpErr != nil {
    54  			if err == nil {
    55  				err = udpErr
    56  			} else {
    57  				return fmt.Errorf("close tcp err: %s, close udp err: %s", err.Error(), udpErr.Error())
    58  			}
    59  		}
    60  	}
    61  
    62  	return err
    63  }
    64  
    65  // Address implements constant.InboundListener
    66  func (s *Socks) Address() string {
    67  	return s.stl.Address()
    68  }
    69  
    70  // Listen implements constant.InboundListener
    71  func (s *Socks) Listen(tunnel C.Tunnel) error {
    72  	var err error
    73  	if s.stl, err = socks.New(s.RawAddress(), tunnel, s.Additions()...); err != nil {
    74  		return err
    75  	}
    76  	if s.udp {
    77  		if s.sul, err = socks.NewUDP(s.RawAddress(), tunnel, s.Additions()...); err != nil {
    78  			return err
    79  		}
    80  	}
    81  
    82  	log.Infoln("SOCKS[%s] proxy listening at: %s", s.Name(), s.Address())
    83  	return nil
    84  }
    85  
    86  var _ C.InboundListener = (*Socks)(nil)