[GH-ISSUE #74] Random unable make connection through the cloak #65

Closed
opened 2026-02-26 12:33:52 +03:00 by kerem · 17 comments
Owner

Originally created by @chenshaoju on GitHub (Nov 5, 2019).
Original GitHub issue: https://github.com/cbeuw/Cloak/issues/74

Sorry for my English.

Server: Debian 10 x64 (shadowsocks-libev 3.2.5)
Client: Windows 7 x64 (shadowsocks-windows 4.1.8.0)
Cloak Version: Build from source (commits 293)

I notice there is a random issue when used with shadowsocks.

Sometimes, Client requests through the local proxy randomly timeout or unable connection to the target server, For firefox is "The connection has timed out" or "Secure Connection Failed",if refresh page 1~2 times will working again.

In my using environment, aways has active connections, maybe there is some request conflict or something else?

Here is a screenshot from curl:
log2

Here is log with the screenshot:

time="2019-11-05T10:03:07+08:00" level=trace msg="65 sent to remote through stream 3733 with err <nil>"
time="2019-11-05T10:03:07+08:00" level=trace msg="2082 read from stream 3733 with err <nil>"
time="2019-11-05T10:03:07+08:00" level=trace msg="2082 sent to remote through stream 3511 with err <nil>"
time="2019-11-05T10:03:07+08:00" level=trace msg="345 sent to remote through stream 3511 with err <nil>"
time="2019-11-05T10:03:07+08:00" level=trace msg="2332 read from stream 3733 with err <nil>"
time="2019-11-05T10:03:07+08:00" level=trace msg="73 sent to remote through stream 3733 with err <nil>"
time="2019-11-05T10:03:07+08:00" level=trace msg="58 sent to remote through stream 3733 with err <nil>"
time="2019-11-05T10:03:07+08:00" level=trace msg="stream 3733 actively closed"
time="2019-11-05T10:03:08+08:00" level=trace msg="stream 3734 of session 1215570355 opened"		(Start Here)
time="2019-11-05T10:03:08+08:00" level=trace msg="84 sent to remote through stream 3734 with err <nil>"
time="2019-11-05T10:03:09+08:00" level=trace msg="551 sent to remote through stream 3734 with err <nil>"
time="2019-11-05T10:03:09+08:00" level=trace msg="577 sent to remote through stream 272 with err <nil>"
time="2019-11-05T10:03:11+08:00" level=trace msg="577 read from stream 272 with err <nil>"
time="2019-11-05T10:03:11+08:00" level=trace msg="1494 read from stream 3511 with err <nil>"
time="2019-11-05T10:03:16+08:00" level=trace msg="577 read from stream 272 with err <nil>"
time="2019-11-05T10:03:21+08:00" level=trace msg="stream 3734 actively closed"				(End Here)
time="2019-11-05T10:03:22+08:00" level=trace msg="86 read from stream 3583 with err <nil>"
time="2019-11-05T10:03:23+08:00" level=trace msg="577 sent to remote through stream 272 with err <nil>"
time="2019-11-05T10:03:23+08:00" level=trace msg="stream 3735 of session 1215570355 opened"
time="2019-11-05T10:03:23+08:00" level=trace msg="85 sent to remote through stream 3735 with err <nil>"
time="2019-11-05T10:03:23+08:00" level=trace msg="213 sent to remote through stream 3735 with err <nil>"

PS: maybe from Start here to End here is curl requesting.

Here is a GIF demo when the issue happened(Click for zoom):
log2_ready

Server configure:

{
  "ProxyBook": {
  },
  "RedirAddr": "111.111.111.111",
  "PrivateKey": "1111111111111111111111111",
  "BypassUID": [
    "1111111111111111111111"
    ],
  "AdminUID": "111111111111111111111",
  "DatabasePath": "/var/cloak/userinfo.db"
}

Client configure:

{
	"Transport":"direct",
	"ProxyMethod":"shadowsocks",
	"EncryptionMethod":"plain",
	"UID":"1111111111111111111111",
	"PublicKey":"11111111111111111111111111",
	"ServerName":"111111111111111",
	"NumConn":6,
	"BrowserSig":"chrome",
	"StreamTimeout":300
}

PS: I try increase NumConn to 12,But unable solve this issue.

If need any information, please feel free to ask.

Thank you.

Originally created by @chenshaoju on GitHub (Nov 5, 2019). Original GitHub issue: https://github.com/cbeuw/Cloak/issues/74 Sorry for my English. Server: Debian 10 x64 (shadowsocks-libev 3.2.5) Client: Windows 7 x64 (shadowsocks-windows 4.1.8.0) Cloak Version: Build from source (commits 293) I notice there is a random issue when used with shadowsocks. Sometimes, Client requests through the local proxy randomly timeout or unable connection to the target server, For firefox is "The connection has timed out" or "Secure Connection Failed",if refresh page 1~2 times will working again. In my using environment, aways has active connections, maybe there is some request conflict or something else? Here is a screenshot from curl: ![log2](https://user-images.githubusercontent.com/515763/68175122-27033680-ffbb-11e9-841b-f6afae572935.png) Here is log with the screenshot: ``` time="2019-11-05T10:03:07+08:00" level=trace msg="65 sent to remote through stream 3733 with err <nil>" time="2019-11-05T10:03:07+08:00" level=trace msg="2082 read from stream 3733 with err <nil>" time="2019-11-05T10:03:07+08:00" level=trace msg="2082 sent to remote through stream 3511 with err <nil>" time="2019-11-05T10:03:07+08:00" level=trace msg="345 sent to remote through stream 3511 with err <nil>" time="2019-11-05T10:03:07+08:00" level=trace msg="2332 read from stream 3733 with err <nil>" time="2019-11-05T10:03:07+08:00" level=trace msg="73 sent to remote through stream 3733 with err <nil>" time="2019-11-05T10:03:07+08:00" level=trace msg="58 sent to remote through stream 3733 with err <nil>" time="2019-11-05T10:03:07+08:00" level=trace msg="stream 3733 actively closed" time="2019-11-05T10:03:08+08:00" level=trace msg="stream 3734 of session 1215570355 opened" (Start Here) time="2019-11-05T10:03:08+08:00" level=trace msg="84 sent to remote through stream 3734 with err <nil>" time="2019-11-05T10:03:09+08:00" level=trace msg="551 sent to remote through stream 3734 with err <nil>" time="2019-11-05T10:03:09+08:00" level=trace msg="577 sent to remote through stream 272 with err <nil>" time="2019-11-05T10:03:11+08:00" level=trace msg="577 read from stream 272 with err <nil>" time="2019-11-05T10:03:11+08:00" level=trace msg="1494 read from stream 3511 with err <nil>" time="2019-11-05T10:03:16+08:00" level=trace msg="577 read from stream 272 with err <nil>" time="2019-11-05T10:03:21+08:00" level=trace msg="stream 3734 actively closed" (End Here) time="2019-11-05T10:03:22+08:00" level=trace msg="86 read from stream 3583 with err <nil>" time="2019-11-05T10:03:23+08:00" level=trace msg="577 sent to remote through stream 272 with err <nil>" time="2019-11-05T10:03:23+08:00" level=trace msg="stream 3735 of session 1215570355 opened" time="2019-11-05T10:03:23+08:00" level=trace msg="85 sent to remote through stream 3735 with err <nil>" time="2019-11-05T10:03:23+08:00" level=trace msg="213 sent to remote through stream 3735 with err <nil>" ``` PS: maybe from `Start here` to `End here` is curl requesting. Here is a GIF demo when the issue happened(Click for zoom): ![log2_ready](https://user-images.githubusercontent.com/515763/68175243-8feaae80-ffbb-11e9-88e6-ed72c8d06c70.gif) Server configure: ``` { "ProxyBook": { }, "RedirAddr": "111.111.111.111", "PrivateKey": "1111111111111111111111111", "BypassUID": [ "1111111111111111111111" ], "AdminUID": "111111111111111111111", "DatabasePath": "/var/cloak/userinfo.db" } ``` Client configure: ``` { "Transport":"direct", "ProxyMethod":"shadowsocks", "EncryptionMethod":"plain", "UID":"1111111111111111111111", "PublicKey":"11111111111111111111111111", "ServerName":"111111111111111", "NumConn":6, "BrowserSig":"chrome", "StreamTimeout":300 } ``` PS: I try increase `NumConn` to 12,But unable solve this issue. If need any information, please feel free to ask. Thank you.
kerem closed this issue 2026-02-26 12:33:52 +03:00
Author
Owner

@notsure2 commented on GitHub (Dec 11, 2019):

@cbeuw

I am also facing this problem. It is easy to trigger it. Set NumConn = 1 and then start and cancel wget on a large file many times. With trace logging I see that the bytes are sent but then no response is ever received by the client and the connection stalls. With the server also on trace logging, I can see that the server read the bytes sent by the client and sent 2 responses, but the client doesn't process the response and hangs. Maybe it is a problem of buffer flushing ? or goroutine starvation ? (noob at go, forgive me if I am mistaken, just throwing an idea).

When this condition happens it seems the entire session hangs. Any future tcp connection hangs in the same way (bytes sent but response never processed) on the tcp connection in the session until the session is closed on the server.

Server log at the moment this happens:

TRAC[0328] 1141 sent to remote through stream 5 with err <nil>
TRAC[0328] 2082 sent to remote through stream 5 with err <nil>
TRAC[0328] 2082 sent to remote through stream 5 with err <nil>
TRAC[0328] 16378 sent to remote through stream 5 with err <nil>
TRAC[0328] 16378 sent to remote through stream 5 with err <nil>
TRAC[0328] 16378 sent to remote through stream 5 with err <nil>
TRAC[0328] 16349 sent to remote through stream 5 with err <nil>
TRAC[0328] 1141 sent to remote through stream 5 with err <nil>
TRAC[0328] 16378 sent to remote through stream 5 with err <nil>
TRAC[0328] 16378 sent to remote through stream 5 with err <nil>
TRAC[0328] 16378 sent to remote through stream 5 with err <nil>
TRAC[0328] 11897 sent to remote through stream 5 with err <nil>
TRAC[0328] stream 5 actively closed
(cancelled wget)
TRAC[0328] session 1824863800 has no active stream left
(wget started again)
TRAC[0329] stream 6 of session 1824863800 accepted
TRAC[0329] shadowsocks endpoint has been successfully connected
TRAC[0329] 518 read from stream 6 with err <nil>
TRAC[0329] 4944 sent to remote through stream 6 with err <nil>
(after some time of hanging)
TRAC[0389] stream 6 actively closed
TRAC[0389] session 1824863800 has no active stream left
DEBU[0419] attempting to actively close session 1824863800
DEBU[0419] a connection for session 1824863800 has closed: read tcp serverip:443->homeip:6072: use of closed network connection
DEBU[0419] session 1824863800 closed gracefully
INFO[0419] Session closed                                UID="iW8RFPqy+OHm1y2BQf84KQ==" reason=timeout sessionID=1824863800
DEBU[0419] attempting to actively close session 1824863800
DEBU[0419] session 1824863800 has already been closed

Client log at the same moment this happens:

time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="3113 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16349 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="2032 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="4164 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="3097 read from stream 5 with err <nil>"
time="2019-12-11T03:17:54+00:00" level=trace msg="stream 5 actively closed"
(wget cancelled)
time="2019-12-11T03:17:54+00:00" level=trace msg="session 1824863800 has no active stream left"
(wget started again)
time="2019-12-11T03:17:55+00:00" level=trace msg="stream 6 of session 1824863800 opened"
time="2019-12-11T03:17:55+00:00" level=trace msg="73 sent to remote through stream 6 with err <nil>"
time="2019-12-11T03:17:55+00:00" level=trace msg="445 sent to remote through stream 6 with err <nil>"
(remains stuck like this even when server closed the session)

Here is another interesting observation: when I added a 10 second keepalive to client and server, the server detects the hang and terminates the session after some time of hanging. TCP Reset received in Wireshark but client doesn't detect it. Client remains stuck.

I checked Wireshark and tcpdump on client and server at the same time. There is packets being received from client and server on both sides, so it is not ISP blocking.

This problem doesn't happen with shadowsocks alone or with goquiet.

I hope that helps to identify the problem. I hope this is solved, it is very annoying and prevents using of Cloak reliably.

<!-- gh-comment-id:564336778 --> @notsure2 commented on GitHub (Dec 11, 2019): @cbeuw I am also facing this problem. It is easy to trigger it. Set NumConn = 1 and then start and cancel wget on a large file many times. With trace logging I see that the bytes are sent but then no response is ever received by the client and the connection stalls. With the server also on trace logging, I can see that the server read the bytes sent by the client and sent 2 responses, but the client doesn't process the response and hangs. Maybe it is a problem of buffer flushing ? or goroutine starvation ? (noob at go, forgive me if I am mistaken, just throwing an idea). When this condition happens it seems the entire session hangs. Any future tcp connection hangs in the same way (bytes sent but response never processed) on the tcp connection in the session until the session is closed on the server. Server log at the moment this happens: ``` TRAC[0328] 1141 sent to remote through stream 5 with err <nil> TRAC[0328] 2082 sent to remote through stream 5 with err <nil> TRAC[0328] 2082 sent to remote through stream 5 with err <nil> TRAC[0328] 16378 sent to remote through stream 5 with err <nil> TRAC[0328] 16378 sent to remote through stream 5 with err <nil> TRAC[0328] 16378 sent to remote through stream 5 with err <nil> TRAC[0328] 16349 sent to remote through stream 5 with err <nil> TRAC[0328] 1141 sent to remote through stream 5 with err <nil> TRAC[0328] 16378 sent to remote through stream 5 with err <nil> TRAC[0328] 16378 sent to remote through stream 5 with err <nil> TRAC[0328] 16378 sent to remote through stream 5 with err <nil> TRAC[0328] 11897 sent to remote through stream 5 with err <nil> TRAC[0328] stream 5 actively closed (cancelled wget) TRAC[0328] session 1824863800 has no active stream left (wget started again) TRAC[0329] stream 6 of session 1824863800 accepted TRAC[0329] shadowsocks endpoint has been successfully connected TRAC[0329] 518 read from stream 6 with err <nil> TRAC[0329] 4944 sent to remote through stream 6 with err <nil> (after some time of hanging) TRAC[0389] stream 6 actively closed TRAC[0389] session 1824863800 has no active stream left DEBU[0419] attempting to actively close session 1824863800 DEBU[0419] a connection for session 1824863800 has closed: read tcp serverip:443->homeip:6072: use of closed network connection DEBU[0419] session 1824863800 closed gracefully INFO[0419] Session closed UID="iW8RFPqy+OHm1y2BQf84KQ==" reason=timeout sessionID=1824863800 DEBU[0419] attempting to actively close session 1824863800 DEBU[0419] session 1824863800 has already been closed ``` Client log at the same moment this happens: ``` time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="3113 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16349 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="2032 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="4164 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="16378 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="3097 read from stream 5 with err <nil>" time="2019-12-11T03:17:54+00:00" level=trace msg="stream 5 actively closed" (wget cancelled) time="2019-12-11T03:17:54+00:00" level=trace msg="session 1824863800 has no active stream left" (wget started again) time="2019-12-11T03:17:55+00:00" level=trace msg="stream 6 of session 1824863800 opened" time="2019-12-11T03:17:55+00:00" level=trace msg="73 sent to remote through stream 6 with err <nil>" time="2019-12-11T03:17:55+00:00" level=trace msg="445 sent to remote through stream 6 with err <nil>" (remains stuck like this even when server closed the session) ``` Here is another interesting observation: when I added a 10 second keepalive to client and server, the server detects the hang and terminates the session after some time of hanging. TCP Reset received in Wireshark but client doesn't detect it. Client remains stuck. I checked Wireshark and tcpdump on client and server at the same time. There is packets being received from client and server on both sides, so it is not ISP blocking. This problem doesn't happen with shadowsocks alone or with goquiet. I hope that helps to identify the problem. I hope this is solved, it is very annoying and prevents using of Cloak reliably.
Author
Owner

@OneOfOne commented on GitHub (Dec 12, 2019):

To help debug this, try to trigger the bug, do pkill -SIGABRT client and pkill -SIGABRT server and include the output in the bug report.

<!-- gh-comment-id:564841976 --> @OneOfOne commented on GitHub (Dec 12, 2019): To help debug this, try to trigger the bug, do `pkill -SIGABRT client` and `pkill -SIGABRT server` and include the output in the bug report.
Author
Owner

@chenshaoju commented on GitHub (Dec 12, 2019):

Windows don't have pkill.

@notsure2 Please? 🙏

<!-- gh-comment-id:564869509 --> @chenshaoju commented on GitHub (Dec 12, 2019): Windows don't have `pkill`. @notsure2 Please? 🙏
Author
Owner

@notsure2 commented on GitHub (Dec 12, 2019):

@chenshaoju @OneOfOne @cbeuw

Here is the stack dumped by kill -s SIGABRT $CLIENT_PID during the hang:

goroutine 0 [idle]:
runtime.futex(0xa4e368, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7fffbfddabd8, 0x40c03f, ...)
        /usr/lib/go-1.13/src/runtime/sys_linux_amd64.s:536 +0x23
runtime.futexsleep(0xa4e368, 0x0, 0xffffffffffffffff)
        /usr/lib/go-1.13/src/runtime/os_linux.go:44 +0x46
runtime.notesleep(0xa4e368)
        /usr/lib/go-1.13/src/runtime/lock_futex.go:151 +0x9f
runtime.stopm()
        /usr/lib/go-1.13/src/runtime/proc.go:1928 +0xc0
runtime.findrunnable(0xc000024500, 0x0)
        /usr/lib/go-1.13/src/runtime/proc.go:2391 +0x53f
runtime.schedule()
        /usr/lib/go-1.13/src/runtime/proc.go:2524 +0x2be
runtime.park_m(0xc000078c00)
        /usr/lib/go-1.13/src/runtime/proc.go:2610 +0x9d
runtime.mcall(0x0)
        /usr/lib/go-1.13/src/runtime/asm_amd64.s:318 +0x5b

goroutine 1 [IO wait]:
internal/poll.runtime_pollWait(0x7fb1bf044f38, 0x72, 0x0)
        /usr/lib/go-1.13/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc0000fa098, 0x72, 0x0, 0x0, 0x7b3043)
        /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
        /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc0000fa080, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/lib/go-1.13/src/internal/poll/fd_unix.go:384 +0x1f8
