src/routing/aodv/aodv-routing-protocol.h
author Borovkova Elena <borovkovaes@iitp.ru>
Wed, 05 Aug 2009 23:04:55 +0400
changeset 5649 4915054ebfb2
parent 5648 85aae1523c46
child 5650 0379b99f18f4
permissions -rw-r--r--
SendPacketFromRawSocket = BuildPacket + socket->SendTo()

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2009 IITP RAS
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Based on 
 *      NS-2 AODV model developed by the CMU/MONARCH group and optimized and
 *      tuned by Samir Das and Mahesh Marina, University of Cincinnati;
 * 
 *      AODV-UU implementation by Erik Nordström of Uppsala University
 *      http://core.it.uu.se/core/index.php/AODV-UU
 *
 * Authors: Elena Borovkova <borovkovaes@iitp.ru>
 *          Pavel Boyko <boyko@iitp.ru>
 */
#ifndef AODVROUTINGPROTOCOL_H_
#define AODVROUTINGPROTOCOL_H_

#include "aodv-rtable.h"
#include "aodv-rqueue.h"
#include "aodv-packet.h"
#include "id-cache.h"
#include "aodv-neighbor.h"

#include "src/internet-stack/ipv4-l3-protocol.h"

#include "ns3/object.h"
#include "ns3/packet.h"
#include "ns3/node.h"
#include "ns3/socket.h"
#include "ns3/timer.h"
#include "ns3/ipv4.h"
#include "ns3/ipv4-routing-protocol.h"
#include <map>

namespace ns3
{
namespace aodv
{

/**
 * \ingroup aodv
 * \brief AODV routing protocol
 */
class RoutingProtocol : public Ipv4RoutingProtocol
{
public:
  static TypeId GetTypeId (void);
  static const uint32_t AODV_PORT;

  RoutingProtocol();
  virtual ~RoutingProtocol();
  virtual void DoDispose ();
  
  ///\name From Ipv4RoutingProtocol
  //\{
  Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, uint32_t oif, Socket::SocketErrno &sockerr);
  bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
                           UnicastForwardCallback ucb, MulticastForwardCallback mcb,
                           LocalDeliverCallback lcb, ErrorCallback ecb);  
  virtual void NotifyInterfaceUp (uint32_t interface);
  virtual void NotifyInterfaceDown (uint32_t interface);
  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
  //\}
  
  ///\name Handle protocol parameters
  //\{
  bool GetDesinationOnlyFlag () const { return DestinationOnly; }
  void SetDesinationOnlyFlag (bool f) { DestinationOnly = f; }
  bool GetGratuitousReplyFlag () const { return GratuitousReply; }
  void SetGratuitousReplyFlag (bool f) { GratuitousReply = f; }
  //\}
private:
  ///\name Protocol parameters. TODO document
  //\{
  uint32_t RreqRetries;        ///< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route
  Time ActiveRouteTimeout;    // 3 seconds
  Time MyRouteTimeout;       // 2 * ActiveRouteTimeout
  uint32_t NetDiameter;
  Time NodeTraversalTime;         //  40 milliseconds
  Time NetTraversalTime;          // 2 * NodeTraversalTime * NetDiameter
  Time PathDiscoveryTime;
  Time HelloInterval;
  uint32_t AllowedHelloLoss;
  /**
   * DeletePeriod is intended to provide an upper bound on the time for which an upstream node A
   * can have a neighbor B as an active next hop for destination D, while B has invalidated the route to D.
   */
  Time DeletePeriod;
  Time MaxHelloInterval; //        (1.25 * HelloInterval)
  Time MinHelloInterval; //        (0.75 * HelloInterval)
  Time FREQUENCY;
  Time NextHopWait;
  uint16_t TtlStart;
  uint16_t TtlIncrement;
  uint16_t TtlThreshold;
  uint16_t  MaxRepairTtl;           // 0.3 * NetDiameter
  uint16_t LOCAL_ADD_TTL;
  uint16_t TIMEOUT_BUFFER;
  Time BLACKLIST_TIMEOUT;
  uint32_t MaxQueueLen;
  Time MaxQueueTime;
  bool DestinationOnly;
  bool GratuitousReply;
  //\}

  /// IP protocol
  Ptr<Ipv4> m_ipv4;
  /// Raw socket per each IP interface, map socket -> iface address (IP + mask)
  std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_socketAddresses;

  /// Routing table
  RoutingTable m_routingTable;
  /// A "drop-front" queue used by the routing layer to buffer packets to which it does not have a route.
  RequestQueue m_queue;
  /// Broadcast ID
  uint32_t m_requestId;
  /// Request sequence number
  uint32_t m_seqNo;
  /// Handle duplicated packets
  IdCache m_idCache;
  /// Handle neighbors
  Neighbors m_nb;

