github.com/metacubex/mihomo@v1.18.5/listener/shadowsocks/tcp.go (about) 1 package shadowsocks 2 3 import ( 4 "net" 5 "strings" 6 7 "github.com/metacubex/mihomo/adapter/inbound" 8 N "github.com/metacubex/mihomo/common/net" 9 C "github.com/metacubex/mihomo/constant" 10 LC "github.com/metacubex/mihomo/listener/config" 11 "github.com/metacubex/mihomo/transport/shadowsocks/core" 12 "github.com/metacubex/mihomo/transport/socks5" 13 ) 14 15 type Listener struct { 16 closed bool 17 config LC.ShadowsocksServer 18 listeners []net.Listener 19 udpListeners []*UDPListener 20 pickCipher core.Cipher 21 } 22 23 var _listener *Listener 24 25 func New(config LC.ShadowsocksServer, tunnel C.Tunnel) (*Listener, error) { 26 pickCipher, err := core.PickCipher(config.Cipher, nil, config.Password) 27 if err != nil { 28 return nil, err 29 } 30 31 sl := &Listener{false, config, nil, nil, pickCipher} 32 _listener = sl 33 34 for _, addr := range strings.Split(config.Listen, ",") { 35 addr := addr 36 37 if config.Udp { 38 //UDP 39 ul, err := NewUDP(addr, pickCipher, tunnel) 40 if err != nil { 41 return nil, err 42 } 43 sl.udpListeners = append(sl.udpListeners, ul) 44 } 45 46 //TCP 47 l, err := inbound.Listen("tcp", addr) 48 if err != nil { 49 return nil, err 50 } 51 sl.listeners = append(sl.listeners, l) 52 53 go func() { 54 for { 55 c, err := l.Accept() 56 if err != nil { 57 if sl.closed { 58 break 59 } 60 continue 61 } 62 N.TCPKeepAlive(c) 63 go sl.HandleConn(c, tunnel) 64 } 65 }() 66 } 67 68 return sl, nil 69 } 70 71 func (l *Listener) Close() error { 72 var retErr error 73 for _, lis := range l.listeners { 74 err := lis.Close() 75 if err != nil { 76 retErr = err 77 } 78 } 79 for _, lis := range l.udpListeners { 80 err := lis.Close() 81 if err != nil { 82 retErr = err 83 } 84 } 85 return retErr 86 } 87 88 func (l *Listener) Config() string { 89 return l.config.String() 90 } 91 92 func (l *Listener) AddrList() (addrList []net.Addr) { 93 for _, lis := range l.listeners { 94 addrList = append(addrList, lis.Addr()) 95 } 96 for _, lis := range l.udpListeners { 97 addrList = append(addrList, lis.LocalAddr()) 98 } 99 return 100 } 101 102 func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) { 103 conn = l.pickCipher.StreamConn(conn) 104 conn = N.NewDeadlineConn(conn) // embed ss can't handle readDeadline correctly 105 106 target, err := socks5.ReadAddr0(conn) 107 if err != nil { 108 _ = conn.Close() 109 return 110 } 111 tunnel.HandleTCPConn(inbound.NewSocket(target, conn, C.SHADOWSOCKS, additions...)) 112 } 113 114 func HandleShadowSocks(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) bool { 115 if _listener != nil && _listener.pickCipher != nil { 116 go _listener.HandleConn(conn, tunnel, additions...) 117 return true 118 } 119 return false 120 }