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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * flowstruct.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: flowstruct.cc,v 1.4 2005/08/25 18:58:04 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. //
  46. // Other copyrights might apply to parts of this software and are so
  47. // noted when applicable.
  48. //
  49. // Ported from CMU/Monarch's code, appropriate copyright applies.  
  50. #include "flowstruct.h"
  51. FlowTable::FlowTable(int size_) : DRTab(size_) {
  52. assert (size_ > 0);
  53. size = 0;
  54. maxSize = size_;
  55. table = new TableEntry[size_];
  56. counter = 0;
  57. }
  58. FlowTable::~FlowTable() {
  59. delete table;
  60. }
  61. TableEntry &FlowTable::operator[](int index) {
  62. assert(index >= 0 && index < size);
  63. return table[index];
  64. }
  65. int FlowTable::find(nsaddr_t source, nsaddr_t destination, u_int16_t flow) {
  66. register int i;
  67. for (i=size-1; i>=0; i--)
  68. if (table[i].sourceIP == source &&
  69.     table[i].destinationIP == destination &&
  70.     table[i].flowId == flow)
  71. break;
  72. return i;
  73. }
  74. int FlowTable::find(nsaddr_t source, nsaddr_t destination, const Path &route) {
  75. register int i;
  76. for (i=size-1; i>=0; i--)
  77. if (table[i].sourceIP == source &&
  78.     table[i].destinationIP == destination &&
  79.     table[i].sourceRoute == route)
  80. break;
  81. return i;
  82. }
  83. void FlowTable::grow() {
  84. assert(0);
  85. TableEntry *temp;
  86. if (!(temp = new TableEntry[maxSize*2]))
  87. return;
  88. bcopy(table, temp, sizeof(TableEntry)*maxSize);
  89. delete table;
  90. maxSize *= 2;
  91. table = temp;
  92. }
  93. u_int16_t FlowTable::generateNextFlowId(nsaddr_t destination, bool allowDefault) {
  94. if ((counter&1)^allowDefault) // make sure parity is correct
  95. counter++;
  96. assert((counter & 1) == allowDefault);
  97. return counter++;
  98. }
  99. int FlowTable::createEntry(nsaddr_t source, nsaddr_t destination, 
  100.    u_int16_t flow) {
  101. if (find(source, destination, flow) != -1)
  102. return -1;
  103. if (size == maxSize)
  104. grow();
  105. if (size == maxSize)
  106. return -1;
  107. table[size].sourceIP = source;
  108. table[size].destinationIP = destination;
  109. table[size].flowId = flow;
  110. if (flow & 1)
  111. DRTab.insert(source, destination, flow);
  112. return size++;
  113. }
  114. void FlowTable::noticeDeadLink(const ID &from, const ID &to) {
  115. double now = Scheduler::instance().clock();
  116. for (int i=0; i<size; i++)
  117. if (table[i].timeout >= now && table[i].sourceIP == net_addr)
  118. for (int n=0; n < (table[i].sourceRoute.length()-1); n++)
  119. if (table[i].sourceRoute[n] == from &&
  120.     table[i].sourceRoute[n+1] == to) {
  121. table[i].timeout = now - 1;
  122. // XXX ych rediscover??? 5/2/01
  123. }
  124. }
  125. // if ent represents a default flow, bad things are going down and we need
  126. // to rid the default flow table of them.
  127. static void checkDefaultFlow(DRTable &DRTab, const TableEntry &ent) {
  128. u_int16_t flow;
  129. if (!DRTab.find(ent.sourceIP, ent.destinationIP, flow))
  130. return;
  131. if (flow == ent.flowId)
  132. DRTab.flush(ent.sourceIP, ent.destinationIP);
  133. }
  134. void FlowTable::cleanup() {
  135. int front, back;
  136. double now = Scheduler::instance().clock();
  137. return; // it's messing up path orders...
  138. // init front to the first expired entry
  139. for (front=0; (front<size) && (table[front].timeout >= now); front++)
  140. ;
  141. // init back to the last unexpired entry
  142. for (back = size-1; (front<back) && (table[back].timeout < now); back--)
  143. checkDefaultFlow(DRTab, table[back]);
  144. while (front < back) {
  145. checkDefaultFlow(DRTab, table[front]);
  146. bcopy(table+back, table+front, sizeof(TableEntry)); // swap
  147. back--;
  148. // next expired entry
  149. while ((front<back) && (table[front].timeout >= now))
  150. front++;
  151. while ((front<back) && (table[back].timeout < now)) {
  152. checkDefaultFlow(DRTab, table[back]);
  153. back--;
  154. }
  155. }
  156. size = back+1;
  157. }
  158. void FlowTable::setNetAddr(nsaddr_t net_id) {
  159. net_addr = net_id;
  160. }
  161. bool FlowTable::defaultFlow(nsaddr_t source, nsaddr_t destination, 
  162.     u_int16_t &flow) {
  163. return DRTab.find(source, destination, flow);
  164. }
  165. DRTable::DRTable(int size_) {
  166. assert (size_ > 0);
  167. size = 0;
  168. maxSize = size_;
  169. table = new DRTabEnt[size_];
  170. }
  171. DRTable::~DRTable() {
  172. delete table;
  173. }
  174. bool DRTable::find(nsaddr_t src, nsaddr_t dst, u_int16_t &flow) {
  175. for (int i = 0; i < size; i++)
  176. if (src == table[i].src && dst == table[i].dst) {
  177. flow = table[i].fid;
  178. return true;
  179. }
  180. return false;
  181. }
  182. void DRTable::grow() {
  183. assert(0);
  184. DRTabEnt *temp;
  185. if (!(temp = new DRTabEnt[maxSize*2]))
  186. return;
  187. bcopy(table, temp, sizeof(DRTabEnt)*maxSize);
  188. delete table;
  189. maxSize *= 2;
  190. table = temp;
  191. }
  192. void DRTable::insert(nsaddr_t src, nsaddr_t dst, u_int16_t flow) {
  193. assert(flow & 1);
  194. for (int i = 0; i < size; i++) {
  195. if (src == table[i].src && dst == table[i].dst) {
  196. if ((short)((flow) - (table[i].fid)) > 0) {
  197. table[i].fid = flow;
  198. } else {
  199. }
  200. return;
  201. }
  202. }
  203. if (size == maxSize)
  204. grow();
  205. assert(size != maxSize);
  206. table[size].src = src;
  207. table[size].dst = dst;
  208. table[size].fid = flow;
  209. size++;
  210. }
  211. void DRTable::flush(nsaddr_t src, nsaddr_t dst) {
  212. for (int i = 0; i < size; i++)
  213. if (src == table[i].src && dst == table[i].dst) {
  214. table[i].src = table[size-1].src;
  215. table[i].dst = table[size-1].dst;
  216. table[i].fid = table[size-1].fid;
  217. size--;
  218. return;
  219. }
  220. assert(0);
  221. }
  222. ARSTable::ARSTable(int size_) {
  223. size = size_;
  224. victim = 0;
  225. table = new ARSTabEnt[size_];
  226. bzero(table, sizeof(ARSTabEnt)*size_);
  227. }
  228. ARSTable::~ARSTable() {
  229. delete table;
  230. }
  231. void ARSTable::insert(int uid, u_int16_t fid, int hopsEarly) {
  232. int i = victim;
  233. assert(hopsEarly);
  234. do {
  235. if (!table[i].hopsEarly)
  236. break; // we found a victim
  237. i = (i+1)%size;
  238. } while (i != victim);
  239. if (table[i].hopsEarly) // full. need extreme measures.
  240. victim = (victim+1)%size;
  241. table[i].hopsEarly = hopsEarly;
  242. table[i].uid       = uid;
  243. table[i].fid    = fid;
  244. }
  245. int ARSTable::findAndClear(int uid, u_int16_t fid) {
  246. int i, retval;
  247. for (i=0; i<size; i++) {
  248.         if (table[i].hopsEarly && table[i].uid == uid) {
  249.         if (table[i].fid == fid) {
  250.         retval = table[i].hopsEarly;
  251. table[i].hopsEarly = 0;
  252. return retval;
  253. } else {
  254. table[i].hopsEarly = 0;
  255. return 0;
  256. }
  257. }
  258. }
  259. return 0;
  260. }