mip-reg.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2000 by the University of Southern California
  3.  * $Id: mip-reg.cc,v 1.13 2007/01/01 17:38:41 mweigle Exp $
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License,
  7.  * version 2, as published by the Free Software Foundation.
  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 General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License along
  15.  * with this program; if not, write to the Free Software Foundation, Inc.,
  16.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  17.  *
  18.  *
  19.  * The copyright of this module includes the following
  20.  * linking-with-specific-other-licenses addition:
  21.  *
  22.  * In addition, as a special exception, the copyright holders of
  23.  * this module give you permission to combine (via static or
  24.  * dynamic linking) this module with free software programs or
  25.  * libraries that are released under the GNU LGPL and with code
  26.  * included in the standard release of ns-2 under the Apache 2.0
  27.  * license or under otherwise-compatible licenses with advertising
  28.  * requirements (or modified versions of such code, with unchanged
  29.  * license).  You may copy and distribute such a system following the
  30.  * terms of the GNU GPL for this module and the licenses of the
  31.  * other code concerned, provided that you include the source code of
  32.  * that other code when and as the GNU GPL requires distribution of
  33.  * source code.
  34.  *
  35.  * Note that people who make modified versions of this module
  36.  * are not obligated to grant this special exception for their
  37.  * modified versions; it is their choice whether to do so.  The GNU
  38.  * General Public License gives permission to release a modified
  39.  * version without this exception; this exception also makes it
  40.  * possible to release a modified version which carries forward this
  41.  * exception.
  42.  *
  43.  */
  44. // $Header: /cvsroot/nsnam/ns-2/mobile/mip-reg.cc,v 1.13 2007/01/01 17:38:41 mweigle Exp $
  45. /*
  46.  * Copyright (c) Sun Microsystems, Inc. 1998 All rights reserved.
  47.  *
  48.  * Redistribution and use in source and binary forms, with or without
  49.  * modification, are permitted provided that the following conditions
  50.  * are met:
  51.  *
  52.  * 1. Redistributions of source code must retain the above copyright
  53.  *    notice, this list of conditions and the following disclaimer.
  54.  *
  55.  * 2. Redistributions in binary form must reproduce the above copyright
  56.  *    notice, this list of conditions and the following disclaimer in the
  57.  *    documentation and/or other materials provided with the distribution.
  58.  *
  59.  * 3. All advertising materials mentioning features or use of this software
  60.  *    must display the following acknowledgement:
  61.  *      This product includes software developed by Sun Microsystems, Inc.
  62.  *
  63.  * 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or
  64.  *      promote products derived from this software without specific prior
  65.  *      written permission.
  66.  *
  67.  * SUN MICROSYSTEMS MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS
  68.  * SOFTWARE FOR ANY PARTICULAR PURPOSE.  The software is provided "as is"
  69.  * without express or implied warranty of any kind.
  70.  *
  71.  * These notices must be retained in any copies of any part of this software.
  72.  */
  73. // #ident "@(#)mip-reg.cc  1.4     98/08/30 SMI"
  74. #include <template.h>
  75. #include <mip.h>
  76. #include <random.h>
  77. #include <address.h>
  78. #include <mobilenode.h>
  79. #if defined (SOLARIS_MIN_MAX)
  80. #include <config.h>     /* for MIN/MAX (if Solaris) */
  81. #else
  82. #include <sys/param.h>  /* for MIN/MAX */
  83. #endif
  84. #define AGENT_ADS_SIZE 48
  85. #define REG_REQUEST_SIZE 52
  86. int hdr_mip::offset_;
  87. static class MIPHeaderClass : public PacketHeaderClass {
  88. public:
  89. MIPHeaderClass() : PacketHeaderClass("PacketHeader/MIP",
  90.      sizeof(hdr_mip)) {
  91. bind_offset(&hdr_mip::offset_);
  92. }
  93. } class_miphdr;
  94. static class MIPBSAgentClass : public TclClass {
  95. public:
  96. MIPBSAgentClass() : TclClass("Agent/MIPBS") {}
  97. TclObject* create(int, const char*const*) {
  98. return (new MIPBSAgent());
  99. }
  100. } class_mipbsagent;
  101. MIPBSAgent::MIPBSAgent() : Agent(PT_UDP), beacon_(1.0), 
  102.   bcast_target_(0), ragent_(0), timer_(this), adlftm_(~0)
  103. {
  104. bind("adSize_", &size_);
  105. //bind("shift_", &shift_);
  106. //bind("mask_", &mask_);
  107. bind("ad_lifetime_", &adlftm_);
  108. size_ = AGENT_ADS_SIZE;
  109. seqno_ = -1;
  110. }
  111. void MIPBSAgent::recv(Packet* p, Handler *)
  112. {
  113. Tcl& tcl = Tcl::instance();
  114. const char *objname = NULL;
  115. NsObject *obj = NULL;
  116. hdr_mip *miph = hdr_mip::access(p);
  117. hdr_ip *iph = hdr_ip::access(p);
  118. hdr_cmn *ch = hdr_cmn::access(p);
  119. int nodeaddr = Address::instance().get_nodeaddr(addr());
  120. switch (miph->type_) {
  121. case MIPT_REG_REQUEST:
  122.   //if (miph->ha_ == (addr_ >> shift_ & mask_)) {
  123.   if (miph->ha_ == (Address::instance().get_nodeaddr(addr()))){
  124.     if (miph->ha_ == miph->coa_) { // back home
  125.       tcl.evalf("%s clear-reg %d", name_,
  126. miph->haddr_);
  127.     }
  128.     else {
  129.       tcl.evalf("%s encap-route %d %d %lf", name_,
  130. miph->haddr_, miph->coa_,
  131. miph->lifetime_);
  132.     }
  133.     iph->dst() = iph->src();
  134.     miph->type_ = MIPT_REG_REPLY;
  135.   }
  136.   else {
  137.     //iph->dst() = iph->dst() & ~(~(nsaddr_t)0 << shift_) | (miph->ha_ & mask_) << shift_;
  138.     iph->daddr() = miph->ha_;
  139.     iph->dport() = 0;
  140.   }
  141.   iph->saddr() = addr();
  142.   iph->sport() = port();
  143.   // by now should be back to normal route
  144.   // if dst is the mobile
  145.   // also initialise forward counter to 0. otherwise routing
  146.   // agent is going to think pkt is looping and drop it!!
  147.   ch->num_forwards() = 0;
  148.   
  149.   send(p, 0);
  150.   break;
  151. case MIPT_REG_REPLY:
  152.   //assert(miph->coa_ == (addr_ >> shift_ & mask_));
  153.   assert(miph->coa_ == nodeaddr);
  154.   tcl.evalf("%s get-link %d %d", name_, nodeaddr, miph->haddr_);
  155.   //
  156.   // XXX hacking mobileip. all this should go away
  157.   // when mobileIP for sun-wired model is no longer reqd.
  158.   //
  159.   obj = (NsObject*)tcl.lookup(objname = tcl.result());
  160.   if (strlen(objname) == 0)
  161.     objname = "XXX";
  162.   tcl.evalf("%s decap-route %d %s %lf", name_, miph->haddr_,
  163.     objname, miph->lifetime_);
  164.   
  165.   iph->src() = iph->dst();
  166.   //iph->dst() = iph->dst() & ~(~(nsaddr_t)0 << shift_) |(miph->haddr_ & mask_) << shift_;
  167.   iph->daddr() = miph->haddr_;
  168.   iph->dport() = 0;
  169.   if (obj == NULL)
  170.     obj = ragent_;
  171.   obj->recv(p, (Handler*)0);
  172.   break;
  173. case MIPT_SOL:
  174.   //tcl.evalf("%s get-link %d %d", name_, addr_ >> shift_ & mask_,miph->haddr_);
  175.   tcl.evalf("%s get-link %d %d",name_,nodeaddr,miph->haddr_);
  176.   send_ads(miph->haddr_, (NsObject*)tcl.lookup(tcl.result()));
  177.   Packet::free(p);
  178.   break;
  179. default:
  180.   Packet::free(p);
  181.   break;
  182. }
  183. }
  184. void MIPBSAgent::timeout(int )
  185. {
  186. send_ads();
  187. timer_.resched(beacon_);
  188. }
  189. int MIPBSAgent::command(int argc, const char*const* argv)
  190. {
  191. if (argc == 3) {
  192. if (strcmp(argv[1], "beacon-period") == 0) {
  193. beacon_ = atof(argv[2]);
  194. timer_.resched(Random::uniform(0, beacon_));
  195. return TCL_OK;
  196. }
  197. if (strcmp(argv[1], "bcast-target") == 0) {
  198. bcast_target_ = (NsObject *)TclObject::lookup(argv[2]);
  199. return TCL_OK;
  200. }
  201. if (strcmp(argv[1], "ragent") == 0) {
  202.   ragent_ = (NsObject *)TclObject::lookup(argv[2]);
  203. return TCL_OK;
  204. }
  205. }
  206. return (Agent::command(argc, argv));
  207. }
  208. void MIPBSAgent::send_ads(int dst, NsObject *target)
  209. {
  210. Packet *p = allocpkt();
  211. hdr_mip *h = hdr_mip::access(p);
  212. hdr_ip *iph = hdr_ip::access(p);
  213. h->haddr_ = h->ha_ = -1;
  214. //h->coa_ = addr_ >> shift_ & mask_;
  215. h->coa_ = Address::instance().get_nodeaddr(addr());
  216. h->type_ = MIPT_ADS;
  217. h->lifetime_ = adlftm_;
  218. h->seqno_ = ++seqno_;
  219. if (dst != -1) {
  220.   iph->daddr() = dst;
  221.   iph->dport() = 0;
  222. }
  223. else {
  224.   // if bcast pkt
  225.   sendOutBCastPkt(p);
  226. }
  227. if (target == NULL) {
  228.   if (bcast_target_) bcast_target_->recv(p, (Handler*) 0);
  229.   else if (target_) target_->recv(p, (Handler*) 0);
  230.   else Packet::free(p); // drop; may log in future code
  231. }
  232. else target->recv(p, (Handler*)0);
  233. }
  234. void
  235. MIPBSAgent::sendOutBCastPkt(Packet *p)
  236. {
  237.   hdr_ip *iph = hdr_ip::access(p);
  238.   hdr_cmn *hdrc = hdr_cmn::access(p);
  239.   hdrc->next_hop_ = IP_BROADCAST;
  240.   hdrc->addr_type_ = NS_AF_INET;
  241.   iph->daddr() = IP_BROADCAST;
  242.   iph->dport() = 0;
  243. }
  244. void AgtListTimer::expire(Event *) {
  245. a_->timeout(MIP_TIMER_AGTLIST);
  246. }
  247. static class MIPMHAgentClass : public TclClass {
  248. public:
  249. MIPMHAgentClass() : TclClass("Agent/MIPMH") {}
  250. TclObject* create(int, const char*const*) {
  251. return (new MIPMHAgent());
  252. }
  253. } class_mipmhagent;
  254. MIPMHAgent::MIPMHAgent() : Agent(PT_UDP), ha_(-1), coa_(-1),
  255. beacon_(1.0),bcast_target_(0),agts_(0),rtx_timer_(this), 
  256. agtlist_timer_(this),reglftm_(~0),adlftm_(0.0), node_ (0)
  257. {
  258. bind("home_agent_", &ha_);
  259. bind("rreqSize_", &size_);
  260. bind("reg_rtx_", &reg_rtx_);
  261. bind("reg_lifetime_", &reglftm_);
  262. size_ = REG_REQUEST_SIZE;
  263. seqno_ = -1;
  264. }
  265. void MIPMHAgent::recv(Packet* p, Handler *)
  266. {
  267. Tcl& tcl = Tcl::instance();
  268. hdr_mip *miph = hdr_mip::access(p);
  269. switch (miph->type_) {
  270. case MIPT_REG_REPLY:
  271. if (miph->coa_ != coa_) break; // not pending
  272. tcl.evalf("%s update-reg %d", name_, coa_);
  273. if (rtx_timer_.status() == TIMER_PENDING)
  274. rtx_timer_.cancel();
  275. break;
  276. case MIPT_ADS:
  277.   {
  278.     AgentList **ppagts = &agts_, *ptr;
  279.     while (*ppagts) {
  280.       if ((*ppagts)->node_ == miph->coa_) break;
  281.       ppagts = &(*ppagts)->next_;
  282.     }
  283.     if (*ppagts) {
  284.       ptr = *ppagts;
  285.       *ppagts = ptr->next_;
  286.       ptr->expire_time_ = beacon_ +
  287. Scheduler::instance().clock();
  288.       ptr->lifetime_ = miph->lifetime_;
  289.       ptr->next_ = agts_;
  290.       agts_ = ptr;
  291.       if (coa_ == miph->coa_) {
  292. seqno_++;
  293. reg();
  294.       }
  295.     }
  296.     else { // new ads
  297.       ptr = new AgentList;
  298.       ptr->node_ = miph->coa_;
  299.       ptr->expire_time_ = beacon_ +
  300. Scheduler::instance().clock();
  301.       ptr->lifetime_ = miph->lifetime_;
  302.       ptr->next_ = agts_;
  303.       agts_ = ptr;
  304.       coa_ = miph->coa_;
  305.   
  306.       // The MHagent now should update the Mobilenode
  307.       // about the changed coa_ : node updates its 
  308.       // base-station to new coa_ accordingly.
  309.       if(node_)
  310. node_->set_base_stn(coa_);
  311.       
  312.       adlftm_ = miph->lifetime_;
  313.       seqno_++;
  314.       reg();
  315.     }
  316.   }
  317.   break;
  318. default:
  319.   break;
  320. }
  321. Packet::free(p);
  322. }
  323. void MIPMHAgent::timeout(int tno)
  324. {
  325. switch (tno) {
  326. case MIP_TIMER_SIMPLE:
  327. reg();
  328. break;
  329. case MIP_TIMER_AGTLIST:
  330. {
  331. double now = Scheduler::instance().clock();
  332. AgentList **ppagts = &agts_, *ptr;
  333. int coalost = 0;
  334. while (*ppagts) {
  335. if ((*ppagts)->expire_time_ < now) {
  336. ptr = *ppagts;
  337. *ppagts = ptr->next_;
  338. if (ptr->node_ == coa_) {
  339. coa_ = -1;
  340. coalost = 1;
  341. }
  342. delete ptr;
  343. }
  344. else ppagts = &(*ppagts)->next_;
  345. }
  346. agtlist_timer_.resched(beacon_);
  347. if (coalost) {
  348. seqno_++;
  349. reg();
  350. }
  351. }
  352. break;
  353. default:
  354. break;
  355. }
  356. }
  357. int MIPMHAgent::command(int argc, const char*const* argv)
  358. {
  359. if (argc == 3) {
  360. if (strcmp(argv[1], "beacon-period") == 0) {
  361. beacon_ = atof(argv[2]);
  362. timeout(MIP_TIMER_AGTLIST);
  363. agtlist_timer_.resched(beacon_);
  364. rtx_timer_.resched(Random::uniform(0, beacon_));
  365. return TCL_OK;
  366. }
  367. else if (strcmp(argv[1], "bcast-target") == 0) {
  368. bcast_target_ = (NsObject *)TclObject::lookup(argv[2]);
  369. return TCL_OK;
  370. }
  371. else if (strcmp (argv[1], "node") == 0) {
  372.   node_ = (MobileNode*)TclObject::lookup(argv[2]);
  373.   if (node_ == 0) {
  374.     fprintf (stderr, "%s: %s lookup of %s failedn", __FILE__, argv[1], argv[2]);
  375.     return TCL_ERROR;
  376.   }
  377.   return TCL_OK;
  378. }
  379. }
  380. // later: agent solicitation (now done!), start of simulation, ...
  381. return (Agent::command(argc, argv));
  382. }
  383. void MIPMHAgent::reg()
  384. {
  385. rtx_timer_.resched(reg_rtx_);
  386. if (agts_ == 0) {
  387. send_sols();
  388. return;
  389. }
  390. if (coa_ < 0) {
  391. coa_ = agts_->node_;
  392. adlftm_ = agts_->lifetime_;
  393. }
  394. Tcl& tcl = Tcl::instance();
  395. Packet *p = allocpkt();
  396. hdr_ip *iph = hdr_ip::access(p);
  397. //iph->dst() = iph->dst() & ~(~(nsaddr_t)0 << shift_) | (coa_ & mask_) << shift_;
  398. iph->daddr() = coa_;
  399. iph->dport() = 0;
  400. hdr_mip *h = hdr_mip::access(p);
  401. //h->haddr_ = addr_ >> shift_ & mask_;
  402. h->haddr_ = Address::instance().get_nodeaddr(addr());
  403. h->ha_ = ha_;
  404. h->coa_ = coa_;
  405. h->type_ = MIPT_REG_REQUEST;
  406. h->lifetime_ = MIN(reglftm_, adlftm_);
  407. h->seqno_ = seqno_;
  408. tcl.evalf("%s get-link %d %d", name_, h->haddr_, coa_);
  409. NsObject *target = (NsObject *)tcl.lookup(tcl.result());
  410. if (target != NULL)
  411.   ((NsObject *)tcl.lookup(tcl.result()))->recv(p, (Handler*) 0);
  412. else
  413.   send(p, 0);
  414. }
  415. void MIPMHAgent::send_sols()
  416. {
  417. Packet *p = allocpkt();
  418. hdr_mip *h = hdr_mip::access(p);
  419. h->coa_ = -1;
  420. //h->haddr_ = addr_ >> shift_ & mask_;
  421. h->haddr_ = Address::instance().get_nodeaddr(addr());
  422. h->ha_ = ha_;
  423. h->type_ = MIPT_SOL;
  424. h->lifetime_ = reglftm_;
  425. h->seqno_ = seqno_;
  426. sendOutBCastPkt(p);
  427. if (bcast_target_) 
  428. bcast_target_->recv(p, (Handler*) 0);
  429. else if (target_) 
  430. target_->recv(p, (Handler*) 0);
  431. else 
  432. Packet::free(p); // drop; may log in future code
  433. }
  434. void MIPMHAgent::sendOutBCastPkt(Packet *p)
  435. {
  436. hdr_ip *iph = hdr_ip::access(p);
  437. hdr_cmn *hdrc = hdr_cmn::access(p);
  438. hdrc->next_hop_ = IP_BROADCAST;
  439. hdrc->addr_type_ = NS_AF_INET;
  440. iph->daddr() = IP_BROADCAST;
  441. iph->dport() = 0;
  442. }