@@ -11,6 +11,7 @@ import (
1111 "net/url"
1212 "os"
1313 "strconv"
14+ "strings"
1415
1516 "github.com/gorilla/websocket"
1617 uuid "github.com/satori/go.uuid"
@@ -46,91 +47,125 @@ func main() {
4647 go handleConnection (conn )
4748 }
4849}
50+ func convertToMap (input string ) map [string ]string {
51+ result := make (map [string ]string )
52+
53+ lines := strings .Split (input , "\n " )
54+ for _ , line := range lines {
55+ parts := strings .SplitN (line , ": " , 2 )
56+ if len (parts ) == 2 {
57+ result [strings .ToLower (strings .TrimSpace (parts [0 ]))] = strings .TrimSpace (parts [1 ])
58+ }
59+ }
60+
61+ return result
62+ }
4963
5064func handleConnection (clientConn net.Conn ) {
5165 defer clientConn .Close ()
5266
5367 // Step 1: Version identification and authentication
5468 // Read and verify the SOCKS5 initial handshake message
5569 buf := make ([]byte , 257 )
56- _ , err := io .ReadAtLeast (clientConn , buf , 2 )
70+ nbytes , err := io .ReadAtLeast (clientConn , buf , 2 )
5771 if err != nil {
5872 log .Printf ("Failed to read client handshake: %v" , err )
5973 return
6074 }
75+ _ = nbytes
6176
77+ var destAddr string
78+ var destPort string
79+ isSocks5 := false
80+ isHttps := false
6281 // Check SOCKS version and authentication methods
63- if buf [0 ] != 0x05 {
64- log .Printf ("Unsupported SOCKS version: %v" , buf [0 ])
65- return
66- }
82+ if buf [0 ] == 0x05 {
83+ isSocks5 = true
84+ // Number of authentication methods supported
85+ numMethods := int (buf [1 ])
86+ authMethods := buf [2 : 2 + numMethods ]
6787
68- // Number of authentication methods supported
69- numMethods := int (buf [1 ])
70- authMethods := buf [2 : 2 + numMethods ]
88+ // Check if "no authentication" method (0x00) is supported
89+ noAuth := false
90+ for _ , m := range authMethods {
91+ if m == 0x00 {
92+ noAuth = true
93+ break
94+ }
95+ }
7196
72- // Check if "no authentication" method (0x00) is supported
73- noAuth := false
74- for _ , m := range authMethods {
75- if m == 0x00 {
76- noAuth = true
77- break
97+ if ! noAuth {
98+ log .Printf ("No supported authentication methods" )
99+ // Send handshake failure response to client
100+ clientConn .Write ([]byte {0x05 , 0xFF })
101+ return
78102 }
79- }
80103
81- if ! noAuth {
82- log .Printf ("No supported authentication methods" )
83- // Send handshake failure response to client
84- clientConn .Write ([]byte {0x05 , 0xFF })
85- return
86- }
104+ // Send handshake response to client indicating "no authentication" method
105+ clientConn .Write ([]byte {0x05 , 0x00 })
87106
88- // Send handshake response to client indicating "no authentication" method
89- clientConn .Write ([]byte {0x05 , 0x00 })
107+ // Step 2: Request processing
108+ // Read and verify the SOCKS5 request
109+ _ , err = io .ReadAtLeast (clientConn , buf , 4 )
110+ if err != nil {
111+ log .Printf ("Failed to read client request: %v" , err )
112+ return
113+ }
90114
91- // Step 2: Request processing
92- // Read and verify the SOCKS5 request
93- _ , err = io .ReadAtLeast (clientConn , buf , 4 )
94- if err != nil {
95- log .Printf ("Failed to read client request: %v" , err )
96- return
97- }
115+ if buf [0 ] != 0x05 {
116+ log .Printf ("Unsupported SOCKS version: %v" , buf [0 ])
117+ return
118+ }
98119
99- if buf [0 ] != 0x05 {
100- log .Printf ("Unsupported SOCKS version : %v" , buf [0 ])
101- return
102- }
120+ if buf [1 ] != 0x01 {
121+ log .Printf ("Unsupported command : %v" , buf [1 ])
122+ return
123+ }
103124
104- if buf [1 ] != 0x01 {
105- log .Printf ("Unsupported command: %v" , buf [1 ])
106- return
107- }
125+ // Check the address type
126+ switch buf [3 ] {
127+ case 0x01 : // IPv4 address
128+ ip := net .IP (buf [4 : 4 + net .IPv4len ])
129+ destAddr = ip .String ()
130+ destPort = fmt .Sprintf ("%d" , int (buf [8 ])<< 8 + int (buf [9 ]))
131+ case 0x03 : // Domain name
132+ domainLen := int (buf [4 ])
133+ domain := string (buf [5 : 5 + domainLen ])
134+ destAddr = domain
135+ destPort = strconv .Itoa (int (buf [5 + domainLen ])<< 8 + int (buf [5 + domainLen + 1 ]))
136+ case 0x04 : // IPv6 address
137+ ip := net .IP (buf [4 : 4 + net .IPv6len ])
138+ destAddr = ip .String ()
139+ destPort = strconv .Itoa (int (buf [20 ])<< 8 + int (buf [21 ]))
140+ default :
141+ log .Printf ("Unsupported address type: %v" , buf [3 ])
142+ return
143+ }
108144
109- // Check the address type
110- var destAddr string
111- var destPort string
112- switch buf [3 ] {
113- case 0x01 : // IPv4 address
114- ip := net .IP (buf [4 : 4 + net .IPv4len ])
115- destAddr = ip .String ()
116- destPort = fmt .Sprintf ("%d" , int (buf [8 ])<< 8 + int (buf [9 ]))
117- case 0x03 : // Domain name
118- domainLen := int (buf [4 ])
119- domain := string (buf [5 : 5 + domainLen ])
120- destAddr = domain
121- destPort = strconv .Itoa (int (buf [5 + domainLen ])<< 8 + int (buf [5 + domainLen + 1 ]))
122- case 0x04 : // IPv6 address
123- ip := net .IP (buf [4 : 4 + net .IPv6len ])
124- destAddr = ip .String ()
125- destPort = strconv .Itoa (int (buf [20 ])<< 8 + int (buf [21 ]))
126- default :
127- log .Printf ("Unsupported address type: %v" , buf [3 ])
128- return
145+ // Send request response to client indicating success
146+ clientConn .Write ([]byte {0x05 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 })
147+ } else if (buf [0 ] == 'G' && buf [1 ] == 'E' ) || (buf [0 ] == 'P' && buf [1 ] == 'O' ) || (buf [0 ] == 'O' && buf [1 ] == 'P' ) || (buf [0 ] == 'P' && buf [1 ] == 'U' ) || (buf [0 ] == 'D' && buf [1 ] == 'E' ) || (buf [0 ] == 'H' && buf [1 ] == 'E' ) || (buf [0 ] == 'T' && buf [1 ] == 'R' ) {
148+ r := convertToMap (string (buf [:nbytes ]))
149+ hosts := r ["host" ]
150+ if strings .Index (hosts , ":" ) == - 1 {
151+ destAddr = hosts
152+ destPort = "80"
153+ } else {
154+ destAddr = strings .Split (hosts , ":" )[0 ]
155+ destPort = strings .Split (hosts , ":" )[1 ]
156+ }
157+ } else if buf [0 ] == 'C' && buf [1 ] == 'O' {
158+ isHttps = true
159+ r := convertToMap (string (buf [:nbytes ]))
160+ hosts := r ["host" ]
161+ if strings .Index (hosts , ":" ) == - 1 {
162+ destAddr = hosts
163+ destPort = "443"
164+ } else {
165+ destAddr = strings .Split (hosts , ":" )[0 ]
166+ destPort = strings .Split (hosts , ":" )[1 ]
167+ }
129168 }
130-
131- // Send request response to client indicating success
132- clientConn .Write ([]byte {0x05 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 })
133-
134169 u := url.URL {
135170 Scheme : "ws" ,
136171 Host : * wsServer ,
@@ -175,6 +210,15 @@ func handleConnection(clientConn net.Conn) {
175210 clientConn .Close ()
176211 return
177212 }
213+ if isHttps {
214+ clientConn .Write ([]byte ("HTTP/1.1 200 Connection Established\r \n \r \n " ))
215+ }
216+ if false == isSocks5 && false == isHttps {
217+ err = ws .Conn .WriteJSON (common.Proto {MsgType : common .ReqData , Data : buf [:nbytes ]})
218+ if err != nil {
219+ log .Printf ("[%s]Failed to send http data to WebSocket server: %v" , msgId , err )
220+ }
221+ }
178222 go func () {
179223 resp := common.Proto {}
180224 for {
0 commit comments