@@ -22,6 +22,30 @@ var DefaultConnectTimeout = 5 * time.Second
2222
2323var log = logging .Logger ("tcp-tpt" )
2424
25+ const keepAlivePeriod = 30 * time .Second
26+
27+ type canKeepAlive interface {
28+ SetKeepAlive (bool ) error
29+ SetKeepAlivePeriod (time.Duration ) error
30+ }
31+
32+ var _ canKeepAlive = & net.TCPConn {}
33+
34+ func tryKeepAlive (conn net.Conn , keepAlive bool ) {
35+ keepAliveConn , ok := conn .(canKeepAlive )
36+ if ! ok {
37+ log .Errorf ("Can't set TCP keepalives." )
38+ return
39+ }
40+ if err := keepAliveConn .SetKeepAlive (keepAlive ); err != nil {
41+ log .Errorf ("Failed to enable TCP keepalive: %s" , err )
42+ return
43+ }
44+ if err := keepAliveConn .SetKeepAlivePeriod (keepAlivePeriod ); err != nil {
45+ log .Errorf ("Failed set keepalive period: %s" , err )
46+ }
47+ }
48+
2549// try to set linger on the connection, if possible.
2650func tryLinger (conn net.Conn , sec int ) {
2751 type canLinger interface {
@@ -33,17 +57,18 @@ func tryLinger(conn net.Conn, sec int) {
3357 }
3458}
3559
36- type lingerListener struct {
60+ type tcpListener struct {
3761 manet.Listener
3862 sec int
3963}
4064
41- func (ll * lingerListener ) Accept () (manet.Conn , error ) {
65+ func (ll * tcpListener ) Accept () (manet.Conn , error ) {
4266 c , err := ll .Listener .Accept ()
4367 if err != nil {
4468 return nil , err
4569 }
4670 tryLinger (c , ll .sec )
71+ tryKeepAlive (c , true )
4772 return c , nil
4873}
4974
@@ -106,6 +131,7 @@ func (t *TcpTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID)
106131 // linger is 0, connections are _reset_ instead of closed with a FIN.
107132 // This means we can immediately reuse the 5-tuple and reconnect.
108133 tryLinger (conn , 0 )
134+ tryKeepAlive (conn , true )
109135 return t .Upgrader .UpgradeOutbound (ctx , t , conn , p )
110136}
111137
@@ -127,7 +153,7 @@ func (t *TcpTransport) Listen(laddr ma.Multiaddr) (transport.Listener, error) {
127153 if err != nil {
128154 return nil , err
129155 }
130- list = & lingerListener {list , 0 }
156+ list = & tcpListener {list , 0 }
131157 return t .Upgrader .UpgradeListener (t , list ), nil
132158}
133159
0 commit comments