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

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

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

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

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

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

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

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