net.(*netFD).accept(0xc0000fa080, 0x37e11d600, 0x0, 0x0)
        /usr/lib/go-1.13/src/net/fd_unix.go:238 +0x42
net.(*TCPListener).accept(0xc0000a8400, 0xc0000ebcf0, 0xc0000ebcf8, 0x20)
        /usr/lib/go-1.13/src/net/tcpsock_posix.go:139 +0x32
net.(*TCPListener).Accept(0xc0000a8400, 0x7cb448, 0x82fec0, 0xc000126f48, 0xc00009a050)
        /usr/lib/go-1.13/src/net/tcpsock.go:261 +0x47
main.routeTCP(0xc0000f4000, 0x0, 0x0, 0x0)
        /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:203 +0x14a
main.main()
        /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:357 +0xb95

goroutine 22 [chan send]:
github.com/cbeuw/Cloak/internal/multiplex.(*Session).recvDataFromRemote(0xc0000fa280, 0xc000132000, 0x400d, 0x5000, 0x5000, 0x400d)
        /d/Users/User/GitHub/Cloak/internal/multiplex/session.go:203 +0x329
github.com/cbeuw/Cloak/internal/multiplex.(*switchboard).deplex(0xc0000c06c0, 0x0, 0x82fec0, 0xc00009a070)
        /d/Users/User/GitHub/Cloak/internal/multiplex/switchboard.go:161 +0x15d
