diff --git a/aurp/transport.go b/aurp/transport.go index 97d252d..706aa23 100644 --- a/aurp/transport.go +++ b/aurp/transport.go @@ -111,6 +111,17 @@ func (tr *Transport) NewOpenRspPacket(envFlags RoutingFlag, rateOrErr int16, opt } } +func (tr *Transport) NewRIRspPacket(connID, seq uint16, last RoutingFlag, nets NetworkTuples) *RIRspPacket { + return &RIRspPacket{ + Header: Header{ + TrHeader: tr.sequenced(connID, seq), + CommandCode: CmdCodeRIRsp, + Flags: last, + }, + Networks: nets, + } +} + func (tr *Transport) NewRIAckPacket(connID, seq uint16, szi RoutingFlag) *RIAckPacket { return &RIAckPacket{ Header: Header{ @@ -121,6 +132,29 @@ func (tr *Transport) NewRIAckPacket(connID, seq uint16, szi RoutingFlag) *RIAckP } } +func (tr *Transport) NewZIRspPacket(zones ZoneTuples) *ZIRspPacket { + nns := make(map[uint16]struct{}) + for _, z := range zones { + nns[z.Network] = struct{}{} + } + // Only one network: use extended + // More than one network: use non-extended + subcode := SubcodeZoneInfoExt + if len(nns) != 1 { + subcode = SubcodeZoneInfoNonExt + } + + return &ZIRspPacket{ + Header: Header{ + TrHeader: tr.transaction(tr.RemoteConnID), + CommandCode: CmdCodeZoneRsp, + Flags: 0, + }, + Subcode: subcode, + Zones: zones, + } +} + func (tr *Transport) NewRDPacket(errCode ErrorCode) *RDPacket { return &RDPacket{ Header: Header{ diff --git a/main.go b/main.go index ac8e9db..c387739 100644 --- a/main.go +++ b/main.go @@ -95,19 +95,18 @@ func main() { } log.Printf("resolved %q to %v", peerStr, raddr) - tr := &aurp.Transport{ - LocalDI: localDI, - RemoteDI: aurp.IPDomainIdentifier(raddr.IP), - LocalConnID: nextConnID, - } - nextConnID++ - peer := &peer{ - tr: tr, + cfg: cfg, + tr: &aurp.Transport{ + LocalDI: localDI, + RemoteDI: aurp.IPDomainIdentifier(raddr.IP), + LocalConnID: nextConnID, + }, conn: ln, raddr: raddr, recv: make(chan aurp.Packet, 1024), } + nextConnID++ goHandler(peer) peers[udpAddrFromNet(raddr)] = peer } @@ -161,6 +160,7 @@ func main() { // New peer! nextConnID++ pr = &peer{ + cfg: cfg, tr: &aurp.Transport{ LocalDI: localDI, RemoteDI: dh.SourceDI, // platinum rule diff --git a/peer.go b/peer.go index 88927be..e8696a5 100644 --- a/peer.go +++ b/peer.go @@ -59,6 +59,7 @@ func (ss senderState) String() string { } type peer struct { + cfg *config tr *aurp.Transport conn *net.UDPConn raddr *net.UDPAddr @@ -225,7 +226,17 @@ func (p *peer) handle(ctx context.Context) error { log.Printf("Received RI-Req but was not expecting one (sender state was %v)", sstate) } - // TODO: Respond with RI-Rsp + nets := aurp.NetworkTuples{ + { + RangeStart: p.cfg.EtherTalk.NetStart, + RangeEnd: p.cfg.EtherTalk.NetEnd, + Distance: 1, + }, + } + if _, err := p.send(p.tr.NewRIRspPacket(pkt.ConnectionID, p.tr.LocalSeq, aurp.RoutingFlagLast, nets)); err != nil { + log.Printf("Couldn't send RI-Rsp packet: %v", err) + } + sstate = ssWaitForRIAck1 case *aurp.RIRspPacket: if rstate != rsWaitForRIRsp { @@ -235,8 +246,37 @@ func (p *peer) handle(ctx context.Context) error { // TODO: Integrate info into route table case *aurp.RIAckPacket: - // TODO: Continue sending next RI-Rsp (streamed) - // TODO: If SZI flag is set, send ZI-Rsp (transaction) + switch sstate { + case ssWaitForRIAck1: + // We sent an RI-Rsp, this is the RI-Ack we expected. + + case ssWaitForRIAck2: + // We sent an RI-Upd, this is the RI-Ack we expected. + + case ssWaitForRIAck3: + // We sent an RD... Why are we here? + continue + + default: + log.Printf("Received RI-Ack but was not waiting for one (sender state was %v)", sstate) + } + + sstate = ssConnected + + // If SZI flag is set, send ZI-Rsp (transaction) + if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 { + zones := aurp.ZoneTuples{ + { + Network: p.cfg.EtherTalk.NetStart, + Name: p.cfg.EtherTalk.ZoneName, + }, + } + if _, err := p.send(p.tr.NewZIRspPacket(zones)); err != nil { + log.Printf("Couldn't send ZI-Rsp packet: %v", err) + } + } + + // TODO: Continue sending next RI-Rsp (streamed)? case *aurp.RIUpdPacket: // TODO: Integrate info into route table