package transport import ( "syscall" ) type Controls []func(network, addr string, conn syscall.RawConn) error func (ctls Controls) Control(network, addr string, conn syscall.RawConn) error { for _, s := range ctls { if err := s(network, addr, conn); err != nil { return err } } return nil } type SocketOpts struct { // ReusePort enables socket option SO_REUSEPORT [1] which allows rebind of // a port already in use. User should keep in mind that flock can fail // in which case lock on data file could result in unexpected // condition. User should take caution to protect against lock race. // [1] https://man7.org/linux/man-pages/man7/socket.7.html ReusePort bool `json:"reuse-port"` // ReuseAddress enables a socket option SO_REUSEADDR which allows // binding to an address in `TIME_WAIT` state. Useful to improve MTTR // in cases where etcd slow to restart due to excessive `TIME_WAIT`. // [1] https://man7.org/linux/man-pages/man7/socket.7.html ReuseAddress bool `json:"reuse-address"` } func getControls(sopts *SocketOpts) Controls { ctls := Controls{} if sopts.ReuseAddress { ctls = append(ctls, setReuseAddress) } if sopts.ReusePort { ctls = append(ctls, setReusePort) } return ctls } func (sopts *SocketOpts) Empty() bool { return !sopts.ReuseAddress && !sopts.ReusePort }