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

通讯编程

开发平台:

Visual C++

  1. // -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- 
  2. /*
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: rtmodule.cc,v 1.16 2005/08/25 18:58:12 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. // $Header: /cvsroot/nsnam/ns-2/routing/rtmodule.cc,v 1.16 2005/08/25 18:58:12 johnh Exp $
  46. #include "rtmodule.h"
  47. #include <assert.h>
  48. #include "node.h"
  49. static class RoutingModuleClass : public TclClass {
  50. public:
  51. RoutingModuleClass() : TclClass("RtModule") {}
  52. TclObject* create(int, const char*const*) {
  53. return (new RoutingModule);
  54. }
  55. } class_routing_module;
  56. static class BaseRoutingModuleClass : public TclClass {
  57. public:
  58. BaseRoutingModuleClass() : TclClass("RtModule/Base") {}
  59. TclObject* create(int, const char*const*) {
  60. return (new BaseRoutingModule);
  61. }
  62. } class_base_routing_module;
  63. static class McastRoutingModuleClass : public TclClass {
  64. public:
  65. McastRoutingModuleClass() : TclClass("RtModule/Mcast") {}
  66. TclObject* create(int, const char*const*) {
  67. return (new McastRoutingModule);
  68. }
  69. } class_mcast_routing_module;
  70. static class HierRoutingModuleClass : public TclClass {
  71. public:
  72. HierRoutingModuleClass() : TclClass("RtModule/Hier") {}
  73. TclObject* create(int, const char*const*) {
  74. return (new HierRoutingModule);
  75. }
  76. } class_hier_routing_module;
  77. static class ManualRoutingModuleClass : public TclClass {
  78. public:
  79. ManualRoutingModuleClass() : TclClass("RtModule/Manual") {}
  80. TclObject* create(int, const char*const*) {
  81. return (new ManualRoutingModule);
  82. }
  83. } class_manual_routing_module;
  84. static class SourceRoutingModuleClass : public TclClass {
  85. public:
  86.         SourceRoutingModuleClass() : TclClass("RtModule/Source") {}
  87.         TclObject* create(int, const char*const*) {
  88.                 return (new SourceRoutingModule);
  89.         }
  90. } class_source_routing_module;
  91. static class QSRoutingModuleClass : public TclClass {
  92. public:
  93.         QSRoutingModuleClass() : TclClass("RtModule/QS") {}
  94.         TclObject* create(int, const char*const*) {
  95.                 return (new QSRoutingModule);
  96.         }
  97. } class_qs_routing_module;
  98. static class VcRoutingModuleClass : public TclClass {
  99. public:
  100. VcRoutingModuleClass() : TclClass("RtModule/VC") {}
  101. TclObject* create(int, const char*const*) {
  102. return (new VcRoutingModule);
  103. }
  104. } class_vc_routing_module;
  105. #ifdef HAVE_STL
  106. static class PgmRoutingModuleClass : public TclClass {
  107. public:
  108.         PgmRoutingModuleClass() : TclClass("RtModule/PGM") {}
  109.         TclObject* create(int, const char*const*) {
  110.                 return (new PgmRoutingModule);
  111.         }
  112. } class_pgm_routing_module;
  113. #endif //STL
  114. // LMS
  115. static class LmsRoutingModuleClass : public TclClass {
  116. public:
  117.         LmsRoutingModuleClass() : TclClass("RtModule/LMS") {}
  118.         TclObject* create(int, const char*const*) {
  119.                 return (new LmsRoutingModule);
  120.         }
  121. } class_lms_routing_module;
  122. RoutingModule::RoutingModule() : 
  123. next_rtm_(NULL), n_(NULL), classifier_(NULL) {
  124. bind("classifier_", (TclObject**)&classifier_);
  125. }
  126. int RoutingModule::command(int argc, const char*const* argv)
  127. {
  128. Tcl& tcl = Tcl::instance();
  129. if (argc == 2) {
  130. if (strcmp(argv[1], "node") == 0) {
  131. assert(n_ != NULL);
  132. tcl.resultf("%s", n_->name());
  133. return TCL_OK;
  134. } else if (strcmp(argv[1], "module-name") == 0) {
  135. if (module_name() != NULL)
  136. tcl.resultf("%s", module_name());
  137. else 
  138. tcl.result("");
  139. return TCL_OK;
  140. }
  141. } else if (argc == 3) {
  142. if (strcmp(argv[1], "attach-node") == 0) {
  143. n_ = (Node*)TclObject::lookup(argv[2]);
  144. if (n_ == NULL) {
  145. tcl.add_errorf("Wrong object name %s",argv[2]);
  146. return TCL_ERROR;
  147. }
  148. return TCL_OK;
  149. }
  150. //if (strcmp(argv[1], "attach-classifier") == 0) {
  151. //classifier_ = (Classifier*)(TclObject::lookup(argv[2]));
  152. //if (classifier_ == NULL) {
  153. //tcl.add_errorf("Wrong object name %s",argv[2]);
  154. //return TCL_ERROR;
  155. //}
  156. //return TCL_OK;
  157. //}
  158. }
  159. return TclObject::command(argc, argv);
  160. }
  161. int BaseRoutingModule::command(int argc, const char*const* argv) {
  162. Tcl& tcl = Tcl::instance();
  163. if (argc == 3) {
  164. if (strcmp(argv[1] , "route-notify") == 0) {
  165. Node *node = (Node *)(TclObject::lookup(argv[2]));
  166. if (node == NULL) {
  167. tcl.add_errorf("Invalid node object %s", argv[2]);
  168. return TCL_ERROR;
  169. }
  170. if (node != n_) {
  171. tcl.add_errorf("Node object %s different from n_", argv[2]);
  172. return TCL_ERROR;
  173. }
  174. n_->route_notify(this);
  175. return TCL_OK;
  176. }
  177. if (strcmp(argv[1] , "unreg-route-notify") == 0) {
  178. Node *node = (Node *)(TclObject::lookup(argv[2]));
  179. if (node == NULL) {
  180. tcl.add_errorf("Invalid node object %s", argv[2]);
  181. return TCL_ERROR;
  182. }
  183. if (node != n_) {
  184. tcl.add_errorf("Node object %s different from n_", argv[2]);
  185. return TCL_ERROR;
  186. }
  187. n_->unreg_route_notify(this);
  188. return TCL_OK;
  189. }
  190. }
  191. return (RoutingModule::command(argc, argv));
  192. }
  193. int SourceRoutingModule::command(int argc, const char*const* argv) {
  194. Tcl& tcl = Tcl::instance();
  195. if (argc == 3) {
  196. if (strcmp(argv[1] , "route-notify") == 0) {
  197. Node *node = (Node *)(TclObject::lookup(argv[2]));
  198. if (node == NULL) {
  199. tcl.add_errorf("Invalid node object %s", argv[2]);
  200. return TCL_ERROR;
  201. }
  202. if (node != n_) {
  203. tcl.add_errorf("Node object %s different from n_", argv[2]);
  204. return TCL_ERROR;
  205. }
  206. n_->route_notify(this);
  207. return TCL_OK;
  208. }
  209. if (strcmp(argv[1] , "unreg-route-notify") == 0) {
  210. Node *node = (Node *)(TclObject::lookup(argv[2]));
  211. if (node == NULL) {
  212. tcl.add_errorf("Invalid node object %s", argv[2]);
  213. return TCL_ERROR;
  214. }
  215. if (node != n_) {
  216. tcl.add_errorf("Node object %s different from n_", argv[2]);
  217. return TCL_ERROR;
  218. }
  219. n_->unreg_route_notify(this);
  220. return TCL_OK;
  221. }
  222. }
  223. return (RoutingModule::command(argc, argv));
  224. }
  225. int QSRoutingModule::command(int argc, const char*const* argv) {
  226. Tcl& tcl = Tcl::instance();
  227. if (argc == 3) {
  228. if (strcmp(argv[1] , "route-notify") == 0) {
  229. Node *node = (Node *)(TclObject::lookup(argv[2]));
  230. if (node == NULL) {
  231. tcl.add_errorf("Invalid node object %s", argv[2]);
  232. return TCL_ERROR;
  233. }
  234. if (node != n_) {
  235. tcl.add_errorf("Node object %s different from n_", argv[2]);
  236. return TCL_ERROR;
  237. }
  238. n_->route_notify(this);
  239. return TCL_OK;
  240. }
  241. if (strcmp(argv[1] , "unreg-route-notify") == 0) {
  242. Node *node = (Node *)(TclObject::lookup(argv[2]));
  243. if (node == NULL) {
  244. tcl.add_errorf("Invalid node object %s", argv[2]);
  245. return TCL_ERROR;
  246. }
  247. if (node != n_) {
  248. tcl.add_errorf("Node object %s different from n_", argv[2]);
  249. return TCL_ERROR;
  250. }
  251. n_->unreg_route_notify(this);
  252. return TCL_OK;
  253. }
  254. }
  255. return (RoutingModule::command(argc, argv));
  256. }
  257. int McastRoutingModule::command(int argc, const char*const* argv) {
  258. Tcl& tcl = Tcl::instance();
  259. if (argc == 3) {
  260. if (strcmp(argv[1] , "route-notify") == 0) {
  261. Node *node = (Node *)(TclObject::lookup(argv[2]));
  262. if (node == NULL) {
  263. tcl.add_errorf("Invalid node object %s", argv[2]);
  264. return TCL_ERROR;
  265. }
  266. if (node != n_) {
  267. tcl.add_errorf("Node object %s different from n_", argv[2]);
  268. return TCL_ERROR;
  269. }
  270. n_->route_notify(this);
  271. return TCL_OK;
  272. }
  273. if (strcmp(argv[1] , "unreg-route-notify") == 0) {
  274. Node *node = (Node *)(TclObject::lookup(argv[2]));
  275. if (node == NULL) {
  276. tcl.add_errorf("Invalid node object %s", argv[2]);
  277. return TCL_ERROR;
  278. }
  279. if (node != n_) {
  280. tcl.add_errorf("Node object %s different from n_", argv[2]);
  281. return TCL_ERROR;
  282. }
  283. n_->unreg_route_notify(this);
  284. return TCL_OK;
  285. }
  286. }
  287. return (RoutingModule::command(argc, argv));
  288. }
  289. int HierRoutingModule::command(int argc, const char*const* argv) {
  290. Tcl& tcl = Tcl::instance();
  291. if (argc == 3) {
  292. //if (strcmp(argv[1], "attach-classifier") == 0) {
  293. //classifier_ = (HierClassifier*)(TclObject::lookup(argv[2]));
  294. //if (classifier_ == NULL) {
  295. //tcl.add_errorf("Wrong object name %s",argv[2]);
  296. //return TCL_ERROR;
  297. //}
  298. //return TCL_OK;
  299. //}
  300. if (strcmp(argv[1] , "route-notify") == 0) {
  301. Node *node = (Node *)(TclObject::lookup(argv[2]));
  302. if (node == NULL) {
  303. tcl.add_errorf("Invalid node object %s", argv[2]);
  304. return TCL_ERROR;
  305. }
  306. if (node != n_) {
  307. tcl.add_errorf("Node object %s different from n_", argv[2]);
  308. return TCL_ERROR;
  309. }
  310. n_->route_notify(this);
  311. return TCL_OK;
  312. }
  313. if (strcmp(argv[1] , "unreg-route-notify") == 0) {
  314. Node *node = (Node *)(TclObject::lookup(argv[2]));
  315. if (node == NULL) {
  316. tcl.add_errorf("Invalid node object %s", argv[2]);
  317. return TCL_ERROR;
  318. }
  319. if (node != n_) {
  320. tcl.add_errorf("Node object %s different from n_", argv[2]);
  321. return TCL_ERROR;
  322. }
  323. n_->unreg_route_notify(this);
  324. return TCL_OK;
  325. }
  326. }
  327. return (RoutingModule::command(argc, argv));
  328. }
  329. int ManualRoutingModule::command(int argc, const char*const* argv) {
  330. Tcl& tcl = Tcl::instance();
  331. if (argc == 3) {
  332. if (strcmp(argv[1] , "route-notify") == 0) {
  333. Node *node = (Node *)(TclObject::lookup(argv[2]));
  334. if (node == NULL) {
  335. tcl.add_errorf("Invalid node object %s", argv[2]);
  336. return TCL_ERROR;
  337. }
  338. if (node != n_) {
  339. tcl.add_errorf("Node object %s different from node_", argv[2]);
  340. return TCL_ERROR;
  341. }
  342. n_->route_notify(this);
  343. return TCL_OK;
  344. }
  345. if (strcmp(argv[1] , "unreg-route-notify") == 0) {
  346. Node *node = (Node *)(TclObject::lookup(argv[2]));
  347. if (node == NULL) {
  348. tcl.add_errorf("Invalid node object %s", argv[2]);
  349. return TCL_ERROR;
  350. }
  351. if (node != n_) {
  352. tcl.add_errorf("Node object %s different from n_", argv[2]);
  353. return TCL_ERROR;
  354. }
  355. n_->unreg_route_notify(this);
  356. return TCL_OK;
  357. }
  358. }
  359. return (RoutingModule::command(argc, argv));
  360. }
  361. void VcRoutingModule::add_route(char *, NsObject *) { }
  362. int VcRoutingModule::command(int argc, const char*const* argv) {
  363. Tcl& tcl = Tcl::instance();
  364. if (argc == 3) {
  365. if (strcmp(argv[1] , "route-notify") == 0) {
  366. Node *node = (Node *)(TclObject::lookup(argv[2]));
  367. if (node == NULL) {
  368. tcl.add_errorf("Invalid node object %s", argv[2]);
  369. return TCL_ERROR;
  370. }
  371. if (node != n_) {
  372. tcl.add_errorf("Node object %s different from n_", argv[2]);
  373. return TCL_ERROR;
  374. }
  375. n_->route_notify(this);
  376. return TCL_OK;
  377. }
  378. if (strcmp(argv[1] , "unreg-route-notify") == 0) {
  379. Node *node = (Node *)(TclObject::lookup(argv[2]));
  380. if (node == NULL) {
  381. tcl.add_errorf("Invalid node object %s", argv[2]);
  382. return TCL_ERROR;
  383. }
  384. if (node != n_) {
  385. tcl.add_errorf("Node object %s different from n_", argv[2]);
  386. return TCL_ERROR;
  387. }
  388. n_->unreg_route_notify(this);
  389. return TCL_OK;
  390. }
  391. }
  392. return (RoutingModule::command(argc, argv));
  393. }
  394. void RoutingModule::route_notify(RoutingModule *rtm) {
  395. if (next_rtm_ != NULL)
  396. next_rtm_->route_notify(rtm);
  397. else
  398. next_rtm_ = rtm;
  399. }
  400. void RoutingModule::unreg_route_notify(RoutingModule *rtm) {
  401. if (next_rtm_) {
  402. if (next_rtm_ == rtm) {
  403. //RoutingModule *tmp = next_rtm_;
  404. next_rtm_ = next_rtm_->next_rtm_;
  405. //free (tmp);
  406. }
  407. else {
  408. next_rtm_->unreg_route_notify(rtm);
  409. }
  410. }
  411. }
  412. void RoutingModule::add_route(char *dst, NsObject *target) 
  413. {
  414. if (classifier_) 
  415. classifier_->do_install(dst,target); 
  416. if (next_rtm_ != NULL)
  417. next_rtm_->add_route(dst, target); 
  418. }
  419. void RoutingModule::delete_route(char *dst, NsObject *nullagent)
  420. {
  421. if (classifier_) 
  422. classifier_->do_install(dst, nullagent); 
  423. if (next_rtm_)
  424. next_rtm_->add_route(dst, nullagent); 
  425. }
  426. void RoutingModule::set_table_size(int nn)
  427. {
  428. if (classifier_)
  429. classifier_->set_table_size(nn);
  430. if (next_rtm_)
  431. next_rtm_->set_table_size(nn);
  432. }
  433. void RoutingModule::set_table_size(int level, int size)
  434. {
  435. if (classifier_)
  436. classifier_->set_table_size(level, size);
  437. if (next_rtm_)
  438. next_rtm_->set_table_size(level, size);
  439. }
  440. //  void BaseRoutingModule::add_route(char *dst, NsObject *target) {
  441. //   if (classifier_) 
  442. //   ((DestHashClassifier *)classifier_)->do_install(dst, target);
  443. //   if (next_rtm_ != NULL)
  444. //   next_rtm_->add_route(dst, target); 
  445. //  }
  446. //  void McastRoutingModule::add_route(char *dst, NsObject *target) {
  447. //   if (classifier_) 
  448. //   ((DestHashClassifier *)classifier_)->do_install(dst, target);
  449. //   if (next_rtm_ != NULL)
  450. //   next_rtm_->add_route(dst, target); 
  451. //  }
  452. //  void HierRoutingModule::add_route(char *dst, NsObject *target) {
  453. //   if (classifier_) 
  454. //   ((HierClassifier *)classifier_)->do_install(dst, target);
  455. //   if (next_rtm_ != NULL)
  456. //   next_rtm_->add_route(dst, target); 
  457. //  }
  458. void ManualRoutingModule::add_route(char *dst, NsObject *target) {
  459. int slot = classifier_->install_next(target);
  460. if (strcmp(dst, "default") == 0) {
  461. classifier_->set_default(slot);
  462. } else {
  463. int encoded_dst_address = 
  464. (atoi(dst)) << (AddrParamsClass::instance().node_shift(1));
  465. if (0 > (classifier_->do_set_hash(0, encoded_dst_address, 0, slot))) {
  466. fprintf(stderr, "HashClassifier::set_hash() return value less than 0n"); }
  467. }
  468. if (next_rtm_ != NULL)
  469. next_rtm_->add_route(dst, target); 
  470. }