mirror of
https://github.com/slackhq/nebula.git
synced 2025-12-06 02:30:57 -08:00
add listen.send_recv_error config option (#670)
By default, Nebula replies to packets it has no tunnel for with a `recv_error` packet. This packet helps speed up re-connection in the case that Nebula on either side did not shut down cleanly. This response can be abused as a way to discover if Nebula is running on a host though. This option lets you configure if you want to send `recv_error` packets always, never, or only to private network remotes. valid values: always, never, private This setting is reloadable with SIGHUP.
This commit is contained in:
parent
85ec807b7e
commit
7b9287709c
5 changed files with 83 additions and 1 deletions
63
interface.go
63
interface.go
|
|
@ -3,7 +3,9 @@ package nebula
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
|
|
@ -68,6 +70,8 @@ type Interface struct {
|
|||
closed int32
|
||||
relayManager *relayManager
|
||||
|
||||
sendRecvErrorConfig sendRecvErrorConfig
|
||||
|
||||
// rebindCount is used to decide if an active tunnel should trigger a punch notification through a lighthouse
|
||||
rebindCount int8
|
||||
version string
|
||||
|
|
@ -84,6 +88,40 @@ type Interface struct {
|
|||
l *logrus.Logger
|
||||
}
|
||||
|
||||
type sendRecvErrorConfig uint8
|
||||
|
||||
const (
|
||||
sendRecvErrorAlways sendRecvErrorConfig = iota
|
||||
sendRecvErrorNever
|
||||
sendRecvErrorPrivate
|
||||
)
|
||||
|
||||
func (s sendRecvErrorConfig) ShouldSendRecvError(ip net.IP) bool {
|
||||
switch s {
|
||||
case sendRecvErrorPrivate:
|
||||
return ip.IsPrivate()
|
||||
case sendRecvErrorAlways:
|
||||
return true
|
||||
case sendRecvErrorNever:
|
||||
return false
|
||||
default:
|
||||
panic(fmt.Errorf("invalid sendRecvErrorConfig value: %d", s))
|
||||
}
|
||||
}
|
||||
|
||||
func (s sendRecvErrorConfig) String() string {
|
||||
switch s {
|
||||
case sendRecvErrorAlways:
|
||||
return "always"
|
||||
case sendRecvErrorNever:
|
||||
return "never"
|
||||
case sendRecvErrorPrivate:
|
||||
return "private"
|
||||
default:
|
||||
return fmt.Sprintf("invalid(%d)", s)
|
||||
}
|
||||
}
|
||||
|
||||
func NewInterface(ctx context.Context, c *InterfaceConfig) (*Interface, error) {
|
||||
if c.Outside == nil {
|
||||
return nil, errors.New("no outside connection")
|
||||
|
|
@ -232,6 +270,7 @@ func (f *Interface) RegisterConfigChangeCallbacks(c *config.C) {
|
|||
c.RegisterReloadCallback(f.reloadCA)
|
||||
c.RegisterReloadCallback(f.reloadCertKey)
|
||||
c.RegisterReloadCallback(f.reloadFirewall)
|
||||
c.RegisterReloadCallback(f.reloadSendRecvError)
|
||||
for _, udpConn := range f.writers {
|
||||
c.RegisterReloadCallback(udpConn.ReloadConfig)
|
||||
}
|
||||
|
|
@ -309,6 +348,30 @@ func (f *Interface) reloadFirewall(c *config.C) {
|
|||
Info("New firewall has been installed")
|
||||
}
|
||||
|
||||
func (f *Interface) reloadSendRecvError(c *config.C) {
|
||||
if c.InitialLoad() || c.HasChanged("listen.send_recv_error") {
|
||||
stringValue := c.GetString("listen.send_recv_error", "always")
|
||||
|
||||
switch stringValue {
|
||||
case "always":
|
||||
f.sendRecvErrorConfig = sendRecvErrorAlways
|
||||
case "never":
|
||||
f.sendRecvErrorConfig = sendRecvErrorNever
|
||||
case "private":
|
||||
f.sendRecvErrorConfig = sendRecvErrorPrivate
|
||||
default:
|
||||
if c.GetBool("listen.send_recv_error", true) {
|
||||
f.sendRecvErrorConfig = sendRecvErrorAlways
|
||||
} else {
|
||||
f.sendRecvErrorConfig = sendRecvErrorNever
|
||||
}
|
||||
}
|
||||
|
||||
f.l.WithField("sendRecvError", f.sendRecvErrorConfig.String()).
|
||||
Info("Loaded send_recv_error config")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Interface) emitStats(ctx context.Context, i time.Duration) {
|
||||
ticker := time.NewTicker(i)
|
||||
defer ticker.Stop()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue