github.com/igoogolx/clash@v1.19.8/listener/redir/tcp.go (about) 1 package redir 2 3 import ( 4 "net" 5 6 "github.com/igoogolx/clash/adapter/inbound" 7 C "github.com/igoogolx/clash/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) (C.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 }