github.com/chwjbn/xclash@v0.2.0/listener/redir/tcp.go (about)

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