created by github.com/cbeuw/Cloak/internal/multiplex.(*switchboard).addConn
        /d/Users/User/GitHub/Cloak/internal/multiplex/switchboard.go:59 +0xbf

goroutine 38 [IO wait]:
internal/poll.runtime_pollWait(0x7fb1bf044e68, 0x72, 0xffffffffffffffff)
        /usr/lib/go-1.13/src/runtime/netpoll.go:184 +0x55
internal/poll.(*pollDesc).wait(0xc0000fa118, 0x72, 0x3f00, 0x3ffa, 0xffffffffffffffff)
        /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
        /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc0000fa100, 0xc002c36000, 0x3ffa, 0x3ffa, 0x0, 0x0, 0x0)
        /usr/lib/go-1.13/src/internal/poll/fd_unix.go:169 +0x1cf
net.(*netFD).Read(0xc0000fa100, 0xc002c36000, 0x3ffa, 0x3ffa, 0x0, 0x3ffa, 0xc002c36000)
        /usr/lib/go-1.13/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc000126f48, 0xc002c36000, 0x3ffa, 0x3ffa, 0x0, 0x0, 0x0)
        /usr/lib/go-1.13/src/net/net.go:184 +0x68
io.ReadAtLeast(0x826dc0, 0xc000126f48, 0xc002c36000, 0x3ffa, 0x3ffa, 0x1, 0xc0000e7f30, 0x28, 0xc000078d80)
        /usr/lib/go-1.13/src/io/io.go:310 +0x87
github.com/cbeuw/Cloak/internal/util.Pipe(0x82fd40, 0xc002b26fc0, 0x82fec0, 0xc000126f48, 0x0)
        /d/Users/User/GitHub/Cloak/internal/util/util.go:103 +0xd6
main.routeTCP.func1(0x82fec0, 0xc000126f48, 0xc00009a050, 0xc0000f4000)
        /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:233 +0x3d1
created by main.routeTCP
        /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:211 +0x200

goroutine 39 [sync.Cond.Wait]:
runtime.goparkunlock(...)
        /usr/lib/go-1.13/src/runtime/proc.go:310
sync.runtime_notifyListWait(0xc002ac97d0, 0x0)
        /usr/lib/go-1.13/src/runtime/sema.go:510 +0xf8
sync.(*Cond).Wait(0xc002ac97c0)
        /usr/lib/go-1.13/src/sync/cond.go:56 +0x9d
github.com/cbeuw/Cloak/internal/multiplex.(*bufferedPipe).Read(0xc002a74760, 0xc002c3a000, 0x3ffa, 0x3ffa, 0x0, 0x0, 0x0)
        /d/Users/User/GitHub/Cloak/internal/multiplex/bufferedPipe.go:40 +0xad
github.com/cbeuw/Cloak/internal/multiplex.(*streamBuffer).Read(0xc002ac9800, 0xc002c3a000, 0x3ffa, 0x3ffa, 0x40d526, 0x7fb1bf090d98, 0xc000131775)
        /d/Users/User/GitHub/Cloak/internal/multiplex/streamBuffer.go:100 +0x4d
github.com/cbeuw/Cloak/internal/multiplex.(*Stream).Read(0xc002b26fc0, 0xc002c3a000, 0x3ffa, 0x3ffa, 0xc000131748, 0x40b595, 0x752880)
        /d/Users/User/GitHub/Cloak/internal/multiplex/stream.go:76 +0xe6
io.ReadAtLeast(0x826bc0, 0xc002b26fc0, 0xc002c3a000, 0x3ffa, 0x3ffa, 0x1, 0x0, 0x0, 0x0)
        /usr/lib/go-1.13/src/io/io.go:310 +0x87
github.com/cbeuw/Cloak/internal/util.Pipe(0x82fec0, 0xc000126f48, 0x82fd40, 0xc002b26fc0, 0x0)
        /d/Users/User/GitHub/Cloak/internal/util/util.go:103 +0xd6
created by main.routeTCP.func1
        /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:232 +0x389

