hmgle / graftcp

A flexible tool for redirecting a given program's TCP traffic to SOCKS5 or HTTP proxy.
GNU General Public License v3.0
2.07k stars 174 forks source link

修复断开后未释放tcp连接资源的问题 #26

Closed ExplosiveBattery closed 4 years ago

hmgle commented 4 years ago

原代码在这里没有未释放 TCP 连接的问题。

这里有两个连接:conn 与 destConn,在等待两个 goroutine 调用 pipe() 返回后,它们都被 Close 了。

新提交的这部分代码会把这两个连接都多 Close 两次,可以加下 Close 的错误打印,重复关闭时就能看到 close tcp xxx->xxx: use of closed network connection 的提示了。

我倾向于把资源释放的操作放在这个资源持有者的外面一层,因为这样的话,可以让传入这个资源的内部函数更专注和纯粹,而且内部的这个函数也不知道还有没有其他协程也在使用这个资源,放在内部关闭也有可能出现问题。 例如这里在 pipe() 里面最早关闭这个连接的协程会让其他也在使用这个连接的地方失效,原来的代码在等待使用这些连接的协程不再使用连接后把它们关闭。

感谢你的关注与支持,如发现问题,欢迎提 issue 或 PR。

ExplosiveBattery commented 4 years ago

外层释放是走不到的,因为io.Copy的src如果没有关闭,这个函数就会堵着。需要在内层检查到一端关闭后关闭另外一端。如下图 37是运行时,35是程序关闭时,自带3行即运行时34个,关闭时32个。 image use of closed network connection 这个问题,我看了下这里面的https://github.com/golang/go/issues/29989 , 我打算用strings.Contains特判

ExplosiveBattery commented 4 years ago

除了连接会一直存在外,pipe也会开着 image

hmgle commented 4 years ago

这个问题是由于关闭前等待两个 pipe() 返回导致的,可以使用 SetDeadline 解决。稍后我更新下。

hmgle commented 4 years ago

@ExplosiveBattery 这个问题已解决了,可以拉取最新代码试试。