@@ -43,9 +43,6 @@ const (
43
43
// MaxAddrLen is the maximum size of SOCKS address in bytes.
44
44
const MaxAddrLen = 1 + 1 + 255 + 2
45
45
46
- // MaxReqLen is the maximum size of SOCKS request in bytes.
47
- const MaxReqLen = 1 + 1 + 1 + MaxAddrLen
48
-
49
46
// Addr represents a SOCKS address as defined in RFC 1928 section 5.
50
47
type Addr []byte
51
48
@@ -68,9 +65,10 @@ func (a Addr) String() string {
68
65
return net .JoinHostPort (host , port )
69
66
}
70
67
71
- // ReadAddr reads just enough bytes from r to get a valid Addr.
72
- func ReadAddr (r io.Reader ) (Addr , error ) {
73
- b := make ([]byte , MaxAddrLen )
68
+ func readAddr (r io.Reader , b []byte ) (Addr , error ) {
69
+ if len (b ) < MaxAddrLen {
70
+ return nil , io .ErrShortBuffer
71
+ }
74
72
_ , err := io .ReadFull (r , b [:1 ]) // read 1st byte for address type
75
73
if err != nil {
76
74
return nil , err
@@ -95,6 +93,11 @@ func ReadAddr(r io.Reader) (Addr, error) {
95
93
return nil , ErrAddressNotSupported
96
94
}
97
95
96
+ // ReadAddr reads just enough bytes from r to get a valid Addr.
97
+ func ReadAddr (r io.Reader ) (Addr , error ) {
98
+ return readAddr (r , make ([]byte , MaxAddrLen ))
99
+ }
100
+
98
101
// SplitAddr slices a SOCKS address from beginning of b. Returns nil if failed.
99
102
func SplitAddr (b []byte ) Addr {
100
103
addrLen := 1
@@ -163,29 +166,32 @@ func ParseAddr(s string) Addr {
163
166
164
167
// Handshake fast-tracks SOCKS initialization to get target address to connect.
165
168
func Handshake (rw io.ReadWriter ) (Addr , error ) {
166
- // Read RFC 1928 section 4 for request and reply structure and sizes
167
- buf := make ([]byte , MaxReqLen )
168
-
169
- _ , err := rw .Read (buf ) // SOCKS version and auth methods
170
- if err != nil {
169
+ // Read RFC 1928 for request and reply structure and sizes.
170
+ buf := make ([]byte , MaxAddrLen )
171
+ // read VER, NMETHODS, METHODS
172
+ if _ , err := io .ReadFull (rw , buf [:2 ]); err != nil {
171
173
return nil , err
172
174
}
173
-
174
- _ , err = rw .Write ([]byte {5 , 0 }) // SOCKS v5, no auth required
175
- if err != nil {
175
+ nmethods := buf [1 ]
176
+ if _ , err := io .ReadFull (rw , buf [:nmethods ]); err != nil {
176
177
return nil , err
177
178
}
178
-
179
- n , err := rw .Read (buf ) // SOCKS request: VER, CMD, RSV, Addr
180
- if err != nil {
179
+ // write VER METHOD
180
+ if _ , err := rw .Write ([]byte {5 , 0 }); err != nil {
181
+ return nil , err
182
+ }
183
+ // read VER CMD RSV ATYP DST.ADDR DST.PORT
184
+ if _ , err := io .ReadFull (rw , buf [:3 ]); err != nil {
181
185
return nil , err
182
186
}
183
- buf = buf [:n ]
184
-
185
187
if buf [1 ] != CmdConnect {
186
188
return nil , ErrCommandNotSupported
187
189
}
188
-
189
- _ , err = rw .Write ([]byte {5 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 }) // SOCKS v5, reply succeeded
190
- return buf [3 :], err // skip VER, CMD, RSV fields
190
+ addr , err := readAddr (rw , buf )
191
+ if err != nil {
192
+ return nil , err
193
+ }
194
+ // write VER REP RSV ATYP BND.ADDR BND.PORT
195
+ _ , err = rw .Write ([]byte {5 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 })
196
+ return addr , err
191
197
}
0 commit comments