PageRenderTime 116ms CodeModel.GetById 45ms RepoModel.GetById 1ms app.codeStats 0ms

/src/transport/sctp/SCTPAssociationUtil.cc

https://github.com/Sorouri/inetmanet
C++ | 2439 lines | 2027 code | 329 blank | 83 comment | 326 complexity | 759f3811fbb168e52b8151238a39b429 MD5 | raw file
Possible License(s): GPL-2.0
  1. //
  2. // Copyright (C) 2008 Irene Ruengeler
  3. //
  4. // This program is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU General Public License
  6. // as published by the Free Software Foundation; either version 2
  7. // 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 General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, see <http://www.gnu.org/licenses/>.
  16. //
  17. #include <string.h>
  18. #include "SCTP.h"
  19. #include "SCTPAssociation.h"
  20. #include "SCTPCommand_m.h"
  21. #include "IPv6ControlInfo.h"
  22. #include "SCTPQueue.h"
  23. #include "SCTPAlgorithm.h"
  24. #include "RoutingTable.h"
  25. #include "RoutingTableAccess.h"
  26. #include "InterfaceTable.h"
  27. #include "InterfaceTableAccess.h"
  28. #include "IPv4InterfaceData.h"
  29. #include "IPv6InterfaceData.h"
  30. #include "IPv6Address.h"
  31. #include <stdlib.h>
  32. #include <sys/time.h>
  33. //
  34. // helper functions
  35. //
  36. inline uint32 uint32rand() {
  37. return ((uint32)intrand(0xffff) << 16) + (uint32)intrand(0xffff);
  38. }
  39. void SCTPAssociation::printSctpPathMap()
  40. {
  41. SCTPPathVariables* path;
  42. sctpEV3<<"\nSCTP PathMap\n";
  43. for (SCTPPathMap::iterator i = sctpPathMap.begin(); i!=sctpPathMap.end(); ++i)
  44. {
  45. path = i->second;
  46. sctpEV3<<"address: "<<path->remoteAddress<<" osb: "<<path->outstandingBytes<<" cwnd: "<<path->cwnd<<"\n";
  47. }
  48. }
  49. const char *SCTPAssociation::stateName(int32 state)
  50. {
  51. #define CASE(x) case x: s=#x+7; break
  52. const char *s = "unknown";
  53. switch (state)
  54. {
  55. CASE(SCTP_S_CLOSED);
  56. CASE(SCTP_S_COOKIE_WAIT);
  57. CASE(SCTP_S_COOKIE_ECHOED);
  58. CASE(SCTP_S_ESTABLISHED);
  59. CASE(SCTP_S_SHUTDOWN_PENDING);
  60. CASE(SCTP_S_SHUTDOWN_SENT);
  61. CASE(SCTP_S_SHUTDOWN_RECEIVED);
  62. CASE(SCTP_S_SHUTDOWN_ACK_SENT);
  63. }
  64. return s;
  65. #undef CASE
  66. }
  67. const char *SCTPAssociation::eventName(int32 event)
  68. {
  69. #define CASE(x) case x: s=#x+7; break
  70. const char *s = "unknown";
  71. switch (event)
  72. {
  73. CASE(SCTP_E_OPEN_PASSIVE);
  74. CASE(SCTP_E_ASSOCIATE);
  75. CASE(SCTP_E_SHUTDOWN);
  76. CASE(SCTP_E_CLOSE);
  77. CASE(SCTP_E_ABORT);
  78. CASE(SCTP_E_SEND);
  79. CASE(SCTP_E_RCV_INIT);
  80. CASE(SCTP_E_RCV_ABORT);
  81. CASE(SCTP_E_RCV_VALID_COOKIE_ECHO);
  82. CASE(SCTP_E_RCV_INIT_ACK);
  83. CASE(SCTP_E_RCV_COOKIE_ACK);
  84. CASE(SCTP_E_RCV_SHUTDOWN);
  85. CASE(SCTP_E_RCV_SHUTDOWN_ACK);
  86. CASE(SCTP_E_RCV_SHUTDOWN_COMPLETE);
  87. CASE(SCTP_E_TIMEOUT_INIT_TIMER);
  88. CASE(SCTP_E_TIMEOUT_SHUTDOWN_TIMER);
  89. CASE(SCTP_E_TIMEOUT_RTX_TIMER);
  90. CASE(SCTP_E_TIMEOUT_HEARTBEAT_TIMER);
  91. CASE(SCTP_E_RECEIVE);
  92. CASE(SCTP_E_DUP_RECEIVED);
  93. CASE(SCTP_E_PRIMARY);
  94. CASE(SCTP_E_QUEUE);
  95. CASE(SCTP_E_NO_MORE_OUTSTANDING);
  96. CASE(SCTP_E_IGNORE);
  97. CASE(SCTP_E_DELIVERED);
  98. CASE(SCTP_E_SEND_SHUTDOWN_ACK);
  99. CASE(SCTP_E_STOP_SENDING);
  100. }
  101. return s;
  102. #undef CASE
  103. }
  104. const char *SCTPAssociation::indicationName(int32 code)
  105. {
  106. #define CASE(x) case x: s=#x+7; break
  107. const char *s = "unknown";
  108. switch (code)
  109. {
  110. CASE(SCTP_I_DATA);
  111. CASE(SCTP_I_DATA_NOTIFICATION);
  112. CASE(SCTP_I_ESTABLISHED);
  113. CASE(SCTP_I_PEER_CLOSED);
  114. CASE(SCTP_I_CLOSED);
  115. CASE(SCTP_I_CONNECTION_REFUSED);
  116. CASE(SCTP_I_CONNECTION_RESET);
  117. CASE(SCTP_I_TIMED_OUT);
  118. CASE(SCTP_I_STATUS);
  119. CASE(SCTP_I_ABORT);
  120. CASE(SCTP_I_SHUTDOWN_RECEIVED);
  121. CASE(SCTP_I_SEND_MSG);
  122. CASE(SCTP_I_SENDQUEUE_FULL);
  123. }
  124. return s;
  125. #undef CASE
  126. }
  127. uint32 SCTPAssociation::chunkToInt(char* type)
  128. {
  129. if (strcmp(type, "DATA")==0) return 0;
  130. if (strcmp(type, "INIT")==0) return 1;
  131. if (strcmp(type, "INIT_ACK")==0) return 2;
  132. if (strcmp(type, "SACK")==0) return 3;
  133. if (strcmp(type, "HEARTBEAT")==0) return 4;
  134. if (strcmp(type, "HEARTBEAT_ACK")==0) return 5;
  135. if (strcmp(type, "ABORT")==0) return 6;
  136. if (strcmp(type, "SHUTDOWN")==0) return 7;
  137. if (strcmp(type, "SHUTDOWN_ACK")==0) return 8;
  138. if (strcmp(type, "ERRORTYPE")==0) return 9;
  139. if (strcmp(type, "COOKIE_ECHO")==0) return 10;
  140. if (strcmp(type, "COOKIE_ACK")==0) return 11;
  141. if (strcmp(type, "SHUTDOWN_COMPLETE")==0) return 14;
  142. sctpEV3<<"ChunkConversion not successful\n";
  143. return 0;
  144. }
  145. void SCTPAssociation::printConnBrief()
  146. {
  147. sctpEV3 << "Connection " << this << " ";
  148. sctpEV3 << localAddr << ":" << localPort << " to " << remoteAddr << ":" << remotePort;
  149. sctpEV3 << " on app[" << appGateIndex << "],assocId=" << assocId;
  150. sctpEV3 << " in " << stateName(fsm->getState()) << "\n";
  151. }
  152. void SCTPAssociation::printSegmentBrief(SCTPMessage *sctpmsg)
  153. {
  154. sctpEV3 << "." << sctpmsg->getSrcPort() << " > ";
  155. sctpEV3 << "." << sctpmsg->getDestPort() << ": ";
  156. sctpEV3 << "initTag "<< sctpmsg->getTag() << "\n";
  157. }
  158. SCTPAssociation *SCTPAssociation::cloneAssociation()
  159. {
  160. SCTPAssociation *assoc = new SCTPAssociation(sctpMain,appGateIndex,assocId);
  161. const char *queueClass = transmissionQ->getClassName();
  162. assoc->transmissionQ = check_and_cast<SCTPQueue *>(createOne(queueClass));
  163. assoc->retransmissionQ = check_and_cast<SCTPQueue *>(createOne(queueClass));
  164. const char *sctpAlgorithmClass = sctpAlgorithm->getClassName();
  165. assoc->sctpAlgorithm = check_and_cast<SCTPAlgorithm *>(createOne(sctpAlgorithmClass));
  166. assoc->sctpAlgorithm->setAssociation(assoc);
  167. assoc->sctpAlgorithm->initialize();
  168. assoc->state = assoc->sctpAlgorithm->createStateVariables();
  169. assoc->state->active = false;
  170. assoc->state->fork = true;
  171. assoc->localAddr = localAddr;
  172. assoc->localPort = localPort;
  173. assoc->localAddressList = localAddressList;
  174. FSM_Goto((*assoc->fsm), SCTP_S_CLOSED);
  175. sctpMain->printInfoConnMap();
  176. return assoc;
  177. }
  178. void SCTPAssociation::sendToIP(SCTPMessage *sctpmsg)
  179. {
  180. // final touches on the segment before sending
  181. sctpmsg->setSrcPort(localPort);
  182. sctpmsg->setDestPort(remotePort);
  183. if (sctpmsg->getTag()==0)
  184. sctpmsg->setTag(localVTag);
  185. sctpmsg->setChecksumOk(true);
  186. if (remoteAddr.isIPv6())
  187. {
  188. IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
  189. controlInfo->setProtocol(IP_PROT_SCTP);
  190. controlInfo->setSrcAddr(IPv6Address());
  191. controlInfo->setDestAddr(remoteAddr.get6());
  192. sctpmsg->setControlInfo(controlInfo);
  193. sctpMain->send(sctpmsg,"to_ipv6");
  194. }
  195. else
  196. {
  197. IPControlInfo *controlInfo = new IPControlInfo();
  198. controlInfo->setProtocol(IP_PROT_SCTP);
  199. controlInfo->setSrcAddr(IPAddress("0.0.0.0"));
  200. controlInfo->setDestAddr(remoteAddr.get4());
  201. sctpmsg->setControlInfo(controlInfo);
  202. sctpMain->send(sctpmsg,"to_ip");
  203. }
  204. }
  205. void SCTPAssociation::sendToIP(SCTPMessage *sctpmsg, IPvXAddress dest)
  206. {
  207. sctpmsg->setSrcPort(localPort);
  208. sctpmsg->setDestPort(remotePort);
  209. sctpmsg->setChecksumOk(true);
  210. SCTPChunk* chunk = (SCTPChunk*)(sctpmsg->peekFirstChunk());
  211. if (chunk->getChunkType() == ABORT)
  212. {
  213. SCTPAbortChunk* abortChunk;
  214. abortChunk = check_and_cast<SCTPAbortChunk *>(chunk);
  215. if (abortChunk->getT_Bit()==1)
  216. sctpmsg->setTag(peerVTag);
  217. else
  218. sctpmsg->setTag(localVTag);
  219. }
  220. else if (sctpmsg->getTag()==0)
  221. sctpmsg->setTag(localVTag);
  222. if (dest.isIPv6())
  223. {
  224. IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
  225. controlInfo->setProtocol(IP_PROT_SCTP);
  226. controlInfo->setSrcAddr(IPv6Address());
  227. controlInfo->setDestAddr(dest.get6());
  228. sctpmsg->setControlInfo(controlInfo);
  229. sctpMain->send(sctpmsg,"to_ipv6");
  230. }
  231. else
  232. {
  233. IPControlInfo *controlInfo = new IPControlInfo();
  234. controlInfo->setProtocol(IP_PROT_SCTP);
  235. controlInfo->setSrcAddr(IPAddress("0.0.0.0"));
  236. controlInfo->setDestAddr(dest.get4());
  237. sctpmsg->setControlInfo(controlInfo);
  238. sctpMain->send(sctpmsg,"to_ip");
  239. }
  240. sctpEV3 << "Sent to "<<dest<<"\n ";
  241. }
  242. void SCTPAssociation::sendToIP(SCTPMessage *sctpmsg, IPvXAddress src, IPvXAddress dest)
  243. {
  244. sctpmsg->setSrcPort(localPort);
  245. sctpmsg->setDestPort(remotePort);
  246. sctpmsg->setChecksumOk(true);
  247. SCTPChunk* chunk = (SCTPChunk*)(sctpmsg->peekFirstChunk());
  248. if (chunk->getChunkType() == ABORT)
  249. {
  250. SCTPAbortChunk* abortChunk;
  251. abortChunk = check_and_cast<SCTPAbortChunk *>(chunk);
  252. if (abortChunk->getT_Bit()==1)
  253. sctpmsg->setTag(peerVTag);
  254. else
  255. sctpmsg->setTag(localVTag);
  256. }
  257. else if (sctpmsg->getTag()==0)
  258. sctpmsg->setTag(localVTag);
  259. if (dest.isIPv6())
  260. {
  261. IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
  262. controlInfo->setProtocol(IP_PROT_SCTP);
  263. controlInfo->setSrcAddr(src.get6());
  264. controlInfo->setDestAddr(dest.get6());
  265. sctpmsg->setControlInfo(controlInfo);
  266. sctpMain->send(sctpmsg,"to_ipv6");
  267. }
  268. else
  269. {
  270. IPControlInfo *controlInfo = new IPControlInfo();
  271. controlInfo->setProtocol(IP_PROT_SCTP);
  272. controlInfo->setSrcAddr(src.get4());
  273. controlInfo->setDestAddr(dest.get4());
  274. sctpmsg->setControlInfo(controlInfo);
  275. sctpMain->send(sctpmsg,"to_ip");
  276. }
  277. sctpEV3 << "Sent to "<<dest<<"\n ";
  278. }
  279. void SCTPAssociation::signalConnectionTimeout()
  280. {
  281. sendIndicationToApp(SCTP_I_TIMED_OUT);
  282. }
  283. void SCTPAssociation::sendIndicationToApp(int32 code)
  284. {
  285. cPacket *msg = new cPacket(indicationName(code));
  286. msg->setKind(code);
  287. SCTPCommand *ind = new SCTPCommand(indicationName(code));
  288. sctpEV3<<"sendIndicationToApp: "<<indicationName(code)<<"\n";
  289. ind->setAssocId(assocId);
  290. ind->setLocalAddr(localAddr);
  291. ind->setRemoteAddr(remoteAddr);
  292. msg->setControlInfo(ind);
  293. sctpMain->send(msg, "to_appl", appGateIndex);
  294. }
  295. void SCTPAssociation::sendEstabIndicationToApp()
  296. {
  297. sctpEV3<<"sendEstabIndicationToApp: localPort="<<localPort<<" remorePort="<<remotePort<<"\n";
  298. cPacket *msg = new cPacket(indicationName(SCTP_I_ESTABLISHED));
  299. msg->setKind(SCTP_I_ESTABLISHED);
  300. SCTPConnectInfo *ind = new SCTPConnectInfo("CI");
  301. ind->setAssocId(assocId);
  302. ind->setLocalAddr(localAddr);
  303. ind->setRemoteAddr(remoteAddr);
  304. ind->setLocalPort(localPort);
  305. ind->setRemotePort(remotePort);
  306. ind->setRemoteAddresses(remoteAddressList);
  307. ind->setInboundStreams(inboundStreams);
  308. ind->setOutboundStreams(outboundStreams);
  309. msg->setControlInfo(ind);
  310. sctpMain->send(msg, "to_appl", appGateIndex);
  311. }
  312. void SCTPAssociation::sendToApp(cPacket *msg)
  313. {
  314. sctpMain->send(msg, "to_appl", appGateIndex);
  315. }
  316. void SCTPAssociation::initAssociation(SCTPOpenCommand *openCmd)
  317. {
  318. sctpEV3<<"SCTPAssociationUtil:initAssociation\n";
  319. // create send/receive queues
  320. const char *queueClass = openCmd->getQueueClass();
  321. transmissionQ = check_and_cast<SCTPQueue *>(createOne(queueClass));
  322. retransmissionQ = check_and_cast<SCTPQueue *>(createOne(queueClass));
  323. outboundStreams = openCmd->getOutboundStreams();
  324. // create algorithm
  325. const char *sctpAlgorithmClass = openCmd->getSctpAlgorithmClass();
  326. if (!sctpAlgorithmClass || !sctpAlgorithmClass[0])
  327. sctpAlgorithmClass = sctpMain->par("sctpAlgorithmClass");
  328. sctpAlgorithm = check_and_cast<SCTPAlgorithm *>(createOne(sctpAlgorithmClass));
  329. sctpAlgorithm->setAssociation(this);
  330. sctpAlgorithm->initialize();
  331. // create state block
  332. state = sctpAlgorithm->createStateVariables();
  333. }
  334. void SCTPAssociation::sendInit()
  335. {
  336. //RoutingTableAccess routingTableAccess;
  337. InterfaceTableAccess interfaceTableAccess;
  338. AddressVector adv;
  339. uint32 length = SCTP_INIT_CHUNK_LENGTH;
  340. if (remoteAddr.isUnspecified() || remotePort==0)
  341. opp_error("Error processing command ASSOCIATE: foreign socket unspecified");
  342. if (localPort==0)
  343. opp_error("Error processing command ASSOCIATE: local port unspecified");
  344. state->primaryPathIndex = remoteAddr;
  345. // create message consisting of INIT chunk
  346. SCTPMessage *sctpmsg = new SCTPMessage();
  347. sctpmsg->setBitLength(SCTP_COMMON_HEADER*8);
  348. SCTPInitChunk *initChunk = new SCTPInitChunk("INIT");
  349. initChunk->setChunkType(INIT);
  350. initChunk->setInitTag(uint32rand());
  351. peerVTag = initChunk->getInitTag();
  352. sctpEV3<<"INIT from "<<localAddr<<":InitTag="<<peerVTag<<"\n";
  353. initChunk->setA_rwnd(sctpMain->par("arwnd"));
  354. initChunk->setNoOutStreams(outboundStreams);
  355. initChunk->setNoInStreams(SCTP_DEFAULT_INBOUND_STREAMS);
  356. initChunk->setInitTSN(1000);
  357. state->nextTSN=initChunk->getInitTSN();
  358. state->lastTSN = initChunk->getInitTSN() + state->numRequests - 1;
  359. initTsn=initChunk->getInitTSN();
  360. IInterfaceTable *ift = interfaceTableAccess.get();
  361. sctpEV3<<"add local address\n";
  362. if (localAddressList.front() == IPvXAddress("0.0.0.0"))
  363. {
  364. for (int32 i=0; i<ift->getNumInterfaces(); ++i)
  365. {
  366. if (ift->getInterface(i)->ipv4Data()!=NULL)
  367. {
  368. adv.push_back(ift->getInterface(i)->ipv4Data()->getIPAddress());
  369. }
  370. else if (ift->getInterface(i)->ipv6Data()!=NULL)
  371. {
  372. for (int32 j=0; j<ift->getInterface(i)->ipv6Data()->getNumAddresses(); j++)
  373. {
  374. sctpEV3<<"add address "<<ift->getInterface(i)->ipv6Data()->getAddress(j)<<"\n";
  375. adv.push_back(ift->getInterface(i)->ipv6Data()->getAddress(j));
  376. }
  377. }
  378. }
  379. }
  380. else
  381. {
  382. adv = localAddressList;
  383. sctpEV3<<"gebundene Adresse "<<localAddr<<" wird hinzugefuegt\n";
  384. }
  385. uint32 addrNum=0;
  386. bool friendly = false;
  387. if (remoteAddr.isIPv6())
  388. {
  389. for (AddressVector::iterator i=adv.begin(); i!=adv.end(); ++i)
  390. {
  391. if (!friendly)
  392. {
  393. initChunk->setAddressesArraySize(addrNum+1);
  394. initChunk->setAddresses(addrNum++,(*i));
  395. length+=20;
  396. }
  397. sctpMain->addLocalAddress(this, (*i));
  398. state->localAddresses.push_back((*i));
  399. if (localAddr.isUnspecified())
  400. localAddr=(*i);
  401. }
  402. }
  403. else
  404. {
  405. uint32 rlevel = getLevel(remoteAddr);
  406. sctpEV3<<"level of remote address="<<rlevel<<"\n";
  407. for (AddressVector::iterator i=adv.begin(); i!=adv.end(); ++i)
  408. {
  409. sctpEV3<<"level of address "<<(*i)<<" = "<<getLevel((*i))<<"\n";
  410. if (getLevel((*i))>=rlevel)
  411. {
  412. initChunk->setAddressesArraySize(addrNum+1);
  413. initChunk->setAddresses(addrNum++,(*i));
  414. length+=8;
  415. sctpMain->addLocalAddress(this, (*i));
  416. state->localAddresses.push_back((*i));
  417. if (localAddr.get4().getInt()==0)
  418. localAddr=(*i);
  419. }
  420. else if (rlevel==4 && getLevel((*i))==3 && friendly)
  421. {
  422. sctpMain->addLocalAddress(this, (*i));
  423. state->localAddresses.push_back((*i));
  424. if (localAddr.get4().getInt()==0)
  425. localAddr=(*i);
  426. }
  427. }
  428. }
  429. sctpMain->printInfoConnMap();
  430. initChunk->setBitLength(length*8);
  431. sctpmsg->addChunk(initChunk);
  432. // set path variables
  433. if (remoteAddressList.size()>0)
  434. {
  435. for (AddressVector::iterator it=remoteAddressList.begin(); it!=remoteAddressList.end(); it++)
  436. {
  437. sctpEV3<<__LINE__<<" get new path for "<<(*it)<<"\n";
  438. SCTPPathVariables* path = new SCTPPathVariables((*it), this);
  439. sctpPathMap[(*it)] = path;
  440. qCounter.roomTransQ[(*it)] = 0;
  441. qCounter.roomRetransQ[(*it)] = 0;
  442. qCounter.bookedTransQ[(*it)] = 0;
  443. }
  444. }
  445. else
  446. {
  447. sctpEV3<<__LINE__<<" get new path for "<<remoteAddr<<"\n";
  448. SCTPPathVariables* path = new SCTPPathVariables(remoteAddr, this);
  449. sctpPathMap[remoteAddr] = path;
  450. qCounter.roomTransQ[remoteAddr] = 0;
  451. qCounter.roomRetransQ[remoteAddr] = 0;
  452. qCounter.bookedTransQ[remoteAddr] = 0;
  453. }
  454. // send it
  455. state->initChunk=check_and_cast<SCTPInitChunk *>(initChunk->dup());
  456. state->initChunk->setName("StateInitChunk");
  457. printSctpPathMap();
  458. sctpEV3<<getFullPath()<<" sendInit: localVTag="<<localVTag<<" peerVTag="<<peerVTag<<"\n";
  459. sendToIP(sctpmsg);
  460. sctpMain->assocList.push_back(this);
  461. }
  462. void SCTPAssociation::retransmitInit()
  463. {
  464. SCTPMessage *sctpmsg = new SCTPMessage();
  465. sctpmsg->setBitLength(SCTP_COMMON_HEADER*8);
  466. SCTPInitChunk *sctpinit;// = new SCTPInitChunk("INIT");
  467. sctpEV3<<"Retransmit InitChunk="<<&sctpinit<<"\n";
  468. sctpinit=check_and_cast<SCTPInitChunk *>(state->initChunk->dup());
  469. sctpinit->setChunkType(INIT);
  470. sctpmsg->addChunk(sctpinit);
  471. sendToIP(sctpmsg);
  472. }
  473. void SCTPAssociation::sendInitAck(SCTPInitChunk* initChunk)
  474. {
  475. uint32 length = SCTP_INIT_CHUNK_LENGTH;
  476. state->primaryPathIndex = remoteAddr;
  477. // create segment
  478. SCTPMessage *sctpinitack = new SCTPMessage();
  479. sctpinitack->setBitLength(SCTP_COMMON_HEADER*8);
  480. sctpinitack->setSrcPort(localPort);
  481. sctpinitack->setDestPort(remotePort);
  482. sctpEV3<<"sendInitAck at "<<localAddr<<". Provided InitTag="<<initChunk->getInitTag()<<"\n";
  483. SCTPInitAckChunk *initAckChunk = new SCTPInitAckChunk("INIT_ACK");
  484. initAckChunk->setChunkType(INIT_ACK);
  485. SCTPCookie *cookie = new SCTPCookie("CookieUtil");
  486. cookie->setCreationTime(simulation.getSimTime());
  487. cookie->setLocalTieTagArraySize(32);
  488. cookie->setPeerTieTagArraySize(32);
  489. if (fsm->getState()==SCTP_S_CLOSED)
  490. {
  491. do
  492. {
  493. peerVTag = (uint32)intrand(RAND_MAX);
  494. } while (peerVTag==0);
  495. initAckChunk->setInitTag(peerVTag);
  496. initAckChunk->setInitTSN(2000);
  497. state->nextTSN=initAckChunk->getInitTSN();
  498. state->lastTSN = initAckChunk->getInitTSN() + state->numRequests - 1;
  499. cookie->setLocalTag(localVTag);
  500. cookie->setPeerTag(peerVTag);
  501. for (int32 i=0; i<32; i++)
  502. {
  503. cookie->setLocalTieTag(i,0);
  504. cookie->setPeerTieTag(i,0);
  505. }
  506. sctpinitack->setTag(localVTag);
  507. sctpEV3<<"state=closed: localVTag="<<localVTag<<" peerVTag="<<peerVTag<<"\n";
  508. }
  509. else if (fsm->getState()==SCTP_S_COOKIE_WAIT || fsm->getState()==SCTP_S_COOKIE_ECHOED)
  510. {
  511. initAckChunk->setInitTag(peerVTag);
  512. sctpEV3<<"different state:set InitTag in InitAck: "<<initAckChunk->getInitTag()<<"\n";
  513. initAckChunk->setInitTSN(state->nextTSN);
  514. initPeerTsn=initChunk->getInitTSN();
  515. state->cTsnAck = initPeerTsn - 1;
  516. cookie->setLocalTag(initChunk->getInitTag());
  517. cookie->setPeerTag(peerVTag);
  518. for (int32 i=0; i<32; i++)
  519. {
  520. cookie->setPeerTieTag(i,(uint8)intrand(256));
  521. state->peerTieTag[i] = cookie->getPeerTieTag(i);
  522. if (fsm->getState()==SCTP_S_COOKIE_ECHOED)
  523. {
  524. cookie->setLocalTieTag(i,(uint8)intrand(256));
  525. state->localTieTag[i] = cookie->getLocalTieTag(i);
  526. }
  527. else
  528. cookie->setLocalTieTag(i,0);
  529. }
  530. sctpinitack->setTag(initChunk->getInitTag());
  531. sctpEV3<<"VTag in InitAck: "<<sctpinitack->getTag()<<"\n";
  532. }
  533. else
  534. {
  535. sctpEV3<<"other state\n";
  536. uint32 tag;
  537. do
  538. {
  539. tag = uint32rand();
  540. } while (tag==0);
  541. initAckChunk->setInitTag(tag);
  542. initAckChunk->setInitTSN(state->nextTSN);
  543. cookie->setLocalTag(localVTag);
  544. cookie->setPeerTag(peerVTag);
  545. for (int32 i=0; i<32; i++)
  546. {
  547. cookie->setPeerTieTag(i,state->peerTieTag[i]);
  548. cookie->setLocalTieTag(i,state->localTieTag[i]);
  549. }
  550. sctpinitack->setTag(initChunk->getInitTag());
  551. }
  552. cookie->setBitLength(SCTP_COOKIE_LENGTH*8);
  553. initAckChunk->setStateCookie(cookie);
  554. initAckChunk->setCookieArraySize(0);
  555. initAckChunk->setA_rwnd(sctpMain->par("arwnd"));
  556. initAckChunk->setNoOutStreams((unsigned int)min(outboundStreams,initChunk->getNoInStreams()));
  557. initAckChunk->setNoInStreams((unsigned int)min(SCTP_DEFAULT_INBOUND_STREAMS,initChunk->getNoOutStreams()));
  558. initTsn=initAckChunk->getInitTSN();
  559. uint32 addrNum=0;
  560. bool friendly = false;
  561. if (!friendly)
  562. for (AddressVector::iterator k=state->localAddresses.begin(); k!=state->localAddresses.end(); ++k)
  563. {
  564. initAckChunk->setAddressesArraySize(addrNum+1);
  565. initAckChunk->setAddresses(addrNum++,(*k));
  566. length+=8;
  567. }
  568. uint32 unknownLen = initChunk->getUnrecognizedParametersArraySize();
  569. if (unknownLen>0)
  570. {
  571. sctpEV3<<"Found unrecognized Parameters in INIT chunk with a length of "<<unknownLen<<" bytes.\n";
  572. initAckChunk->setUnrecognizedParametersArraySize(unknownLen);
  573. for (uint32 i=0; i<unknownLen; i++)
  574. initAckChunk->setUnrecognizedParameters(i,initChunk->getUnrecognizedParameters(i));
  575. length+=unknownLen;
  576. }
  577. else
  578. initAckChunk->setUnrecognizedParametersArraySize(0);
  579. initAckChunk->setBitLength((length+initAckChunk->getCookieArraySize())*8 + cookie->getBitLength());
  580. inboundStreams = ((initChunk->getNoOutStreams()<initAckChunk->getNoInStreams())?initChunk->getNoOutStreams():initAckChunk->getNoInStreams());
  581. outboundStreams = ((initChunk->getNoInStreams()<initAckChunk->getNoOutStreams())?initChunk->getNoInStreams():initAckChunk->getNoOutStreams());
  582. (this->*ssFunctions.ssInitStreams)(inboundStreams, outboundStreams);
  583. sctpinitack->addChunk(initAckChunk);
  584. if (fsm->getState()==SCTP_S_CLOSED)
  585. {
  586. sendToIP(sctpinitack, state->initialPrimaryPath);
  587. }
  588. else
  589. {
  590. sendToIP(sctpinitack);
  591. }
  592. printSctpPathMap();
  593. }
  594. void SCTPAssociation::sendCookieEcho(SCTPInitAckChunk* initAckChunk)
  595. {
  596. SCTPMessage *sctpcookieecho = new SCTPMessage();
  597. sctpcookieecho->setBitLength(SCTP_COMMON_HEADER*8);
  598. sctpEV3<<"SCTPAssociationUtil:sendCookieEcho\n";
  599. sctpcookieecho->setSrcPort(localPort);
  600. sctpcookieecho->setDestPort(remotePort);
  601. SCTPCookieEchoChunk* cookieEchoChunk=new SCTPCookieEchoChunk("COOKIE_ECHO");
  602. cookieEchoChunk->setChunkType(COOKIE_ECHO);
  603. int32 len = initAckChunk->getCookieArraySize();
  604. cookieEchoChunk->setCookieArraySize(len);
  605. if (len>0)
  606. {
  607. for (int32 i=0; i<len; i++)
  608. cookieEchoChunk->setCookie(i, initAckChunk->getCookie(i));
  609. cookieEchoChunk->setBitLength((SCTP_COOKIE_ACK_LENGTH+len)*8);
  610. }
  611. else
  612. {
  613. SCTPCookie* cookie = check_and_cast <SCTPCookie*> (initAckChunk->getStateCookie());
  614. cookieEchoChunk->setStateCookie(cookie);
  615. cookieEchoChunk->setBitLength(SCTP_COOKIE_ACK_LENGTH*8 + cookie->getBitLength());
  616. }
  617. uint32 unknownLen = initAckChunk->getUnrecognizedParametersArraySize();
  618. if (unknownLen>0)
  619. {
  620. sctpEV3<<"Found unrecognized Parameters in INIT-ACK chunk with a length of "<<unknownLen<<" bytes.\n";
  621. cookieEchoChunk->setUnrecognizedParametersArraySize(unknownLen);
  622. for (uint32 i=0; i<unknownLen; i++)
  623. cookieEchoChunk->setUnrecognizedParameters(i,initAckChunk->getUnrecognizedParameters(i));
  624. }
  625. else
  626. cookieEchoChunk->setUnrecognizedParametersArraySize(0);
  627. state->cookieChunk=check_and_cast<SCTPCookieEchoChunk*>(cookieEchoChunk->dup());
  628. if (len==0)
  629. {
  630. state->cookieChunk->setStateCookie(initAckChunk->getStateCookie()->dup());
  631. }
  632. sctpcookieecho->addChunk(cookieEchoChunk);
  633. sendToIP(sctpcookieecho);
  634. }
  635. void SCTPAssociation::retransmitCookieEcho()
  636. {
  637. SCTPMessage *sctpmsg = new SCTPMessage();
  638. sctpmsg->setBitLength(SCTP_COMMON_HEADER*8);
  639. SCTPCookieEchoChunk* cookieEchoChunk=check_and_cast<SCTPCookieEchoChunk*>(state->cookieChunk->dup());
  640. if (cookieEchoChunk->getCookieArraySize()==0)
  641. {
  642. cookieEchoChunk->setStateCookie(state->cookieChunk->getStateCookie()->dup());
  643. }
  644. sctpmsg->addChunk(cookieEchoChunk);
  645. sctpEV3<<"retransmitCookieEcho localAddr="<<localAddr<<" remoteAddr"<<remoteAddr<<"\n";
  646. sendToIP(sctpmsg);
  647. }
  648. void SCTPAssociation::sendHeartbeat(SCTPPathVariables *path, bool local)
  649. {
  650. SCTPMessage *sctpheartbeat = new SCTPMessage();
  651. sctpheartbeat->setBitLength(SCTP_COMMON_HEADER*8);
  652. sctpheartbeat->setSrcPort(localPort);
  653. sctpheartbeat->setDestPort(remotePort);
  654. SCTPHeartbeatChunk* heartbeatChunk=new SCTPHeartbeatChunk("HEARTBEAT");
  655. heartbeatChunk->setChunkType(HEARTBEAT);
  656. heartbeatChunk->setRemoteAddr(path->remoteAddress);
  657. heartbeatChunk->setTimeField(simulation.getSimTime());
  658. heartbeatChunk->setBitLength((SCTP_HEARTBEAT_CHUNK_LENGTH+12)*8);
  659. //heartbeatChunk->setBitLength((SCTP_HEARTBEAT_CHUNK_LENGTH+12+1000)*8);
  660. sctpheartbeat->addChunk(heartbeatChunk);
  661. if (local)
  662. {
  663. sctpEV3<<"sendHeartbeat: sendToIP from "<<localAddr<<" to "<<path->remoteAddress<<"\n";
  664. sendToIP(sctpheartbeat, localAddr, path->remoteAddress);
  665. }
  666. else
  667. {
  668. sctpEV3<<"sendHeartbeat: sendToIP to "<<path->remoteAddress<<"\n";
  669. sendToIP(sctpheartbeat, path->remoteAddress);
  670. }
  671. }
  672. void SCTPAssociation::sendHeartbeatAck(SCTPHeartbeatChunk* heartbeatChunk, IPvXAddress src, IPvXAddress dest)
  673. {
  674. SCTPMessage *sctpheartbeatack = new SCTPMessage();
  675. sctpheartbeatack->setBitLength(SCTP_COMMON_HEADER*8);
  676. sctpheartbeatack->setSrcPort(localPort);
  677. sctpheartbeatack->setDestPort(remotePort);
  678. SCTPHeartbeatAckChunk* heartbeatAckChunk=new SCTPHeartbeatAckChunk("HEARTBEAT_ACK");
  679. heartbeatAckChunk->setChunkType(HEARTBEAT_ACK);
  680. heartbeatAckChunk->setRemoteAddr(heartbeatChunk->getRemoteAddr());
  681. heartbeatAckChunk->setTimeField(heartbeatChunk->getTimeField());
  682. int32 len=heartbeatChunk->getInfoArraySize();
  683. if (len>0)
  684. {
  685. heartbeatAckChunk->setInfoArraySize(len);
  686. for (int32 i=0; i<len; i++)
  687. heartbeatAckChunk->setInfo(i,heartbeatChunk->getInfo(i));
  688. }
  689. heartbeatAckChunk->setBitLength(heartbeatChunk->getBitLength());
  690. sctpheartbeatack->addChunk(heartbeatAckChunk);
  691. sctpEV3<<"try to get path for "<<dest<<"\n";
  692. sctpEV3<<"send heartBeatAck from "<<src<<" to "<<dest<<"\n";
  693. sendToIP(sctpheartbeatack, src, dest);
  694. }
  695. void SCTPAssociation::sendCookieAck(IPvXAddress dest)
  696. {
  697. SCTPMessage *sctpcookieack = new SCTPMessage();
  698. sctpcookieack->setBitLength(SCTP_COMMON_HEADER*8);
  699. sctpEV3<<"SCTPAssociationUtil:sendCookieACK\n";
  700. sctpcookieack->setSrcPort(localPort);
  701. sctpcookieack->setDestPort(remotePort);
  702. SCTPCookieAckChunk* cookieAckChunk=new SCTPCookieAckChunk("COOKIE_ACK");
  703. cookieAckChunk->setChunkType(COOKIE_ACK);
  704. cookieAckChunk->setBitLength(SCTP_COOKIE_ACK_LENGTH*8);
  705. sctpcookieack->addChunk(cookieAckChunk);
  706. sendToIP(sctpcookieack, dest);
  707. }
  708. void SCTPAssociation::sendShutdownAck(IPvXAddress dest)
  709. {
  710. sendAll(dest);
  711. if (dest!=state->primaryPathIndex)
  712. sendAll(state->primaryPathIndex);
  713. if (getOutstandingBytes()==0)
  714. {
  715. performStateTransition(SCTP_E_NO_MORE_OUTSTANDING);
  716. SCTPMessage *sctpshutdownack = new SCTPMessage();
  717. sctpshutdownack->setBitLength(SCTP_COMMON_HEADER*8);
  718. sctpEV3<<"SCTPAssociationUtil:sendShutdownACK\n";
  719. sctpshutdownack->setSrcPort(localPort);
  720. sctpshutdownack->setDestPort(remotePort);
  721. SCTPShutdownAckChunk* shutdownAckChunk=new SCTPShutdownAckChunk("SHUTDOWN_ACK");
  722. shutdownAckChunk->setChunkType(SHUTDOWN_ACK);
  723. shutdownAckChunk->setBitLength(SCTP_COOKIE_ACK_LENGTH*8);
  724. sctpshutdownack->addChunk(shutdownAckChunk);
  725. state->initRexmitTimeout = SCTP_TIMEOUT_INIT_REXMIT;
  726. state->initRetransCounter = 0;
  727. stopTimer(T2_ShutdownTimer);
  728. startTimer(T2_ShutdownTimer,state->initRexmitTimeout);
  729. stopTimer(T5_ShutdownGuardTimer);
  730. startTimer(T5_ShutdownGuardTimer,SHUTDOWN_GUARD_TIMEOUT);
  731. state->shutdownAckChunk=check_and_cast<SCTPShutdownAckChunk*>(shutdownAckChunk->dup());
  732. sendToIP(sctpshutdownack, dest);
  733. }
  734. }
  735. void SCTPAssociation::sendShutdownComplete()
  736. {
  737. SCTPMessage *sctpshutdowncomplete = new SCTPMessage();
  738. sctpshutdowncomplete->setBitLength(SCTP_COMMON_HEADER*8);
  739. sctpEV3<<"SCTPAssociationUtil:sendShutdownComplete\n";
  740. sctpshutdowncomplete->setSrcPort(localPort);
  741. sctpshutdowncomplete->setDestPort(remotePort);
  742. SCTPShutdownCompleteChunk* shutdownCompleteChunk=new SCTPShutdownCompleteChunk("SHUTDOWN_COMPLETE");
  743. shutdownCompleteChunk->setChunkType(SHUTDOWN_COMPLETE);
  744. shutdownCompleteChunk->setTBit(0);
  745. shutdownCompleteChunk->setBitLength(SCTP_SHUTDOWN_ACK_LENGTH*8);
  746. sctpshutdowncomplete->addChunk(shutdownCompleteChunk);
  747. sendToIP(sctpshutdowncomplete);
  748. }
  749. void SCTPAssociation::sendAbort()
  750. {
  751. SCTPMessage *msg = new SCTPMessage();
  752. msg->setBitLength(SCTP_COMMON_HEADER*8);
  753. sctpEV3<<"SCTPAssociationUtil:sendABORT localPort="<<localPort<<" remotePort="<<remotePort<<"\n";
  754. msg->setSrcPort(localPort);
  755. msg->setDestPort(remotePort);
  756. SCTPAbortChunk* abortChunk = new SCTPAbortChunk("ABORT");
  757. abortChunk->setChunkType(ABORT);
  758. abortChunk->setT_Bit(0);
  759. abortChunk->setBitLength(SCTP_ABORT_CHUNK_LENGTH*8);
  760. msg->addChunk(abortChunk);
  761. sendToIP(msg, remoteAddr);
  762. }
  763. void SCTPAssociation::sendShutdown()
  764. {
  765. SCTPMessage *msg = new SCTPMessage();
  766. msg->setBitLength(SCTP_COMMON_HEADER*8);
  767. sctpEV3<<"SCTPAssociationUtil:sendShutdown localPort="<<localPort<<" remotePort="<<remotePort<<"\n";
  768. msg->setSrcPort(localPort);
  769. msg->setDestPort(remotePort);
  770. SCTPShutdownChunk* shutdownChunk = new SCTPShutdownChunk("SHUTDOWN");
  771. shutdownChunk->setChunkType(SHUTDOWN);
  772. //shutdownChunk->setCumTsnAck(state->lastTsnAck);
  773. shutdownChunk->setCumTsnAck(state->cTsnAck);
  774. shutdownChunk->setBitLength(SCTP_SHUTDOWN_CHUNK_LENGTH*8);
  775. state->initRexmitTimeout = SCTP_TIMEOUT_INIT_REXMIT;
  776. state->initRetransCounter = 0;
  777. stopTimer(T5_ShutdownGuardTimer);
  778. startTimer(T5_ShutdownGuardTimer,SHUTDOWN_GUARD_TIMEOUT);
  779. stopTimer(T2_ShutdownTimer);
  780. startTimer(T2_ShutdownTimer,state->initRexmitTimeout);
  781. state->shutdownChunk=check_and_cast<SCTPShutdownChunk*>(shutdownChunk->dup());
  782. msg->addChunk(shutdownChunk);
  783. sendToIP(msg, remoteAddr);
  784. performStateTransition(SCTP_E_NO_MORE_OUTSTANDING);
  785. }
  786. void SCTPAssociation::retransmitShutdown()
  787. {
  788. SCTPMessage *sctpmsg = new SCTPMessage();
  789. sctpmsg->setBitLength(SCTP_COMMON_HEADER*8);
  790. SCTPShutdownChunk* shutdownChunk;
  791. shutdownChunk=check_and_cast<SCTPShutdownChunk*>(state->shutdownChunk->dup());
  792. sctpmsg->addChunk(shutdownChunk);
  793. sctpEV3<<"retransmitShutdown localAddr="<<localAddr<<" remoteAddr"<<remoteAddr<<"\n";
  794. sendToIP(sctpmsg);
  795. }
  796. void SCTPAssociation::retransmitShutdownAck()
  797. {
  798. SCTPMessage *sctpmsg = new SCTPMessage();
  799. sctpmsg->setBitLength(SCTP_COMMON_HEADER*8);
  800. SCTPShutdownAckChunk* shutdownAckChunk;
  801. shutdownAckChunk=check_and_cast<SCTPShutdownAckChunk*>(state->shutdownAckChunk->dup());
  802. sctpmsg->addChunk(shutdownAckChunk);
  803. sctpEV3<<"retransmitShutdownAck localAddr="<<localAddr<<" remoteAddr"<<remoteAddr<<"\n";
  804. sendToIP(sctpmsg);
  805. }
  806. void SCTPAssociation::scheduleSack(void)
  807. {
  808. /* increase SACK counter, we received another data PACKET */
  809. if (state->firstChunkReceived)
  810. state->ackState++;
  811. else
  812. {
  813. state->ackState = sackFrequency;
  814. state->firstChunkReceived = true;
  815. }
  816. sctpEV3<<"scheduleSack() : ackState is now: "<<state->ackState<<"\n";
  817. if (state->ackState <= sackFrequency - 1)
  818. {
  819. /* start a SACK timer if none is running, to expire 200 ms (or parameter) from now */
  820. if (!SackTimer->isScheduled())
  821. {
  822. startTimer(SackTimer, sackPeriod);
  823. }
  824. /* else: leave timer running, and do nothing... */ else {
  825. /* is this possible at all ? Check this... */
  826. sctpEV3<<"SACK timer running, but scheduleSack() called\n";
  827. }
  828. }
  829. }
  830. SCTPSackChunk* SCTPAssociation::createSack()
  831. {
  832. uint32 key=0, arwnd=0;
  833. sctpEV3<<"SCTPAssociationUtil:createSACK localPort="<<localPort<<" remotePort="<<remotePort<<"\n";
  834. sctpEV3<<" localRwnd="<<state->localRwnd<<" queuedBytes="<<state->queuedRcvBytes<<"\n";
  835. if ((int32)(state->localRwnd - state->queuedRcvBytes) <= 0)
  836. {
  837. arwnd = 0;
  838. if (state->swsLimit > 0)
  839. state->swsAvoidanceInvoked = true;
  840. }
  841. else if (state->localRwnd - state->queuedRcvBytes < state->swsLimit || state->swsAvoidanceInvoked == true)
  842. {
  843. arwnd = 1;
  844. if (state->swsLimit > 0)
  845. state->swsAvoidanceInvoked = true;
  846. //std::cout<<"arwnd=1; createSack : SWS Avoidance ACTIVE !!!\n";
  847. }
  848. else
  849. {
  850. arwnd = state->localRwnd - state->queuedRcvBytes;
  851. sctpEV3<<simulation.getSimTime()<<" arwnd = "<<state->localRwnd<<" - "<<state->queuedRcvBytes<<" = "<<arwnd<<"\n";
  852. }
  853. advRwnd->record(arwnd);
  854. quBytes->record(state->queuedRcvBytes);
  855. SCTPSackChunk* sackChunk=new SCTPSackChunk("SACK");
  856. sackChunk->setChunkType(SACK);
  857. sackChunk->setCumTsnAck(state->cTsnAck);
  858. sackChunk->setA_rwnd(arwnd);
  859. uint32 numGaps=state->numGaps;
  860. uint32 numDups=state->dupList.size();
  861. uint16 sackLength=SCTP_SACK_CHUNK_LENGTH + numGaps*4 + numDups*4;
  862. uint32 mtu = getPath(remoteAddr)->pmtu;
  863. if (sackLength > mtu-32) // FIXME
  864. {
  865. if (SCTP_SACK_CHUNK_LENGTH + numGaps*4 > mtu-32)
  866. {
  867. numDups = 0;
  868. numGaps = (uint32)((mtu-32-SCTP_SACK_CHUNK_LENGTH)/4);
  869. }
  870. else
  871. {
  872. numDups = (uint32)((mtu-32-SCTP_SACK_CHUNK_LENGTH - numGaps*4)/4);
  873. }
  874. sackLength=SCTP_SACK_CHUNK_LENGTH + numGaps*4 + numDups*4;
  875. }
  876. sackChunk->setNumGaps(numGaps);
  877. sackChunk->setNumDupTsns(numDups);
  878. sackChunk->setBitLength(sackLength*8);
  879. sctpEV3<<"Sack arwnd="<<sackChunk->getA_rwnd()<<" ctsnAck="<<state->cTsnAck<<" numGaps="<<numGaps<<" numDups="<<numDups<<"\n";
  880. if (numGaps > 0)
  881. {
  882. sackChunk->setGapStartArraySize(numGaps);
  883. sackChunk->setGapStopArraySize(numGaps);
  884. for (key=0; key<numGaps; key++)
  885. {
  886. sackChunk->setGapStart(key, state->gapStartList[key]);
  887. sackChunk->setGapStop(key, state->gapStopList[key]);
  888. }
  889. }
  890. if (numDups > 0)
  891. {
  892. sackChunk->setDupTsnsArraySize(numDups);
  893. key=0;
  894. for(std::list<uint32>::iterator iter=state->dupList.begin(); iter!=state->dupList.end(); iter++)
  895. {
  896. sackChunk->setDupTsns(key, (*iter));
  897. key++;
  898. if (key == numDups)
  899. break;
  900. }
  901. state->dupList.clear();
  902. }
  903. sctpEV3<<endl;
  904. for (uint32 i=0; i<numGaps; i++)
  905. sctpEV3<<sackChunk->getGapStart(i)<<" - "<<sackChunk->getGapStop(i)<<"\n";
  906. sctpEV3<<"send "<<sackChunk->getName()<<" from "<<localAddr<<" to "<<state->lastDataSourceAddress<<"\n";
  907. return sackChunk;
  908. }
  909. void SCTPAssociation::sendSack(void)
  910. {
  911. sctpEV3<<"sendSack\n";
  912. SCTPSackChunk* sackChunk;
  913. IPvXAddress dpi; /* destination path index that will actually be used/was used on last send */
  914. /* sack timer has expired, reset flag, and send SACK */
  915. stopTimer(SackTimer);
  916. state->ackState = 0;
  917. sackChunk = createSack();
  918. /* return the SACK to the address where we last got a data chunk from */
  919. dpi = state->lastDataSourceAddress;
  920. SCTPMessage* sctpmsg = new SCTPMessage();
  921. sctpmsg->setBitLength(SCTP_COMMON_HEADER*8);
  922. sctpmsg->addChunk(sackChunk);
  923. sendToIP(sctpmsg, dpi);
  924. }
  925. void SCTPAssociation::sendDataArrivedNotification(uint16 sid)
  926. {
  927. sctpEV3<<"SendDataArrivedNotification\n";
  928. cPacket* cmsg = new cPacket("DataArrivedNotification");
  929. cmsg->setKind(SCTP_I_DATA_NOTIFICATION);
  930. SCTPCommand *cmd = new SCTPCommand("notification");
  931. cmd->setAssocId(assocId);
  932. cmd->setSid(sid);
  933. cmd->setNumMsgs(1);
  934. cmsg->setControlInfo(cmd);
  935. sendToApp(cmsg);
  936. }
  937. void SCTPAssociation::putInDeliveryQ(uint16 sid)
  938. {
  939. SCTPReceiveStream* rStream;
  940. SCTPDataVariables* chunk;
  941. SCTPReceiveStreamMap::iterator iter=receiveStreams.find(sid);
  942. rStream = iter->second;
  943. sctpEV3<<"putInDeliveryQ: SSN "<<rStream->getExpectedStreamSeqNum()<<" SID "<<sid<<" QueueSize "<<rStream->getOrderedQ()->getQueueSize()<<"\n";
  944. while (rStream->getOrderedQ()->getQueueSize()>0)
  945. {
  946. /* dequeue first from reassembly Q */
  947. chunk = rStream->getOrderedQ()-> dequeueVarBySsn(rStream->getExpectedStreamSeqNum());
  948. if (chunk)
  949. {
  950. sctpEV3<<"putInDeliveryQ::chunk "<<chunk->tsn<<" , sid "<<chunk->sid<<" and ssn "<<chunk->ssn<<" dequeued from ordered queue. queuedRcvBytes="<<state->queuedRcvBytes<<" will be reduced by "<<chunk->len/8<<"\n";
  951. state->queuedRcvBytes-=chunk->len/8;
  952. qCounter.roomSumRcvStreams -= ADD_PADDING(chunk->len/8 + SCTP_DATA_CHUNK_LENGTH);
  953. if (rStream->getDeliveryQ()->checkAndInsertVar(chunk->tsn, chunk))
  954. {
  955. state->queuedRcvBytes+=chunk->len/8;
  956. sctpEV3<<"data put in deliveryQ; queuedBytes now "<<state->queuedRcvBytes<<"\n";
  957. qCounter.roomSumRcvStreams += ADD_PADDING(chunk->len/8 + SCTP_DATA_CHUNK_LENGTH);
  958. int32 seqnum=rStream->getExpectedStreamSeqNum();
  959. rStream->setExpectedStreamSeqNum(++seqnum);
  960. if (rStream->getExpectedStreamSeqNum() > 65535)
  961. rStream->setExpectedStreamSeqNum(0);
  962. sendDataArrivedNotification(sid);
  963. }
  964. }
  965. else
  966. {
  967. break;
  968. }
  969. }
  970. }
  971. void SCTPAssociation::pushUlp()
  972. {
  973. int32 count=0;
  974. SCTPReceiveStream* rStream;
  975. SCTPDataVariables* chunk;
  976. for (unsigned i=0; i<inboundStreams; i++) //12.06.08
  977. putInDeliveryQ(i);
  978. if (state->pushMessagesLeft <=0)
  979. state->pushMessagesLeft = state->messagesToPush;
  980. bool restrict = false;
  981. if (state->pushMessagesLeft > 0)
  982. restrict = true;
  983. quBytes->record(state->queuedRcvBytes);
  984. sctpEV3<<simulation.getSimTime()<<" Calling PUSH_ULP ("<<state->queuedRcvBytes<<" bytes queued)...\n";
  985. uint32 i=state->nextRSid;
  986. do
  987. {
  988. SCTPReceiveStreamMap::iterator iter=receiveStreams.find(i);
  989. rStream=iter->second;
  990. sctpEV3<<"Size of stream "<<iter->first<<": "<<rStream->getDeliveryQ()->getQueueSize()<<"\n";
  991. while (!rStream->getDeliveryQ()->payloadQueue.empty() && (!restrict || (restrict && state->pushMessagesLeft>0)))
  992. {
  993. chunk = rStream->getDeliveryQ()->extractMessage();
  994. qCounter.roomSumRcvStreams -= ADD_PADDING(chunk->len/8 + SCTP_DATA_CHUNK_LENGTH);
  995. if (state->pushMessagesLeft >0)
  996. state->pushMessagesLeft--;
  997. state->queuedRcvBytes-=chunk->len/8;
  998. if (state->swsAvoidanceInvoked)
  999. {
  1000. quBytes->record(state->queuedRcvBytes);
  1001. if ((int32)(state->localRwnd - state->queuedRcvBytes) >= (int32)(state->swsLimit) && (int32)(state->localRwnd - state->queuedRcvBytes) <= (int32)(state->swsLimit+state->assocPmtu))
  1002. {
  1003. /* only if the window has opened up more than one MTU we will send a SACK */
  1004. state->swsAvoidanceInvoked = false;
  1005. sctpEV3<<"pushUlp: Window opens up to "<<(int32)state->localRwnd-state->queuedRcvBytes<<" bytes: sending a SACK. SWS Avoidance INACTIVE\n";
  1006. sendSack();
  1007. }
  1008. }
  1009. sctpEV3<<"Push TSN "<<chunk->tsn<<": sid="<<chunk->sid<<" ssn="<<chunk->ssn<<"\n";
  1010. cPacket* msg= (cPacket *)chunk->userData;
  1011. msg->setKind(SCTP_I_DATA);
  1012. SCTPRcvCommand *cmd = new SCTPRcvCommand("push");
  1013. cmd->setAssocId(assocId);
  1014. cmd->setGate(appGateIndex);
  1015. cmd->setSid(chunk->sid);
  1016. cmd->setSsn(chunk->ssn);
  1017. cmd->setSendUnordered(!chunk->ordered);
  1018. cmd->setLocalAddr(localAddr);
  1019. cmd->setRemoteAddr(remoteAddr);
  1020. cmd->setPpid(chunk->ppid);
  1021. cmd->setTsn(chunk->tsn);
  1022. cmd->setCumTsn(state->lastTsnAck);
  1023. msg->setControlInfo(cmd);
  1024. state->numMsgsReq[count]--;
  1025. delete chunk;
  1026. sendToApp(msg);
  1027. }
  1028. i = (i+1)%inboundStreams;
  1029. count++;
  1030. } while (i!=state->nextRSid);
  1031. state->nextRSid = (state->nextRSid+1)%inboundStreams;
  1032. if (state->queuedRcvBytes==0 && fsm->getState()==SCTP_S_SHUTDOWN_ACK_SENT)
  1033. {
  1034. sctpEV3<<"SCTP_E_CLOSE\n";
  1035. performStateTransition(SCTP_E_CLOSE);
  1036. }
  1037. }
  1038. SCTPDataChunk* SCTPAssociation::transformDataChunk(SCTPDataVariables* datVar)
  1039. {
  1040. SCTPDataChunk* dataChunk=new SCTPDataChunk("DATA");
  1041. SCTPSimpleMessage* msg=check_and_cast<SCTPSimpleMessage*>(datVar->userData->dup());
  1042. dataChunk->setChunkType(DATA);
  1043. dataChunk->setBBit(datVar->bbit);
  1044. dataChunk->setEBit(datVar->ebit);
  1045. if (datVar->ordered)
  1046. dataChunk->setUBit(0);
  1047. else
  1048. dataChunk->setUBit(1);
  1049. dataChunk->setTsn(datVar->tsn);
  1050. dataChunk->setSid(datVar->sid);
  1051. dataChunk->setSsn(datVar->ssn);
  1052. dataChunk->setPpid(datVar->ppid);
  1053. dataChunk->setEnqueuingTime(datVar->enqueuingTime);
  1054. dataChunk->setBitLength(SCTP_DATA_CHUNK_LENGTH*8);
  1055. msg->setBitLength(datVar->len);
  1056. dataChunk->encapsulate(msg);
  1057. return dataChunk;
  1058. }
  1059. void SCTPAssociation::addPath(IPvXAddress addr)
  1060. {
  1061. sctpEV3<<"Add Path remote address: "<<addr<<"\n";
  1062. SCTPPathMap::iterator i = sctpPathMap.find(addr);
  1063. if (i==sctpPathMap.end())
  1064. {
  1065. sctpEV3<<__LINE__<<" get new path for "<<addr<<"\n";
  1066. SCTPPathVariables* path = new SCTPPathVariables(addr, this);
  1067. sctpPathMap[addr] = path;
  1068. qCounter.roomTransQ[addr] = 0;
  1069. qCounter.roomRetransQ[addr] = 0;
  1070. qCounter.bookedTransQ[addr] = 0;
  1071. }
  1072. sctpEV3<<"path added\n";
  1073. }
  1074. void SCTPAssociation::removePath(IPvXAddress addr)
  1075. {
  1076. SCTPPathMap::iterator j = sctpPathMap.find(addr);
  1077. if (j!=sctpPathMap.end())
  1078. {
  1079. stopTimer(j->second->HeartbeatTimer);
  1080. delete j->second->HeartbeatTimer;
  1081. stopTimer(j->second->HeartbeatIntervalTimer);
  1082. delete j->second->HeartbeatIntervalTimer;
  1083. stopTimer(j->second->T3_RtxTimer);
  1084. delete j->second->T3_RtxTimer;
  1085. stopTimer(j->second->CwndTimer);
  1086. delete j->second->CwndTimer;
  1087. sctpPathMap.erase(j);
  1088. delete j->second;
  1089. }
  1090. }
  1091. void SCTPAssociation::deleteStreams()
  1092. {
  1093. for (SCTPSendStreamMap::iterator it=sendStreams.begin(); it != sendStreams.end(); it++)
  1094. {
  1095. it->second->deleteQueue();
  1096. }
  1097. for (SCTPReceiveStreamMap::iterator it=receiveStreams.begin(); it != receiveStreams.end(); it++)
  1098. {
  1099. delete it->second;
  1100. }
  1101. }
  1102. void SCTPAssociation::removeLastPath(IPvXAddress addr)
  1103. {
  1104. SCTPPathVariables* path = getPath(addr);
  1105. stopTimer(path->HeartbeatTimer);
  1106. delete path->HeartbeatTimer;
  1107. stopTimer(path->HeartbeatIntervalTimer);
  1108. delete path->HeartbeatIntervalTimer;
  1109. stopTimer(path->T3_RtxTimer);
  1110. delete path->T3_RtxTimer;
  1111. stopTimer(path->CwndTimer);
  1112. delete path->CwndTimer;
  1113. }
  1114. bool SCTPAssociation::makeRoomForTsn(uint32 tsn, uint32 length, bool uBit)
  1115. {
  1116. SCTPDataVariables* datVar=NULL;
  1117. SCTPQueue* stream, dStream;
  1118. uint32 sum=0, comp=0;
  1119. bool delQ = false;
  1120. uint32 high = state->highestTsnStored;
  1121. sctpEV3<<simulation.getSimTime()<<": makeRoomForTsn: tsn="<<tsn<<", length="<<length<<" high="<<high<<"\n";
  1122. while (sum<length && state->highestTsnReceived>state->lastTsnAck)
  1123. {
  1124. comp = sum;
  1125. for (SCTPReceiveStreamMap::iterator iter=receiveStreams.begin();iter!=receiveStreams.end(); iter++)
  1126. {
  1127. if (tsn > high)
  1128. return false;
  1129. if (uBit)
  1130. stream = iter->second->getUnorderedQ();
  1131. else
  1132. stream = iter->second->getOrderedQ();
  1133. datVar = stream->getVar(high);
  1134. if (datVar==NULL) //12.06.08
  1135. {
  1136. sctpEV3<<high<<" not found in orderedQ. Try deliveryQ\n";
  1137. stream = iter->second->getDeliveryQ();
  1138. datVar = stream->getVar(high);
  1139. delQ = true;
  1140. }
  1141. if (datVar!=NULL)
  1142. {
  1143. sum+=datVar->len;
  1144. if (stream->deleteMsg(high))
  1145. {
  1146. sctpEV3<<high<<" found and deleted\n";
  1147. state->queuedRcvBytes-=datVar->len/8; //12.06.08
  1148. if (ssnGt(iter->second->getExpectedStreamSeqNum(),datVar->ssn))
  1149. iter->second->setExpectedStreamSeqNum(datVar->ssn);
  1150. }
  1151. qCounter.roomSumRcvStreams -= ADD_PADDING(datVar->len/8 + SCTP_DATA_CHUNK_LENGTH);
  1152. if (high == state->highestTsnReceived)
  1153. state->highestTsnReceived--;
  1154. removeFromGapList(high);
  1155. if (tsn > state->highestTsnReceived)
  1156. state->highestTsnReceived=tsn;
  1157. high--;
  1158. break;
  1159. }
  1160. else
  1161. {
  1162. sctpEV3<<"TSN "<<high<<" not found in stream "<<iter->second->getStreamId()<<"\n";
  1163. }
  1164. }
  1165. if (comp == sum)
  1166. {
  1167. //removeFromGapList(high);
  1168. sctpEV3<<high<<" not found in any stream\n";
  1169. high--;
  1170. }
  1171. state->highestTsnStored = high;
  1172. if (tsn > state->highestTsnReceived)
  1173. return false;
  1174. }
  1175. return true;
  1176. }
  1177. bool SCTPAssociation::tsnIsDuplicate(uint32 tsn)
  1178. {
  1179. for (std::list<uint32>::iterator it=state->dupList.begin(); it!=state->dupList.end(); it++)
  1180. {
  1181. if ((*it)==tsn)
  1182. return true;
  1183. }
  1184. for (uint32 i=0; i<state->numGaps; i++)
  1185. if (tsnBetween(state->gapStartList[i], tsn, state->gapStopList[i]))
  1186. return true;
  1187. return false;
  1188. }
  1189. void SCTPAssociation::removeFromGapList(uint32 removedTsn)
  1190. {
  1191. int32 gapsize, numgaps;
  1192. numgaps = state->numGaps;
  1193. sctpEV3<<"remove TSN "<<removedTsn<<" from GapList. "<<numgaps<<" gaps present, cumTsnAck="<<state->cTsnAck<<"\n";
  1194. for (int32 j=0; j<numgaps; j++)
  1195. sctpEV3<<state->gapStartList[j]<<" - "<<state->gapStopList[j]<<"\n";
  1196. for (int32 i=numgaps-1; i>=0; i--)
  1197. {
  1198. sctpEV3<<"gapStartList["<<i<<"]="<<state->gapStartList[i]<<", state->gapStopList["<<i<<"]="<<state->gapStopList[i]<<"\n";
  1199. if (tsnBetween(state->gapStartList[i], removedTsn, state->gapStopList[i]))
  1200. {
  1201. gapsize = (int32)(state->gapStopList[i] - state->gapStartList[i]+1);
  1202. if (gapsize>1)
  1203. {
  1204. if (state->gapStopList[i]==removedTsn)
  1205. {
  1206. state->gapStopList[i]--;
  1207. }
  1208. else if (state->gapStartList[i]==removedTsn)
  1209. {
  1210. state->gapStartList[i]++;
  1211. }
  1212. else //gap is split in two
  1213. {
  1214. for (int32 j=numgaps-1; j>=i; j--)
  1215. {
  1216. state->gapStopList[j+1] = state->gapStopList[j];
  1217. state->gapStartList[j+1] = state->gapStartList[j];
  1218. }
  1219. state->gapStopList[i] = removedTsn-1;
  1220. state->gapStartList[i+1] = removedTsn+1;
  1221. state->numGaps++;
  1222. }
  1223. }
  1224. else
  1225. {
  1226. for (int32 j=i; j<=numgaps-1; j++)
  1227. {
  1228. state->gapStopList[j] = state->gapStopList[j+1];
  1229. state->gapStartList[j] = state->gapStartList[j+1];
  1230. }
  1231. state->gapStartList[numgaps-1]=0;
  1232. state->gapStopList[numgaps-1]=0;
  1233. state->numGaps--;
  1234. if (state->numGaps == 0)
  1235. {
  1236. if (removedTsn == state->lastTsnAck+1)
  1237. {
  1238. state->lastTsnAck = removedTsn;
  1239. }
  1240. }
  1241. }
  1242. }
  1243. }
  1244. if (state->numGaps>0)
  1245. state->highestTsnReceived = state->gapStopList[state->numGaps-1];
  1246. else
  1247. state->highestTsnReceived = state->cTsnAck;
  1248. }
  1249. bool SCTPAssociation::updateGapList(uint32 receivedTsn)
  1250. {
  1251. uint32 lo, hi, gapsize;
  1252. sctpEV3<<"Entering updateGapList(tsn=="<< receivedTsn<<" cTsnAck="<<state->cTsnAck<<" Number of Gaps="<<state->numGaps<<"\n";
  1253. lo = state->cTsnAck + 1;
  1254. if ((int32)(state->localRwnd-state->queuedRcvBytes)<=0)
  1255. {
  1256. sctpEV3<<"window full\n";
  1257. //only check if cumTsnAck can be advanced
  1258. if (receivedTsn == lo)
  1259. {
  1260. sctpEV3<<"Window full, but cumTsnAck can be advanced:"<<lo<<"\n";
  1261. }
  1262. else
  1263. return false;
  1264. }
  1265. if (tsnGt(receivedTsn, state->highestTsnStored)) //17.06.08
  1266. state->highestTsnStored = receivedTsn;
  1267. for (uint32 i=0; i<state->numGaps; i++)
  1268. {
  1269. if (state->gapStartList[i]>0)
  1270. {
  1271. hi = state->gapStartList[i] - 1;
  1272. if (tsnBetween(lo, receivedTsn, hi))
  1273. {
  1274. gapsize = hi - lo + 1;
  1275. sctpEV3<<"tsn between lo and hi and gapsize="<<gapsize<<"\n";
  1276. if (gapsize > 1)
  1277. {
  1278. /**
  1279. * TSN either sits at the end of one gap, and thus changes gap
  1280. * boundaries, or it is in between two gaps, and becomes a new gap
  1281. */
  1282. if (receivedTsn == hi)
  1283. {
  1284. sctpEV3<<"receivedTsn==hi:"<<hi<<"\n";
  1285. state->gapStartList[i] = receivedTsn;
  1286. state->newChunkReceived = true;
  1287. return true;
  1288. }
  1289. else if (receivedTsn == lo)
  1290. {
  1291. sctpEV3<<"receivedTsn=="<<receivedTsn<<"lo=="<<lo<<"\n";
  1292. if (receivedTsn == (state->cTsnAck + 1))
  1293. {
  1294. state->cTsnAck++;
  1295. state->newChunkReceived = true;
  1296. return true;
  1297. }
  1298. /* some gap must increase its upper bound */
  1299. state->gapStopList[i-1] = receivedTsn;
  1300. state->newChunkReceived = true;
  1301. return true;
  1302. }
  1303. else
  1304. { /* a gap in between */
  1305. state->numGaps++;
  1306. sctpEV3<<"Inserting new gap (start==stop=="<<receivedTsn<<"\n";
  1307. for (uint32 j=state->numGaps; j>i; j--)
  1308. {
  1309. state->gapStartList[j] = state->gapStartList[j-1];
  1310. state->gapStopList[j] = state->gapStopList[j-1];
  1311. }
  1312. state->gapStartList[i]=receivedTsn;
  1313. state->gapStopList[i]=receivedTsn;
  1314. state->newChunkReceived = true;
  1315. for (uint32 k=0; k<state->numGaps; k++)
  1316. sctpEV3<<"Gap "<<k<<": "<<state->gapStartList[k]<<" - "<<state->gapStopList[k]<<"\n";
  1317. return true;
  1318. }
  1319. }
  1320. else
  1321. { /* alright: gapsize is 1: our received tsn may close gap between fragments */
  1322. sctpEV3<<"gapsize="<<gapsize<<"\n";
  1323. if (lo == state->cTsnAck + 1)
  1324. {
  1325. state->cTsnAck = state->gapStopList[i];
  1326. if (i==state->numGaps-1)
  1327. {
  1328. state->gapStartList[i] = 0;
  1329. state->gapStopList[i] = 0;
  1330. }
  1331. else
  1332. for (uint32 j=i; j<state->numGaps; j++)
  1333. {
  1334. state->gapStartList[j] = state->gapStartList[j+1];
  1335. state->gapStopList[j] = state->gapStopList[j+1];
  1336. }
  1337. state->numGaps--;
  1338. sctpEV3<<"state->numGaps="<<state->numGaps<<"\n";
  1339. state->newChunkReceived = true;
  1340. return true;
  1341. }
  1342. else
  1343. {
  1344. state->gapStopList[i-1] = state->gapStopList[i];
  1345. if (i==state->numGaps-1)
  1346. {
  1347. state->gapStartList[i] = 0;
  1348. state->gapStopList[i] = 0;
  1349. }
  1350. else
  1351. for (uint32 j=i; j<=state->numGaps; j++)
  1352. {
  1353. state->gapStartList[j] = state->gapStartList[j+1];
  1354. state->gapStopList[j] = state->gapStopList[j+1];
  1355. }
  1356. state->numGaps--;
  1357. state->newChunkReceived = true;
  1358. return true;
  1359. }
  1360. }
  1361. }
  1362. else
  1363. { /* receivedTsn is not in the gap between these fragments... */
  1364. lo = state->gapStopList[i] + 1;
  1365. }
  1366. } /* end: for */
  1367. }/* end: for */
  1368. /* (NULL LIST) OR (End of Gap List passed) */
  1369. if (receivedTsn == lo)
  1370. {
  1371. /* just increase ctsna, handle further update of ctsna later */
  1372. if (receivedTsn == state->cTsnAck + 1)
  1373. {
  1374. sctpEV3<<"Updating cTsnAck....now cTsnAck=="<<receivedTsn<<"\n";
  1375. state->cTsnAck = receivedTsn;
  1376. state->newChunkReceived = true;
  1377. return true;
  1378. }
  1379. /* Update last fragment....increase stop_tsn by one */
  1380. state->gapStopList[state->numGaps-1]++;
  1381. state->newChunkReceived = true;
  1382. return true;
  1383. }
  1384. else
  1385. { /* a new fragment altogether, past the end of the list */
  1386. sctpEV3<<"Inserting new fragment after the end of the list (start==stop=="<<receivedTsn<<" numberOfGaps="<<state->numGaps<<"\n";
  1387. state->gapStartList[state->numGaps] = receivedTsn;
  1388. state->gapStopList[state->numGaps] = receivedTsn;
  1389. state->numGaps++;
  1390. state->newChunkReceived = true;
  1391. for (uint32 k=0; k<state->numGaps; k++)
  1392. sctpEV3<<"Gap "<<k<<": "<<state->gapStartList[k]<<" - "<<state->gapStopList[k]<<"\n";
  1393. return true;
  1394. }
  1395. return false;
  1396. }
  1397. bool SCTPAssociation::advanceCtsna(void)
  1398. {
  1399. int32 listLength, counter;
  1400. ev<<"Entering advanceCtsna(ctsna now =="<< state->cTsnAck<<"\n";;
  1401. listLength = state->numGaps;
  1402. /* if there are no fragments, we cannot advance the ctsna */
  1403. if (listLength == 0) return false;
  1404. counter = 0;
  1405. while(counter < listLength)
  1406. {
  1407. /* if we take out a fragment here, we need to modify either counter or list_length */
  1408. if (state->cTsnAck + 1 == state->gapStartList[0])
  1409. {
  1410. /* BINGO ! */
  1411. state->cTsnAck = state->gapStopList[0];
  1412. /* we can take out a maximum of list_length fragments */
  1413. counter++;
  1414. for (uint32 i=1; i<state->numGaps; i++)
  1415. {
  1416. state->gapStartList[i-1] = state->gapStartList[i];
  1417. state->gapStopList[i-1] = state->gapStopList[i];
  1418. }
  1419. }
  1420. else
  1421. {
  1422. ev<<"Entering advanceCtsna(when leaving: ctsna=="<<state->cTsnAck<<"\n";
  1423. return false;
  1424. }
  1425. } /* end while */
  1426. ev<<"Entering advanceCtsna(when leaving: ctsna=="<< state->cTsnAck<<"\n";
  1427. return true;
  1428. }
  1429. SCTPDataVariables* SCTPAssociation::makeVarFromMsg(SCTPDataChunk* dataChunk)
  1430. {
  1431. SCTPDataVariables* datVar=new SCTPDataVariables();
  1432. datVar->bbit = dataChunk->getBBit();
  1433. datVar->ebit = dataChunk->getEBit();
  1434. datVar->sid = dataChunk->getSid();
  1435. datVar->ssn = dataChunk->getSsn();
  1436. datVar->ppid = dataChunk->getPpid();
  1437. datVar->tsn = dataChunk->getTsn();
  1438. if (!dataChunk->getUBit())
  1439. datVar->ordered = true;
  1440. else
  1441. datVar->ordered = false;
  1442. SCTPSimpleMessage* smsg=check_and_cast<SCTPSimpleMessage*>(dataChunk->decapsulate());
  1443. datVar->userData = smsg;
  1444. datVar->len = smsg->getDataLen()*8;
  1445. sctpEV3<<"Datenlaenge="<<datVar->len/8<<"\n";
  1446. sctpEV3<<"makeVarFromMsg::queuedBytes have been increased to "<<state->queuedRcvBytes<<"\n";
  1447. return datVar;
  1448. }
  1449. SCTPDataVariables* SCTPAssociation::getOutboundDataChunk(IPvXAddress pid, int32 bytes)
  1450. {
  1451. int32 len;
  1452. /* are there chunks in the transmission queue ? If Yes -> dequeue and return it */
  1453. sctpEV3<<"getOutboundDataChunk: pid="<<pid<<" bytes="<<bytes<<"\n";
  1454. sctpEV3<<"chunks in transmissionQ="<<transmissionQ->getQueueSize()<<"\n";
  1455. if (!transmissionQ->payloadQueue.empty())
  1456. {
  1457. sctpEV3<<"transmissionQ not empty\n";
  1458. for(SCTPQueue::PayloadQueue::iterator it=transmissionQ->payloadQueue.begin(); it!=transmissionQ->payloadQueue.end(); it++)
  1459. {
  1460. SCTPDataVariables* chunk=it->second;
  1461. sctpEV3<<"chunk->nextDestination="<<chunk->nextDestination<<"\n";
  1462. if (chunk->nextDestination == pid)
  1463. {
  1464. len = ADD_PADDING(chunk->len/8+SCTP_DATA_CHUNK_LENGTH);
  1465. sctpEV3<<"getOutboundDataChunk() found chunk "<<chunk->tsn<<" in the transmission queue, length="<<len<<"\n";
  1466. if (len<=bytes)
  1467. {
  1468. transmissionQ->payloadQueue.erase(it);
  1469. CounterMap::iterator i=qCounter.roomTransQ.find(pid);
  1470. i->second-= ADD_PADDING(chunk->len/8+SCTP_DATA_CHUNK_LENGTH);
  1471. CounterMap::iterator ib=qCounter.bookedTransQ.find(pid);
  1472. ib->second-= chunk->booksize;
  1473. if (chunk->hasBeenAcked==false)
  1474. return chunk;
  1475. }
  1476. }
  1477. }
  1478. }
  1479. else
  1480. sctpEV3<<"transmissionQ empty!\n";
  1481. return NULL;
  1482. }
  1483. SCTPDataVariables* SCTPAssociation::peekOutboundDataChunk(IPvXAddress pid)
  1484. {
  1485. SCTPDataVariables* chunk = NULL;
  1486. /* are there chunks in the transmission queue ? If Yes -> dequeue and return it */
  1487. if (!transmissionQ->payloadQueue.empty())
  1488. {
  1489. for(SCTPQueue::PayloadQueue::iterator it=transmissionQ->payloadQueue.begin(); it!=transmissionQ->payloadQueue.end(); it++)
  1490. {
  1491. chunk = it->second;
  1492. if (chunk->nextDestination == pid)
  1493. {
  1494. sctpEV3<<"peekOutboundDataChunk() found chunk "<<chunk->tsn<<" in the transmission queue\n";
  1495. if (chunk->hasBeenAcked)
  1496. {
  1497. transmissionQ->payloadQueue.erase(it);
  1498. CounterMap::iterator i=qCounter.roomTransQ.find(pid);
  1499. i->second-= ADD_PADDING(chunk->len/8+SCTP_DATA_CHUNK_LENGTH);
  1500. CounterMap::iterator ib=qCounter.bookedTransQ.find(pid);
  1501. ib->second-= chunk->booksize;
  1502. }
  1503. else
  1504. {
  1505. return chunk;
  1506. }
  1507. }
  1508. }
  1509. }
  1510. return NULL;
  1511. }
  1512. SCTPDataVariables* SCTPAssociation::peekAbandonedChunk(IPvXAddress pid)
  1513. {
  1514. SCTPDataVariables* chunk = NULL;
  1515. /* are there chunks in the retransmission queue ? If Yes -> dequeue and return it */
  1516. if (!retransmissionQ->payloadQueue.empty())
  1517. {
  1518. for(SCTPQueue::PayloadQueue::iterator it=retransmissionQ->payloadQueue.begin(); it!=retransmissionQ->payloadQueue.end(); it++)
  1519. {
  1520. chunk=it->second;
  1521. sctpEV3<<"peek Chunk "<<chunk->tsn<<"\n";
  1522. if (chunk->lastDestination == pid && chunk->hasBeenAbandoned)
  1523. {
  1524. sctpEV3<<"peekAbandonedChunk() found chunk in the retransmission queue\n";
  1525. return chunk;
  1526. }
  1527. }
  1528. }
  1529. return NULL;
  1530. }
  1531. SCTPDataMsg* SCTPAssociation::peekOutboundDataMsg(void)
  1532. {
  1533. SCTPDataMsg* datMsg=NULL;
  1534. int32 nextStream = -1;
  1535. nextStream = (this->*ssFunctions.ssGetNextSid)(true);
  1536. if (nextStream == -1)
  1537. {
  1538. sctpEV3<<"peekOutboundDataMsg(): no valid stream found -> returning NULL !\n";
  1539. return NULL;
  1540. }
  1541. for (SCTPSendStreamMap::iterator iter=sendStreams.begin(); iter!=sendStreams.end(); ++iter)
  1542. {
  1543. if ((int32)iter->first==nextStream)
  1544. {
  1545. SCTPSendStream* stream=iter->second;
  1546. if (!stream->getUnorderedStreamQ()->empty())
  1547. {
  1548. return (datMsg);
  1549. }
  1550. if (!stream->getStreamQ()->empty())
  1551. {
  1552. return (datMsg);
  1553. }
  1554. }
  1555. }
  1556. return NULL;
  1557. }
  1558. SCTPDataMsg* SCTPAssociation::dequeueOutboundDataMsg(int32 bytes)
  1559. {
  1560. SCTPDataMsg* datMsg=NULL;
  1561. int32 nextStream = -1;
  1562. sctpEV3<<"dequeueOutboundDataMsg: "<<bytes<<" bytes left to be sent\n";
  1563. nextStream = (this->*ssFunctions.ssGetNextSid)(false);
  1564. if (nextStream == -1)
  1565. return NULL;
  1566. sctpEV3<<"dequeueOutboundDataMsg: now stream "<< nextStream << endl;
  1567. for (SCTPSendStreamMap::iterator iter=sendStreams.begin(); iter!=sendStreams.end(); ++iter)
  1568. {
  1569. if ((int32)iter->first==nextStream)
  1570. {
  1571. SCTPSendStream* stream=iter->second;
  1572. cQueue* streamQ = NULL;
  1573. if (!stream->getUnorderedStreamQ()->empty())
  1574. {
  1575. streamQ = stream->getUnorderedStreamQ();
  1576. sctpEV3<<"DequeueOutboundDataMsg() found chunks in stream "<<iter->first<<" unordered queue, queue size="<<stream->getUnorderedStreamQ()->getLength()<<"\n";
  1577. }
  1578. else if (!stream->getStreamQ()->empty())
  1579. {
  1580. streamQ = stream->getStreamQ();
  1581. sctpEV3<<"DequeueOutboundDataMsg() found chunks in stream "<<iter->first<<" ordered queue, queue size="<<stream->getStreamQ()->getLength()<<"\n";
  1582. }
  1583. if (streamQ)
  1584. {
  1585. int32 b=ADD_PADDING( (check_and_cast<SCTPSimpleMessage*>(((SCTPDataMsg*)streamQ->front())->getEncapsulatedMsg())->getByteLength()+SCTP_DATA_CHUNK_LENGTH));
  1586. /* check if chunk found in queue has to be fragmented */
  1587. if (b > (int32)state->assocPmtu - IP_HEADER_LENGTH - SCTP_COMMON_HEADER)
  1588. {
  1589. /* START FRAGMENTATION */
  1590. SCTPDataMsg* datMsgQueued = (SCTPDataMsg*)streamQ->pop();
  1591. SCTPSimpleMessage *datMsgQueuedSimple = check_and_cast<SCTPSimpleMessage*>(datMsgQueued->getEncapsulatedMsg());
  1592. SCTPDataMsg* datMsgLastFragment = NULL;
  1593. uint32 offset = 0;
  1594. sctpEV3<<"Fragmentation: chunk " << &datMsgQueued << ", size = " << datMsgQueued->getByteLength() << endl;
  1595. while (datMsgQueued)
  1596. {
  1597. /* detemine size of fragment, either max payload or what's left */
  1598. uint32 msgbytes = state->assocPmtu - IP_HEADER_LENGTH - SCTP_COMMON_HEADER - SCTP_DATA_CHUNK_LENGTH;
  1599. if (msgbytes > datMsgQueuedSimple->getDataLen() - offset)
  1600. msgbytes = datMsgQueuedSimple->getDataLen() - offset;
  1601. /* new DATA msg */
  1602. SCTPDataMsg* datMsgFragment = new SCTPDataMsg();
  1603. datMsgFragment->setSid(datMsgQueued->getSid());
  1604. datMsgFragment->setPpid(datMsgQueued->getPpid());
  1605. datMsgFragment->setInitialDestination(datMsgQueued->getInitialDestination());
  1606. datMsgFragment->setEnqueuingTime(datMsgQueued->getEnqueuingTime());
  1607. datMsgFragment->setMsgNum(datMsgQueued->getMsgNum());
  1608. datMsgFragment->setOrdered(datMsgQueued->getOrdered());
  1609. datMsgFragment->setExpiryTime(datMsgQueued->getExpiryTime());
  1610. datMsgFragment->setRtx(datMsgQueued->getRtx());
  1611. datMsgFragment->setFragment(true);
  1612. datMsgFragment->setBooksize(msgbytes + state->header);
  1613. /* is this the first fragment? */
  1614. if (offset == 0)
  1615. datMsgFragment->setBBit(true);
  1616. /* new msg */
  1617. SCTPSimpleMessage *datMsgFragmentSimple = new SCTPSimpleMessage();
  1618. datMsgFragmentSimple->setName(datMsgQueuedSimple->getName());
  1619. datMsgFragmentSimple->setCreationTime(datMsgQueuedSimple->getCreationTime());
  1620. datMsgFragmentSimple->setDataArraySize(msgbytes);
  1621. datMsgFragmentSimple->setDataLen(msgbytes);
  1622. datMsgFragmentSimple->setByteLength(msgbytes);
  1623. /* copy data */
  1624. for (uint32 i = offset; i < offset + msgbytes; i++)
  1625. datMsgFragmentSimple->setData(i - offset, datMsgQueuedSimple->getData(i));
  1626. offset += msgbytes;
  1627. datMsgFragment->encapsulate(datMsgFragmentSimple);
  1628. /* insert fragment into queue */
  1629. if (!streamQ->empty())
  1630. {
  1631. if (!datMsgLastFragment)
  1632. {
  1633. /* insert first fragment at the begining of the queue*/
  1634. streamQ->insertBefore((SCTPDataMsg*)streamQ->front(), datMsgFragment);
  1635. }
  1636. else
  1637. {
  1638. /* insert fragment after last inserted */
  1639. streamQ->insertAfter(datMsgLastFragment, datMsgFragment);
  1640. }
  1641. }
  1642. else
  1643. streamQ->insert(datMsgFragment);
  1644. state->queuedMessages++;
  1645. qCounter.roomSumSendStreams += ADD_PADDING(datMsgFragment->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
  1646. qCounter.bookedSumSendStreams += datMsgFragment->getBooksize();
  1647. sctpEV3<<"Fragmentation: fragment " << &datMsgFragment << " created, length = " << datMsgFragmentSimple->getByteLength() << ", queue size = " << streamQ->getLength() << endl;
  1648. datMsgLastFragment = datMsgFragment;
  1649. /* all fragments done? */
  1650. if (datMsgQueuedSimple->getDataLen() == offset)
  1651. {
  1652. datMsgFragment->setEBit(true);
  1653. /* remove original element */
  1654. sctpEV3<<"Fragmentation: delete " << &datMsgQueued << endl;
  1655. //streamQ->pop();
  1656. qCounter.roomSumSendStreams -= ADD_PADDING(datMsgQueued->getByteLength() + SCTP_DATA_CHUNK_LENGTH);
  1657. qCounter.bookedSumSendStreams -= datMsgQueued->getBooksize();
  1658. delete datMsgQueued;
  1659. datMsgQueued = NULL;
  1660. state->queuedMessages--;
  1661. }
  1662. }
  1663. /* the next chunk returned will always be a fragment */
  1664. state->lastMsgWasFragment = true;
  1665. b=ADD_PADDING( (check_and_cast<SCTPSimpleMessage*>(((SCTPDataMsg*)streamQ->front())->getEncapsulatedMsg())->getBitLength()/8+SCTP_DATA_CHUNK_LENGTH));
  1666. /* FRAGMENTATION DONE */
  1667. }
  1668. if (b<=bytes)
  1669. {
  1670. datMsg = (SCTPDataMsg*)streamQ->pop();
  1671. if (!state->appSendAllowed && streamQ->getLength()<=state->sendQueueLimit)
  1672. {
  1673. state->appSendAllowed = true;
  1674. sendIndicationToApp(SCTP_I_SENDQUEUE_ABATED);
  1675. }
  1676. sendQueue->record(streamQ->getLength());
  1677. if (!datMsg->getFragment())
  1678. {
  1679. datMsg->setBBit(true);
  1680. datMsg->setEBit(true);
  1681. state->lastMsgWasFragment = false;
  1682. }
  1683. else
  1684. {
  1685. if (datMsg->getEBit())
  1686. state->lastMsgWasFragment = false;
  1687. else
  1688. state->lastMsgWasFragment = true;
  1689. }
  1690. sctpEV3<<"DequeueOutboundDataMsg() found chunk ("<<&datMsg<<") in the stream queue "<<&iter->first<<"("<<streamQ<<") queue size="<<streamQ->getLength()<<"\n";
  1691. }
  1692. }
  1693. break;
  1694. }
  1695. }
  1696. if (datMsg != NULL)
  1697. {
  1698. qCounter.roomSumSendStreams -= ADD_PADDING( (check_and_cast<SCTPSimpleMessage*>(datMsg->getEncapsulatedMsg())->getBitLength()/8+SCTP_DATA_CHUNK_LENGTH));
  1699. qCounter.bookedSumSendStreams -= datMsg->getBooksize();
  1700. }
  1701. return (datMsg);
  1702. }
  1703. IPvXAddress SCTPAssociation::getNextAddress(IPvXAddress pid)
  1704. {
  1705. int32 hit=0;
  1706. if (sctpPathMap.size()>1)
  1707. {
  1708. for (SCTPPathMap::iterator iter=sctpPathMap.begin(); iter!=sctpPathMap.end(); iter++)
  1709. {
  1710. if (iter->first==pid)
  1711. {
  1712. if (++hit==1)
  1713. continue;
  1714. else
  1715. break;
  1716. }
  1717. if (iter->second->activePath)
  1718. return iter->first;
  1719. }
  1720. }
  1721. return IPvXAddress("0.0.0.0");
  1722. }
  1723. IPvXAddress SCTPAssociation::getNextDestination(SCTPDataVariables* chk)
  1724. {
  1725. IPvXAddress dpi, last;
  1726. sctpEV3<<"getNextDestination\n";
  1727. if (chk->numberOfTransmissions == 0)
  1728. {
  1729. if (chk->initialDestination == IPvXAddress("0.0.0.0"))
  1730. {
  1731. dpi = state->primaryPathIndex;
  1732. }
  1733. else
  1734. {
  1735. dpi = chk->initialDestination;
  1736. }
  1737. }
  1738. else
  1739. {
  1740. if (chk->hasBeenFastRetransmitted)
  1741. {
  1742. sctpEV3<<"Chunk is scheduled for FastRetransmission. Next destination = "<<chk->lastDestination<<"\n";
  1743. //chk->hasBeenFastRetransmitted=false;
  1744. return chk->lastDestination;
  1745. }
  1746. dpi = last = chk->lastDestination;
  1747. /* if this is a retransmission, we should choose another, active path */
  1748. SCTPPathMap::iterator iter=sctpPathMap.find(dpi);
  1749. do
  1750. {
  1751. sctpEV3<<"old dpi="<<iter->first<<"\n";
  1752. iter++;
  1753. if (iter==sctpPathMap.end())
  1754. iter=sctpPathMap.begin();
  1755. dpi=iter->first;
  1756. } while ((iter->first != last && iter->second->activePath == false) || iter->second->confirmed==false);
  1757. }
  1758. sctpEV3<<"sctp_get_next_destination: chunk was last sent to "<<last<<", will next be sent to path "<<dpi<<"\n";
  1759. sctpEV3<<"new dpi="<<dpi<<"\n";
  1760. return (dpi);
  1761. }
  1762. void SCTPAssociation::bytesAllowedToSend(IPvXAddress dpi)
  1763. {
  1764. uint32 osb = 0;
  1765. int32 diff = 0;
  1766. SCTPPathMap::iterator iter;
  1767. bytes.chunk = false;
  1768. bytes.packet = false;
  1769. bytes.bytesToSend = 0;
  1770. iter=sctpPathMap.find(dpi);
  1771. osb = getPath(dpi)->outstandingBytes;
  1772. sctpEV3<<"bytesAllowedToSend: osb="<<osb<<" cwnd="<<iter->second->cwnd<<"\n";
  1773. if (!state->firstDataSent)
  1774. {
  1775. bytes.chunk = true;
  1776. return;
  1777. }
  1778. if (state->peerWindowFull)
  1779. {
  1780. if (osb==0)
  1781. {
  1782. sctpEV3<<"probingIsAllowed\n";
  1783. state->zeroWindowProbing=true;
  1784. bytes.chunk = true;
  1785. }
  1786. return;
  1787. }
  1788. else
  1789. {
  1790. sctpEV3<<"bytesAllowedToSend: osb="<<osb<<" cwnd="<<iter->second->cwnd<<"\n";
  1791. CounterMap::iterator it = qCounter.roomTransQ.find(dpi);
  1792. sctpEV3<<"bytes in transQ="<<it->second<<"\n";
  1793. if (it->second>0)
  1794. {
  1795. diff = iter->second->cwnd - osb;
  1796. sctpEV3<<"cwnd-osb="<<diff<<"\n";
  1797. if (state->peerRwnd<iter->second->pmtu)
  1798. {
  1799. bytes.bytesToSend = state->peerRwnd;
  1800. return;
  1801. }
  1802. if (diff > 0)
  1803. {
  1804. CounterMap::iterator bit = qCounter.bookedTransQ.find(dpi);
  1805. if (bit->second > (uint32)diff)
  1806. {
  1807. bytes.bytesToSend = diff;
  1808. sctpEV3<<"cwnd does not allow all RTX\n";
  1809. return;
  1810. }
  1811. else
  1812. {
  1813. bytes.bytesToSend = bit->second;
  1814. sctpEV3<<"cwnd allows more than those "<<bytes.bytesToSend<<" bytes for retransmission\n";
  1815. }
  1816. }
  1817. else // You may transmit one packet
  1818. {
  1819. bytes.packet = true;
  1820. sctpEV3<<"diff<=0: retransmit one packet\n";
  1821. return;
  1822. }
  1823. }
  1824. if (!bytes.chunk && !bytes.packet)
  1825. {
  1826. if (osb < iter->second->cwnd && !state->peerWindowFull )
  1827. {
  1828. sctpEV3<<"bookedSumSendStreams="<<qCounter.bookedSumSendStreams<<" bytes.bytesToSend="<<bytes.bytesToSend<<"\n";
  1829. diff = iter->second->cwnd - osb - bytes.bytesToSend;
  1830. if (diff>0)
  1831. {
  1832. if (qCounter.bookedSumSendStreams > (uint32)diff)
  1833. {
  1834. bytes.bytesToSend = iter->second->cwnd - osb ;
  1835. sctpEV3<<"bytesToSend are limited by cwnd: "<<bytes.bytesToSend<<"\n";
  1836. }
  1837. else
  1838. {
  1839. bytes.bytesToSend += qCounter.bookedSumSendStreams;
  1840. sctpEV3<<"send all stored bytes: "<<bytes.bytesToSend<<"\n";
  1841. }
  1842. }
  1843. }
  1844. }
  1845. }
  1846. }
  1847. void SCTPAssociation::printOutstandingTsns()
  1848. {
  1849. uint32 first=0, second = 0;
  1850. if (retransmissionQ->payloadQueue.empty())
  1851. {
  1852. return;
  1853. }
  1854. for(SCTPQueue::PayloadQueue::iterator pl=retransmissionQ->payloadQueue.begin();pl!=retransmissionQ->payloadQueue.end();pl++)
  1855. {
  1856. if (pl->second->hasBeenAcked == false && pl->second->countsAsOutstanding == true)
  1857. {
  1858. if (pl->second->tsn > second+1)
  1859. {
  1860. if (second != 0)
  1861. {
  1862. sctpEV3<<" - "<<second<<"\t";;
  1863. }
  1864. first = second = pl->second->tsn;
  1865. sctpEV3<<pl->second->tsn;
  1866. }
  1867. else if (pl->second->tsn == second+1)
  1868. {
  1869. second = pl->second->tsn;
  1870. }
  1871. first = pl->second->tsn;
  1872. }
  1873. }
  1874. sctpEV3<<" - "<<second<<"\n";
  1875. }
  1876. uint32 SCTPAssociation::getOutstandingBytesOnPath(IPvXAddress pathId)
  1877. {
  1878. uint32 osb = 0, queueLength = 0, first=0, second = 0;
  1879. if (retransmissionQ->payloadQueue.empty()) return 0;
  1880. queueLength = retransmissionQ->getQueueSize();
  1881. sctpEV3<<"queueLength of retransmissionQ="<<queueLength<<"\n";
  1882. sctpEV3<<"outstanding TSNs\n";
  1883. for(SCTPQueue::PayloadQueue::iterator pl=retransmissionQ->payloadQueue.begin();pl!=retransmissionQ->payloadQueue.end();pl++)
  1884. {
  1885. if (pl->second->lastDestination == pathId)
  1886. {
  1887. if (pl->second->hasBeenAcked == false && pl->second->countsAsOutstanding == true)
  1888. {
  1889. //osb += pl->second->len/8;
  1890. if (pl->second->tsn > second+1)
  1891. {
  1892. if (second != 0)
  1893. {
  1894. sctpEV3<<" - "<<second<<"\t";;
  1895. }
  1896. first = second = pl->second->tsn;
  1897. sctpEV3<<pl->second->tsn;
  1898. }
  1899. else if (pl->second->tsn == second+1)
  1900. {
  1901. second = pl->second->tsn;
  1902. }
  1903. first = pl->second->tsn;
  1904. osb += pl->second->booksize;
  1905. }
  1906. }
  1907. }
  1908. sctpEV3<<" - "<<second<<"\n";
  1909. sctpEV3<<"getOutstandingBytesOnPath("<<(pathId)<<") : currently "<<osb<<" bytes outstanding\n";
  1910. return (osb);
  1911. }
  1912. SCTPPathVariables* SCTPAssociation::getPath(IPvXAddress pid)
  1913. {
  1914. SCTPPathMap::iterator i=sctpPathMap.find(pid);
  1915. if (i!=sctpPathMap.end())
  1916. {
  1917. return i->second;
  1918. }
  1919. else
  1920. {
  1921. return NULL;
  1922. }
  1923. }
  1924. void SCTPAssociation::pmDataIsSentOn(IPvXAddress pathId)
  1925. {
  1926. SCTPPathVariables* path;
  1927. /* restart hb_timer on this path */
  1928. path=getPath(pathId);
  1929. path->heartbeatTimeout = path->pathRto+ (double)sctpMain->par("hbInterval");
  1930. stopTimer(path->HeartbeatTimer);
  1931. startTimer(path->HeartbeatTimer, path->heartbeatTimeout);
  1932. path->cwndTimeout = path->pathRto;
  1933. stopTimer(path->CwndTimer);
  1934. startTimer(path->CwndTimer, path->cwndTimeout);
  1935. sctpEV3<<"Restarting HB timer on path "<<(pathId)<<" to expire at time "<<path->heartbeatTimeout<<"\n";
  1936. sctpEV3<<"Restarting CWND timer on path "<<(pathId)<<" to expire at time "<<path->cwndTimeout<<"\n";
  1937. /* AJ - 02-04-2004 - added for fullfilling section 8.2 */
  1938. state->lastUsedDataPath = pathId;
  1939. }
  1940. void SCTPAssociation::pmStartPathManagement(void)
  1941. {
  1942. RoutingTableAccess routingTableAccess;
  1943. SCTPPathVariables* path;
  1944. int32 i=0;
  1945. /* populate path structures !!! */
  1946. /* set a high start value...this is appropriately decreased later (below) */
  1947. state->assocPmtu = state->localRwnd;
  1948. for(SCTPPathMap::iterator piter=sctpPathMap.begin(); piter!=sctpPathMap.end(); piter++)
  1949. {
  1950. path=piter->second;
  1951. path->pathErrorCount = 0;
  1952. InterfaceEntry *rtie = routingTableAccess.get()->getInterfaceForDestAddr(path->remoteAddress.get4());
  1953. path->pmtu = rtie->getMTU();
  1954. sctpEV3 << "Path MTU of Interface "<< i << " = " << path->pmtu <<"\n";
  1955. if (path->pmtu < state->assocPmtu)
  1956. {
  1957. state->assocPmtu = path->pmtu;
  1958. }
  1959. initCCParameters(path);
  1960. path->pathRto = (double)sctpMain->par("rtoInitial");
  1961. path->srtt = path->pathRto;
  1962. path->rttvar = SIMTIME_ZERO;
  1963. /* from now on we may have one update per RTO/SRTT */
  1964. path->updateTime = SIMTIME_ZERO;
  1965. path->partialBytesAcked = 0;
  1966. path->outstandingBytes = 0;
  1967. path->activePath = true;
  1968. // Timer probably not running, but stop it anyway I.R.
  1969. stopTimer(path->T3_RtxTimer);
  1970. if (path->remoteAddress == state->initialPrimaryPath && !path->confirmed)
  1971. {
  1972. path->confirmed = true;
  1973. }
  1974. sctpEV3<<getFullPath()<<" numberOfLocalAddresses="<<state->localAddresses.size()<<"\n";
  1975. path->heartbeatTimeout= (double)sctpMain->par("hbInterval")+i*path->pathRto;
  1976. stopTimer(path->HeartbeatTimer);
  1977. if (state->localAddresses.size()>1)
  1978. sendHeartbeat(path, false);
  1979. else
  1980. sendHeartbeat(path, true);
  1981. startTimer(path->HeartbeatTimer, path->heartbeatTimeout);
  1982. startTimer(path->HeartbeatIntervalTimer, path->heartbeatIntervalTimeout);
  1983. path->pathRTO->record(path->pathRto);
  1984. i++;
  1985. }
  1986. }
  1987. int32 SCTPAssociation::getQueuedBytes(void)
  1988. {
  1989. int32 qb = 0;
  1990. SCTPReceiveStream* rStream;
  1991. SCTPQueue* sq;
  1992. for (SCTPReceiveStreamMap::iterator iter=receiveStreams.begin(); iter!=receiveStreams.end(); iter++)
  1993. {
  1994. rStream = iter->second;
  1995. sq = rStream->getOrderedQ();
  1996. if (sq)
  1997. {
  1998. qb+=sq->getNumBytes();
  1999. }
  2000. sq = rStream->getUnorderedQ();
  2001. if (sq)
  2002. {
  2003. qb+=sq->getNumBytes();
  2004. }
  2005. sq = rStream->getDeliveryQ();
  2006. if (sq)
  2007. {
  2008. qb+=sq->getNumBytes();
  2009. }
  2010. }
  2011. sctpEV3<<"getQueuedBytes : currently "<<qb<<" bytes buffered\n";
  2012. return (qb);
  2013. }
  2014. int32 SCTPAssociation::getOutstandingBytes(void)
  2015. {
  2016. int32 osb = 0;
  2017. for (SCTPPathMap::iterator pm=sctpPathMap.begin(); pm != sctpPathMap.end(); pm++)
  2018. osb += pm->second->outstandingBytes;
  2019. return osb;
  2020. }
  2021. void SCTPAssociation::pmClearPathCounter(IPvXAddress pathId)
  2022. {
  2023. SCTPPathMap::iterator pm=sctpPathMap.find(pathId);
  2024. if (pm!=sctpPathMap.end())
  2025. {
  2026. pm->second->pathErrorCount = 0;
  2027. if (pm->second->activePath==false)
  2028. {
  2029. /* notify the application */
  2030. pathStatusIndication(pathId, true);
  2031. sctpEV3<<"Path "<<pathId<<" state changes from INACTIVE to ACTIVE !!!!\n";
  2032. }
  2033. }
  2034. }
  2035. void SCTPAssociation::pathStatusIndication(IPvXAddress pid, bool status)
  2036. {
  2037. cPacket* msg=new cPacket("StatusInfo");
  2038. msg->setKind(SCTP_I_STATUS);
  2039. SCTPStatusInfo *cmd = new SCTPStatusInfo();
  2040. cmd->setPathId(pid);
  2041. cmd->setAssocId(assocId);
  2042. cmd->setActive(status);
  2043. msg->setControlInfo(cmd);
  2044. if (!status)
  2045. {
  2046. SCTP::AssocStatMap::iterator iter=sctpMain->assocStatMap.find(assocId);
  2047. iter->second.numPathFailures++;
  2048. }
  2049. sendToApp(msg);
  2050. }
  2051. void SCTPAssociation::pmRttMeasurement(IPvXAddress pathId, simtime_t rttEstimate, int32 acknowledgedBytes)
  2052. {
  2053. if (rttEstimate != MAXTIME)
  2054. {
  2055. /* we have a valid estimation */
  2056. SCTPPathVariables* path=getPath(pathId);
  2057. if (simulation.getSimTime() > path->updateTime)
  2058. {
  2059. if (path->updateTime == SIMTIME_ZERO)
  2060. {
  2061. path->rttvar = rttEstimate / 2;
  2062. path->srtt = rttEstimate;
  2063. path->pathRto = 3 * rttEstimate;
  2064. path->pathRto = max(min(path->pathRto.dbl(), sctpMain->par("rtoMax")), (double)sctpMain->par("rtoMin"));
  2065. }
  2066. else
  2067. {
  2068. path->rttvar = (1.0 - (double)sctpMain->par("rtoBeta")) * path->rttvar + (double)sctpMain->par("rtoBeta") * fabs(path->srtt - rttEstimate);
  2069. path->srtt = (1.0 - (double)sctpMain->par("rtoAlpha")) * path->srtt + (double)sctpMain->par("rtoAlpha") * rttEstimate;
  2070. path->pathRto = path->srtt + 4 * path->rttvar;
  2071. path->pathRto = max(min(path->pathRto.dbl(), sctpMain->par("rtoMax")), (double)sctpMain->par("rtoMin"));
  2072. }
  2073. sctpEV3<<simulation.getSimTime()<<": Updating timer values for path "<<pathId<<"...RTO == "<<path->pathRto<<"\n";
  2074. sctpEV3<<" rttEstimat="<<rttEstimate<<" SRTT == "<<path->srtt<<" ------> RTTVAR == "<<path->rttvar<<"\n";
  2075. /* RFC2960, sect.6.3.1: new RTT measurements SHOULD be made no more than once per round-trip */
  2076. path->updateTime = simulation.getSimTime() + path->srtt;
  2077. }
  2078. path->pathRTO->record(path->pathRto);
  2079. path->pathRTT->record(rttEstimate);
  2080. }
  2081. if (acknowledgedBytes > 0)
  2082. {
  2083. /* we received a (new) SACK/HB ACK from our peer -- reset the error counters for this path */
  2084. state->errorCount = 0;
  2085. pmClearPathCounter(pathId);
  2086. }
  2087. }
  2088. bool SCTPAssociation::allPathsInactive(void)
  2089. {
  2090. for(SCTPPathMap::iterator i=sctpPathMap.begin(); i!=sctpPathMap.end(); i++)
  2091. {
  2092. if (i->second->activePath)
  2093. return false;
  2094. }
  2095. return true;
  2096. }
  2097. void SCTPAssociation::disposeOf(SCTPMessage* sctpmsg)
  2098. {
  2099. SCTPChunk* chunk;
  2100. uint32 numberOfChunks = sctpmsg->getChunksArraySize();
  2101. if (numberOfChunks>0)
  2102. for (uint32 i=0; i<numberOfChunks; i++)
  2103. {
  2104. chunk = (SCTPChunk*)(sctpmsg->removeChunk());
  2105. if (chunk->getChunkType()==DATA)
  2106. delete (SCTPSimpleMessage*)chunk->decapsulate();
  2107. delete chunk;
  2108. }
  2109. delete sctpmsg;
  2110. }