V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
logic2
V2EX  ›  外包

帮忙修复一个 golang 的连接问题,红包 50 元

  •  
  •   logic2 · 7 天前 · 1916 次点击
    问题是服务端连接断开后,或者服务端完全挂壁了之后,本地的透明代理的协程并没有关闭,且 TCP 状态还保持着,目标,服务端断开后,客户端自动断开与被代理端的 tcp 连接

    https://github.com/fqdeng/x-proxy

    感谢
    第 1 条附言  ·  7 天前
    https://github.com/fqdeng/x-proxy#

    定位了,不是 io.copy 的问题,纯粹只有透明代理的情况下 无法关闭客户端的 IO ,我继续排查一下
    第 2 条附言  ·  6 天前

    大家有AI一顿搞,根本没解决问题,果然AI不是万能的

    最后我试了一下socks5是没问题的,问题只可能出在获取src地址的调用上了 把这段代码 让qwen3-coder看了下

    • 定位到了

    https://github.com/fqdeng/x-proxy/blob/master/pkg/proxy/transparent_linux.go

    • 这个文件的的 110行
    fd := file.Fd()
    

    这个会对文件描述符进行复制,复制后 Conn的行为会异常,导致Conn无法关闭,最终协程无法退出

    潜在影响:会严重影响 Conn 关闭! 问题所在: tcpConn.File() 会复制文件描述符 这个操作会将 TCP 连接的文件描述符复制给一个新的 *os.File 但原始的 net.Conn 仍然持有该连接 file.Close() 只关闭复制的文件描述符 当你调用 file.Close() 时,只是关闭了复制的 fd 原始的 net.Conn 仍然可以正常使用 但是!这会破坏连接的状态 在某些系统上,复制 fd 后再关闭它,可能会影响原始连接的行为 特别是在透明代理场景下,可能影响后续的数据传输

    第 3 条附言  ·  6 天前
    AI 确实不是万能的,一堆代码弄过去分析 它一定给你弄错,还是要不断测试,把问题可能性缩小,最后把代码拿给 AI 分析才是理性的
    17 条回复    2025-08-15 22:18:23 +08:00
    suruiran
        1
    suruiran  
       7 天前
    读的时候加个 buf 。定时的读一个字节,然后放到 buf 里面,用来检测连接。然后业务读都从 buf 里取,还要加个锁或者 chan 来实现同步。
    676529483
        2
    676529483  
       7 天前
    加个心跳吧
    logic2
        3
    logic2  
    OP
       7 天前
    @suruiran 佬,能直接帮忙修复一下 io.go 文件 给我看看么,我对 golang 不是很懂的
    logic2
        4
    logic2  
    OP
       7 天前
    问题大概率出在这里,看有没有办法 加入心跳连接之类的功能
    https://github.com/fqdeng/x-proxy/blob/master/pkg/proxy/io.go
    logic2
        5
    logic2  
    OP
       7 天前
    @676529483 可以,我用 AI 试下,在应用层把协议改了,再加一层心跳检测
    mainjzb
        6
    mainjzb  
       7 天前
    io.go 文件 copyWithTimeout
    再写一个 copyTCPWithTimeout ,110 行 Read 失败后,调用 dst.CloseWrite() [dst 需要改成 net.TCPConn
    logic2
        7
    logic2  
    OP
       7 天前
    @mainjzb 佬,麻烦直接提个 PR 看看
    mrjnamei
        8
    mrjnamei  
       7 天前
    logic2
        9
    logic2  
    OP
       7 天前
    @mrjnamei 一眼看了,AI 投递的,哈哈,测试了还是不行,服务端即使关闭的情况下,客户端还是维持了跟被代理端的 TCP 连接
    zhouyin
        10
    zhouyin  
       7 天前
    以外包 fix bug 类项目 50 人民币怎么够 50 只够解决很小的 css html
    这种难度起码 400 美元
    ZGeek
        11
    ZGeek  
       7 天前
    看样子想做一个 windows 下的隧道,但是这样的东西其实已经很多了,为什么要自己开发呢?
    logic2
        12
    logic2  
    OP
       7 天前
    @ZGeek 看样子回复很多了,你为什么要发这个回复呢
    ChunkitAu
        13
    ChunkitAu  
       7 天前
    猜测: 卡在了`read`函数,设置了`SetReadDeadline`导致下一次循环还没开始,无法从`<-ctx.Done()` 退出

    感觉可以在起一个协程来来单独控制连接的关闭
    ```
    go func() {
    <-ctx.Done()
    src.Close()
    dst.Close()
    }()
    ```
    suruiran
        14
    suruiran  
       6 天前
    怎么仓库都没了,我上午都没进去看呢……
    logic2
        15
    logic2  
    OP
       6 天前
    @suruiran #14 私有化了
    logic2
        16
    logic2  
    OP
       6 天前
    @suruiran #14 又公开了,老哥看下,后续,问题出在 conn.Fd()上面了,这个方法会影响 Conn 的后续行为
    logic2
        17
    logic2  
    OP
       6 天前
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2532 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 11:56 · PVG 19:56 · LAX 04:56 · JFK 07:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.