rax    0xfffffffffffffffc
rbx    0xa4e220
rcx    0x0
rdx    0x0
rdi    0xa4e368
rsi    0x80
rbp    0x7fffbfddaba0
rsp    0x7fffbfddab58
r8     0x0
r9     0x0
r10    0x0
r11    0x0
r12    0xc00009a070
r13    0xc000132000
r14    0x5000
r15    0x0
rip    0x45d1e3
rflags 0x286
cs     0x33
fs     0x53
gs     0x2b
<!-- gh-comment-id:565116419 --> @notsure2 commented on GitHub (Dec 12, 2019): @chenshaoju @OneOfOne @cbeuw Here is the stack dumped by `kill -s SIGABRT $CLIENT_PID` during the hang: ``` goroutine 0 [idle]: runtime.futex(0xa4e368, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7fffbfddabd8, 0x40c03f, ...) /usr/lib/go-1.13/src/runtime/sys_linux_amd64.s:536 +0x23 runtime.futexsleep(0xa4e368, 0x0, 0xffffffffffffffff) /usr/lib/go-1.13/src/runtime/os_linux.go:44 +0x46 runtime.notesleep(0xa4e368) /usr/lib/go-1.13/src/runtime/lock_futex.go:151 +0x9f runtime.stopm() /usr/lib/go-1.13/src/runtime/proc.go:1928 +0xc0 runtime.findrunnable(0xc000024500, 0x0) /usr/lib/go-1.13/src/runtime/proc.go:2391 +0x53f runtime.schedule() /usr/lib/go-1.13/src/runtime/proc.go:2524 +0x2be runtime.park_m(0xc000078c00) /usr/lib/go-1.13/src/runtime/proc.go:2610 +0x9d runtime.mcall(0x0) /usr/lib/go-1.13/src/runtime/asm_amd64.s:318 +0x5b goroutine 1 [IO wait]: internal/poll.runtime_pollWait(0x7fb1bf044f38, 0x72, 0x0) /usr/lib/go-1.13/src/runtime/netpoll.go:184 +0x55 internal/poll.(*pollDesc).wait(0xc0000fa098, 0x72, 0x0, 0x0, 0x7b3043) /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:87 +0x45 internal/poll.(*pollDesc).waitRead(...) /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:92 internal/poll.(*FD).Accept(0xc0000fa080, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) /usr/lib/go-1.13/src/internal/poll/fd_unix.go:384 +0x1f8 net.(*netFD).accept(0xc0000fa080, 0x37e11d600, 0x0, 0x0) /usr/lib/go-1.13/src/net/fd_unix.go:238 +0x42 net.(*TCPListener).accept(0xc0000a8400, 0xc0000ebcf0, 0xc0000ebcf8, 0x20) /usr/lib/go-1.13/src/net/tcpsock_posix.go:139 +0x32 net.(*TCPListener).Accept(0xc0000a8400, 0x7cb448, 0x82fec0, 0xc000126f48, 0xc00009a050) /usr/lib/go-1.13/src/net/tcpsock.go:261 +0x47 main.routeTCP(0xc0000f4000, 0x0, 0x0, 0x0) /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:203 +0x14a main.main() /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:357 +0xb95 goroutine 22 [chan send]: github.com/cbeuw/Cloak/internal/multiplex.(*Session).recvDataFromRemote(0xc0000fa280, 0xc000132000, 0x400d, 0x5000, 0x5000, 0x400d) /d/Users/User/GitHub/Cloak/internal/multiplex/session.go:203 +0x329 github.com/cbeuw/Cloak/internal/multiplex.(*switchboard).deplex(0xc0000c06c0, 0x0, 0x82fec0, 0xc00009a070) /d/Users/User/GitHub/Cloak/internal/multiplex/switchboard.go:161 +0x15d created by github.com/cbeuw/Cloak/internal/multiplex.(*switchboard).addConn /d/Users/User/GitHub/Cloak/internal/multiplex/switchboard.go:59 +0xbf goroutine 38 [IO wait]: internal/poll.runtime_pollWait(0x7fb1bf044e68, 0x72, 0xffffffffffffffff) /usr/lib/go-1.13/src/runtime/netpoll.go:184 +0x55 internal/poll.(*pollDesc).wait(0xc0000fa118, 0x72, 0x3f00, 0x3ffa, 0xffffffffffffffff) /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:87 +0x45 internal/poll.(*pollDesc).waitRead(...) /usr/lib/go-1.13/src/internal/poll/fd_poll_runtime.go:92 internal/poll.(*FD).Read(0xc0000fa100, 0xc002c36000, 0x3ffa, 0x3ffa, 0x0, 0x0, 0x0) /usr/lib/go-1.13/src/internal/poll/fd_unix.go:169 +0x1cf net.(*netFD).Read(0xc0000fa100, 0xc002c36000, 0x3ffa, 0x3ffa, 0x0, 0x3ffa, 0xc002c36000) /usr/lib/go-1.13/src/net/fd_unix.go:202 +0x4f net.(*conn).Read(0xc000126f48, 0xc002c36000, 0x3ffa, 0x3ffa, 0x0, 0x0, 0x0) /usr/lib/go-1.13/src/net/net.go:184 +0x68 io.ReadAtLeast(0x826dc0, 0xc000126f48, 0xc002c36000, 0x3ffa, 0x3ffa, 0x1, 0xc0000e7f30, 0x28, 0xc000078d80) /usr/lib/go-1.13/src/io/io.go:310 +0x87 github.com/cbeuw/Cloak/internal/util.Pipe(0x82fd40, 0xc002b26fc0, 0x82fec0, 0xc000126f48, 0x0) /d/Users/User/GitHub/Cloak/internal/util/util.go:103 +0xd6 main.routeTCP.func1(0x82fec0, 0xc000126f48, 0xc00009a050, 0xc0000f4000) /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:233 +0x3d1 created by main.routeTCP /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:211 +0x200 goroutine 39 [sync.Cond.Wait]: runtime.goparkunlock(...) /usr/lib/go-1.13/src/runtime/proc.go:310 sync.runtime_notifyListWait(0xc002ac97d0, 0x0) /usr/lib/go-1.13/src/runtime/sema.go:510 +0xf8 sync.(*Cond).Wait(0xc002ac97c0) /usr/lib/go-1.13/src/sync/cond.go:56 +0x9d github.com/cbeuw/Cloak/internal/multiplex.(*bufferedPipe).Read(0xc002a74760, 0xc002c3a000, 0x3ffa, 0x3ffa, 0x0, 0x0, 0x0) /d/Users/User/GitHub/Cloak/internal/multiplex/bufferedPipe.go:40 +0xad github.com/cbeuw/Cloak/internal/multiplex.(*streamBuffer).Read(0xc002ac9800, 0xc002c3a000, 0x3ffa, 0x3ffa, 0x40d526, 0x7fb1bf090d98, 0xc000131775) /d/Users/User/GitHub/Cloak/internal/multiplex/streamBuffer.go:100 +0x4d github.com/cbeuw/Cloak/internal/multiplex.(*Stream).Read(0xc002b26fc0, 0xc002c3a000, 0x3ffa, 0x3ffa, 0xc000131748, 0x40b595, 0x752880) /d/Users/User/GitHub/Cloak/internal/multiplex/stream.go:76 +0xe6 io.ReadAtLeast(0x826bc0, 0xc002b26fc0, 0xc002c3a000, 0x3ffa, 0x3ffa, 0x1, 0x0, 0x0, 0x0) /usr/lib/go-1.13/src/io/io.go:310 +0x87 github.com/cbeuw/Cloak/internal/util.Pipe(0x82fec0, 0xc000126f48, 0x82fd40, 0xc002b26fc0, 0x0) /d/Users/User/GitHub/Cloak/internal/util/util.go:103 +0xd6 created by main.routeTCP.func1 /d/Users/User/GitHub/Cloak/cmd/ck-client/ck-client.go:232 +0x389 rax 0xfffffffffffffffc rbx 0xa4e220 rcx 0x0 rdx 0x0 rdi 0xa4e368 rsi 0x80 rbp 0x7fffbfddaba0 rsp 0x7fffbfddab58 r8 0x0 r9 0x0 r10 0x0 r11 0x0 r12 0xc00009a070 r13 0xc000132000 r14 0x5000 r15 0x0 rip 0x45d1e3 rflags 0x286 cs 0x33 fs 0x53 gs 0x2b ```
Author
Owner

@notsure2 commented on GitHub (Dec 12, 2019):

I'm not sure, but analyzing the code... I think it's a situation where deplex ends up in the path where it didn't find the stream ID because somehow it ended up running before OpenStream() was called... but I don't understand why it was waiting on the channel in session.go:203.

Anyway when it doesn't find the stream ID, it creates a new stream and writes the response packets to that instead of to the correct stream that is waiting for that reply... so the original correct stream hangs forever waiting for response.

It's confusing to me, but I'll try to confirm it with logging.

<!-- gh-comment-id:565208105 --> @notsure2 commented on GitHub (Dec 12, 2019): I'm not sure, but analyzing the code... I think it's a situation where deplex ends up in the path where it didn't find the stream ID because somehow it ended up running before OpenStream() was called... but I don't understand why it was waiting on the channel in session.go:203. Anyway when it doesn't find the stream ID, it creates a new stream and writes the response packets to that instead of to the correct stream that is waiting for that reply... so the original correct stream hangs forever waiting for response. It's confusing to me, but I'll try to confirm it with logging.
Author
Owner

@OneOfOne commented on GitHub (Dec 12, 2019):

@notsure2 this feels like a race, any chance you can go build -race both the client and server?

<!-- gh-comment-id:565216948 --> @OneOfOne commented on GitHub (Dec 12, 2019): @notsure2 this feels like a race, any chance you can `go build -race` both the client and server?
Author
Owner

@notsure2 commented on GitHub (Dec 13, 2019):

@OneOfOne I tried, but no race messages are emitted.

@chenshaoju I noticed a pattern. I made some changes in this branch https://github.com/notsure2/Cloak/tree/debug-stall to add more logging messages and now I noticed this log when the hang happens:

Server:

TRAC[0034] 16378 sent to remote through stream 1 with err <nil>
TRAC[0034] 16378 sent to remote through stream 1 with err <nil>
TRAC[0034] Received frame for stream 1
TRAC[0034] 16378 sent to remote through stream 1 with err <nil>
TRAC[0034] stream 1 actively closed
TRAC[0034] session 1014238462 has no active stream left
(cancel of previous wget)
(start of new wget)
TRAC[0036] Received frame for UNKNOWN stream 2
TRAC[0036] Received frame for UNKNOWN stream 2
TRAC[0036] stream 2 of session 1014238462 accepted
TRAC[0036] shadowsocks endpoint has been successfully connected
TRAC[0036] stream 2 of session 1014238462 accepted
TRAC[0036] shadowsocks endpoint has been successfully connected
TRAC[0036] 73 read from stream 2 with err <nil>

Client:

TRAC[0036] Received frame for UNKNOWN stream 1
TRAC[0036] Received frame for UNKNOWN stream 1
TRAC[0036] Received frame for UNKNOWN stream 1
TRAC[0036] Received frame for UNKNOWN stream 1
TRAC[0036] Received frame for UNKNOWN stream 1
TRAC[0038] stream 2 of session 1014238462 opened
TRAC[0038] 73 sent to remote through stream 2 with err <nil>
TRAC[0038] 445 sent to remote through stream 2 with err <nil>

100% of the time when it hangs: this message is duplicated on the server:

TRAC[0036] stream 2 of session 1014238462 accepted
TRAC[0036] shadowsocks endpoint has been successfully connected
TRAC[0036] stream 2 of session 1014238462 accepted
TRAC[0036] shadowsocks endpoint has been successfully connected

But when it doesn't hang, this message doesn't repeat. I will try to add more messages or reach the root of this.

<!-- gh-comment-id:565485609 --> @notsure2 commented on GitHub (Dec 13, 2019): @OneOfOne I tried, but no race messages are emitted. @chenshaoju I noticed a pattern. I made some changes in this branch https://github.com/notsure2/Cloak/tree/debug-stall to add more logging messages and now I noticed this log when the hang happens: Server: ``` TRAC[0034] 16378 sent to remote through stream 1 with err <nil> TRAC[0034] 16378 sent to remote through stream 1 with err <nil> TRAC[0034] Received frame for stream 1 TRAC[0034] 16378 sent to remote through stream 1 with err <nil> TRAC[0034] stream 1 actively closed TRAC[0034] session 1014238462 has no active stream left (cancel of previous wget) (start of new wget) TRAC[0036] Received frame for UNKNOWN stream 2 TRAC[0036] Received frame for UNKNOWN stream 2 TRAC[0036] stream 2 of session 1014238462 accepted TRAC[0036] shadowsocks endpoint has been successfully connected TRAC[0036] stream 2 of session 1014238462 accepted TRAC[0036] shadowsocks endpoint has been successfully connected TRAC[0036] 73 read from stream 2 with err <nil> ``` Client: ``` TRAC[0036] Received frame for UNKNOWN stream 1 TRAC[0036] Received frame for UNKNOWN stream 1 TRAC[0036] Received frame for UNKNOWN stream 1 TRAC[0036] Received frame for UNKNOWN stream 1 TRAC[0036] Received frame for UNKNOWN stream 1 TRAC[0038] stream 2 of session 1014238462 opened TRAC[0038] 73 sent to remote through stream 2 with err <nil> TRAC[0038] 445 sent to remote through stream 2 with err <nil> ``` 100% of the time when it hangs: this message is duplicated on the server: ``` TRAC[0036] stream 2 of session 1014238462 accepted TRAC[0036] shadowsocks endpoint has been successfully connected TRAC[0036] stream 2 of session 1014238462 accepted TRAC[0036] shadowsocks endpoint has been successfully connected ``` But when it doesn't hang, this message doesn't repeat. I will try to add more messages or reach the root of this.
Author
Owner

