[GH-ISSUE #2534] Low Bandwidth, Configurable TCP/IP KeepAlive for server and client code <-> in **golib** net and mux #2011

Closed
opened 2026-05-05 13:18:06 -06:00 by gitea-mirror · 4 comments
Owner

Originally created by @adioanca on GitHub (Aug 18, 2021).
Original GitHub issue: https://github.com/fatedier/frp/issues/2534

The solution you want

Low Bandwidth, Configurable TCP/IP KeepAlive for server and client code <-> in golib net and mux

Alternatives considered

Have previously played with options in frp[sc]-full.ini

there is a 15sec TCP KeepAlive sequence enabled by golang's net module. This adds a lot, 4 packets on the wire every 15 seconds; tcp/http Keep-Alive(s) added on top.

would like to keep idle bandwidth down, with TCP connections opened for minutes/hours/days

NOTE I'm a go beginner, would like some help in converting this into a feature, or a configurable option, or just disable TCP Keep-Alive. This a complete hack with some code I've found across the net.

Ref: https://stackoverflow.com/questions/46686360/difference-of-dialcontext-keepalive-and-transport-idletimeout-of-go-http-client?answertab=active#tab-top
Ref: https://thenotexpert.com/golang-tcp-keepalive/
Ref: some other place I can't find now

How to implement this function

        if proxyStr == "" {
                return net.Dial("tcp", addr)
        }

with

        if proxyStr == "" {
                var dialer = &net.Dialer{
                        KeepAlive: 30*60 * time.Second, // change to the value you want
                }
                return dialer.Dial("tcp", addr)
                //return net.Dial("tcp", addr)
        }

in vendor/github.com/fatedier/golib/net/proxy.go for the client

and

                go mux.handleConn(conn)

with

  tcpconn, ok := conn.(*net.TCPConn)
  if !ok {
    fmt.Println("error in casting *net.Conn to *net.TCPConn!")
    //os.Exit(1)
  }
  file, err := tcpconn.File()
  if err != nil {
    fmt.Println("error in getting file for the connection!")
    //os.Exit(1)
  }
  err = syscall.SetsockoptInt(int(file.Fd()), syscall.SOL_TCP, syscall.TCP_KEEPINTVL, 60*60)
  file.Close()
  if err != nil {
    fmt.Println("error in setting priority option on socket:", err)
    //os.Exit(1)
  }
fmt.Println("The CODE wass EXECUTED")
                go mux.handleConn(conn)

in vendor/github.com/fatedier/golib/net/mux/mux.go for the server

Application scenarios of this function

Need the entire frp solution to consume network bandwidth at a minimum. Fo example we'd like to test with heartbeats(as captured by tcpdump) at 15min, 30m, 1h, 2h, 1d, etc. This would give as a compromise between network bangwidth consumption VS responsiveness.

Originally created by @adioanca on GitHub (Aug 18, 2021). Original GitHub issue: https://github.com/fatedier/frp/issues/2534 <!-- From Chinese to English by machine translation, welcome to revise and polish. --> **The solution you want** <!--A clear and concise description of the solution you want. --> Low Bandwidth, Configurable TCP/IP `KeepAlive` for server and client code <-> in **[golib](https://github.com/fatedier/golib)** `net` and `mux` **Alternatives considered** <!--A clear and concise description of any alternative solutions or features you have considered. --> Have previously played with options in frp[sc]-full.ini there is a 15sec `TCP KeepAlive sequence` enabled by golang's `net` module. This adds a lot, 4 packets on the wire every 15 seconds; tcp/http Keep-Alive(s) added on top. would like to keep idle bandwidth down, with TCP connections opened for minutes/hours/days **NOTE** I'm a go beginner, would like some help in converting this into a feature, or a configurable option, or just disable TCP Keep-Alive. This a complete hack with some code I've found across the net. Ref: https://stackoverflow.com/questions/46686360/difference-of-dialcontext-keepalive-and-transport-idletimeout-of-go-http-client?answertab=active#tab-top Ref: https://thenotexpert.com/golang-tcp-keepalive/ Ref: some other place I can't find now **How to implement this function** <!--Implementation steps for the solution you want. --> ```go if proxyStr == "" { return net.Dial("tcp", addr) } ``` with ```go if proxyStr == "" { var dialer = &net.Dialer{ KeepAlive: 30*60 * time.Second, // change to the value you want } return dialer.Dial("tcp", addr) //return net.Dial("tcp", addr) } ``` in `vendor/github.com/fatedier/golib/net/proxy.go` for the client and ```go go mux.handleConn(conn) ``` with ```go tcpconn, ok := conn.(*net.TCPConn) if !ok { fmt.Println("error in casting *net.Conn to *net.TCPConn!") //os.Exit(1) } file, err := tcpconn.File() if err != nil { fmt.Println("error in getting file for the connection!") //os.Exit(1) } err = syscall.SetsockoptInt(int(file.Fd()), syscall.SOL_TCP, syscall.TCP_KEEPINTVL, 60*60) file.Close() if err != nil { fmt.Println("error in setting priority option on socket:", err) //os.Exit(1) } fmt.Println("The CODE wass EXECUTED") go mux.handleConn(conn) ``` in `vendor/github.com/fatedier/golib/net/mux/mux.go` for the server **Application scenarios of this function** <!--Make a clear and concise description of the application scenario of the solution you want. --> Need the entire frp solution to consume network bandwidth at a minimum. Fo example we'd like to test with heartbeats(as captured by `tcpdump`) at 15min, 30m, 1h, 2h, 1d, etc. This would give as a compromise between network bangwidth consumption VS responsiveness.
Author
Owner

@fatedier commented on GitHub (Aug 18, 2021):

TCP KeepAlive package may only consume 64 byte traffic and will not be sent if there are already traffics in connections.

frp also has app-level heartbeat to ensure it works fine, you can specify heartbeat interval in configuretion file.

If you really care about traffic like 100KB, this project may be not suitable for your scenario.

<!-- gh-comment-id:900772250 --> @fatedier commented on GitHub (Aug 18, 2021): TCP KeepAlive package may only consume 64 byte traffic and will not be sent if there are already traffics in connections. frp also has app-level heartbeat to ensure it works fine, you can specify heartbeat interval in configuretion file. If you really care about traffic like 100KB, this project may be not suitable for your scenario.
Author
Owner

@adioanca commented on GitHub (Aug 22, 2021):

3 days test looks great. under 30kb/day with hearbeat put at 3600 and TCP KeepAlive(s) back to OS default of 7200 sec.

Thank you for this project.

Let me know if want to see the changes that were done - in a nutshell: refatored the code from above and changed a couple hardcoded values in frp source code.

PS: do you foresee any problem if we bump the heartbeat interval from 3600 to 86400 sec? (will disable TCP KeepAlive of course) - this would be usefull in a closed (V)LAN/network

<!-- gh-comment-id:903283462 --> @adioanca commented on GitHub (Aug 22, 2021): 3 days test looks great. under 30kb/day with hearbeat put at 3600 and TCP KeepAlive(s) back to OS default of 7200 sec. Thank you for this project. Let me know if want to see the changes that were done - in a nutshell: refatored the code from above and changed a couple hardcoded values in frp source code. PS: do you foresee any problem if we bump the heartbeat interval from 3600 to 86400 sec? (will disable TCP KeepAlive of course) - this would be usefull in a closed (V)LAN/network
Author
Owner

@fatedier commented on GitHub (Aug 23, 2021):

If you can make sure there will be no network error in your environment, any heartbeat interval is ok.

<!-- gh-comment-id:903402603 --> @fatedier commented on GitHub (Aug 23, 2021): If you can make sure there will be no network error in your environment, any heartbeat interval is ok.
Author
Owner

@adioanca commented on GitHub (Aug 23, 2021):

Cool. Thanks.

I'll close this issue, as the talk and changes from above, plus 3-4 days test with heartbeat @1h and TCP KeepAlives @7200 would get us under 30KB/day idle traffic and that fulfills the *low bandwidth" requirement.

<!-- gh-comment-id:903585750 --> @adioanca commented on GitHub (Aug 23, 2021): Cool. Thanks. I'll close this issue, as the talk and changes from above, plus 3-4 days test with heartbeat @1h and TCP KeepAlives @7200 would get us under 30KB/day idle traffic and that fulfills the *low bandwidth" requirement.
Sign in to join this conversation.
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: github-starred/frp#2011
No description provided.