This repository has been archived by the owner on Jun 10, 2024. It is now read-only.
forked from jwhited/corebgp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
peer_options.go
134 lines (118 loc) · 3.89 KB
/
peer_options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package corebgp
import (
"errors"
"net/netip"
"syscall"
"time"
)
type peerOptions struct {
holdTime time.Duration
idleHoldTime time.Duration
connectRetryTime time.Duration
port int
passive bool
dialerControlFn func(network, address string, c syscall.RawConn) error
localAddress netip.Addr
}
func (p peerOptions) validate() error {
if p.holdTime < time.Second*3 && p.holdTime != 0 {
return errors.New("hold time must be 0 or >= 3 seconds")
}
if p.port < 1 || p.port > 65535 {
return errors.New("port must be between 1 and 65535")
}
return nil
}
type PeerOption interface {
apply(*peerOptions)
}
const (
// DefaultHoldTimeSeconds is the default hold down time in seconds.
DefaultHoldTimeSeconds uint16 = 90
// DefaultIdleHoldTime is the default idle state hold time for a peer.
DefaultIdleHoldTime = time.Second * 5
// DefaultConnectRetryTime is the default maximum time spent waiting for an
// outbound dial to connect.
//
// https://tools.ietf.org/html/rfc4271#section-8.2.2
// The exact value of the ConnectRetryTimer is a local matter, but it
// SHOULD be sufficiently large to allow TCP initialization.
DefaultConnectRetryTime = time.Second * 5
// DefaultPort is the default TCP port for a peer.
DefaultPort = 179
)
func defaultPeerOptions() peerOptions {
return peerOptions{
holdTime: time.Second * time.Duration(DefaultHoldTimeSeconds),
idleHoldTime: DefaultIdleHoldTime,
connectRetryTime: DefaultConnectRetryTime,
port: DefaultPort,
passive: false,
localAddress: netip.Addr{},
}
}
type funcPeerOption struct {
fn func(*peerOptions)
}
func (f *funcPeerOption) apply(p *peerOptions) {
f.fn(p)
}
func newFuncPeerOption(f func(*peerOptions)) *funcPeerOption {
return &funcPeerOption{
fn: f,
}
}
// WithPassive returns a PeerOption that sets a Peer to passive mode. In passive
// mode a peer will not dial out and will only accept incoming connections.
func WithPassive() PeerOption {
return newFuncPeerOption(func(o *peerOptions) {
o.passive = true
})
}
// WithIdleHoldTime returns a PeerOption that sets the idle hold time for a
// peer. Idle hold time controls how quickly a peer can oscillate from idle to
// the connect state.
func WithIdleHoldTime(t time.Duration) PeerOption {
return newFuncPeerOption(func(o *peerOptions) {
o.idleHoldTime = t
})
}
// WithConnectRetryTime returns a PeerOption that sets the connect retry time
// for a peer.
func WithConnectRetryTime(t time.Duration) PeerOption {
return newFuncPeerOption(func(o *peerOptions) {
o.connectRetryTime = t
})
}
// WithPort returns a PeerOption that sets the TCP port for a peer.
func WithPort(p int) PeerOption {
return newFuncPeerOption(func(o *peerOptions) {
o.port = p
})
}
// WithDialerControl returns a PeerOption that sets the outbound net.Dialer
// Control field. This is commonly used to set socket options, e.g. ip TTL, tcp
// md5, tcp_nodelay, etc...
func WithDialerControl(fn func(network, address string,
c syscall.RawConn) error) PeerOption {
return newFuncPeerOption(func(o *peerOptions) {
o.dialerControlFn = fn
})
}
// WithLocalAddress returns a PeerOption that specifies the source address to
// use when dialing outbound, and to verify as a destination for inbound
// connections. Without this PeerOption corebgp behaves loosely, accepting
// inbound connections regardless of the destination address, and falling back
// on the OS for outbound source address selection.
func WithLocalAddress(localAddress netip.Addr) PeerOption {
return newFuncPeerOption(func(o *peerOptions) {
o.localAddress = localAddress
})
}
// WithHoldTime returns a PeerOption that sets the hold time (in seconds) to be
// advertised to the peer via OPEN message. Hold time MUST be 0 or >= 3 seconds.
func WithHoldTime(seconds uint16) PeerOption {
return newFuncPeerOption(func(o *peerOptions) {
o.holdTime = time.Duration(seconds) * time.Second
})
}