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