@notsure2 commented on GitHub (Dec 13, 2019):

@chenshaoju @cbeuw @OneOfOne

I have a theory on what's the problem. The problem is that the creation of the stream object representing a single client stream is mistakenly asynchronous relative to the reception of the first packet in it by the server, so it is possible for another packet to get received and mistakenly get assigned to a new stream object because the first packet in the stream finished processing before the stream object was added to the streams map by the other goroutine.

Here in this code:

// from session.go
func (sesh *Session) recvDataFromRemote(data []byte) error {
	frame, err := sesh.Deobfs(data)
	if err != nil {
		return fmt.Errorf("Failed to decrypt a frame for session %v: %v", sesh.id, err)
	}

	streamI, existing := sesh.streams.Load(frame.StreamID)
	if existing {
		log.Tracef("Received frame for stream %v", frame.StreamID)
		stream := streamI.(*Stream)
		return stream.writeFrame(*frame)
	} else {
		if frame.Closing == C_STREAM {
			// If the stream has been closed and the current frame is a closing frame, we do noop
			return nil
		} else if frame.Closing == C_SESSION {
			// Closing session
			sesh.SetTerminalMsg("Received a closing notification frame")
			return sesh.passiveClose()
		} else {
			log.Tracef("Received frame for UNKNOWN stream %v", frame.StreamID)
			// it may be tempting to use the connId from which the frame was received. However it doesn't make
			// any difference because we only care to send the data from the same stream through the same
			// TCP connection. The remote may use a different connection to send the same stream than the one the client
			// use to send.
			connId, _, _ := sesh.sb.pickRandConn()
			// we ignore the error here. If the switchboard is broken, it will be reflected upon stream.Write
			stream := makeStream(sesh, frame.StreamID, connId)
			sesh.acceptCh <- stream
			return stream.writeFrame(*frame)
		}
	}
}

In the case of the server, it will receive a packet for which there is no stream in the streams found, so it will make a new stream and then send it to acceptCh channel.

Who reads from this channel ? This code:

// from session.go
func (sesh *Session) Accept() (net.Conn, error) {
	if sesh.IsClosed() {
		return nil, ErrBrokenSession
	}
	stream := <-sesh.acceptCh
	if stream == nil {
		return nil, ErrBrokenSession
	}
	sesh.streams.Store(stream.id, stream)
	log.Tracef("stream %v of session %v accepted", stream.id, sesh.id)
	return stream, nil
}

This method will be all the time sleeping waiting to receive a new stream from the acceptCh and then store it in the session streams map.

So the problem is that the first goroutine that put the stream in the channel resumes and gets called again for the next packet before sesh.streams.Store(stream.id, stream) executes, so it gets mistakenly assigned to a new stream.

The solution is to remove this channel and move the creation of streams to be directly in the path of packet processing instead of async by a separate goroutine.

I will test this and report back.

<!-- gh-comment-id:565653336 --> @notsure2 commented on GitHub (Dec 13, 2019): @chenshaoju @cbeuw @OneOfOne I have a theory on what's the problem. The problem is that the creation of the stream object representing a single client stream is mistakenly asynchronous relative to the reception of the first packet in it by the server, so it is possible for another packet to get received and mistakenly get assigned to a new stream object because the first packet in the stream finished processing before the stream object was added to the streams map by the other goroutine. Here in this code: ```go // from session.go func (sesh *Session) recvDataFromRemote(data []byte) error { frame, err := sesh.Deobfs(data) if err != nil { return fmt.Errorf("Failed to decrypt a frame for session %v: %v", sesh.id, err) } streamI, existing := sesh.streams.Load(frame.StreamID) if existing { log.Tracef("Received frame for stream %v", frame.StreamID) stream := streamI.(*Stream) return stream.writeFrame(*frame) } else { if frame.Closing == C_STREAM { // If the stream has been closed and the current frame is a closing frame, we do noop return nil } else if frame.Closing == C_SESSION { // Closing session sesh.SetTerminalMsg("Received a closing notification frame") return sesh.passiveClose() } else { log.Tracef("Received frame for UNKNOWN stream %v", frame.StreamID) // it may be tempting to use the connId from which the frame was received. However it doesn't make // any difference because we only care to send the data from the same stream through the same // TCP connection. The remote may use a different connection to send the same stream than the one the client // use to send. connId, _, _ := sesh.sb.pickRandConn() // we ignore the error here. If the switchboard is broken, it will be reflected upon stream.Write stream := makeStream(sesh, frame.StreamID, connId) sesh.acceptCh <- stream return stream.writeFrame(*frame) } } } ``` In the case of the server, it will receive a packet for which there is no stream in the streams found, so it will make a new stream and then send it to acceptCh channel. Who reads from this channel ? This code: ```go // from session.go func (sesh *Session) Accept() (net.Conn, error) { if sesh.IsClosed() { return nil, ErrBrokenSession } stream := <-sesh.acceptCh if stream == nil { return nil, ErrBrokenSession } sesh.streams.Store(stream.id, stream) log.Tracef("stream %v of session %v accepted", stream.id, sesh.id) return stream, nil } ``` This method will be all the time sleeping waiting to receive a new stream from the acceptCh and then store it in the session streams map. So the problem is that the first goroutine that put the stream in the channel resumes and gets called again for the next packet before `sesh.streams.Store(stream.id, stream)` executes, so it gets mistakenly assigned to a new stream. The solution is to remove this channel and move the creation of streams to be directly in the path of packet processing instead of async by a separate goroutine. I will test this and report back.
Author
Owner

@notsure2 commented on GitHub (Dec 14, 2019):

@OneOfOne @cbeuw
I have made a pull request with a fix for this issue.

https://github.com/cbeuw/Cloak/pull/81/

@chenshaoju Please test this change, it should fix your problem.

<!-- gh-comment-id:565669562 --> @notsure2 commented on GitHub (Dec 14, 2019): @OneOfOne @cbeuw I have made a pull request with a fix for this issue. https://github.com/cbeuw/Cloak/pull/81/ @chenshaoju Please test this change, it should fix your problem.
Author
Owner

@chenshaoju commented on GitHub (Dec 14, 2019):

@notsure2 Thank you, I have successfully built the server and client side. 👍

Test is running.

<!-- gh-comment-id:565692823 --> @chenshaoju commented on GitHub (Dec 14, 2019): @notsure2 Thank you, I have successfully built the server and client side. 👍 Test is running.
Author
Owner

@cbeuw commented on GitHub (Dec 14, 2019):

@notsure2
Thank you very much for your work! My uni work was quite intense over the last month so sorry I couldn't chime in with the debugging.

The log you gave

100% of the time when it hangs: this message is duplicated on the server:

TRAC[0036] stream 2 of session 1014238462 accepted
TRAC[0036] shadowsocks endpoint has been successfully connected
TRAC[0036] stream 2 of session 1014238462 accepted
TRAC[0036] shadowsocks endpoint has been successfully connected

was very helpful as this presents quite clearly a race situation. I'm fairly certain that your theory is correct:

Two frames of a new stream number arrives at the server at roughly the same time, which means that two recvDataFromRemote() invocations were called with these two frames at roughly the same time as well. One of the invocations will reach streamI, existing := sesh.streams.Load(frame.StreamID) first, and start making a new stream instance. However, before this stream instance is stored in the map in Accept(), the other invocation will reach streamI, existing := sesh.streams.Load(frame.StreamID) and start making a duplicate stream instance.

I believe https://github.com/cbeuw/Cloak/pull/81 will vastly reduce the chance the race condition happens, as the stream instance is immediately stored into the map after its creation; however it doesn't completely fix it because as the first invocation is progressing from streamI, existing := sesh.streams.Load(frame.StreamID), before it reaches sesh.streams.Store(stream.id, stream), the second invocation could reach streamI, existing := sesh.streams.Load(frame.StreamID), with existing returning false, and proceed with a duplicate stream instantiation.
Like this:
image

Note that for this to happen, the two frames need to be processed on two separate goroutines. For this to happen, the two frames have to arrive on two separate TCP connections since the invocation of recvDataFromRemote() is not async in deplex(). This may never happen because at the moment, each stream is assigned one TCP connection and all frames of that stream sticks to the same connection; but this is not guaranteed by design as it depends on the frame-TCP connection distribution strategy, which may change in the future.

