2024-03-31 09:31:50 +11:00
|
|
|
|
/*
|
|
|
|
|
Copyright 2024 Josh Deprez
|
|
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
|
limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
2024-04-19 14:57:25 +10:00
|
|
|
|
package router
|
2024-03-25 19:30:06 +11:00
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
2024-03-30 14:13:34 +11:00
|
|
|
|
"context"
|
2024-03-25 19:30:06 +11:00
|
|
|
|
"log"
|
|
|
|
|
"net"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
"sync"
|
2024-03-30 14:13:34 +11:00
|
|
|
|
"time"
|
2024-03-25 19:30:06 +11:00
|
|
|
|
|
2024-10-18 13:20:34 +11:00
|
|
|
|
"drjosh.dev/jrouter/aurp"
|
2024-04-12 16:14:27 +10:00
|
|
|
|
"github.com/sfiera/multitalk/pkg/ddp"
|
2024-03-25 19:30:06 +11:00
|
|
|
|
)
|
|
|
|
|
|
2024-03-30 16:43:14 +11:00
|
|
|
|
const (
|
|
|
|
|
// TODO: check these parameters
|
2024-04-01 15:42:35 +11:00
|
|
|
|
lastHeardFromTimer = 90 * time.Second
|
2024-03-30 16:48:47 +11:00
|
|
|
|
tickleRetryLimit = 10
|
|
|
|
|
sendRetryTimer = 10 * time.Second
|
|
|
|
|
sendRetryLimit = 5
|
2024-04-21 15:26:07 +10:00
|
|
|
|
reconnectTimer = 10 * time.Minute
|
2024-04-20 12:01:03 +10:00
|
|
|
|
updateTimer = 10 * time.Second
|
2024-03-30 16:43:14 +11:00
|
|
|
|
)
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
type ReceiverState int
|
2024-03-30 16:14:18 +11:00
|
|
|
|
|
|
|
|
|
const (
|
2024-04-26 16:15:02 +10:00
|
|
|
|
ReceiverUnconnected ReceiverState = iota
|
|
|
|
|
ReceiverConnected
|
|
|
|
|
ReceiverWaitForOpenRsp
|
|
|
|
|
ReceiverWaitForRIRsp
|
|
|
|
|
ReceiverWaitForTickleAck
|
2024-03-30 16:14:18 +11:00
|
|
|
|
)
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
func (rs ReceiverState) String() string {
|
2024-04-26 14:37:38 +10:00
|
|
|
|
switch rs {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverUnconnected:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "unconnected"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverConnected:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "connected"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverWaitForOpenRsp:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "waiting for Open-Rsp"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverWaitForRIRsp:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "waiting for RI-Rsp"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverWaitForTickleAck:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "waiting for Tickle-Ack"
|
|
|
|
|
default:
|
|
|
|
|
return "unknown"
|
|
|
|
|
}
|
2024-03-30 18:01:28 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
type SenderState int
|
2024-03-30 16:14:18 +11:00
|
|
|
|
|
|
|
|
|
const (
|
2024-04-26 16:15:02 +10:00
|
|
|
|
SenderUnconnected SenderState = iota
|
|
|
|
|
SenderConnected
|
|
|
|
|
SenderWaitForRIRspAck
|
|
|
|
|
SenderWaitForRIUpdAck
|
|
|
|
|
SenderWaitForRDAck
|
2024-03-30 16:14:18 +11:00
|
|
|
|
)
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
func (ss SenderState) String() string {
|
2024-04-26 14:37:38 +10:00
|
|
|
|
switch ss {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderUnconnected:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "unconnected"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderConnected:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "connected"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderWaitForRIRspAck:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "waiting for RI-Ack for RI-Rsp"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderWaitForRIUpdAck:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "waiting for RI-Ack for RI-Upd"
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderWaitForRDAck:
|
2024-04-26 14:37:38 +10:00
|
|
|
|
return "waiting for RI-Ack for RD"
|
|
|
|
|
default:
|
|
|
|
|
return "unknown"
|
|
|
|
|
}
|
2024-03-30 18:01:28 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 09:32:57 +10:00
|
|
|
|
// AURPPeer handles the peering with a peer AURP router.
|
|
|
|
|
type AURPPeer struct {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
// AURP-Tr state for producing packets.
|
|
|
|
|
Transport *aurp.Transport
|
|
|
|
|
|
|
|
|
|
// Connection to reply to packets on.
|
|
|
|
|
UDPConn *net.UDPConn
|
|
|
|
|
|
|
|
|
|
// The string that appeared in the config file / peer list file (with a
|
|
|
|
|
// ":387" appended as necessary).
|
|
|
|
|
// May be empty if this peer was not configured (it connected to us).
|
|
|
|
|
ConfiguredAddr string
|
|
|
|
|
|
|
|
|
|
// The resolved address of the peer.
|
|
|
|
|
RemoteAddr *net.UDPAddr
|
|
|
|
|
|
|
|
|
|
// Incoming packet channel.
|
|
|
|
|
ReceiveCh chan aurp.Packet
|
|
|
|
|
|
2024-05-05 17:01:23 +10:00
|
|
|
|
// Route table (the peer will add/remove/update routes and zones)
|
|
|
|
|
RouteTable *RouteTable
|
2024-04-26 16:15:02 +10:00
|
|
|
|
|
2024-05-24 15:55:34 +10:00
|
|
|
|
// Event tuples yet to be sent to this peer in an RI-Upd.
|
2024-06-07 16:00:43 +10:00
|
|
|
|
pendingEventsMu sync.Mutex
|
|
|
|
|
pendingEvents aurp.EventTuples
|
2024-05-24 15:55:34 +10:00
|
|
|
|
|
2024-05-12 18:07:27 +10:00
|
|
|
|
// The internal states below are only set within the Handle loop, but can
|
|
|
|
|
// be read concurrently from outside.
|
|
|
|
|
mu sync.RWMutex
|
|
|
|
|
rstate ReceiverState
|
|
|
|
|
sstate SenderState
|
|
|
|
|
lastReconnect time.Time
|
|
|
|
|
lastHeardFrom time.Time
|
|
|
|
|
lastSend time.Time // TODO: clarify use of lastSend / sendRetries
|
|
|
|
|
lastUpdate time.Time
|
|
|
|
|
sendRetries int
|
2024-04-26 16:15:02 +10:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-24 16:52:59 +10:00
|
|
|
|
func NewAURPPeer(routes *RouteTable, udpConn *net.UDPConn, peerAddr string, raddr *net.UDPAddr, localDI, remoteDI aurp.DomainIdentifier, connID uint16) *AURPPeer {
|
|
|
|
|
if remoteDI == nil {
|
|
|
|
|
remoteDI = aurp.IPDomainIdentifier(raddr.IP)
|
|
|
|
|
}
|
|
|
|
|
return &AURPPeer{
|
|
|
|
|
Transport: &aurp.Transport{
|
|
|
|
|
LocalDI: localDI,
|
|
|
|
|
RemoteDI: remoteDI,
|
|
|
|
|
LocalConnID: connID,
|
|
|
|
|
},
|
|
|
|
|
UDPConn: udpConn,
|
|
|
|
|
ConfiguredAddr: peerAddr,
|
|
|
|
|
RemoteAddr: raddr,
|
|
|
|
|
ReceiveCh: make(chan aurp.Packet, 1024),
|
|
|
|
|
RouteTable: routes,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-24 15:55:34 +10:00
|
|
|
|
func (p *AURPPeer) addPendingEvent(ec aurp.EventCode, route *Route) {
|
|
|
|
|
// Don't advertise routes to AURP peers to other AURP peers
|
|
|
|
|
if route.AURPPeer != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
et := aurp.EventTuple{
|
|
|
|
|
EventCode: ec,
|
|
|
|
|
Extended: route.Extended,
|
|
|
|
|
RangeStart: route.NetStart,
|
|
|
|
|
Distance: route.Distance,
|
|
|
|
|
RangeEnd: route.NetEnd,
|
|
|
|
|
}
|
|
|
|
|
switch ec {
|
|
|
|
|
case aurp.EventCodeND, aurp.EventCodeNRC:
|
|
|
|
|
et.Distance = 0 // "The distance field does not apply to ND or NRC event tuples and should be set to 0."
|
|
|
|
|
}
|
2024-06-07 16:00:43 +10:00
|
|
|
|
p.pendingEventsMu.Lock()
|
|
|
|
|
defer p.pendingEventsMu.Unlock()
|
|
|
|
|
p.pendingEvents = append(p.pendingEvents, et)
|
2024-05-24 15:55:34 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) RouteAdded(route *Route) {
|
|
|
|
|
p.addPendingEvent(aurp.EventCodeNA, route)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) RouteDeleted(route *Route) {
|
|
|
|
|
p.addPendingEvent(aurp.EventCodeND, route)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) RouteDistanceChanged(route *Route) {
|
|
|
|
|
p.addPendingEvent(aurp.EventCodeNDC, route)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) RouteForwarderChanged(route *Route) {
|
|
|
|
|
p.addPendingEvent(aurp.EventCodeNRC, route)
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-03 16:13:59 +10:00
|
|
|
|
func (p *AURPPeer) Forward(ddpkt *ddp.ExtPacket) error {
|
|
|
|
|
outPkt, err := ddp.ExtMarshal(*ddpkt)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-05-12 18:31:01 +10:00
|
|
|
|
_, err = p.send(p.Transport.NewAppleTalkPacket(outPkt))
|
2024-05-03 16:13:59 +10:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 09:32:57 +10:00
|
|
|
|
func (p *AURPPeer) ReceiverState() ReceiverState {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.mu.RLock()
|
|
|
|
|
defer p.mu.RUnlock()
|
|
|
|
|
return p.rstate
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 09:32:57 +10:00
|
|
|
|
func (p *AURPPeer) SenderState() SenderState {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.mu.RLock()
|
|
|
|
|
defer p.mu.RUnlock()
|
|
|
|
|
return p.sstate
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-12 18:07:27 +10:00
|
|
|
|
func (p *AURPPeer) LastReconnectAgo() string {
|
|
|
|
|
p.mu.RLock()
|
|
|
|
|
defer p.mu.RUnlock()
|
2024-05-12 18:12:27 +10:00
|
|
|
|
return ago(p.lastReconnect)
|
2024-05-12 18:07:27 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) LastHeardFromAgo() string {
|
|
|
|
|
p.mu.RLock()
|
|
|
|
|
defer p.mu.RUnlock()
|
2024-05-12 18:12:27 +10:00
|
|
|
|
return ago(p.lastHeardFrom)
|
2024-05-12 18:07:27 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) LastSendAgo() string {
|
|
|
|
|
p.mu.RLock()
|
|
|
|
|
defer p.mu.RUnlock()
|
2024-05-12 18:12:27 +10:00
|
|
|
|
return ago(p.lastSend)
|
2024-05-12 18:07:27 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) LastUpdateAgo() string {
|
|
|
|
|
p.mu.RLock()
|
|
|
|
|
defer p.mu.RUnlock()
|
2024-05-12 18:12:27 +10:00
|
|
|
|
return ago(p.lastUpdate)
|
2024-05-12 18:07:27 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) SendRetries() int {
|
|
|
|
|
p.mu.RLock()
|
|
|
|
|
defer p.mu.RUnlock()
|
|
|
|
|
return p.sendRetries
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 09:32:57 +10:00
|
|
|
|
func (p *AURPPeer) setRState(rstate ReceiverState) {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.rstate = rstate
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 09:32:57 +10:00
|
|
|
|
func (p *AURPPeer) setSState(sstate SenderState) {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.sstate = sstate
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-12 18:07:27 +10:00
|
|
|
|
func (p *AURPPeer) incSendRetries() {
|
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.sendRetries++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) resetSendRetries() {
|
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.sendRetries = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) bumpLastHeardFrom() {
|
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.lastHeardFrom = time.Now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) bumpLastReconnect() {
|
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.lastReconnect = time.Now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) bumpLastSend() {
|
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.lastSend = time.Now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *AURPPeer) bumpLastUpdate() {
|
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.lastUpdate = time.Now()
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 09:32:57 +10:00
|
|
|
|
func (p *AURPPeer) disconnect() {
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.mu.Lock()
|
|
|
|
|
defer p.mu.Unlock()
|
|
|
|
|
p.rstate = ReceiverUnconnected
|
|
|
|
|
p.sstate = SenderUnconnected
|
2024-03-25 19:30:06 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-12 18:31:01 +10:00
|
|
|
|
// send encodes and sends pkt to the remote host.
|
|
|
|
|
func (p *AURPPeer) send(pkt aurp.Packet) (int, error) {
|
2024-03-25 19:30:06 +11:00
|
|
|
|
var b bytes.Buffer
|
|
|
|
|
if _, err := pkt.WriteTo(&b); err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Sending %T (len %d) to %v", pkt, b.Len(), p.RemoteAddr)
|
2024-04-19 14:57:25 +10:00
|
|
|
|
return p.UDPConn.WriteToUDP(b.Bytes(), p.RemoteAddr)
|
2024-03-25 19:30:06 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-29 09:32:57 +10:00
|
|
|
|
func (p *AURPPeer) Handle(ctx context.Context) error {
|
2024-06-07 16:00:43 +10:00
|
|
|
|
// Stop listening to events if the goroutine exits
|
|
|
|
|
defer p.RouteTable.RemoveObserver(p)
|
|
|
|
|
|
2024-04-20 12:01:03 +10:00
|
|
|
|
rticker := time.NewTicker(1 * time.Second)
|
|
|
|
|
defer rticker.Stop()
|
|
|
|
|
sticker := time.NewTicker(1 * time.Second)
|
|
|
|
|
defer sticker.Stop()
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.mu.Lock()
|
|
|
|
|
p.lastReconnect = time.Now()
|
|
|
|
|
p.lastHeardFrom = time.Now()
|
|
|
|
|
p.lastSend = time.Now() // TODO: clarify use of lastSend / sendRetries
|
|
|
|
|
p.lastUpdate = time.Now()
|
|
|
|
|
p.sendRetries = 0
|
|
|
|
|
p.mu.Unlock()
|
2024-03-30 14:24:16 +11:00
|
|
|
|
|
2024-04-21 14:18:58 +10:00
|
|
|
|
var lastRISent aurp.Packet
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.disconnect()
|
2024-03-30 16:14:18 +11:00
|
|
|
|
|
2024-03-25 19:30:06 +11:00
|
|
|
|
// Write an Open-Req packet
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewOpenReqPacket(nil)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Open-Req packet: %v", err)
|
2024-03-30 14:13:34 +11:00
|
|
|
|
return err
|
2024-03-25 19:30:06 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverWaitForOpenRsp)
|
2024-03-30 16:14:18 +11:00
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
for {
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.sstate == SenderUnconnected {
|
2024-03-30 16:48:47 +11:00
|
|
|
|
// Return immediately
|
2024-03-30 16:14:18 +11:00
|
|
|
|
return ctx.Err()
|
|
|
|
|
}
|
2024-03-30 14:24:16 +11:00
|
|
|
|
// Send a best-effort Router Down before returning
|
2024-04-21 14:18:58 +10:00
|
|
|
|
lastRISent = p.Transport.NewRDPacket(aurp.ErrCodeNormalClose)
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(lastRISent); err != nil {
|
2024-03-30 14:24:16 +11:00
|
|
|
|
log.Printf("Couldn't send RD packet: %v", err)
|
|
|
|
|
}
|
2024-03-30 14:13:34 +11:00
|
|
|
|
return ctx.Err()
|
|
|
|
|
|
2024-04-20 12:01:03 +10:00
|
|
|
|
case <-rticker.C:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
switch p.rstate {
|
|
|
|
|
case ReceiverWaitForOpenRsp:
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastSend) <= sendRetryTimer {
|
2024-03-30 16:43:14 +11:00
|
|
|
|
break
|
|
|
|
|
}
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if p.sendRetries >= sendRetryLimit {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Send retry limit reached while waiting for Open-Rsp, closing connection")
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverUnconnected)
|
2024-03-30 16:43:14 +11:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Send another Open-Req
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.incSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewOpenReqPacket(nil)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Open-Req packet: %v", err)
|
2024-03-30 16:43:14 +11:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverConnected:
|
2024-03-30 16:14:18 +11:00
|
|
|
|
// Check LHFT, send tickle?
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastHeardFrom) <= lastHeardFromTimer {
|
2024-03-30 16:48:47 +11:00
|
|
|
|
break
|
|
|
|
|
}
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewTicklePacket()); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Tickle: %v", err)
|
2024-03-30 16:48:47 +11:00
|
|
|
|
return err
|
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverWaitForTickleAck)
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.resetSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-03-30 16:48:47 +11:00
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverWaitForTickleAck:
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastSend) <= sendRetryTimer {
|
2024-03-30 16:48:47 +11:00
|
|
|
|
break
|
|
|
|
|
}
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if p.sendRetries >= tickleRetryLimit {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Send retry limit reached while waiting for Tickle-Ack, closing connection")
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverUnconnected)
|
2024-05-05 17:01:23 +10:00
|
|
|
|
p.RouteTable.DeleteAURPPeer(p)
|
2024-03-30 16:48:47 +11:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.incSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewTicklePacket()); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Tickle: %v", err)
|
2024-03-30 16:48:47 +11:00
|
|
|
|
return err
|
2024-03-30 14:13:34 +11:00
|
|
|
|
}
|
2024-04-19 16:32:27 +10:00
|
|
|
|
// still in Wait For Tickle-Ack
|
2024-04-01 15:43:53 +11:00
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverWaitForRIRsp:
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastSend) <= sendRetryTimer {
|
2024-04-19 16:32:27 +10:00
|
|
|
|
break
|
|
|
|
|
}
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if p.sendRetries >= sendRetryLimit {
|
2024-04-19 16:32:27 +10:00
|
|
|
|
log.Printf("AURP Peer: Send retry limit reached while waiting for RI-Rsp, closing connection")
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverUnconnected)
|
2024-05-05 17:01:23 +10:00
|
|
|
|
p.RouteTable.DeleteAURPPeer(p)
|
2024-04-19 16:32:27 +10:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RI-Req is stateless, so we don't need to cache the one we
|
|
|
|
|
// sent earlier just to send it again
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.incSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewRIReqPacket()); err != nil {
|
2024-04-19 16:32:27 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Req packet: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
// still in Wait For RI-Rsp
|
2024-04-01 15:43:53 +11:00
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case ReceiverUnconnected:
|
2024-04-21 14:18:58 +10:00
|
|
|
|
// Data receiver is unconnected. If data sender is connected,
|
|
|
|
|
// send a null RI-Upd to check if the sender is also unconnected
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if p.sstate == SenderConnected && time.Since(p.lastSend) > sendRetryTimer {
|
|
|
|
|
if p.sendRetries >= sendRetryLimit {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
log.Printf("AURP Peer: Send retry limit reached while probing sender connect, closing connection")
|
|
|
|
|
}
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.incSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-04-20 12:01:03 +10:00
|
|
|
|
aurp.Inc(&p.Transport.LocalSeq)
|
|
|
|
|
events := aurp.EventTuples{{
|
|
|
|
|
EventCode: aurp.EventCodeNull,
|
|
|
|
|
}}
|
2024-04-21 14:18:58 +10:00
|
|
|
|
lastRISent = p.Transport.NewRIUpdPacket(events)
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(lastRISent); err != nil {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Upd packet: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setSState(SenderWaitForRIUpdAck)
|
2024-04-20 12:01:03 +10:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.ConfiguredAddr != "" {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
// Periodically try to reconnect, if this peer is in the config file
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastReconnect) <= reconnectTimer {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
// In case it's a DNS name, re-resolve it before reconnecting
|
|
|
|
|
raddr, err := net.ResolveUDPAddr("udp4", p.ConfiguredAddr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Printf("couldn't resolve UDP address, skipping: %v", err)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
log.Printf("AURP Peer: resolved %q to %v", p.ConfiguredAddr, raddr)
|
|
|
|
|
p.RemoteAddr = raddr
|
|
|
|
|
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.bumpLastReconnect()
|
|
|
|
|
p.resetSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewOpenReqPacket(nil)); err != nil {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Open-Req packet: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverWaitForOpenRsp)
|
2024-04-20 12:01:03 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case <-sticker.C:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
switch p.sstate {
|
|
|
|
|
case SenderUnconnected:
|
2024-04-20 12:01:03 +10:00
|
|
|
|
// Do nothing
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderConnected:
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastUpdate) <= updateTimer {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
break
|
|
|
|
|
}
|
2024-06-07 16:00:43 +10:00
|
|
|
|
|
|
|
|
|
// Are there routing updates to send?
|
|
|
|
|
p.pendingEventsMu.Lock()
|
|
|
|
|
if len(p.pendingEvents) == 0 {
|
|
|
|
|
p.pendingEventsMu.Unlock()
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
// Yes - swap the slices, release the mutex, then send them
|
|
|
|
|
pending := p.pendingEvents
|
|
|
|
|
p.pendingEvents = make(aurp.EventTuples, 0, cap(pending))
|
|
|
|
|
p.pendingEventsMu.Unlock()
|
|
|
|
|
|
|
|
|
|
// TODO: eliminate events that cancel out (e.g. NA then ND)
|
|
|
|
|
// TODO: split pending events to fit within a packet
|
|
|
|
|
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.bumpLastUpdate()
|
2024-06-07 16:00:43 +10:00
|
|
|
|
aurp.Inc(&p.Transport.LocalSeq)
|
|
|
|
|
lastRISent = p.Transport.NewRIUpdPacket(pending)
|
|
|
|
|
if _, err := p.send(lastRISent); err != nil {
|
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Upd packet: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
p.setSState(SenderWaitForRIUpdAck)
|
2024-04-20 12:01:03 +10:00
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderWaitForRIRspAck, SenderWaitForRIUpdAck:
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastSend) <= sendRetryTimer {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
break
|
|
|
|
|
}
|
2024-04-21 14:18:58 +10:00
|
|
|
|
if lastRISent == nil {
|
|
|
|
|
log.Print("AURP Peer: sender retry: lastRISent = nil?")
|
|
|
|
|
continue
|
|
|
|
|
}
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if p.sendRetries >= sendRetryLimit {
|
2024-04-21 14:18:58 +10:00
|
|
|
|
log.Printf("AURP Peer: Send retry limit reached, closing connection")
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setSState(SenderUnconnected)
|
2024-06-07 16:00:43 +10:00
|
|
|
|
p.RouteTable.RemoveObserver(p)
|
2024-04-21 14:18:58 +10:00
|
|
|
|
continue
|
|
|
|
|
}
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.incSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(lastRISent); err != nil {
|
2024-04-21 14:18:58 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't re-send %T: %v", lastRISent, err)
|
|
|
|
|
return err
|
2024-04-20 12:01:03 +10:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderWaitForRDAck:
|
2024-05-12 18:07:27 +10:00
|
|
|
|
if time.Since(p.lastSend) <= sendRetryTimer {
|
2024-04-20 12:01:03 +10:00
|
|
|
|
break
|
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setSState(SenderUnconnected)
|
2024-06-07 16:00:43 +10:00
|
|
|
|
p.RouteTable.RemoveObserver(p)
|
2024-03-25 19:30:06 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case pkt := <-p.ReceiveCh:
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.bumpLastHeardFrom()
|
2024-03-30 15:26:23 +11:00
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
switch pkt := pkt.(type) {
|
|
|
|
|
case *aurp.OpenReqPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.sstate != SenderUnconnected {
|
|
|
|
|
log.Printf("AURP Peer: Open-Req received but sender state is not unconnected (was %v)", p.sstate)
|
2024-03-30 16:14:18 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
// The peer tells us their connection ID in Open-Req.
|
2024-04-19 14:57:25 +10:00
|
|
|
|
p.Transport.RemoteConnID = pkt.ConnectionID
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
|
|
|
|
// Formulate a response.
|
|
|
|
|
var orsp *aurp.OpenRspPacket
|
|
|
|
|
switch {
|
|
|
|
|
case pkt.Version != 1:
|
|
|
|
|
// Respond with Open-Rsp with unknown version error.
|
2024-04-19 14:57:25 +10:00
|
|
|
|
orsp = p.Transport.NewOpenRspPacket(0, int16(aurp.ErrCodeInvalidVersion), nil)
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
|
|
|
|
case len(pkt.Options) > 0:
|
|
|
|
|
// Options? OPTIONS? We don't accept no stinkin' _options_
|
2024-04-19 14:57:25 +10:00
|
|
|
|
orsp = p.Transport.NewOpenRspPacket(0, int16(aurp.ErrCodeOptionNegotiation), nil)
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
// Accept it I guess.
|
2024-04-19 14:57:25 +10:00
|
|
|
|
orsp = p.Transport.NewOpenRspPacket(0, 1, nil)
|
2024-03-30 14:13:34 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(orsp); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Open-Rsp: %v", err)
|
2024-03-30 16:48:47 +11:00
|
|
|
|
return err
|
2024-03-30 14:13:34 +11:00
|
|
|
|
}
|
2024-03-30 16:14:18 +11:00
|
|
|
|
if orsp.RateOrErrCode >= 0 {
|
2024-06-07 16:00:43 +10:00
|
|
|
|
// Data sender is successfully in connected state
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setSState(SenderConnected)
|
2024-06-07 16:00:43 +10:00
|
|
|
|
p.RouteTable.AddObserver(p)
|
2024-03-30 16:14:18 +11:00
|
|
|
|
}
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
2024-03-30 18:53:31 +11:00
|
|
|
|
// If receiver is unconnected, commence connecting
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.rstate == ReceiverUnconnected {
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.resetSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewOpenReqPacket(nil)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Open-Req packet: %v", err)
|
2024-03-30 18:53:31 +11:00
|
|
|
|
return err
|
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverWaitForOpenRsp)
|
2024-03-30 18:53:31 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
case *aurp.OpenRspPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.rstate != ReceiverWaitForOpenRsp {
|
|
|
|
|
log.Printf("AURP Peer: Received Open-Rsp but was not waiting for one (receiver state was %v)", p.rstate)
|
2024-03-30 16:14:18 +11:00
|
|
|
|
}
|
2024-03-30 14:13:34 +11:00
|
|
|
|
if pkt.RateOrErrCode < 0 {
|
|
|
|
|
// It's an error code.
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Open-Rsp error code from peer %v: %d", p.RemoteAddr.IP, pkt.RateOrErrCode)
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverUnconnected)
|
2024-03-30 18:01:28 +11:00
|
|
|
|
break
|
2024-03-30 14:13:34 +11:00
|
|
|
|
}
|
2024-04-19 16:25:39 +10:00
|
|
|
|
//log.Printf("AURP Peer: Data receiver is connected!")
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverConnected)
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
2024-04-01 14:44:51 +11:00
|
|
|
|
// Send an RI-Req
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.resetSendRetries()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewRIReqPacket()); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Req packet: %v", err)
|
2024-04-01 14:44:51 +11:00
|
|
|
|
return err
|
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverWaitForRIRsp)
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
|
|
|
|
case *aurp.RIReqPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.sstate != SenderConnected {
|
|
|
|
|
log.Printf("AURP Peer: Received RI-Req but was not expecting one (sender state was %v)", p.sstate)
|
2024-03-30 18:01:28 +11:00
|
|
|
|
}
|
2024-03-30 18:53:31 +11:00
|
|
|
|
|
2024-05-05 17:25:11 +10:00
|
|
|
|
var nets aurp.NetworkTuples
|
|
|
|
|
for _, r := range p.RouteTable.ValidNonAURPRoutes() {
|
|
|
|
|
nets = append(nets, aurp.NetworkTuple{
|
|
|
|
|
Extended: r.Extended,
|
|
|
|
|
RangeStart: r.NetStart,
|
|
|
|
|
RangeEnd: r.NetEnd,
|
|
|
|
|
Distance: r.Distance,
|
|
|
|
|
})
|
2024-03-30 20:27:24 +11:00
|
|
|
|
}
|
2024-04-19 14:57:25 +10:00
|
|
|
|
p.Transport.LocalSeq = 1
|
2024-05-05 17:25:11 +10:00
|
|
|
|
// TODO: Split tuples across multiple packets as required
|
2024-04-21 14:18:58 +10:00
|
|
|
|
lastRISent = p.Transport.NewRIRspPacket(aurp.RoutingFlagLast, nets)
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(lastRISent); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Rsp packet: %v", err)
|
2024-04-01 14:56:49 +11:00
|
|
|
|
return err
|
2024-03-30 20:27:24 +11:00
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setSState(SenderWaitForRIRspAck)
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
|
|
|
|
case *aurp.RIRspPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.rstate != ReceiverWaitForRIRsp {
|
|
|
|
|
log.Printf("Received RI-Rsp but was not waiting for one (receiver state was %v)", p.rstate)
|
2024-03-30 18:01:28 +11:00
|
|
|
|
}
|
2024-04-01 14:56:49 +11:00
|
|
|
|
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Learned about these networks: %v", pkt.Networks)
|
2024-04-01 14:56:49 +11:00
|
|
|
|
|
2024-04-12 16:14:27 +10:00
|
|
|
|
for _, nt := range pkt.Networks {
|
2024-05-05 17:01:23 +10:00
|
|
|
|
p.RouteTable.InsertAURPRoute(
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p,
|
2024-04-13 15:47:58 +10:00
|
|
|
|
nt.Extended,
|
|
|
|
|
ddp.Network(nt.RangeStart),
|
|
|
|
|
ddp.Network(nt.RangeEnd),
|
2024-04-26 13:22:48 +10:00
|
|
|
|
nt.Distance+1,
|
2024-04-13 15:47:58 +10:00
|
|
|
|
)
|
2024-04-12 16:14:27 +10:00
|
|
|
|
}
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
2024-04-01 14:56:49 +11:00
|
|
|
|
// TODO: track which networks we don't have zone info for, and
|
|
|
|
|
// only set SZI for those ?
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, aurp.RoutingFlagSendZoneInfo)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Ack packet: %v", err)
|
2024-04-01 14:56:49 +11:00
|
|
|
|
return err
|
|
|
|
|
}
|
2024-04-01 15:09:26 +11:00
|
|
|
|
if pkt.Flags&aurp.RoutingFlagLast != 0 {
|
|
|
|
|
// No longer waiting for an RI-Rsp
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverConnected)
|
2024-04-01 15:09:26 +11:00
|
|
|
|
}
|
2024-04-01 14:56:49 +11:00
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
case *aurp.RIAckPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
switch p.sstate {
|
|
|
|
|
case SenderWaitForRIRspAck:
|
2024-03-30 20:27:24 +11:00
|
|
|
|
// We sent an RI-Rsp, this is the RI-Ack we expected.
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderWaitForRIUpdAck:
|
2024-03-30 20:27:24 +11:00
|
|
|
|
// We sent an RI-Upd, this is the RI-Ack we expected.
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
case SenderWaitForRDAck:
|
2024-03-30 20:27:24 +11:00
|
|
|
|
// We sent an RD... Why are we here?
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
default:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
log.Printf("AURP Peer: Received RI-Ack but was not waiting for one (sender state was %v)", p.sstate)
|
2024-03-30 20:27:24 +11:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setSState(SenderConnected)
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.resetSendRetries()
|
2024-06-07 16:00:43 +10:00
|
|
|
|
p.RouteTable.AddObserver(p)
|
2024-03-30 20:27:24 +11:00
|
|
|
|
|
|
|
|
|
// If SZI flag is set, send ZI-Rsp (transaction)
|
|
|
|
|
if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 {
|
2024-05-05 17:25:11 +10:00
|
|
|
|
// Inspect last routing info packet sent to determine
|
|
|
|
|
// networks to gather names for
|
|
|
|
|
var nets []ddp.Network
|
|
|
|
|
switch last := lastRISent.(type) {
|
|
|
|
|
case *aurp.RIRspPacket:
|
|
|
|
|
for _, nt := range last.Networks {
|
|
|
|
|
nets = append(nets, nt.RangeStart)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case *aurp.RIUpdPacket:
|
|
|
|
|
for _, et := range last.Events {
|
|
|
|
|
// Only networks that were added
|
|
|
|
|
if et.EventCode != aurp.EventCodeNA {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
nets = append(nets, et.RangeStart)
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 20:27:24 +11:00
|
|
|
|
}
|
2024-05-05 17:25:11 +10:00
|
|
|
|
zones := p.RouteTable.ZonesForNetworks(nets)
|
|
|
|
|
// TODO: split ZI-Rsp packets similarly to ZIP Replies
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewZIRspPacket(zones)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send ZI-Rsp packet: %v", err)
|
2024-03-30 20:27:24 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Continue sending next RI-Rsp (streamed)?
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.rstate == ReceiverUnconnected {
|
2024-04-23 17:05:06 +10:00
|
|
|
|
// Receiver is unconnected, but their receiver sent us an
|
|
|
|
|
// RI-Ack for something
|
|
|
|
|
// Try to reconnect?
|
2024-05-12 18:07:27 +10:00
|
|
|
|
p.resetSendRetries()
|
|
|
|
|
p.bumpLastSend()
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewOpenReqPacket(nil)); err != nil {
|
2024-04-23 17:05:06 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Open-Req packet: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverWaitForOpenRsp)
|
2024-04-23 17:05:06 +10:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
case *aurp.RIUpdPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
var ackFlag aurp.RoutingFlag
|
|
|
|
|
|
2024-04-19 16:48:59 +10:00
|
|
|
|
for _, et := range pkt.Events {
|
|
|
|
|
log.Printf("AURP Peer: RI-Upd event %v", et)
|
2024-04-26 16:15:02 +10:00
|
|
|
|
switch et.EventCode {
|
|
|
|
|
case aurp.EventCodeNull:
|
|
|
|
|
// Do nothing except respond with RI-Ack
|
|
|
|
|
|
|
|
|
|
case aurp.EventCodeNA:
|
2024-05-05 17:01:23 +10:00
|
|
|
|
if err := p.RouteTable.InsertAURPRoute(
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p,
|
|
|
|
|
et.Extended,
|
|
|
|
|
et.RangeStart,
|
|
|
|
|
et.RangeEnd,
|
|
|
|
|
et.Distance+1,
|
|
|
|
|
); err != nil {
|
|
|
|
|
log.Printf("AURP Peer: couldn't insert route: %v", err)
|
|
|
|
|
}
|
|
|
|
|
ackFlag = aurp.RoutingFlagSendZoneInfo
|
|
|
|
|
|
|
|
|
|
case aurp.EventCodeND:
|
2024-05-05 17:01:23 +10:00
|
|
|
|
p.RouteTable.DeleteAURPPeerNetwork(p, et.RangeStart)
|
2024-04-26 16:15:02 +10:00
|
|
|
|
|
|
|
|
|
case aurp.EventCodeNDC:
|
2024-05-05 17:01:23 +10:00
|
|
|
|
p.RouteTable.UpdateAURPRouteDistance(p, et.RangeStart, et.Distance+1)
|
2024-04-26 16:15:02 +10:00
|
|
|
|
|
|
|
|
|
case aurp.EventCodeNRC:
|
|
|
|
|
// "An exterior router sends a Network Route Change
|
|
|
|
|
// (NRC) event if the path to an exported network
|
|
|
|
|
// through its local internet changes to a path through
|
|
|
|
|
// a tunneling port, causing split-horizoned processing
|
|
|
|
|
// to eliminate that network’s routing information."
|
2024-05-05 17:01:23 +10:00
|
|
|
|
p.RouteTable.DeleteAURPPeerNetwork(p, et.RangeStart)
|
2024-04-26 16:15:02 +10:00
|
|
|
|
|
|
|
|
|
case aurp.EventCodeZC:
|
|
|
|
|
// "This event is reserved for future use."
|
|
|
|
|
}
|
2024-04-19 16:48:59 +10:00
|
|
|
|
}
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, ackFlag)); err != nil {
|
2024-04-19 17:10:00 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Ack: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
case *aurp.RDPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.rstate == ReceiverUnconnected || p.rstate == ReceiverWaitForOpenRsp {
|
|
|
|
|
log.Printf("AURP Peer: Received RD but was not expecting one (receiver state was %v)", p.rstate)
|
2024-03-30 18:01:28 +11:00
|
|
|
|
}
|
2024-03-30 16:16:46 +11:00
|
|
|
|
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Router Down: error code %d %s", pkt.ErrorCode, pkt.ErrorCode)
|
2024-05-05 17:01:23 +10:00
|
|
|
|
p.RouteTable.DeleteAURPPeer(p)
|
2024-04-19 16:25:39 +10:00
|
|
|
|
|
2024-03-30 16:14:18 +11:00
|
|
|
|
// Respond with RI-Ack
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, 0)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send RI-Ack: %v", err)
|
2024-03-30 16:48:47 +11:00
|
|
|
|
return err
|
2024-03-30 16:14:18 +11:00
|
|
|
|
}
|
2024-04-20 12:01:03 +10:00
|
|
|
|
// Connections closed
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.disconnect()
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
|
|
|
|
case *aurp.ZIReqPacket:
|
2024-04-19 16:48:59 +10:00
|
|
|
|
// TODO: split ZI-Rsp packets similarly to ZIP Replies
|
2024-05-05 17:01:23 +10:00
|
|
|
|
zones := p.RouteTable.ZonesForNetworks(pkt.Networks)
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewZIRspPacket(zones)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send ZI-Rsp packet: %v", err)
|
2024-04-01 15:33:57 +11:00
|
|
|
|
return err
|
2024-04-01 14:56:49 +11:00
|
|
|
|
}
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
|
|
|
|
case *aurp.ZIRspPacket:
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Learned about these zones: %v", pkt.Zones)
|
2024-04-14 18:29:29 +10:00
|
|
|
|
for _, zt := range pkt.Zones {
|
2024-05-05 17:59:49 +10:00
|
|
|
|
p.RouteTable.AddZonesToNetwork(zt.Network, zt.Name)
|
2024-04-14 18:29:29 +10:00
|
|
|
|
}
|
2024-03-30 14:13:34 +11:00
|
|
|
|
|
2024-04-01 15:33:57 +11:00
|
|
|
|
case *aurp.GDZLReqPacket:
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewGDZLRspPacket(-1, nil)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send GDZL-Rsp packet: %v", err)
|
2024-04-01 15:33:57 +11:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case *aurp.GDZLRspPacket:
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Received a GDZL-Rsp, but I wouldn't have sent a GDZL-Req - that's weird")
|
2024-04-01 15:33:57 +11:00
|
|
|
|
|
|
|
|
|
case *aurp.GZNReqPacket:
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewGZNRspPacket(pkt.ZoneName, false, nil)); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send GZN-Rsp packet: %v", err)
|
2024-04-01 15:33:57 +11:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case *aurp.GZNRspPacket:
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Received a GZN-Rsp, but I wouldn't have sent a GZN-Req - that's weird")
|
2024-04-01 15:33:57 +11:00
|
|
|
|
|
2024-03-30 14:13:34 +11:00
|
|
|
|
case *aurp.TicklePacket:
|
2024-03-30 15:26:23 +11:00
|
|
|
|
// Immediately respond with Tickle-Ack
|
2024-05-12 18:31:01 +10:00
|
|
|
|
if _, err := p.send(p.Transport.NewTickleAckPacket()); err != nil {
|
2024-04-19 16:25:39 +10:00
|
|
|
|
log.Printf("AURP Peer: Couldn't send Tickle-Ack: %v", err)
|
2024-03-30 16:48:47 +11:00
|
|
|
|
return err
|
2024-03-30 14:13:34 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case *aurp.TickleAckPacket:
|
2024-04-26 16:15:02 +10:00
|
|
|
|
if p.rstate != ReceiverWaitForTickleAck {
|
|
|
|
|
log.Printf("AURP Peer: Received Tickle-Ack but was not waiting for one (receiver state was %v)", p.rstate)
|
2024-03-30 16:14:18 +11:00
|
|
|
|
}
|
2024-04-26 16:15:02 +10:00
|
|
|
|
p.setRState(ReceiverConnected)
|
2024-03-25 19:30:06 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|