socks5 matcher not working
munding opened this issue · 2 comments
I wrote a socks5 matcher like TLS,just match one byte
func SOCKS5(versions ...int) Matcher {
if len(versions) == 0 {
versions = []int{
0x05,
}
}
prefixes := [][]byte{}
for _, v := range versions {
prefixes = append(prefixes, []byte{byte(v)})
}
return prefixByteMatcher(prefixes...)
}
when I put socks5 matcher after HTTP1Fast
matcher, it is not working, not reach the socks5 server handler
but put it before http matcher, it's working
// failed!
httpL := m.Match(cmux.HTTP1FastOptions())
socksL := m.Match(cmux.SOCKS5())
I also found this problem. After reading the code, I found this problem: HTTP1 Matcher tried to read a line and match it in the form of a newline character, while requests like socks did not contain a newline character.
This causes all HTTP1 Matchers to be blocked.
Related code:
Lines 93 to 94 in 5ec6847
I also read the code. HTTP1Fast
use prefixByteMatcher
, then use ReadAtLeast(r Reader, buf []byte, min int)
min
is the max length of HTTP method(CONNECT
or OPTIONS
, just 7 bytes), so it needs to read at least 7 bytes.
but socks first payload usually less than 7 bytes,so it is blocked...
socks5 proto fist payload at least 3 bytes, like below:
# +----+----------+----------+
# |VER | NMETHODS | METHODS |
# +----+----------+----------+
# | 1 | 1 | 1 to 255 |
# +----+----------+----------+
so i change the defaultHTTPMethods
like this (just 3 bytes):
var defaultSimpleHTTPMethods = []string{
"OPT", //OPTIONS
"GET", //GET
"HEA", //HEAD
"POS", //POST
"PUT", //PUT
"DEL", //DELETE
"TRA", //TRACE
"CON", //CONNECT
}