PageRenderTime 44ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/networklayer/manetrouting/dymo/dymoum/dymo_rerr.cc

https://github.com/Sorouri/inetmanet
C++ | 330 lines | 256 code | 47 blank | 27 comment | 50 complexity | c08ce3f3c4c897561db9cbdbb3f36533 MD5 | raw file
Possible License(s): GPL-2.0
  1. /***************************************************************************
  2. * Copyright (C) 2005 by Francisco J. Ros *
  3. * fjrm@dif.um.es *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  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 *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #define NS_PORT
  21. #define OMNETPP
  22. #ifdef NS_PORT
  23. #ifndef OMNETPP
  24. #include "ns/dymo_um.h"
  25. #else
  26. #include "../dymo_um_omnet.h"
  27. #endif
  28. #else
  29. #include "dymo_rerr.h"
  30. #include "dymo_socket.h"
  31. #include <string.h>
  32. #endif /* NS_PORT */
  33. RERR *NS_CLASS rerr_create(struct rerr_block *blocks, int nblocks, int ttl)
  34. {
  35. int i;
  36. RERR *rerr;
  37. #ifndef OMNETPP
  38. rerr = (RERR *) dymo_socket_new_element();
  39. #else
  40. rerr = new RERR();
  41. rerr->newBocks(nblocks);
  42. #endif
  43. rerr->m = 0;
  44. rerr->h = 0;
  45. rerr->type = DYMO_RERR_TYPE;
  46. rerr->len = RERR_BASIC_SIZE + (nblocks * RERR_BLOCK_SIZE);
  47. rerr->ttl = ttl;
  48. rerr->i = 0;
  49. for (i = 0; i < nblocks; i++)
  50. {
  51. rerr->rerr_blocks[i].unode_addr = blocks[i].unode_addr;
  52. rerr->rerr_blocks[i].unode_seqnum = blocks[i].unode_seqnum;
  53. }
  54. return rerr;
  55. }
  56. void NS_CLASS rerr_send(struct in_addr addr, int ttl, rtable_entry_t *entry)
  57. {
  58. int i = 1;
  59. struct rerr_block blocks[MAX_RERR_BLOCKS];
  60. dlog(LOG_DEBUG, 0, __FUNCTION__, "sending RERR");
  61. memset(blocks, '\0', MAX_RERR_BLOCKS * sizeof(struct rerr_block));
  62. blocks[0].unode_addr = addr.s_addr;
  63. if (entry)
  64. {
  65. dlist_head_t *pos;
  66. blocks[0].unode_seqnum = entry->rt_seqnum;
  67. #ifndef MAPROUTINGTABLE
  68. dlist_for_each(pos, &rtable.l)
  69. {
  70. if (i >= MAX_RERR_BLOCKS)
  71. continue;
  72. rtable_entry_t *e = (rtable_entry_t *) pos;
  73. if (e != entry && (e->rt_nxthop_addr.s_addr
  74. == entry->rt_nxthop_addr.s_addr) &&
  75. (e->rt_ifindex == entry->rt_ifindex))
  76. {
  77. i++;
  78. blocks[i-1].unode_addr = e->rt_dest_addr.s_addr;
  79. blocks[i-1].unode_seqnum = e->rt_seqnum;
  80. }
  81. }
  82. #else
  83. for (DymoRoutingTable::iterator it = dymoRoutingTable.begin();it != dymoRoutingTable.end();it++)
  84. {
  85. if (i >= MAX_RERR_BLOCKS)
  86. continue;
  87. rtable_entry_t *e = it->second;
  88. if (e != entry && (e->rt_nxthop_addr.s_addr
  89. == entry->rt_nxthop_addr.s_addr) &&
  90. (e->rt_ifindex == entry->rt_ifindex))
  91. {
  92. i++;
  93. blocks[i-1].unode_addr = e->rt_dest_addr.s_addr;
  94. blocks[i-1].unode_seqnum = e->rt_seqnum;
  95. }
  96. }
  97. #endif
  98. }
  99. else
  100. blocks[0].unode_seqnum = 0;
  101. RERR *rerr = rerr_create(blocks, i, ttl);
  102. rerr_forward(rerr);
  103. }
  104. void NS_CLASS rerr_process(RERR *rerr,struct in_addr src, u_int32_t ifindex)
  105. {
  106. struct in_addr node_addr;
  107. rtable_entry_t *entry;
  108. int i;
  109. #ifdef OMNETPP
  110. int num_blk_del;
  111. #endif
  112. // Be sure that there is a block at least
  113. if (rerr_numblocks(rerr) <= 0)
  114. {
  115. dlog(LOG_WARNING, 0, __FUNCTION__, "malformed RERR received");
  116. #ifdef OMNETPP
  117. delete rerr;
  118. rerr=NULL;
  119. #endif
  120. return;
  121. }
  122. #ifdef OMNETPP
  123. num_blk_del=0;
  124. totalRerrRec++;
  125. #endif
  126. for (i = 0; i < rerr_numblocks(rerr); i++)
  127. {
  128. int changed = 0;
  129. node_addr.s_addr = rerr->rerr_blocks[i].unode_addr;
  130. entry = rtable_find(node_addr);
  131. if (entry && entry->rt_state == RT_VALID)
  132. {
  133. int32_t sub;
  134. u_int32_t unode_seqnum =
  135. ntohl(rerr->rerr_blocks[i].unode_seqnum);
  136. u_int32_t rt_seqnum = ntohl(entry->rt_seqnum);
  137. sub = (int32_t) unode_seqnum - (int32_t) rt_seqnum;
  138. if (entry->rt_nxthop_addr.s_addr == src.s_addr &&
  139. entry->rt_ifindex == ifindex &&
  140. (unode_seqnum == 0 || sub <= 0))
  141. {
  142. rtable_expire_timeout(entry);
  143. changed = 1;
  144. }
  145. }
  146. if (!changed)
  147. {
  148. // drop block
  149. int n = rerr_numblocks(rerr) - i - 1;
  150. memmove(&rerr->rerr_blocks[i], &rerr->rerr_blocks[i+1],
  151. n * sizeof(struct rerr_block));
  152. memset(&rerr->rerr_blocks[i + n], 0, sizeof(struct rerr_block));
  153. rerr->len -= RERR_BLOCK_SIZE;
  154. i--;
  155. #ifdef OMNETPP
  156. num_blk_del++;
  157. #endif
  158. }
  159. }
  160. #ifdef OMNETPP
  161. rerr->delBocks(num_blk_del);
  162. #endif
  163. if (rerr_numblocks(rerr) > 0 &&
  164. generic_postprocess((DYMO_element *) rerr))
  165. {
  166. rerr_forward(rerr);
  167. }
  168. #ifdef OMNETPP
  169. else
  170. {
  171. delete rerr;
  172. rerr=NULL;
  173. }
  174. #endif
  175. }
  176. void NS_CLASS rerr_forward(RERR *rerr)
  177. {
  178. struct in_addr dest_addr;
  179. int i;
  180. dlog(LOG_DEBUG, 0, __FUNCTION__, "forwarding RERR");
  181. #ifdef OMNETPP
  182. double delay = -1;
  183. if (par("EqualDelay"))
  184. delay = par("broadCastDelay");
  185. rerr->setByteLength(0);
  186. int cont = numInterfacesActive;
  187. if (numInterfacesActive==0)
  188. {
  189. delete rerr;
  190. rerr=NULL;
  191. return;
  192. }
  193. dest_addr.s_addr = DYMO_BROADCAST;
  194. // Send RE over all enabled interfaces
  195. for (i = 0; i < DYMO_MAX_NR_INTERFACES; i++)
  196. {
  197. if (DEV_NR(i).enabled)
  198. {
  199. if (cont>1)
  200. dymo_socket_queue((DYMO_element *) rerr->dup());
  201. else
  202. dymo_socket_queue((DYMO_element *) rerr);
  203. dymo_socket_send(dest_addr, &DEV_NR(i),delay);
  204. cont--;
  205. }
  206. }
  207. #else
  208. // Queue the new RERR
  209. rerr = (RERR *) dymo_socket_queue((DYMO_element *) rerr);
  210. // Send RERR over all enabled interfaces
  211. dest_addr.s_addr = DYMO_BROADCAST;
  212. for (i = 0; i < DYMO_MAX_NR_INTERFACES; i++)
  213. if (DEV_NR(i).enabled)
  214. dymo_socket_send(dest_addr, &DEV_NR(i));
  215. #endif
  216. }
  217. #ifdef OMNETPP
  218. void NS_CLASS rerr_send(struct in_addr addr, int ttl, rtable_entry_t *entry,struct in_addr dest_addr)
  219. {
  220. int i = 1;
  221. struct rerr_block blocks[MAX_RERR_BLOCKS];
  222. dlog(LOG_DEBUG, 0, __FUNCTION__, "sending RERR");
  223. memset(blocks, '\0', MAX_RERR_BLOCKS * sizeof(struct rerr_block));
  224. blocks[0].unode_addr = addr.s_addr;
  225. if (entry)
  226. {
  227. dlist_head_t *pos;
  228. blocks[0].unode_seqnum = entry->rt_seqnum;
  229. #ifndef MAPROUTINGTABLE
  230. dlist_for_each(pos, &rtable.l)
  231. {
  232. rtable_entry_t *e = (rtable_entry_t *) pos;
  233. if (e != entry && (e->rt_nxthop_addr.s_addr
  234. == entry->rt_nxthop_addr.s_addr) &&
  235. (e->rt_ifindex == entry->rt_ifindex))
  236. {
  237. i++;
  238. blocks[i-1].unode_addr = e->rt_dest_addr.s_addr;
  239. blocks[i-1].unode_seqnum = e->rt_seqnum;
  240. }
  241. }
  242. #else
  243. for (DymoRoutingTable::iterator it = dymoRoutingTable.begin();it != dymoRoutingTable.end();it++)
  244. {
  245. rtable_entry_t *e = it->second;
  246. if (e != entry && (e->rt_nxthop_addr.s_addr
  247. == entry->rt_nxthop_addr.s_addr) &&
  248. (e->rt_ifindex == entry->rt_ifindex))
  249. {
  250. i++;
  251. blocks[i-1].unode_addr = e->rt_dest_addr.s_addr;
  252. blocks[i-1].unode_seqnum = e->rt_seqnum;
  253. }
  254. }
  255. #endif
  256. }
  257. else
  258. blocks[0].unode_seqnum = 0;
  259. RERR *rerr = rerr_create(blocks, i, ttl);
  260. rerr_forward(rerr,dest_addr);
  261. }
  262. void NS_CLASS rerr_forward(RERR *rerr,struct in_addr dest_addr)
  263. {
  264. //int i;
  265. dlog(LOG_DEBUG, 0, __FUNCTION__, "forwarding RERR");
  266. //int cont = numInterfacesActive;
  267. if (numInterfacesActive==0)
  268. {
  269. delete rerr;
  270. rerr=NULL;
  271. return;
  272. }
  273. // Send RE over all enabled interfaces
  274. rtable_entry_t *entry = rtable_find(dest_addr);
  275. dymo_socket_queue((DYMO_element *) rerr);
  276. if (entry)
  277. {
  278. dymo_socket_send(dest_addr, &DEV_IFINDEX(entry->rt_ifindex));
  279. }
  280. else
  281. dymo_socket_send(dest_addr, &DEV_IFINDEX(NS_IFINDEX));
  282. }
  283. #endif