Nevertheless I will merge the pull request as it is a step forward. I'll try to think of a way to solve this race condition completely.

<!-- gh-comment-id:565714087 --> @cbeuw commented on GitHub (Dec 14, 2019): @notsure2 Thank you very much for your work! My uni work was quite intense over the last month so sorry I couldn't chime in with the debugging. The log you gave > 100% of the time when it hangs: this message is duplicated on the server: > > ``` > TRAC[0036] stream 2 of session 1014238462 accepted > TRAC[0036] shadowsocks endpoint has been successfully connected > TRAC[0036] stream 2 of session 1014238462 accepted > TRAC[0036] shadowsocks endpoint has been successfully connected > ``` was very helpful as this presents quite clearly a race situation. I'm fairly certain that your theory is correct: Two frames of a new stream number arrives at the server at roughly the same time, which means that two recvDataFromRemote() invocations were called with these two frames at roughly the same time as well. One of the invocations will reach `streamI, existing := sesh.streams.Load(frame.StreamID)` first, and start making a new stream instance. However, before this stream instance is stored in the map in Accept(), the other invocation will reach `streamI, existing := sesh.streams.Load(frame.StreamID)` and start making a duplicate stream instance. I believe https://github.com/cbeuw/Cloak/pull/81 will vastly reduce the chance the race condition happens, as the stream instance is immediately stored into the map after its creation; however it doesn't completely fix it because as the first invocation is progressing from `streamI, existing := sesh.streams.Load(frame.StreamID)`, before it reaches `sesh.streams.Store(stream.id, stream)`, the second invocation could reach `streamI, existing := sesh.streams.Load(frame.StreamID)`, with `existing` returning false, and proceed with a duplicate stream instantiation. Like this: ![image](https://user-images.githubusercontent.com/7034308/70848772-3012dd80-1e6e-11ea-952d-6e036fc56143.png) Note that for this to happen, the two frames need to be processed on two separate goroutines. For this to happen, the two frames have to arrive on two separate TCP connections since the invocation of recvDataFromRemote() is not async in deplex(). This may never happen because at the moment, each stream is assigned one TCP connection and all frames of that stream sticks to the same connection; but this is not guaranteed by design as it depends on the frame-TCP connection distribution strategy, which may change in the future. Nevertheless I will merge the pull request as it is a step forward. I'll try to think of a way to solve this race condition completely.
Author
Owner

@notsure2 commented on GitHub (Dec 14, 2019):

At the moment I don't think there is any benefit at all of allowing different frames of the same stream of getting distributed over multiple tcp connections as they are produced sequentially at the source in the first place. If you allow this, you will also have to handle out of order delivery and reassembly and suddenly we are reinventing tcp again. There's no benefit I can see of doing this...

I've been running with this fix for 9 hours and the problem didn't resurface and I didn't need to restart Cloak even once.

Thanks for merging the fix :-)

<!-- gh-comment-id:565714728 --> @notsure2 commented on GitHub (Dec 14, 2019): At the moment I don't think there is any benefit at all of allowing different frames of the same stream of getting distributed over multiple tcp connections as they are produced sequentially at the source in the first place. If you allow this, you will also have to handle out of order delivery and reassembly and suddenly we are reinventing tcp again. There's no benefit I can see of doing this... I've been running with this fix for 9 hours and the problem didn't resurface and I didn't need to restart Cloak even once. Thanks for merging the fix :-)
Author
Owner

@cbeuw commented on GitHub (Dec 14, 2019):

you will also have to handle out of order delivery and reassembly

Actually this was the one of the first things I wrote when I started the project :P. Until a few months ago the strategy was to evenly distribute frames across all the connections, but then I realised that this is a bit unnecessary and I should've let TCP handle ordered delievery instead.

Besides, Cloak currently has (experimental) support for UDP based proxy protocols (it's preferable to use OpenVPN in UDP mode). In this case all frames are evenly spread across all TCP connections. Although ordered delivery is not needed, frames still need to be allocated to their correct streams to be sent to their correct UDP connections. This race condition may still happen.

<!-- gh-comment-id:565717932 --> @cbeuw commented on GitHub (Dec 14, 2019): >you will also have to handle out of order delivery and reassembly Actually this was the one of the first things I wrote when I started the project :P. Until a few months ago the strategy was to evenly distribute frames across all the connections, but then I realised that this is a bit unnecessary and I should've let TCP handle ordered delievery instead. Besides, Cloak currently has (experimental) support for UDP based proxy protocols (it's preferable to use OpenVPN in UDP mode). In this case all frames are evenly spread across all TCP connections. Although ordered delivery is not needed, frames still need to be allocated to their correct streams to be sent to their correct UDP connections. This race condition may still happen.
Author
Owner

@chenshaoju commented on GitHub (Dec 15, 2019):

After 24 hours test, This issue not happen again.

But somehow, the connection is a little unstable...Not sure is a network issue or not.

Log from server:

Dec 15 03:13:32 localhost ss-server[4227]:  2019-12-15 03:13:32 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:14:37 localhost ss-server[4227]:  2019-12-15 03:14:37 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:14:48 localhost ss-server[4227]:  2019-12-15 03:14:48 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:15:15 localhost ss-server[4227]:  2019-12-15 03:15:15 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:15:40 localhost ss-server[4227]:  2019-12-15 03:15:40 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:15:42 localhost ss-server[4227]:  2019-12-15 03:15:42 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:15:46 localhost ss-server[4227]:  2019-12-15 03:15:46 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:16:03 localhost ss-server[4227]: time="2019-12-15T03:16:03Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=1602203160
Dec 15 03:16:03 localhost ss-server[4227]: time="2019-12-15T03:16:03Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=714856184
Dec 15 03:16:28 localhost ss-server[4227]:  2019-12-15 03:16:28 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:16:35 localhost ss-server[4227]: time="2019-12-15T03:16:35Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA=" reason="a connection has dropped unexpectedly" sessionID=714856184
Dec 15 03:16:36 localhost ss-server[4227]: time="2019-12-15T03:16:36Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=2903889926
Dec 15 03:17:33 localhost ss-server[4227]: time="2019-12-15T03:17:33Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=2903889926
Dec 15 03:17:34 localhost ss-server[4227]: time="2019-12-15T03:17:34Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=4271994453
Dec 15 03:17:59 localhost ss-server[4227]:  2019-12-15 03:17:59 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:18:15 localhost ss-server[4227]:  2019-12-15 03:18:15 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:18:43 localhost ss-server[4227]: time="2019-12-15T03:18:43Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=4271994453
Dec 15 03:18:43 localhost ss-server[4227]: time="2019-12-15T03:18:43Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=3673555845
Dec 15 03:18:54 localhost ss-server[4227]:  2019-12-15 03:18:54 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:19:25 localhost ss-server[4227]:  2019-12-15 03:19:25 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:21:27 localhost ss-server[4227]: time="2019-12-15T03:21:27Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=3673555845
Dec 15 03:21:28 localhost ss-server[4227]: time="2019-12-15T03:21:28Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=4294037910
Dec 15 03:22:19 localhost ss-server[4227]:  2019-12-15 03:22:19 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:23:06 localhost ss-server[4227]:  2019-12-15 03:23:06 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:23:17 localhost ss-server[4227]:  2019-12-15 03:23:17 ERROR: getpeername: Transport endpoint is not connected
Dec 15 03:23:34 localhost ss-server[4227]:  2019-12-15 03:23:34 ERROR: getpeername: Transport endpoint is not connected

Log from client:

