From 7f1c630a0be7a249506675e66cf37139c4cf7b8c Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 6 Jan 2015 12:09:34 -0800 Subject: [PATCH] *: use keepalive listener to detect dead clients --- etcdmain/etcd.go | 2 +- pkg/transport/keepalive_listener.go | 51 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 pkg/transport/keepalive_listener.go diff --git a/etcdmain/etcd.go b/etcdmain/etcd.go index 1327ce829..50d759692 100644 --- a/etcdmain/etcd.go +++ b/etcdmain/etcd.go @@ -126,7 +126,7 @@ func startEtcd(cfg *config) (<-chan struct{}, error) { clns := make([]net.Listener, 0) for _, u := range cfg.lcurls { var l net.Listener - l, err = transport.NewListener(u.Host, u.Scheme, cfg.clientTLSInfo) + l, err = transport.NewKeepAliveListener(u.Host, u.Scheme, cfg.clientTLSInfo) if err != nil { return nil, err } diff --git a/pkg/transport/keepalive_listener.go b/pkg/transport/keepalive_listener.go new file mode 100644 index 000000000..b33e3ff54 --- /dev/null +++ b/pkg/transport/keepalive_listener.go @@ -0,0 +1,51 @@ +/* + Copyright 2015 CoreOS, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package transport + +import ( + "net" + "time" +) + +// NewKeepAliveListener returns a listener that listens on the given address. +// http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html +func NewKeepAliveListener(addr string, scheme string, info TLSInfo) (net.Listener, error) { + ln, err := NewListener(addr, scheme, info) + if err != nil { + return nil, err + } + return &keepaliveListener{ + Listener: ln, + }, nil +} + +type keepaliveListener struct { + net.Listener +} + +func (kln *keepaliveListener) Accept() (net.Conn, error) { + c, err := kln.Listener.Accept() + if err != nil { + return nil, err + } + tcpc := c.(*net.TCPConn) + // detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl + // default on linux: 30 + 8 * 30 + // default on osx: 30 + 8 * 75 + tcpc.SetKeepAlivePeriod(30 * time.Second) + return tcpc, nil +}