  UnicastForwardCallback m_scb;
  ErrorCallback m_ecb;

private:
  /// Start protocol operation
  void Start ();
  /// Start local route repair procedure
  void LocalRouteRepair (Ipv4Address dst, Ipv4Address origin);
  /**
   * If route exists and valid, forward packet.
   * If route exists and down try to repair route if following conditions is true
   *    1. Using local route repair technique enable
   *    2. The destination is no farther than MAX_REPAIR_TTL hops away.
   * During local repair data packets SHOULD be buffered.
   * \return true if node forward packet or try to repair route.
   */
  bool Forwarding (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb);
  /// Process broken link
  void HandleLinkFailure (Ipv4Address id);
  /**
  * To reduce congestion in a network, repeated attempts by a source node at route discovery
  * for a single destination MUST utilize a binary exponential backoff.
  */
  void ScheduleRreqRetry (Ipv4Address dst,  uint16_t ttl);
  /**
   * Update route lifetime.
   * \param addr - destination address
   * \return true if route to destination address addr exist
   */
  bool UpdateRouteLifeTime(Ipv4Address addr, Time lifetime);
  /// Update neighbor record. \param receiver is supposed to be my interface
  void UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver);
  /// Check that packet is send from own interface
  bool IsMyOwnPacket(Ipv4Address src);
  /// Find socket with local interface address iface
  Ptr<Socket> FindSocketWithInterfaceAddress(Ipv4Address iface) const;
  /// Process hello message
  void ProcessHello(RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr);
  
  ///\name Receive control packets
  //\{
  /// Receive and process control packet
  void RecvAodv (Ptr<Socket> socket);
  /// Receive RREQ
  void RecvRequest (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src, Ipv4Header ipv4Header);
  /// Receive RREP
  void RecvReply (Ptr<Packet> p, Ipv4Address my ,Ipv4Address src, Ipv4Header ipv4Header);
  /// Receive RREP_ACK
  void RecvReplyAck(Ipv4Address neighbor);
  /// Receive RERR from node with address src
  void RecvError (Ptr<Packet> p, Ipv4Address src);
  //\}
  
  ///\name Send
  //\{
  /// Forward packet from route request queue
  void SendPacketFromQueue(Ipv4Address dst, Ptr<Ipv4Route> route);
  /// Aux. send helper
  void Send(Ptr<Ipv4Route>, Ptr<const Packet>, const Ipv4Header &);
  /// Send hello
  void SendHello ();
  /// Send RREQ
  void SendRequest (Ipv4Address dst, uint16_t ttl);
  /// Send RREP
  void SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin);
  /** Send RREP by intermediate node
   * \param toDst routing table entry to destination
   * \param toOrigin routing table entry to originator
   * \param gratRep indicates whether a gratuitous RREP should be unicast to destination
   */
  void SendReplyByIntermediateNode (RoutingTableEntry & toDst, RoutingTableEntry & toOrigin, bool gratRep);
  /// Send RREP_ACK
  void SendReplyAck (Ipv4Address neighbor);
  /// Initiate RERR
  void SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop);
  /// Forward RERR
  void SendRerrMessage(Ptr<Packet> packet,  std::vector<Ipv4Address> precursors);
  /**
  * Add UDP and IP header to packet.
  * \param sport - source port number
  * \param dport - destination port number
  * \param src - source IP address
  * \param dst - destination IP address
  * \param identification - used as sequence number for broadcast traffic
  */
  void SendPacketFromRawSocket (Ptr<Packet> packet, std::pair<Ptr<Socket> , Ipv4InterfaceAddress> socketAddress, Ipv4Address dst, uint16_t ttl, uint16_t id);
  //\}
  
  /// Notify that packet is dropped for some reason 
  void Drop(Ptr<const Packet>, const Ipv4Header &, Socket::SocketErrno) {}
  void DropFromQueue (Ipv4Address dst);

  ///\name Timers. TODO comment each one
  //\{
  Timer htimer; // TODO independent hello timers for all interfaces
  void HelloTimerExpire ();
  Timer rtimer;
  void RouteCacheTimerExpire ();
  Timer lrtimer;
  void LocalRepairTimerExpire ();
  std::map<Ipv4Address, Timer> m_addressReqTimer;
  void RouteRequestTimerExpire(Ipv4Address dst, uint16_t lastTtl);
  void AckTimerExpire (Ipv4Address neighbor,  Time blacklistTimeout);
  void RoutingTableEntryTimerExpire(Ipv4Address dst);
  //\}
};

}
}
#endif /* AODVROUTINGPROTOCOL_H_ */