time="2019-12-15T11:17:06+08:00" level=trace msg="2082 read from stream 25 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="2082 read from stream 25 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="16378 read from stream 25 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="14574 read from stream 25 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="1668 read from stream 10 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="16378 read from stream 25 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="1883 read from stream 25 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="stream 25 actively closed"
time="2019-12-15T11:17:06+08:00" level=trace msg="1697 read from stream 10 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="2082 sent to remote through stream 10 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="8328 sent to remote through stream 10 with err <nil>"
time="2019-12-15T11:17:06+08:00" level=trace msg="4164 sent to remote through stream 10 with err <nil>"
time="2019-12-15T11:17:07+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:07+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:07+08:00" level=trace msg="16378 sent to remote through stream 10 with err <nil>"
time="2019-12-15T11:17:08+08:00" level=trace msg="577 read from stream 16 with err <nil>"
time="2019-12-15T11:17:09+08:00" level=trace msg="10146 sent to remote through stream 10 with err <nil>"
time="2019-12-15T11:17:09+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:10+08:00" level=trace msg="300 read from stream 1 with err <nil>"
time="2019-12-15T11:17:10+08:00" level=trace msg="300 read from stream 2 with err <nil>"
time="2019-12-15T11:17:11+08:00" level=trace msg="16378 sent to remote through stream 10 with err <nil>"
time="2019-12-15T11:17:12+08:00" level=trace msg="577 read from stream 16 with err <nil>"
time="2019-12-15T11:17:12+08:00" level=trace msg="139 read from stream 22 with err <nil>"
time="2019-12-15T11:17:13+08:00" level=trace msg="stream 30 of session 2903889926 opened"
time="2019-12-15T11:17:13+08:00" level=trace msg="stream 31 of session 2903889926 opened"
time="2019-12-15T11:17:13+08:00" level=trace msg="stream 32 of session 2903889926 opened"
time="2019-12-15T11:17:13+08:00" level=trace msg="stream 33 of session 2903889926 opened"
time="2019-12-15T11:17:13+08:00" level=trace msg="stream 34 of session 2903889926 opened"
time="2019-12-15T11:17:13+08:00" level=trace msg="259 sent to remote through stream 1 with err <nil>"
time="2019-12-15T11:17:13+08:00" level=trace msg="1091 read from stream 10 with err <nil>"
time="2019-12-15T11:17:14+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:14+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:16+08:00" level=trace msg="stream 35 of session 2903889926 opened"
time="2019-12-15T11:17:16+08:00" level=trace msg="stream 36 of session 2903889926 opened"
time="2019-12-15T11:17:21+08:00" level=trace msg="577 sent to remote through stream 16 with err <nil>"
time="2019-12-15T11:17:21+08:00" level=trace msg="577 read from stream 16 with err <nil>"
time="2019-12-15T11:17:21+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:23+08:00" level=trace msg="139 read from stream 22 with err <nil>"
time="2019-12-15T11:17:24+08:00" level=trace msg="577 sent to remote through stream 16 with err <nil>"
time="2019-12-15T11:17:25+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:25+08:00" level=trace msg="stream 37 of session 2903889926 opened"
time="2019-12-15T11:17:27+08:00" level=trace msg="stream 38 of session 2903889926 opened"
time="2019-12-15T11:17:27+08:00" level=trace msg="stream 39 of session 2903889926 opened"
time="2019-12-15T11:17:29+08:00" level=trace msg="stream 40 of session 2903889926 opened"
time="2019-12-15T11:17:29+08:00" level=trace msg="577 read from stream 16 with err <nil>"
time="2019-12-15T11:17:30+08:00" level=trace msg="577 read from stream 10 with err <nil>"
time="2019-12-15T11:17:32+08:00" level=trace msg="stream 41 of session 2903889926 opened"
time="2019-12-15T11:17:32+08:00" level=trace msg="stream 42 of session 2903889926 opened"
time="2019-12-15T11:17:32+08:00" level=trace msg="stream 43 of session 2903889926 opened"
time="2019-12-15T11:17:33+08:00" level=debug msg="attempting to passively close session 2903889926"
time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61910->111.111.111.111:443: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61915->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="6910 sent to remote through stream 10 with err write tcp 192.168.1.2:61910->111.111.111.111:443: wsasend: An existing connection was forcibly closed by the remote host."
time="2019-12-15T11:17:33+08:00" level=trace msg="639 sent to remote through stream 31 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="99 sent to remote through stream 30 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="82 sent to remote through stream 32 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="99 sent to remote through stream 33 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="633 sent to remote through stream 34 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="122 sent to remote through stream 1 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="94 sent to remote through stream 35 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="94 sent to remote through stream 36 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="2082 sent to remote through stream 21 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="187 sent to remote through stream 22 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61913->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61914->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61912->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61911->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=debug msg="session 2903889926 closed gracefully"
time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 38 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 37 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="298 sent to remote through stream 41 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 39 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 40 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="85 sent to remote through stream 42 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="85 sent to remote through stream 43 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=info msg="Attemtping to start a new session"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="259 sent to remote through stream 2 with err write tcp 192.168.1.2:61910->111.111.111.111:443: wsasend: An existing connection was forcibly closed by the remote host."
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection"
time="2019-12-15T11:17:33+08:00" level=trace msg="client hello sent successfully"
time="2019-12-15T11:17:33+08:00" level=trace msg="waiting for ServerHello"
time="2019-12-15T11:17:33+08:00" level=trace msg="client hello sent successfully"
time="2019-12-15T11:17:33+08:00" level=trace msg="waiting for ServerHello"
time="2019-12-15T11:17:36+08:00" level=trace msg="client hello sent successfully"
time="2019-12-15T11:17:36+08:00" level=trace msg="waiting for ServerHello"
time="2019-12-15T11:17:54+08:00" level=error msg="Failed to establish new connections to remote: dial tcp 111.111.111.111:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
time="2019-12-15T11:17:54+08:00" level=error msg="Failed to establish new connections to remote: dial tcp 111.111.111.111:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
time="2019-12-15T11:17:54+08:00" level=error msg="Failed to establish new connections to remote: dial tcp 111.111.111.111:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
time="2019-12-15T11:17:57+08:00" level=trace msg="client hello sent successfully"
time="2019-12-15T11:17:57+08:00" level=trace msg="waiting for ServerHello"
time="2019-12-15T11:17:57+08:00" level=trace msg="client hello sent successfully"
time="2019-12-15T11:17:57+08:00" level=trace msg="waiting for ServerHello"
time="2019-12-15T11:17:58+08:00" level=trace msg="client hello sent successfully"
time="2019-12-15T11:17:58+08:00" level=trace msg="waiting for ServerHello"
time="2019-12-15T11:17:58+08:00" level=debug msg="All underlying connections established"
time="2019-12-15T11:17:58+08:00" level=info msg="Session 4271994453 established"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 1 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="454 sent to remote through stream 1 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 4 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 5 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="406 sent to remote through stream 5 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 5 actively closed"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 6 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 10 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="236 sent to remote through stream 10 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 2 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 9 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="454 sent to remote through stream 4 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 3 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 7 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 8 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 12 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="298 sent to remote through stream 6 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 11 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 13 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 14 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 10 actively closed"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 15 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="212 sent to remote through stream 2 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 16 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="298 sent to remote through stream 9 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 17 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 18 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 19 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 20 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 21 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 22 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 23 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 24 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="224 sent to remote through stream 3 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 25 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 26 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 27 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="298 sent to remote through stream 7 with err <nil>"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 28 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 29 of session 4271994453 opened"
time="2019-12-15T11:17:58+08:00" level=trace msg="stream 30 of session 4271994453 opened"
<!-- gh-comment-id:565784376 --> @chenshaoju commented on GitHub (Dec 15, 2019): After 24 hours test, This issue not happen again. But somehow, the connection is a little unstable...Not sure is a network issue or not. Log from server: ``` Dec 15 03:13:32 localhost ss-server[4227]: 2019-12-15 03:13:32 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:14:37 localhost ss-server[4227]: 2019-12-15 03:14:37 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:14:48 localhost ss-server[4227]: 2019-12-15 03:14:48 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:15:15 localhost ss-server[4227]: 2019-12-15 03:15:15 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:15:40 localhost ss-server[4227]: 2019-12-15 03:15:40 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:15:42 localhost ss-server[4227]: 2019-12-15 03:15:42 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:15:46 localhost ss-server[4227]: 2019-12-15 03:15:46 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:16:03 localhost ss-server[4227]: time="2019-12-15T03:16:03Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=1602203160 Dec 15 03:16:03 localhost ss-server[4227]: time="2019-12-15T03:16:03Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=714856184 Dec 15 03:16:28 localhost ss-server[4227]: 2019-12-15 03:16:28 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:16:35 localhost ss-server[4227]: time="2019-12-15T03:16:35Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA=" reason="a connection has dropped unexpectedly" sessionID=714856184 Dec 15 03:16:36 localhost ss-server[4227]: time="2019-12-15T03:16:36Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=2903889926 Dec 15 03:17:33 localhost ss-server[4227]: time="2019-12-15T03:17:33Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=2903889926 Dec 15 03:17:34 localhost ss-server[4227]: time="2019-12-15T03:17:34Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=4271994453 Dec 15 03:17:59 localhost ss-server[4227]: 2019-12-15 03:17:59 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:18:15 localhost ss-server[4227]: 2019-12-15 03:18:15 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:18:43 localhost ss-server[4227]: time="2019-12-15T03:18:43Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=4271994453 Dec 15 03:18:43 localhost ss-server[4227]: time="2019-12-15T03:18:43Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=3673555845 Dec 15 03:18:54 localhost ss-server[4227]: 2019-12-15 03:18:54 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:19:25 localhost ss-server[4227]: 2019-12-15 03:19:25 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:21:27 localhost ss-server[4227]: time="2019-12-15T03:21:27Z" level=info msg="Session closed" UID="AAAAAAAAAAAAAAAAAA" reason="a connection has dropped unexpectedly" sessionID=3673555845 Dec 15 03:21:28 localhost ss-server[4227]: time="2019-12-15T03:21:28Z" level=info msg="New session" UID="AAAAAAAAAAAAAAAAAA" sessionID=4294037910 Dec 15 03:22:19 localhost ss-server[4227]: 2019-12-15 03:22:19 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:23:06 localhost ss-server[4227]: 2019-12-15 03:23:06 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:23:17 localhost ss-server[4227]: 2019-12-15 03:23:17 ERROR: getpeername: Transport endpoint is not connected Dec 15 03:23:34 localhost ss-server[4227]: 2019-12-15 03:23:34 ERROR: getpeername: Transport endpoint is not connected ``` Log from client: ``` time="2019-12-15T11:17:06+08:00" level=trace msg="2082 read from stream 25 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="2082 read from stream 25 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="16378 read from stream 25 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="14574 read from stream 25 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="1668 read from stream 10 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="16378 read from stream 25 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="1883 read from stream 25 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="stream 25 actively closed" time="2019-12-15T11:17:06+08:00" level=trace msg="1697 read from stream 10 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="2082 sent to remote through stream 10 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="8328 sent to remote through stream 10 with err <nil>" time="2019-12-15T11:17:06+08:00" level=trace msg="4164 sent to remote through stream 10 with err <nil>" time="2019-12-15T11:17:07+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:07+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:07+08:00" level=trace msg="16378 sent to remote through stream 10 with err <nil>" time="2019-12-15T11:17:08+08:00" level=trace msg="577 read from stream 16 with err <nil>" time="2019-12-15T11:17:09+08:00" level=trace msg="10146 sent to remote through stream 10 with err <nil>" time="2019-12-15T11:17:09+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:10+08:00" level=trace msg="300 read from stream 1 with err <nil>" time="2019-12-15T11:17:10+08:00" level=trace msg="300 read from stream 2 with err <nil>" time="2019-12-15T11:17:11+08:00" level=trace msg="16378 sent to remote through stream 10 with err <nil>" time="2019-12-15T11:17:12+08:00" level=trace msg="577 read from stream 16 with err <nil>" time="2019-12-15T11:17:12+08:00" level=trace msg="139 read from stream 22 with err <nil>" time="2019-12-15T11:17:13+08:00" level=trace msg="stream 30 of session 2903889926 opened" time="2019-12-15T11:17:13+08:00" level=trace msg="stream 31 of session 2903889926 opened" time="2019-12-15T11:17:13+08:00" level=trace msg="stream 32 of session 2903889926 opened" time="2019-12-15T11:17:13+08:00" level=trace msg="stream 33 of session 2903889926 opened" time="2019-12-15T11:17:13+08:00" level=trace msg="stream 34 of session 2903889926 opened" time="2019-12-15T11:17:13+08:00" level=trace msg="259 sent to remote through stream 1 with err <nil>" time="2019-12-15T11:17:13+08:00" level=trace msg="1091 read from stream 10 with err <nil>" time="2019-12-15T11:17:14+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:14+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:16+08:00" level=trace msg="stream 35 of session 2903889926 opened" time="2019-12-15T11:17:16+08:00" level=trace msg="stream 36 of session 2903889926 opened" time="2019-12-15T11:17:21+08:00" level=trace msg="577 sent to remote through stream 16 with err <nil>" time="2019-12-15T11:17:21+08:00" level=trace msg="577 read from stream 16 with err <nil>" time="2019-12-15T11:17:21+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:23+08:00" level=trace msg="139 read from stream 22 with err <nil>" time="2019-12-15T11:17:24+08:00" level=trace msg="577 sent to remote through stream 16 with err <nil>" time="2019-12-15T11:17:25+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:25+08:00" level=trace msg="stream 37 of session 2903889926 opened" time="2019-12-15T11:17:27+08:00" level=trace msg="stream 38 of session 2903889926 opened" time="2019-12-15T11:17:27+08:00" level=trace msg="stream 39 of session 2903889926 opened" time="2019-12-15T11:17:29+08:00" level=trace msg="stream 40 of session 2903889926 opened" time="2019-12-15T11:17:29+08:00" level=trace msg="577 read from stream 16 with err <nil>" time="2019-12-15T11:17:30+08:00" level=trace msg="577 read from stream 10 with err <nil>" time="2019-12-15T11:17:32+08:00" level=trace msg="stream 41 of session 2903889926 opened" time="2019-12-15T11:17:32+08:00" level=trace msg="stream 42 of session 2903889926 opened" time="2019-12-15T11:17:32+08:00" level=trace msg="stream 43 of session 2903889926 opened" time="2019-12-15T11:17:33+08:00" level=debug msg="attempting to passively close session 2903889926" time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61910->111.111.111.111:443: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61915->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="6910 sent to remote through stream 10 with err write tcp 192.168.1.2:61910->111.111.111.111:443: wsasend: An existing connection was forcibly closed by the remote host." time="2019-12-15T11:17:33+08:00" level=trace msg="639 sent to remote through stream 31 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="99 sent to remote through stream 30 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="82 sent to remote through stream 32 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="99 sent to remote through stream 33 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="633 sent to remote through stream 34 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="122 sent to remote through stream 1 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="94 sent to remote through stream 35 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="94 sent to remote through stream 36 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="2082 sent to remote through stream 21 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="187 sent to remote through stream 22 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61913->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61914->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61912->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=debug msg="a connection for session 2903889926 has closed: read tcp 192.168.1.2:61911->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=debug msg="session 2903889926 closed gracefully" time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 38 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 37 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="298 sent to remote through stream 41 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 39 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="73 sent to remote through stream 40 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="85 sent to remote through stream 42 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="85 sent to remote through stream 43 with err write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=info msg="Attemtping to start a new session" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="259 sent to remote through stream 2 with err write tcp 192.168.1.2:61910->111.111.111.111:443: wsasend: An existing connection was forcibly closed by the remote host." time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=error msg="Failed to write to stream: write tcp 192.168.1.2:61910->111.111.111.111:443: use of closed network connection" time="2019-12-15T11:17:33+08:00" level=trace msg="client hello sent successfully" time="2019-12-15T11:17:33+08:00" level=trace msg="waiting for ServerHello" time="2019-12-15T11:17:33+08:00" level=trace msg="client hello sent successfully" time="2019-12-15T11:17:33+08:00" level=trace msg="waiting for ServerHello" time="2019-12-15T11:17:36+08:00" level=trace msg="client hello sent successfully" time="2019-12-15T11:17:36+08:00" level=trace msg="waiting for ServerHello" time="2019-12-15T11:17:54+08:00" level=error msg="Failed to establish new connections to remote: dial tcp 111.111.111.111:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." time="2019-12-15T11:17:54+08:00" level=error msg="Failed to establish new connections to remote: dial tcp 111.111.111.111:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." time="2019-12-15T11:17:54+08:00" level=error msg="Failed to establish new connections to remote: dial tcp 111.111.111.111:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." time="2019-12-15T11:17:57+08:00" level=trace msg="client hello sent successfully" time="2019-12-15T11:17:57+08:00" level=trace msg="waiting for ServerHello" time="2019-12-15T11:17:57+08:00" level=trace msg="client hello sent successfully" time="2019-12-15T11:17:57+08:00" level=trace msg="waiting for ServerHello" time="2019-12-15T11:17:58+08:00" level=trace msg="client hello sent successfully" time="2019-12-15T11:17:58+08:00" level=trace msg="waiting for ServerHello" time="2019-12-15T11:17:58+08:00" level=debug msg="All underlying connections established" time="2019-12-15T11:17:58+08:00" level=info msg="Session 4271994453 established" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 1 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="454 sent to remote through stream 1 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 4 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 5 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="406 sent to remote through stream 5 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 5 actively closed" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 6 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 10 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="236 sent to remote through stream 10 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 2 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 9 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="454 sent to remote through stream 4 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 3 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 7 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 8 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 12 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="298 sent to remote through stream 6 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 11 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 13 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 14 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 10 actively closed" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 15 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="212 sent to remote through stream 2 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 16 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="298 sent to remote through stream 9 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 17 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 18 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 19 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 20 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 21 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 22 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 23 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 24 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="224 sent to remote through stream 3 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 25 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 26 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 27 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="298 sent to remote through stream 7 with err <nil>" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 28 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 29 of session 4271994453 opened" time="2019-12-15T11:17:58+08:00" level=trace msg="stream 30 of session 4271994453 opened" ```
Author
Owner

