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

     1  package tunnel
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  
     7  	"github.com/igoogolx/clash/adapter/inbound"
     8  	C "github.com/igoogolx/clash/constant"
     9  	"github.com/igoogolx/clash/transport/socks5"
    10  )
    11  
    12  type Listener struct {
    13  	listener net.Listener
    14  	addr     string
    15  	target   socks5.Addr
    16  	proxy    string
    17  	closed   bool
    18  }
    19  
    20  // RawAddress implements C.Listener
    21  func (l *Listener) RawAddress() string {
    22  	return l.addr
    23  }
    24  
    25  // Address implements C.Listener
    26  func (l *Listener) Address() string {
    27  	return l.listener.Addr().String()
    28  }
    29  
    30  // Close implements C.Listener
    31  func (l *Listener) Close() error {
    32  	l.closed = true
    33  	return l.listener.Close()
    34  }
    35  
    36  func (l *Listener) handleTCP(conn net.Conn, in chan<- C.ConnContext) {
    37  	conn.(*net.TCPConn).SetKeepAlive(true)
    38  	ctx := inbound.NewSocket(l.target, conn, C.TUNNEL)
    39  	ctx.Metadata().SpecialProxy = l.proxy
    40  	in <- ctx
    41  }
    42  
    43  func New(addr, target, proxy string, in chan<- C.ConnContext) (*Listener, error) {
    44  	l, err := net.Listen("tcp", addr)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	targetAddr := socks5.ParseAddr(target)
    50  	if targetAddr == nil {
    51  		return nil, fmt.Errorf("invalid target address %s", target)
    52  	}
    53  
    54  	rl := &Listener{
    55  		listener: l,
    56  		target:   targetAddr,
    57  		proxy:    proxy,
    58  		addr:     addr,
    59  	}
    60  
    61  	go func() {
    62  		for {
    63  			c, err := l.Accept()
    64  			if err != nil {
    65  				if rl.closed {
    66  					break
    67  				}
    68  				continue
    69  			}
    70  			go rl.handleTCP(c, in)
    71  		}
    72  	}()
    73  
    74  	return rl, nil
    75  }