Skip to content
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 critical bugs in session opening for TCP and UDP in case of Singleplex mode. #145

Merged
merged 5 commits into from
Dec 19, 2020

Conversation

notsure2
Copy link
Contributor

  • In case of TCP, don't open the session in the listener accept thread. This
    causes resource exhaustion of the tcp listener backlog queue in case of internet
    connection disruption or timeout.

  • In case of UDP, don't create a new session for every UDP packet.

This also fixes cbeuw/Cloak-android#17 and corrects a lot of wrong behaviors.
@cbeuw Please check and merge, and I recommend a new release.

…eplex mode.

- In case of TCP, don't open the session in the listener accept thread. This
  causes resource exhaustion of the tcp listener backlog queue in case of internet
  connection disruption or timeout.

- In case of UDP, don't create a new session for every UDP packet.
@notsure2
Copy link
Contributor Author

Travis says there's a data race in the integration test, but I think it's a bug in the test.

@codecov
Copy link

codecov bot commented Dec 14, 2020

Codecov Report

Merging #145 (6b6b1b3) into master (7b6a82b) will decrease coverage by 0.14%.
The diff coverage is 33.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #145      +/-   ##
==========================================
- Coverage   67.62%   67.48%   -0.15%     
==========================================
  Files          37       37              
  Lines        2400     2405       +5     
==========================================
  Hits         1623     1623              
- Misses        615      618       +3     
- Partials      162      164       +2     
Impacted Files Coverage Δ
cmd/ck-client/ck-client.go 0.00% <0.00%> (ø)
internal/client/piper.go 45.56% <44.44%> (+0.23%) ⬆️
internal/multiplex/streamBufferedPipe.go 90.54% <0.00%> (-2.71%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7b6a82b...6b6b1b3. Read the comment docs.

@cbeuw
Copy link
Owner

cbeuw commented Dec 18, 2020

Sorry it took me a while to get back to this. I agree that for singleplexing TCP, the new session function should be called inside the newly created goroutine. The behaviour with UDP is slightly trickier because there isn't a strict sense of connection. Currently Cloak assumes each incoming ip:port pair represents a "connection", which may not be correct to begin with

@cbeuw
Copy link
Owner

cbeuw commented Dec 18, 2020

The race condition also exists here, where SessionId in authInfo is written to. Previously this seshMaker() is always called by a single goroutine so this is fine, now we need to copy authInfo from the outside scope to a local variable

seshMaker = func() *mux.Session {
// sessionID is usergenerated. There shouldn't be a security concern because the scope of
// sessionID is limited to its UID.
quad := make([]byte, 4)
common.RandRead(authInfo.WorldState.Rand, quad)
authInfo.SessionId = binary.BigEndian.Uint32(quad)
return client.MakeSession(remoteConfig, authInfo, d)
}

@cbeuw
Copy link
Owner

cbeuw commented Dec 18, 2020

Just some small changes - passing newSeshFunc as an argument to the goroutine function isn't necessary because we are not mutating the variable, we are only reading it. Also I don't think the explicit variable of multiplexSession is necessary. For TCP, the variable becomes local on entry to the goroutine function (despite the name shadowing), and for UDP there isn't any concurrency in session opening anyway. I hope that still gives the right behaviours

@notsure2
Copy link
Contributor Author

notsure2 commented Dec 19, 2020

Just some small changes - passing newSeshFunc as an argument to the goroutine function isn't necessary because we are not mutating the variable, we are only reading it.

I considered it as an optimization to avoid allocation of an object to hold the variables captured in the closure, passing it as a parameter reduces memory use (object allocation on every time the goroutine is called).

Also I don't think the explicit variable of multiplexSession is necessary. For TCP, the variable becomes local on entry to the goroutine function (despite the name shadowing),

It is not technically necessary but it makes the code clearer and it clarifies the intention of what we are doing.

And for UDP there isn't any concurrency in session opening anyway.

The problem in UDP was that it was opening a new session for every packet, not a concurrency issue.

I hope that still gives the right behaviours.

I will review and test.

@notsure2
Copy link
Contributor Author

@cbeuw ok i tested tcp singleplex and multiplex, udp singleplex and multiplex and seems to work.

@cbeuw cbeuw merged commit cfbf0df into cbeuw:master Dec 19, 2020
@notsure2 notsure2 deleted the fix-blocking-make-session branch December 19, 2020 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cloak android stops working after a period of idle or when the server is restarted
2 participants