-
Notifications
You must be signed in to change notification settings - Fork 4.9k
fix false success from SOCKS server when Dispatch() fails #3431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix false success from SOCKS server when Dispatch() fails #3431
Conversation
2676d11 to
e84d5c7
Compare
|
Thanks for your contribution. Would you mind making this behavior adjustable via a configuration flag? The reason socks inbound return an successful reply to the remote end before the link is actually setup is there to make sure that the initial content of traffic is available for 1. routing decisions, 2. bundling protocol handshake with first payload message to reduce rtt and fingerprint overhead-free. For those reasons, the current behavior is the default and expected action for a specific reasons, and cannot be changed without impacting existing use cases. I assume you wish to know whether a connection has been successfully created before sending traffic content that lacks reentrancy, and I am happy to discuss alternative solution of the issue you are interested. |
|
I got your point. Give me some time |
|
Not sure if it's easy to do in v2ray, but in my project shadowsocks-go, the behavior is determined by a config option Of course, in v2ray this would be further complicated by the potential use of sniffers, whereas in shadowsocks-go the router does not consume payload. |
|
Also you might want to implement the same thing for HTTP CONNECT requests. |
Thanks @database64128. In my opinion due to V2Ray's complexity, I don't recommend any contributor to implement such feature as it would require specialized knowledge and tools to implement it correctly, and significantly increase the difficulty to make application's behavior predictable.
If such thing does get implemented, please submit under a separate pull request. |
Postpone SOCKS server ok reply to a TCP Connect command until Dispatch() actually creates an upstream Link. Previously it was sent immediately inside Handshake(). UDP works as before.
e84d5c7 to
992d5d8
Compare
|
I added a flag to ServerConfig. |
xiaokangwang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! I think this pill request is ready to be merged.
Thanks, but this is v5 config only, right? {
"tag": "socks-1080",
"protocol": "socks",
"listen": "0.0.0.0",
"port": 1080,
"settings": {
"auth": "noauth",
"udp": true,
"DeferLastReply": true
},
"sniffing": {
"enabled": true,
"destOverride": ["fakedns"],
"metadataOnly": true
},
"streamSettings": {
"sockopt": {
"tcpFastOpen": true,
"mptcp": true
}
}
}, |
|
@4-FLOSS-Free-Libre-Open-Source-Software
Are you asking will it work with socks4? Yes. Both protocol-specific handshake functions setup their own callbacks that send the Last Reply. |
|
Sorry that my message was not clear. Of course, I do NOT want to use an older version than socks5 (ipv6+hostname support). I was asking if this is only working in version 5 of v2ray configuration or in json v4 too? |
| } | ||
| closeInDefer = false | ||
| } else { | ||
| d.serverSession.flushLastReply(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In handshakeFinalizingDispatcher.Dispatch, if d.serverSession.flushLastReply(false) returns an error, it is ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this error is unimportant because we're about to return the upstream error. The downstream will be closed anyway by the caller.
| } | ||
|
|
||
| // Sets the callback and calls or postpones it based on the boolean field | ||
| func (s *ServerSession) setupLastReply(callback func(bool) error) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setupLastReply function sets up a stateful callback (flushLastReply) that is intended to be called exactly once. However, if flushLastReply is called multiple times (with different boolean values), only the first call will have effect, and subsequent calls will be no-ops?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
Okay, I didn't dive into this because in my project I don't use config files and just configure the socks server programmatically. Can you post the v4 config you're stuck with? The v5cfg and v4 both use RawMessage for settings, maybe it will just work. |
Postpone SOCKS server ok reply to a TCP Connect command until Dispatch() actually creates an upstream Link. Previously it was sent immediately inside Handshake(). UDP works as before.
Tested in a standalone go program that only starts a V2Ray SOCKS server.
before:
Results(V5): Succeeded (0)after:
_

Results(V5): Connection refused (5)