github.com/yaling888/clash@v1.53.0/listener/socks/tcp.go (about) 1 package socks 2 3 import ( 4 "io" 5 "net" 6 7 "github.com/yaling888/clash/adapter/inbound" 8 N "github.com/yaling888/clash/common/net" 9 "github.com/yaling888/clash/component/auth" 10 C "github.com/yaling888/clash/constant" 11 authStore "github.com/yaling888/clash/listener/auth" 12 "github.com/yaling888/clash/transport/socks4" 13 "github.com/yaling888/clash/transport/socks5" 14 ) 15 16 type Listener struct { 17 listener net.Listener 18 addr string 19 auth auth.Authenticator 20 closed bool 21 } 22 23 // RawAddress implements C.Listener 24 func (l *Listener) RawAddress() string { 25 return l.addr 26 } 27 28 // Address implements C.Listener 29 func (l *Listener) Address() string { 30 return l.listener.Addr().String() 31 } 32 33 // Close implements C.Listener 34 func (l *Listener) Close() error { 35 l.closed = true 36 return l.listener.Close() 37 } 38 39 // SetAuthenticator implements C.AuthenticatorListener 40 func (l *Listener) SetAuthenticator(users []auth.AuthUser) { 41 l.auth = auth.NewAuthenticator(users) 42 } 43 44 func New(addr string, in chan<- C.ConnContext) (C.Listener, error) { 45 l, err := net.Listen("tcp", addr) 46 if err != nil { 47 return nil, err 48 } 49 50 sl := &Listener{ 51 listener: l, 52 addr: addr, 53 } 54 go func() { 55 for { 56 c, err := l.Accept() 57 if err != nil { 58 if sl.closed { 59 break 60 } 61 continue 62 } 63 go handleSocks(c, in, sl.auth) 64 } 65 }() 66 67 return sl, nil 68 } 69 70 func New4(addr string, in chan<- C.ConnContext) (C.Listener, error) { 71 l, err := net.Listen("tcp", addr) 72 if err != nil { 73 return nil, err 74 } 75 76 sl := &Listener{ 77 listener: l, 78 addr: addr, 79 } 80 go func() { 81 for { 82 c, err := l.Accept() 83 if err != nil { 84 if sl.closed { 85 break 86 } 87 continue 88 } 89 _ = c.(*net.TCPConn).SetKeepAlive(true) 90 go HandleSocks4(c, in, sl.auth) 91 } 92 }() 93 94 return sl, nil 95 } 96 97 func New5(addr string, in chan<- C.ConnContext) (C.Listener, error) { 98 l, err := net.Listen("tcp", addr) 99 if err != nil { 100 return nil, err 101 } 102 103 sl := &Listener{ 104 listener: l, 105 addr: addr, 106 } 107 go func() { 108 for { 109 c, err := l.Accept() 110 if err != nil { 111 if sl.closed { 112 break 113 } 114 continue 115 } 116 _ = c.(*net.TCPConn).SetKeepAlive(true) 117 go HandleSocks5(c, in, sl.auth) 118 } 119 }() 120 121 return sl, nil 122 } 123 124 func handleSocks(conn net.Conn, in chan<- C.ConnContext, auth auth.Authenticator) { 125 _ = conn.(*net.TCPConn).SetKeepAlive(true) 126 bufConn := N.NewBufferedConn(conn) 127 head, err := bufConn.Peek(1) 128 if err != nil { 129 _ = conn.Close() 130 return 131 } 132 133 switch head[0] { 134 case socks4.Version: 135 HandleSocks4(bufConn, in, auth) 136 case socks5.Version: 137 HandleSocks5(bufConn, in, auth) 138 default: 139 _ = conn.Close() 140 } 141 } 142 143 func HandleSocks4(conn net.Conn, in chan<- C.ConnContext, auth auth.Authenticator) { 144 authenticator := auth 145 if authenticator == nil { 146 authenticator = authStore.Authenticator() 147 } 148 addr, _, err := socks4.ServerHandshake(conn, authenticator) 149 if err != nil { 150 _ = conn.Close() 151 return 152 } 153 in <- inbound.NewSocket(socks5.ParseAddr(addr), conn, C.SOCKS4) 154 } 155 156 func HandleSocks5(conn net.Conn, in chan<- C.ConnContext, auth auth.Authenticator) { 157 authenticator := auth 158 if authenticator == nil { 159 authenticator = authStore.Authenticator() 160 } 161 target, command, err := socks5.ServerHandshake(conn, authenticator) 162 if err != nil { 163 _ = conn.Close() 164 return 165 } 166 if command == socks5.CmdUDPAssociate { 167 _, _ = io.Copy(io.Discard, conn) 168 _ = conn.Close() 169 return 170 } 171 in <- inbound.NewSocket(target, conn, C.SOCKS5) 172 }