public Rrep(Rrep rrep) { R = rrep.R; A = rrep.A; PrefixSize = rrep.PrefixSize; HopCount = rrep.HopCount; DestinationAddress = rrep.DestinationAddress; DestinationSequenceNumber = rrep.DestinationSequenceNumber; OriginatorAddress = rrep.OriginatorAddress; Lifetime = rrep.Lifetime; }
/// <summary> /// Handles an incoming RREQ packet. /// </summary> /// <param name="incomingPacket"></param> private void HandleRreq(Message incomingPacket) { //Processing RREQ according to section 6.5 var rreq = (Rreq)incomingPacket.Payload; //Cast message to right type //Check that received RREQ has not been received and processed before if (_aodvHelper.RreqAttemptExist(rreq.DestinationAddress, rreq.OriginatorAddress)) { _logger.WriteLine("Incoming RREQ from " + rreq.OriginatorAddress + " discarded, since it has been processed before."); return; //Discard RREQ } //RREQ not received before, place in buffer with 0 as attempt number _aodvHelper.AddBufferedRreqAttempt(new BufferedRreqAttempt(0, rreq, _conf.AodvConfiguration.PathDiscoveryTime)); //First, create/update route to previous hop. If route to previous hop exists, update lifetime if (_aodvHelper.RoutingTable.ActiveRouteExists(incomingPacket.PreviousHop)) { var prevRoute = _aodvHelper.RoutingTable.GetEntry(incomingPacket.PreviousHop); prevRoute.Valid = true; prevRoute.HopCount = 1; prevRoute.NextHop = incomingPacket.PreviousHop; prevRoute.ExpirationTime = _time.GetFutureTime(_aodvParameters.ActiveRouteTimeout); _logger.WriteLine("RREQ handler: Updating route to previous hop: " + incomingPacket.PreviousHop + " for RREQ #" + rreq.RouteRequestId); _aodvHelper.RoutingTable.UpdateEntry(prevRoute); } else //Route did not exist, so create it { var prevHopEntry = new AodvTableEntry { Valid = true, DestinationAddress = incomingPacket.PreviousHop, DestinationSequenceNumber = 0, ValidDestinationSequenceNumberFlag = false, //(He's my neighbour, so even though I dont know his sequence number, I know that he's there) HopCount = 1, //Only 1 hop to previous neighbour (duh) NextHop = incomingPacket.PreviousHop, ExpirationTime = _time.GetFutureTime(_aodvParameters.ActiveRouteTimeout) }; _logger.WriteLine("RREQ handler: Adding route to previous hop: " + incomingPacket.PreviousHop + " for RREQ #" + rreq.RouteRequestId); _aodvHelper.RoutingTable.AddEntry(prevHopEntry); } //RREQ has not been seen before or was not sent by me, continue to process it. rreq.HopCount = rreq.HopCount + 1; //Increment HopCount in RREQ, since me receiving it, was one hop more //Create or update reverse route to RREQ Originator var oldEntry = _aodvHelper.RoutingTable.GetEntry(rreq.OriginatorAddress); var minimalLifetime = _aodvParameters.MinimalLifetime(rreq.HopCount); //No route to originator exists, create it if (oldEntry == null) { var originatorRoute = new AodvTableEntry { DestinationAddress = rreq.OriginatorAddress, DestinationSequenceNumber = rreq.OriginatorSequenceNumber, ValidDestinationSequenceNumberFlag = true, HopCount = rreq.HopCount, Valid = true, NextHop = incomingPacket.PreviousHop, ExpirationTime = minimalLifetime }; _logger.WriteLine("RREQ handler: Adding route to originator: " + rreq.OriginatorAddress + " for RREQ #" + rreq.RouteRequestId); _aodvHelper.RoutingTable.AddEntry(originatorRoute); } else //Route exists, update existing entry { var originatorRoute = new AodvTableEntry { DestinationAddress = rreq.OriginatorAddress, DestinationSequenceNumber = rreq.OriginatorSequenceNumber > oldEntry.DestinationSequenceNumber ? rreq.OriginatorSequenceNumber : oldEntry.DestinationSequenceNumber, //See section 6.5, action 1. ValidDestinationSequenceNumberFlag = true, HopCount = rreq.HopCount, Valid = true, NextHop = incomingPacket.PreviousHop, ExpirationTime = oldEntry.ExpirationTime > minimalLifetime ? oldEntry.ExpirationTime : minimalLifetime }; _logger.WriteLine("RREQ handler: Updating route to originator: " + rreq.OriginatorAddress + " for RREQ #" + rreq.RouteRequestId); _aodvHelper.RoutingTable.UpdateEntry(originatorRoute); //And now we have a route towards the originator that can be used. neat-o. } //If I am the destination specified in RREQ if (rreq.DestinationAddress == _localAddress) //Section 6.6 (i) and section 6.6.1 { //Increment my sequence number, if DSN in RREQ is 1 larger per secton 6.6.1 if (rreq.DestinationSequenceNumber == _aodvHelper.RoutingTable.SequenceNumber + 1) { _aodvHelper.RoutingTable.IncrementSequenceNumber(); } var rrep = new Rrep { OriginatorAddress = rreq.OriginatorAddress, DestinationAddress = rreq.DestinationAddress, DestinationSequenceNumber = _aodvHelper.RoutingTable.SequenceNumber, HopCount = 0, Lifetime = _time.GetFutureTime(_aodvParameters.MyRouteTimeout) //Section 6.6.1, see also section 10. }; var responseMsg = new Message(rrep, rreq.OriginatorAddress, _localAddress, _conf.MessageTtlValue); SendAodvMessage(responseMsg, incomingPacket.PreviousHop); //Send RREP to previous hop, which is where I received the RREQ from } //If I have an active route to destination, which upholds requirements in section 6.6 (ii), see section 6.6.2 else if (_aodvHelper.RoutingTable.ActiveRouteExists(rreq.DestinationAddress) && //If I have an active route _aodvHelper.RoutingTable.GetEntry(rreq.DestinationAddress).ValidDestinationSequenceNumberFlag && //and the route has a valid dsn _aodvHelper.RoutingTable.GetEntry(rreq.DestinationAddress).DestinationSequenceNumber >= rreq.DestinationSequenceNumber && //and route dsn is >= rreq.dsn !rreq.D) //and rreq must NOT only be answered by destination { var forwardRoute = _aodvHelper.RoutingTable.GetEntry(rreq.DestinationAddress); var rrep = new Rrep { OriginatorAddress = rreq.OriginatorAddress, DestinationAddress = rreq.DestinationAddress, DestinationSequenceNumber = forwardRoute.DestinationSequenceNumber, HopCount = forwardRoute.HopCount, Lifetime = _time.GetFutureTime((forwardRoute.ExpirationTime - _time.CurrentTime).TotalSeconds) //6.6.2, "subtract current time from expiration time in route table entry" }; //Add previous hop of incoming message to precursor list of destination _aodvHelper.RoutingTable.AddPrecursorToEntry(rreq.DestinationAddress, incomingPacket.PreviousHop); //Add next-hop of forward route to precursor list of originator _aodvHelper.RoutingTable.AddPrecursorToEntry(rreq.OriginatorAddress, forwardRoute.NextHop); //Place RREP in outbox var responseMsg = new Message(rrep, rreq.OriginatorAddress, _localAddress, _conf.MessageTtlValue); SendAodvMessage(responseMsg, incomingPacket.PreviousHop); //Send RREP to previous hop, which is where I received the RREQ from //Send gratuitous RREP if required in RREQ, specified in section 6.6.3. Dont send it, if path to destination goes through previousHop if (rreq.G) { var gratuitousRrep = new Rrep { HopCount = _aodvHelper.RoutingTable.GetEntry(rreq.OriginatorAddress).HopCount, DestinationAddress = rreq.OriginatorAddress, DestinationSequenceNumber = rreq.OriginatorSequenceNumber, OriginatorAddress = rreq.DestinationAddress, Lifetime = _time.GetFutureTime((_aodvHelper.RoutingTable.GetEntry(rreq.OriginatorAddress).ExpirationTime - _time.CurrentTime).TotalSeconds) //"Remaining lifetime of route towards RREQ originator, as known by intermediate node" (expiration time - current time = remaining time) }; var gratuitousMsg = new Message(gratuitousRrep, rreq.DestinationAddress, _localAddress, _conf.MessageTtlValue); SendAodvMessage(gratuitousMsg, forwardRoute.NextHop); //Gratuitous RREP sent forward } } //Else, I have no active route and am not the destination else { var outMsg = new Message(incomingPacket); rreq.DestinationSequenceNumber = Math.Max(rreq.DestinationSequenceNumber, _aodvHelper.RoutingTable.GetEntry(rreq.DestinationAddress)?.DestinationSequenceNumber ?? -1); //Set DSN to max of rreq.dsn or table[destination].dsn outMsg.Payload = new Rreq(rreq); outMsg.DestinationAddress = SimulationConstants.BroadcastAddress; SendAodvMessage(outMsg, SimulationConstants.BroadcastAddress); } }