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 }