Skip to content
Snippets Groups Projects
peer.go 2.34 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oliver Herms's avatar
    Oliver Herms committed
    package server
    
    import (
    	"net"
    
    
    	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
    	"github.com/bio-routing/bio-rd/routingtable"
    
    Oliver Herms's avatar
    Oliver Herms committed
    	"github.com/bio-routing/bio-rd/routingtable/locRIB"
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    	"github.com/bio-routing/bio-rd/config"
    
    Oliver Herms's avatar
    Oliver Herms committed
    )
    
    type Peer struct {
    
    	addr              net.IP
    	asn               uint32
    	fsm               *FSM
    	rib               *locRIB.LocRIB
    	routerID          uint32
    	addPathSend       routingtable.ClientOptions
    	addPathRecv       bool
    	optOpenParams     []packet.OptParam
    	reconnectInterval time.Duration
    
    Oliver Herms's avatar
    Oliver Herms committed
    }
    
    
    // NewPeer creates a new peer with the given config. If an connection is established, the adjRIBIN of the peer is connected
    // to the given rib. To actually connect the peer, call Start() on the returned peer.
    
    Oliver Herms's avatar
    Oliver Herms committed
    func NewPeer(c config.Peer, rib *locRIB.LocRIB) (*Peer, error) {
    
    Oliver Herms's avatar
    Oliver Herms committed
    	p := &Peer{
    
    		addr:              c.PeerAddress,
    		asn:               c.PeerAS,
    		rib:               rib,
    		addPathSend:       c.AddPathSend,
    		addPathRecv:       c.AddPathRecv,
    		optOpenParams:     make([]packet.OptParam, 0),
    		reconnectInterval: c.ReconnectInterval,
    
    Oliver Herms's avatar
    Oliver Herms committed
    	}
    
    	p.fsm = NewFSM(p, c, rib)
    
    	caps := make([]packet.Capability, 0)
    
    	addPath := uint8(0)
    
    Oliver Herms's avatar
    Oliver Herms committed
    	if c.AddPathRecv {
    
    		addPath += packet.AddPathReceive
    	}
    	if !c.AddPathSend.BestOnly {
    		addPath += packet.AddPathSend
    	}
    
    	if addPath > 0 {
    		caps = append(caps, packet.Capability{
    			Code: packet.AddPathCapabilityCode,
    			Value: packet.AddPathCapability{
    				AFI:         packet.IPv4AFI,
    				SAFI:        packet.UnicastSAFI,
    				SendReceive: addPath,
    			},
    		})
    	}
    
    	for _, cap := range caps {
    		p.optOpenParams = append(p.optOpenParams, packet.OptParam{
    			Type:  packet.CapabilitiesParamType,
    			Value: cap,
    		})
    	}
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    	return p, nil
    }
    
    
    // GetAddr returns the IP address of the peer
    
    Oliver Herms's avatar
    Oliver Herms committed
    func (p *Peer) GetAddr() net.IP {
    	return p.addr
    }
    
    
    // GetASN returns the configured AS number of the peer
    
    Oliver Herms's avatar
    Oliver Herms committed
    func (p *Peer) GetASN() uint32 {
    	return p.asn
    }
    
    
    // Start the peers fsm. It starts from the Idle state and will get an ManualStart event. To trigger
    // reconnects if the fsm falls back into the Idle state, every reconnectInterval a ManualStart event is send.
    // The default value for reconnectInterval is 30 seconds.
    
    Oliver Herms's avatar
    Oliver Herms committed
    func (p *Peer) Start() {
    	p.fsm.start()
    
    	if p.reconnectInterval == 0 {
    		p.reconnectInterval = 30 * time.Second
    	}
    	t := time.Tick(p.reconnectInterval)
    
    Oliver Herms's avatar
    Oliver Herms committed
    }