Skip to content

Commit

Permalink
Merge pull request #29 from sapcc/timeouts
Browse files Browse the repository at this point in the history
Timeouts and mutex
  • Loading branch information
defo89 committed Nov 7, 2022
2 parents 21fdec2 + e72ac86 commit 6661704
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 27 deletions.
2 changes: 1 addition & 1 deletion cmd/go-pmtud/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import "github.com/sapcc/go-pmtud/internal/cmd"

func main() {
cmd.Execute()
}
}
27 changes: 22 additions & 5 deletions internal/arp/resolve.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,48 @@
package arp

import (
"net"
"sync"
"time"

"github.com/go-logr/logr"
mdarp "github.com/mdlayher/arp"
"github.com/sapcc/go-pmtud/internal/config"
"net"
"time"
)

var mutex sync.Mutex

type Resolver struct {
Log logr.Logger
Cfg *config.Config
}

func (r *Resolver) Resolve (ip string) (string, error) {
func (r *Resolver) Resolve(ip string) (string, error) {
// avoid ARP DDoS towards single node
time.Sleep(time.Duration(r.Cfg.RandDelay) * time.Millisecond)

log := r.Log.WithName("arp-resolver").WithValues("ip", ip)
ifi, err := net.InterfaceByName(r.Cfg.ReplicationInterface)
if err != nil {
log.Error(err, "error getting interface")
return "", err
}

// Lock so only one ARP resolver runs at a time
mutex.Lock()
c, err := mdarp.Dial(ifi)
if err != nil {
log.Error(err, "error dialing")
return "", err
}
defer c.Close()
err = c.SetDeadline(time.Now().Add(1*time.Second))
defer func() {
err = c.Close()
if err != nil {
log.Error(err, "error closing arp client")
}
mutex.Unlock()
}()
err = c.SetDeadline(time.Now().Add(time.Duration(r.Cfg.ArpRequestTimeoutSeconds) * time.Second))
if err != nil {
log.Error(err, "error setting deadline")
return "", err
Expand All @@ -37,5 +53,6 @@ func (r *Resolver) Resolve (ip string) (string, error) {
log.Error(err, "error resolving mac for ip")
return "", err
}

return mac.String(), nil
}
7 changes: 7 additions & 0 deletions internal/cmd/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package cmd
import (
goflag "flag"
"fmt"
"math/rand"
"os"
"time"

conf "github.com/sapcc/go-pmtud/internal/config"
metr "github.com/sapcc/go-pmtud/internal/metrics"
Expand Down Expand Up @@ -49,10 +51,15 @@ func init() {
rootCmd.PersistentFlags().IntVar(&cfg.HealthPort, "health_port", 30041, "Port for healthz")
rootCmd.PersistentFlags().Uint16Var(&cfg.NfGroup, "nflog_group", 33, "NFLOG group")
rootCmd.PersistentFlags().IntVar(&cfg.TimeToLive, "ttl", 1, "TTL for resent packets")
rootCmd.PersistentFlags().IntVar(&cfg.ArpCacheTimeoutMinutes, "node-timeout-minutes", 5, "Timeout in minutes for node arp entry")
rootCmd.PersistentFlags().IntVar(&cfg.ArpRequestTimeoutSeconds, "arp-timeout-seconds", 1, "Timeout in seconds for node arp request")
rootCmd.PersistentFlags().StringVar(&cfg.KubeContext, "kube_context", "", "kube-context to use")
rootCmd.PersistentFlags().AddGoFlagSet(goflag.CommandLine)
_ = viper.BindPFlags(rootCmd.PersistentFlags())

rand.Seed(time.Now().UnixNano())
cfg.RandDelay = rand.Intn(1000) + 1000

metrics.Registry.MustRegister(metr.SentError, metr.Error, metr.ArpResolveError, metr.SentPacketsPeer, metr.SentPackets, metr.RecvPackets, metr.CallbackDuration)
cfg.PeerList = make(map[string]conf.PeerEntry)
}
Expand Down
30 changes: 17 additions & 13 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,26 @@ import (

type PeerEntry struct {
LastUpdated time.Time
Mac string
Mac string
}

type Config struct {
//Peers []string
InterfaceNames []string
NodeName string
MetricsPort int
HealthPort int
TimeToLive int
NfGroup uint16
KubeContext string
NodeName string
MetricsPort int
HealthPort int
TimeToLive int
NfGroup uint16
KubeContext string

ReplicationInterface string
DefaultInterface string
InterfaceMtu int
PeerMutex sync.Mutex
PeerList map[string]PeerEntry
}
ReplicationInterface string
DefaultInterface string
InterfaceMtu int
PeerMutex sync.Mutex
PeerList map[string]PeerEntry
ArpCacheTimeoutMinutes int
ArpRequestTimeoutSeconds int

RandDelay int
}
2 changes: 1 addition & 1 deletion internal/nflog/pmtud.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (nfc *Controller) Start(startCtx context.Context) error {

nodeIface := cfg.ReplicationInterface
//ensure counters are reported
metrics.RecvPackets.WithLabelValues(cfg.NodeName).Add(0)
metrics.RecvPackets.WithLabelValues(cfg.NodeName, "").Add(0)
metrics.Error.WithLabelValues(cfg.NodeName).Add(0)

//TODO: make this a better logger
Expand Down
10 changes: 5 additions & 5 deletions internal/node/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import (
)

type Reconciler struct {
Log logr.Logger
Log logr.Logger
Client client.Client
Cfg *config.Config
Cfg *config.Config
}

func (r *Reconciler) Reconcile (ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
log := r.Log.WithValues("node", request.Name)

// We do not consider our own node
Expand All @@ -31,7 +31,7 @@ func (r *Reconciler) Reconcile (ctx context.Context, request reconcile.Request)
// We do not want to update every mac on every update
e, ok := r.Cfg.PeerList[request.Name]
if ok {
if time.Now().Before(e.LastUpdated.Add(1 * time.Minute)) {
if time.Now().Before(e.LastUpdated.Add(time.Duration(r.Cfg.ArpCacheTimeoutMinutes) * time.Minute)) {
return reconcile.Result{}, nil
}
}
Expand Down Expand Up @@ -60,7 +60,7 @@ func (r *Reconciler) Reconcile (ctx context.Context, request reconcile.Request)
log.Info("found mac " + mac)
entry := config.PeerEntry{
LastUpdated: time.Now(),
Mac: mac,
Mac: mac,
}
r.Cfg.PeerMutex.Lock()
r.Cfg.PeerList[request.Name] = entry
Expand Down
4 changes: 2 additions & 2 deletions internal/util/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func GetInterfaceIp(name string, log logr.Logger) (string, error) {
}
for _, addr := range addrs {
var ip net.IP
switch v:= addr.(type) {
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
Expand All @@ -91,4 +91,4 @@ func GetInterfaceIp(name string, log logr.Logger) (string, error) {
err = fmt.Errorf("%s is not connected to the network", name)
log.Error(err, "error finding interface ip")
return "", err
}
}

0 comments on commit 6661704

Please sign in to comment.