@notsure2 commented on GitHub (Dec 15, 2019):

@chenshaoju maybe try my tcp keepalive patch.

<!-- gh-comment-id:565821728 --> @notsure2 commented on GitHub (Dec 15, 2019): @chenshaoju maybe try my tcp keepalive patch.
Author
Owner

@chenshaoju commented on GitHub (Dec 17, 2019):

@notsure2 Thank you, I have successfully merge your code and build. 👍

The test is running.

<!-- gh-comment-id:566348246 --> @chenshaoju commented on GitHub (Dec 17, 2019): @notsure2 Thank you, I have successfully merge your code and build. 👍 The test is running.
Author
Owner

@chenshaoju commented on GitHub (Dec 17, 2019):

Disconnect still happens, But I think it's a network issue.
When the disconnect happened, It's very difficult to connect SSH to the server at the same time.

After used @notsure2 TCP keepalive code, connection reliability has been improved, just a few seconds will rebuild the connection, no need waiting for a few minutes to rebuild the connection.
client.txt
server.txt

This issue will close after 24 hours, Thanks for everyone.

Cheers! 🍻

<!-- gh-comment-id:566364988 --> @chenshaoju commented on GitHub (Dec 17, 2019): Disconnect still happens, But I think it's a network issue. When the disconnect happened, It's very difficult to connect SSH to the server at the same time. After used @notsure2 TCP keepalive code, connection reliability has been improved, just a few seconds will rebuild the connection, no need waiting for a few minutes to rebuild the connection. [client.txt](https://github.com/cbeuw/Cloak/files/3971283/client.txt) [server.txt](https://github.com/cbeuw/Cloak/files/3971284/server.txt) This issue will close after 24 hours, Thanks for everyone. Cheers! 🍻
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/Cloak#65
No description provided.