github.com/metacubex/mihomo@v1.18.5/listener/redir/tcp.go (about)

     1  package redir
     2  
     3  import (
     4  	"net"
     5  
     6  	"github.com/metacubex/mihomo/adapter/inbound"
     7  	N "github.com/metacubex/mihomo/common/net"
     8  	C "github.com/metacubex/mihomo/constant"
     9  )
    10  
    11  type Listener struct {
    12  	listener net.Listener
    13  	addr     string
    14  	closed   bool
    15  }
    16  
    17  // RawAddress implements C.Listener
    18  func (l *Listener) RawAddress() string {
    19  	return l.addr
    20  }
    21  
    22  // Address implements C.Listener
    23  func (l *Listener) Address() string {
    24  	return l.listener.Addr().String()
    25  }
    26  
    27  // Close implements C.Listener
    28  func (l *Listener) Close() error {
    29  	l.closed = true
    30  	return l.listener.Close()
    31  }
    32  
    33  func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) {
    34  	if len(additions) == 0 {
    35  		additions = []inbound.Addition{
    36  			inbound.WithInName("DEFAULT-REDIR"),
    37  			inbound.WithSpecialRules(""),
    38  		}
    39  	}
    40  	l, err := net.Listen("tcp", addr)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	rl := &Listener{
    45  		listener: l,
    46  		addr:     addr,
    47  	}
    48  
    49  	go func() {
    50  		for {
    51  			c, err := l.Accept()
    52  			if err != nil {
    53  				if rl.closed {
    54  					break
    55  				}
    56  				continue
    57  			}
    58  			go handleRedir(c, tunnel, additions...)
    59  		}
    60  	}()
    61  
    62  	return rl, nil
    63  }
    64  
    65  func handleRedir(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) {
    66  	target, err := parserPacket(conn)
    67  	if err != nil {
    68  		conn.Close()
    69  		return
    70  	}
    71  	N.TCPKeepAlive(conn)
    72  	tunnel.HandleTCPConn(inbound.NewSocket(target, conn, C.REDIR, additions...))
    73  }