Skip to content

Commit

Permalink
implement WithDialerControl
Browse files Browse the repository at this point in the history
  • Loading branch information
jwhited committed Mar 12, 2021
1 parent dd049c8 commit dd6b120
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 104 deletions.
14 changes: 10 additions & 4 deletions examples/simple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,18 @@ var (

func main() {
flag.Parse()
serverOpts := make([]corebgp.ServerOption, 0)
var (
lis net.Listener
err error
)
if len(*bindAddr) > 0 {
serverOpts = append(serverOpts, corebgp.LocalAddrs([]string{*bindAddr}))
lis, err = net.Listen("tcp", *bindAddr)
if err != nil {
log.Fatalf("error constructing listener: %v", err)
}
}
corebgp.SetLogger(log.Print)
srv, err := corebgp.NewServer(net.ParseIP(*routerID), serverOpts...)
srv, err := corebgp.NewServer(net.ParseIP(*routerID))
if err != nil {
log.Fatalf("error constructing server: %v", err)
}
Expand All @@ -52,7 +58,7 @@ func main() {

srvErrCh := make(chan error)
go func() {
err := srv.Serve()
err := srv.Serve([]net.Listener{lis})
srvErrCh <- err
}()

Expand Down
1 change: 1 addition & 0 deletions fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ func (f *fsm) dialPeer() {
}
dialer := &net.Dialer{
LocalAddr: laddr,
Control: f.peer.options.dialerControlFn,
}
conn, err := dialer.DialContext(ctx, "tcp",
net.JoinHostPort(f.peer.config.RemoteAddress.String(),
Expand Down
12 changes: 12 additions & 0 deletions peer_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package corebgp

import (
"errors"
"syscall"
"time"
)

Expand All @@ -11,6 +12,7 @@ type peerOptions struct {
connectRetryTime time.Duration
port int
passive bool
dialerControlFn func(network, address string, c syscall.RawConn) error
}

func (p peerOptions) validate() error {
Expand Down Expand Up @@ -98,3 +100,13 @@ func WithPort(p int) PeerOption {
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
})
}
38 changes: 8 additions & 30 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import (

// Server is a BGP server that manages peers.
type Server struct {
mu sync.Mutex
id uint32
peers map[string]*peer
options serverOptions
mu sync.Mutex
id uint32
peers map[string]*peer

// control channels & run state
serving bool
Expand All @@ -23,26 +22,16 @@ type Server struct {
}

// NewServer creates a new Server.
func NewServer(routerID net.IP, opts ...ServerOption) (*Server, error) {
func NewServer(routerID net.IP) (*Server, error) {
v4 := routerID.To4()
if v4 == nil {
return nil, errors.New("invalid router ID")
}

o := defaultServerOptions()
for _, opt := range opts {
opt.apply(&o)
}
err := o.validate()
if err != nil {
return nil, err
}

s := &Server{
mu: sync.Mutex{},
id: binary.BigEndian.Uint32(v4),
peers: make(map[string]*peer),
options: o,
doneServingCh: make(chan struct{}),
closeCh: make(chan struct{}),
}
Expand All @@ -54,10 +43,10 @@ var (
ErrPeerNotExist = errors.New("peer does not exist")
)

// Serve starts all peers' FSMs, binds to local sockets for incoming connection
// handling (if Server was created with LocalAddrs), and then blocks. Serve
// returns ErrServerClosed upon Close() or a listener/bind error if one occurs.
func (s *Server) Serve() error {
// Serve starts all peers' FSMs, starts handling incoming connections if a
// non-nil listener is provided, and then blocks. Serve returns ErrServerClosed
// upon Close() or a listener error if one occurs.
func (s *Server) Serve(listeners []net.Listener) error {
s.mu.Lock()
// check if server has been closed
select {
Expand Down Expand Up @@ -88,18 +77,7 @@ func (s *Server) Serve() error {
s.mu.Unlock()
}()

// construct and bind listeners
lisErrCh := make(chan error)
listeners := make([]net.Listener, 0)
for laddr := range s.options.localAddrs {
lis, err := net.Listen("tcp", laddr)
if err != nil {
return err
}
defer lis.Close()
listeners = append(listeners, lis)
}

lisWG := &sync.WaitGroup{}
closingListeners := make(chan struct{})
for _, lis := range listeners {
Expand Down
58 changes: 0 additions & 58 deletions server_options.go

This file was deleted.

33 changes: 21 additions & 12 deletions test/bird_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,7 @@ func TestCleanBGPSession(t *testing.T) {
event: eventCh,
}

opts := make([]corebgp.ServerOption, 0)
opts = append(opts, corebgp.LocalAddrs([]string{fmt.Sprintf("%s:179", myAddress)}))
server, err := corebgp.NewServer(net.ParseIP(myAddress), opts...)
server, err := corebgp.NewServer(net.ParseIP(myAddress))
if err != nil {
t.Fatalf("error constructing server: %v", err)
}
Expand All @@ -184,7 +182,12 @@ func TestCleanBGPSession(t *testing.T) {
// enable BGP session on BIRD side
birdControl(t, "enable corebgp")

go server.Serve() // nolint: errcheck
lis, err := net.Listen("tcp", net.JoinHostPort(myAddress, "179"))
if err != nil {
t.Fatalf("error constructing listener: %v", err)
}
defer lis.Close()
go server.Serve([]net.Listener{lis}) // nolint: errcheck
defer server.Close()

// verify GetCapabilities
Expand Down Expand Up @@ -365,9 +368,7 @@ func TestNotificationSentOnOpen(t *testing.T) {
event: eventCh,
}

opts := make([]corebgp.ServerOption, 0)
opts = append(opts, corebgp.LocalAddrs([]string{fmt.Sprintf("%s:179", myAddress)}))
server, err := corebgp.NewServer(net.ParseIP(myAddress), opts...)
server, err := corebgp.NewServer(net.ParseIP(myAddress))
if err != nil {
t.Fatalf("error constructing server: %v", err)
}
Expand All @@ -387,7 +388,12 @@ func TestNotificationSentOnOpen(t *testing.T) {
// enable BGP session on BIRD side
birdControl(t, "enable corebgp")

go server.Serve() // nolint: errcheck
lis, err := net.Listen("tcp", net.JoinHostPort(myAddress, "179"))
if err != nil {
t.Fatalf("error constructing listener: %v", err)
}
defer lis.Close()
go server.Serve([]net.Listener{lis}) // nolint: errcheck
defer server.Close()

// expect get caps event
Expand Down Expand Up @@ -451,9 +457,7 @@ func TestNotificationSentOnUpdate(t *testing.T) {
event: eventCh,
}

opts := make([]corebgp.ServerOption, 0)
opts = append(opts, corebgp.LocalAddrs([]string{fmt.Sprintf("%s:179", myAddress)}))
server, err := corebgp.NewServer(net.ParseIP(myAddress), opts...)
server, err := corebgp.NewServer(net.ParseIP(myAddress))
if err != nil {
t.Fatalf("error constructing server: %v", err)
}
Expand All @@ -473,7 +477,12 @@ func TestNotificationSentOnUpdate(t *testing.T) {
// enable BGP session on BIRD side
birdControl(t, "enable corebgp")

go server.Serve() // nolint: errcheck
lis, err := net.Listen("tcp", net.JoinHostPort(myAddress, "179"))
if err != nil {
t.Fatalf("error constructing listener: %v", err)
}
defer lis.Close()
go server.Serve([]net.Listener{lis}) // nolint: errcheck
defer server.Close()

// expect get caps event
Expand Down

0 comments on commit dd6b120

Please sign in to comment.