PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Network/MIPv6/MIPv6CDSMobileNode.h

https://github.com/revenant/ipv6suite
C Header | 360 lines | 102 code | 71 blank | 187 comment | 0 complexity | d2b1e510fc5bc9de40bd36221e17c19a MD5 | raw file
  1. // -*- C++ -*-
  2. // Copyright (C) 2002, 2003, 2004, 2005 CTIE, Monash University
  3. //
  4. // This program is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. /**
  18. * @file MIPv6CDSMobileNode.h
  19. * @author Johnny Lai
  20. * @date 05 May 2002
  21. * @brief Conceptual Data Structures for Mobile Node and the interface to it
  22. */
  23. #ifndef MIPV6CDSMOBILENODE_H
  24. #define MIPV6CDSMOBILENODE_H 1
  25. #include "MIPv6CDS.h"
  26. #ifndef MAP
  27. #define MAP
  28. #include <map>
  29. #endif //MAP
  30. #ifndef LIST
  31. #define LIST
  32. #include <list>
  33. #endif //LIST
  34. #ifndef IPV6ADDRESS_H
  35. #include "IPv6Address.h"
  36. #endif //IPV6ADDRESS_H
  37. class InterfaceEntry;
  38. class IPv6Mobility;
  39. namespace MobileIPv6
  40. {
  41. class MIPv6RouterEntry;
  42. class bu_entry;
  43. /**
  44. * @class MIPv6CDSMobileNode
  45. *
  46. * @brief Interface to the CDS of a MobileNode and some implementation specific
  47. * data structures are added too
  48. *
  49. * detailed description
  50. */
  51. class MIPv6CDSMobileNode
  52. {
  53. friend class MIPv6NDStateHost;
  54. friend class MIPv6MStateMobileNode;
  55. friend class IPv6Mobility; //_homeAddr
  56. public:
  57. //@name constructors, destructors and operators
  58. //@{
  59. MIPv6CDSMobileNode(size_t interfaceCount);
  60. ~MIPv6CDSMobileNode();
  61. //@}
  62. ///@name Home Agents/MIPv6 Routers List
  63. //@{
  64. boost::shared_ptr<MIPv6RouterEntry>& primaryHA() const
  65. {
  66. // if (!halEmpty())
  67. // {
  68. // boost::weak_ptr<MIPv6RouterEntry> ha = *(mrl.begin());
  69. // //We will not add any routers to the rtr list until we add our very
  70. // //first homeAgent
  71. // assert(ha->isHomeAgent() == true);
  72. // return ha;
  73. // }
  74. // return boost::weak_ptr<MIPv6RouterEntry>();
  75. //The previous implementation was too restrictive as it prevented
  76. //foreign HA from been added to the list if the primary HA has not been
  77. //added yet (startup in foreign network case)
  78. return _primaryHA;
  79. }
  80. /**
  81. * We need a separate defaultRouter variable because defaultRouter will
  82. * automatically return reachable routers and does not notify us of this
  83. * change.
  84. *
  85. */
  86. //This could have been implemented as the last entry in the ha/router list
  87. //but then we'd have to insert new routers into the hal just one before the
  88. //last position and swap them around if it becomes the new " default
  89. //router"
  90. boost::shared_ptr<MIPv6RouterEntry>& currentRouter() const
  91. {
  92. return _currentRouter;
  93. }
  94. /**
  95. @brief Returns the last known MIPv6 router
  96. L2 trigger and low ping intervals (20-70ms) causes conceptual sending to
  97. regenerate destination cache entries using defaultRouter that was in the
  98. previous subnet. Thus we need to store the previous Default router as
  99. currentRouter() gets set to null when moving to new subnet and no
  100. router's detected yet(For case when oldRtr and newRtr are known then this
  101. function is not necessary) . With this variable we are able to update the
  102. dest cache entries pointing to previousDefaultRtr and redirect them to
  103. the new router. This is done in handover from oldRtr=none to newRtr.
  104. If this updating of dest entries was not done then BUs to CNs may go via
  105. old default router and route optimised CNs will continue sending to our
  106. prior access network. And end up with many dropped packets.
  107. */
  108. boost::shared_ptr<MIPv6RouterEntry>& previousDefaultRouter() const
  109. {
  110. return _previousDefaultRtr;
  111. }
  112. /**
  113. @brief fn to return newly visited router
  114. In case router has already been visited before e.g. coming back to the
  115. HA. If this is not done then when it detects movement and has already
  116. received RA from this "newly" visited router it will not know about this
  117. and send an RS again. Thus there is an extra unsolicited router
  118. advertisement delay before it completes handover properly.
  119. Previously I detected new routers by looking into the mlr in this
  120. class. However only new routers/HAs get inserted into there so if we ever
  121. return home or go back to a previous router that we've visited before
  122. these are not added to the end of mrl. When movement is detected the MN
  123. thinks that there have been no router advs yet from the default router on
  124. visited subnet.
  125. */
  126. boost::shared_ptr<MIPv6RouterEntry>& potentialNewDefaultRtr() const
  127. {
  128. return _potentialNewDefaultRtr;
  129. }
  130. ///Return the homeagent with link local address in addr
  131. boost::shared_ptr<MIPv6RouterEntry> findRouter(const ipv6_addr& ll_addr);
  132. ///Return the homeagent with the global address in g_addr
  133. boost::shared_ptr<MIPv6RouterEntry> findHomeAgent(const ipv6_addr& g_addr);
  134. bool halEmpty() const
  135. {
  136. return mrl.empty();
  137. }
  138. ///Should remove the corresponding BUL entry too
  139. bool removeHomeAgent(boost::weak_ptr<MIPv6RouterEntry> ha);
  140. void insertHomeAgent(MIPv6RouterEntry* ha);
  141. /**
  142. * @param ha is either the Homeagent or the foreign MIPv6 router or HA
  143. *
  144. * @param primary is true if inserting the Primary HA otherwise it is false
  145. * for the current Router.
  146. *
  147. * This hack is necessary due to the unknown order of setup i.e. whether the
  148. * primary home agent is discovered first or an MIPv6 Router or HA on
  149. * foreign network
  150. */
  151. void setHomeAgent(boost::shared_ptr<MIPv6RouterEntry> ha, bool primary);
  152. //@}
  153. ///@name MIPv6 state
  154. //@{
  155. /**
  156. * Looks to me like you can only have one primary home agent per node
  157. * instead of per interface just like one default router per node not per
  158. * interface
  159. *
  160. */
  161. const ipv6_prefix& homePrefix() const;
  162. /**
  163. * There can be many home addr but they usually mean previous care of addr.
  164. * Another possibility is many global on-link prefixes on home subnet so
  165. * many homeAddr from that. However we will only register one home addr so
  166. * far for simplicity's sake. Although if nodes contact us on those other
  167. * prefixes we should still be reachable on them (how would forwarding of
  168. * these other prefixes be implemented?).
  169. */
  170. //Return a cached version of the home addr and update it if needed later on
  171. //for cases when home addr statically configured but no home agent
  172. const ipv6_addr& homeAddr() const { return _homeAddr.prefix; }
  173. /**
  174. * @return homeAddr corresponding to ha
  175. *
  176. * Usually the returned home addr is the primary home address. However when
  177. * forwarding from previous care of addr the home addr is the previous care
  178. * of addr (this should have been sent as a BU to ha)
  179. *
  180. *
  181. */
  182. const ipv6_addr& homeAddr(boost::shared_ptr<MIPv6RouterEntry> ha) const;
  183. /**
  184. * There is only one current care of addr and that is the one registred with
  185. * primary HA.
  186. *
  187. */
  188. const ipv6_addr& careOfAddr() const;
  189. //@}
  190. ///@name Binding Update List
  191. //@{
  192. bool bulEmpty() const { return bul.empty(); }
  193. void addBU(bu_entry* bu);
  194. ///return the bul entry or 0 if no BUs were sent to destAddr
  195. bu_entry* findBU(const ipv6_addr& destAddr) const;
  196. bool removeBU(const ipv6_addr& addr);
  197. ///returns addresses of CNs where coa registered prefix matches addr
  198. std::vector<ipv6_addr> findBUToCNCoaMatchPrefix(const ipv6_addr& addr);
  199. ///returns address of HA from which coa was formed from
  200. const bu_entry * findHAOwns(const ipv6_addr& coa);
  201. //@}
  202. bool awayFromHome() const { return away; }
  203. void setAwayFromHome(bool notAtHome);
  204. bool movementDetected() const { return moved; }
  205. void setMovementDetected(bool move) { moved = move; }
  206. /**
  207. * @param re the MIPv6 router to form coa from
  208. * @param ie the interface to retrieve Interface ID from
  209. */
  210. ipv6_addr formCareOfAddress(boost::weak_ptr<MIPv6RouterEntry> re,
  211. InterfaceEntry *ie) const;
  212. /**
  213. * @param re the MIPv6 router to form hoa from
  214. * @param ie the interface to retrieve Interface ID from
  215. * @param primaryHoa sets homeAddr/homePrefix if true
  216. */
  217. ipv6_prefix formHomeAddress(boost::weak_ptr<MIPv6RouterEntry> re,
  218. InterfaceEntry *ie, bool primaryHoa);
  219. ///lifetime for registrations with HAs for previous coa forwarding purposes
  220. simtime_t pcoaLifetime(){ return _pcoaLifetime; }
  221. bool eagerHandover() { return eagerHO; }
  222. void setEagerHandover(bool eager) { eagerHO = eager; }
  223. bool sendBUAckFlag() { return buAckFlag; }
  224. void setSendBUAckFlag(bool ack) { buAckFlag = ack; }
  225. std::ostream& operator<<(std::ostream& os) const;
  226. protected:
  227. void expireLifetimes(cTimerMessage* tmr);
  228. private:
  229. typedef std::list<boost::shared_ptr<bu_entry> > BindingUpdateList;
  230. typedef BindingUpdateList::iterator BULI;
  231. typedef std::list<boost::shared_ptr<MIPv6RouterEntry> > MIPv6RouterList;
  232. typedef MIPv6RouterList::iterator MRLI;
  233. bool findRouter(const ipv6_addr& ll_addr, MRLI& it);
  234. private:
  235. /**
  236. * @brief Mobile Routers List - routers with MIPv6 support i.e. global address in RA.
  237. *
  238. * Should only contain MIPv6 routers i.e. routers with global prefix
  239. * advertised including HAs.
  240. *
  241. * Serves as the Home Agent's list too for the entries that return true for
  242. * isHomeAgent. Required to perform handovers which does not always depend on HA's
  243. * existing on every foreign network only that there be a global prefix
  244. * available on every foreign network to create a care of addr to register
  245. * with Home HA.
  246. *
  247. * mrl stores only new routers and is not a history list of visited routers
  248. * @todo implement such a history list as you can not insert the same pointer
  249. * into mrl it justs removes the original shared_ptr. Need a weak_ptr list
  250. * for this.
  251. */
  252. MIPv6RouterList mrl;
  253. /**
  254. * List of CN and HA to which a binding has been sent to recently. The
  255. * primaryHA should always be the first one in this list
  256. */
  257. mutable BindingUpdateList bul;
  258. ipv6_prefix _homeAddr;
  259. ///Maintains running state of whether we are away from home
  260. bool away;
  261. ///flag for movementDetected func
  262. bool moved;
  263. simtime_t _pcoaLifetime;
  264. mutable boost::shared_ptr<MIPv6RouterEntry> _primaryHA;
  265. mutable boost::shared_ptr<MIPv6RouterEntry> _currentRouter;
  266. mutable boost::shared_ptr<MIPv6RouterEntry> _previousDefaultRtr;
  267. mutable boost::shared_ptr<MIPv6RouterEntry> _potentialNewDefaultRtr;
  268. /**
  269. @brief when true will handover to new router regardless of movement detection
  270. Read from XML conf. Does not affect HMIP operation since HMIP relies on
  271. RA from routers to trigger MAP handover anyway.
  272. @note It will mistakenly handover to new router on same subnet if both
  273. advertise so this option is best only for one adv. router per subnet.
  274. */
  275. bool eagerHO;
  276. /**
  277. @brief determines state of ack flag in BUs to CNs
  278. */
  279. bool buAckFlag;
  280. };
  281. std::ostream& operator<<(std::ostream& os, const MIPv6CDSMobileNode& cds);
  282. } //namespace MobileIPv6
  283. #endif /* MIPV6CDSMOBILENODE_H */