diff --git a/.dev/br-lft-act.yaml b/.dev/br-lft-act.yaml index 7ea0bfa..77a0043 100644 --- a/.dev/br-lft-act.yaml +++ b/.dev/br-lft-act.yaml @@ -7,6 +7,7 @@ bridges: status_addr: 10.0.0.2:8080 partner_url: http://10.0.0.3:8080/ + partner_polling_interface: eth0 probe_interval: 1s probe_location: left/active diff --git a/.dev/br-lft-sby.yaml b/.dev/br-lft-sby.yaml index 8e3c26c..13fc980 100644 --- a/.dev/br-lft-sby.yaml +++ b/.dev/br-lft-sby.yaml @@ -7,6 +7,7 @@ bridges: status_addr: 10.0.0.3:8080 partner_url: http://10.0.0.2:8080/ + partner_polling_interface: eth0 probe_interval: 1s probe_location: left/standby diff --git a/bridge/server.go b/bridge/server.go index 96f2818..1969305 100644 --- a/bridge/server.go +++ b/bridge/server.go @@ -17,6 +17,7 @@ import ( "github.com/flashbots/vpnham/reconciler" "github.com/flashbots/vpnham/transponder" "github.com/flashbots/vpnham/types" + "github.com/flashbots/vpnham/utils" "github.com/google/uuid" "go.uber.org/zap" ) @@ -77,6 +78,18 @@ func NewServer(ctx context.Context, cfg *config.Bridge) (*Server, error) { Timeout: cfg.PartnerStatusTimeout, KeepAlive: 2 * cfg.PartnerStatusTimeout, } + if cfg.PartnerPollingInterface != "" { + ipv4s, ipv6s, err := utils.GetInterfaceIPs(cfg.PartnerPollingInterface) + if err != nil { + return nil, err + } + if len(ipv4s) > 0 { + dialer.LocalAddr = &net.TCPAddr{IP: net.ParseIP(ipv4s[0])} + } + if len(ipv6s) > 0 { + dialer.LocalAddr = &net.TCPAddr{IP: net.ParseIP(ipv6s[0])} + } + } transport := &http.Transport{ DialContext: dialer.DialContext, IdleConnTimeout: 4 * cfg.PartnerStatusTimeout, diff --git a/config/bridge.go b/config/bridge.go index 9183400..496661a 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -27,6 +27,7 @@ type Bridge struct { StatusAddr types.Address `yaml:"status_addr"` PartnerURL string `yaml:"partner_url"` + PartnerPollingInterface string `yaml:"partner_polling_interface"` PartnerStatusTimeout time.Duration `yaml:"partner_status_timeout"` PartnerStatusThresholdDown int `yaml:"partner_status_threshold_down"` PartnerStatusThresholdUp int `yaml:"partner_status_threshold_up"` @@ -41,11 +42,12 @@ type Bridge struct { var ( errBridgeActiveTunnelInterfacesCountIsInvalid = errors.New("bridge has invalid count of active interfaces configured (must be only 1)") + errBridgeExtraPeerCIDRIsInvalid = errors.New("bridge extra peer cidr is invalid") errBridgeInterfaceIsInvalid = errors.New("bridge interface is invalid") + errBridgePartnerPollingInterfaceIsInvalid = errors.New("bridge polling interface is invalid") errBridgePartnerStatusThresholdsAreInvalid = errors.New("bridge partner status thresholds are invalid") errBridgePartnerStatusURLIsInvalid = errors.New("bridge partner status url is invalid") errBridgePeerCIDRIsInvalid = errors.New("bridge peer cidr is invalid") - errBridgeExtraPeerCIDRIsInvalid = errors.New("bridge extra peer cidr is invalid") errBridgeReconcileConfigurationIsInvalid = errors.New("bridge reconcile configuration is invalid") errBridgeRoleIsInvalid = errors.New("bridge role is invalid") errBridgeStatusAddrIsInvalid = errors.New("bridge status addr is invalid") @@ -145,6 +147,16 @@ func (b *Bridge) Validate(ctx context.Context) error { } } + { // partner_polling_interface + if b.PartnerPollingInterface != "" { + if _, _, err := utils.GetInterfaceIPs(b.PartnerPollingInterface); err != nil { + return fmt.Errorf("%w: %w", + errBridgePartnerPollingInterfaceIsInvalid, err, + ) + } + } + } + { // partner_status_threshold_down, partner_status_threshold_up if _, err := monitor.New(b.PartnerStatusThresholdDown, b.PartnerStatusThresholdUp); err != nil { return fmt.Errorf("%w: %w",