PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/src/transport/tcp/TCPConnectionUtil.cc

https://github.com/Sorouri/inetmanet
C++ | 1710 lines | 1105 code | 211 blank | 394 comment | 254 complexity | 8015d7ab0eb0da40be613b3478a1142b MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. //
  2. // Copyright (C) 2004 Andras Varga
  3. // 2009 Thomas Reschka
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU Lesser General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (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 Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public License
  16. // along with this program; if not, see <http://www.gnu.org/licenses/>.
  17. //
  18. #include <string.h>
  19. #include <algorithm> // min,max
  20. #include "TCP.h"
  21. #include "TCPConnection.h"
  22. #include "TCPSegment.h"
  23. #include "TCPCommand_m.h"
  24. #include "IPControlInfo.h"
  25. #include "IPv6ControlInfo.h"
  26. #include "TCPSendQueue.h"
  27. #include "TCPSACKRexmitQueue.h"
  28. #include "TCPReceiveQueue.h"
  29. #include "TCPAlgorithm.h"
  30. //
  31. // helper functions
  32. //
  33. const char *TCPConnection::stateName(int state)
  34. {
  35. #define CASE(x) case x: s=#x+6; break
  36. const char *s = "unknown";
  37. switch (state)
  38. {
  39. CASE(TCP_S_INIT);
  40. CASE(TCP_S_CLOSED);
  41. CASE(TCP_S_LISTEN);
  42. CASE(TCP_S_SYN_SENT);
  43. CASE(TCP_S_SYN_RCVD);
  44. CASE(TCP_S_ESTABLISHED);
  45. CASE(TCP_S_CLOSE_WAIT);
  46. CASE(TCP_S_LAST_ACK);
  47. CASE(TCP_S_FIN_WAIT_1);
  48. CASE(TCP_S_FIN_WAIT_2);
  49. CASE(TCP_S_CLOSING);
  50. CASE(TCP_S_TIME_WAIT);
  51. }
  52. return s;
  53. #undef CASE
  54. }
  55. const char *TCPConnection::eventName(int event)
  56. {
  57. #define CASE(x) case x: s=#x+6; break
  58. const char *s = "unknown";
  59. switch (event)
  60. {
  61. CASE(TCP_E_IGNORE);
  62. CASE(TCP_E_OPEN_ACTIVE);
  63. CASE(TCP_E_OPEN_PASSIVE);
  64. CASE(TCP_E_SEND);
  65. CASE(TCP_E_CLOSE);
  66. CASE(TCP_E_ABORT);
  67. CASE(TCP_E_STATUS);
  68. CASE(TCP_E_RCV_DATA);
  69. CASE(TCP_E_RCV_ACK);
  70. CASE(TCP_E_RCV_SYN);
  71. CASE(TCP_E_RCV_SYN_ACK);
  72. CASE(TCP_E_RCV_FIN);
  73. CASE(TCP_E_RCV_FIN_ACK);
  74. CASE(TCP_E_RCV_RST);
  75. CASE(TCP_E_RCV_UNEXP_SYN);
  76. CASE(TCP_E_TIMEOUT_2MSL);
  77. CASE(TCP_E_TIMEOUT_CONN_ESTAB);
  78. CASE(TCP_E_TIMEOUT_FIN_WAIT_2);
  79. }
  80. return s;
  81. #undef CASE
  82. }
  83. const char *TCPConnection::indicationName(int code)
  84. {
  85. #define CASE(x) case x: s=#x+6; break
  86. const char *s = "unknown";
  87. switch (code)
  88. {
  89. CASE(TCP_I_DATA);
  90. CASE(TCP_I_URGENT_DATA);
  91. CASE(TCP_I_ESTABLISHED);
  92. CASE(TCP_I_PEER_CLOSED);
  93. CASE(TCP_I_CLOSED);
  94. CASE(TCP_I_CONNECTION_REFUSED);
  95. CASE(TCP_I_CONNECTION_RESET);
  96. CASE(TCP_I_TIMED_OUT);
  97. CASE(TCP_I_STATUS);
  98. }
  99. return s;
  100. #undef CASE
  101. }
  102. void TCPConnection::printConnBrief()
  103. {
  104. tcpEV << "Connection ";
  105. tcpEV << localAddr << ":" << localPort << " to " << remoteAddr << ":" << remotePort;
  106. tcpEV << " on app[" << appGateIndex << "],connId=" << connId;
  107. tcpEV << " in " << stateName(fsm.getState());
  108. tcpEV << " (ptr=0x" << this << ")\n";
  109. }
  110. void TCPConnection::printSegmentBrief(TCPSegment *tcpseg)
  111. {
  112. tcpEV << "." << tcpseg->getSrcPort() << " > ";
  113. tcpEV << "." << tcpseg->getDestPort() << ": ";
  114. if (tcpseg->getSynBit()) tcpEV << (tcpseg->getAckBit() ? "SYN+ACK " : "SYN ");
  115. if (tcpseg->getFinBit()) tcpEV << "FIN(+ACK) ";
  116. if (tcpseg->getRstBit()) tcpEV << (tcpseg->getAckBit() ? "RST+ACK " : "RST ");
  117. if (tcpseg->getPshBit()) tcpEV << "PSH ";
  118. if (tcpseg->getPayloadLength()>0 || tcpseg->getSynBit())
  119. {
  120. tcpEV << "[" << tcpseg->getSequenceNo() << ".." << (tcpseg->getSequenceNo()+tcpseg->getPayloadLength()) << ") ";
  121. tcpEV << "(l=" << tcpseg->getPayloadLength() << ") ";
  122. }
  123. if (tcpseg->getAckBit()) tcpEV << "ack " << tcpseg->getAckNo() << " ";
  124. tcpEV << "win " << tcpseg->getWindow() << "\n";
  125. if (tcpseg->getUrgBit()) tcpEV << "urg " << tcpseg->getUrgentPointer() << " ";
  126. }
  127. TCPConnection *TCPConnection::cloneListeningConnection()
  128. {
  129. TCPConnection *conn = new TCPConnection(tcpMain,appGateIndex,connId);
  130. // following code to be kept consistent with initConnection()
  131. const char *sendQueueClass = sendQueue->getClassName();
  132. conn->sendQueue = check_and_cast<TCPSendQueue *>(createOne(sendQueueClass));
  133. conn->sendQueue->setConnection(conn);
  134. const char *receiveQueueClass = receiveQueue->getClassName();
  135. conn->receiveQueue = check_and_cast<TCPReceiveQueue *>(createOne(receiveQueueClass));
  136. conn->receiveQueue->setConnection(conn);
  137. // create SACK retransmit queue
  138. rexmitQueue = new TCPSACKRexmitQueue();
  139. rexmitQueue->setConnection(this);
  140. const char *tcpAlgorithmClass = tcpAlgorithm->getClassName();
  141. conn->tcpAlgorithm = check_and_cast<TCPAlgorithm *>(createOne(tcpAlgorithmClass));
  142. conn->tcpAlgorithm->setConnection(conn);
  143. conn->state = conn->tcpAlgorithm->getStateVariables();
  144. configureStateVariables();
  145. conn->tcpAlgorithm->initialize();
  146. // put it into LISTEN, with our localAddr/localPort
  147. conn->state->active = false;
  148. conn->state->fork = true;
  149. conn->localAddr = localAddr;
  150. conn->localPort = localPort;
  151. FSM_Goto(conn->fsm, TCP_S_LISTEN);
  152. return conn;
  153. }
  154. void TCPConnection::sendToIP(TCPSegment *tcpseg)
  155. {
  156. // record seq (only if we do send data) and ackno
  157. if (sndNxtVector && tcpseg->getPayloadLength()!=0)
  158. sndNxtVector->record(tcpseg->getSequenceNo());
  159. if (sndAckVector)
  160. sndAckVector->record(tcpseg->getAckNo());
  161. // final touches on the segment before sending
  162. tcpseg->setSrcPort(localPort);
  163. tcpseg->setDestPort(remotePort);
  164. ASSERT(tcpseg->getHeaderLength() >= TCP_HEADER_OCTETS); // TCP_HEADER_OCTETS = 20 (without options)
  165. ASSERT(tcpseg->getHeaderLength() <= TCP_MAX_HEADER_OCTETS); // TCP_MAX_HEADER_OCTETS = 60
  166. tcpseg->setByteLength(tcpseg->getHeaderLength() + tcpseg->getPayloadLength());
  167. tcpEV << "Sending: ";
  168. printSegmentBrief(tcpseg);
  169. // TBD reuse next function for sending
  170. if (!remoteAddr.isIPv6())
  171. {
  172. // send over IPv4
  173. IPControlInfo *controlInfo = new IPControlInfo();
  174. controlInfo->setProtocol(IP_PROT_TCP);
  175. controlInfo->setSrcAddr(localAddr.get4());
  176. controlInfo->setDestAddr(remoteAddr.get4());
  177. tcpseg->setControlInfo(controlInfo);
  178. tcpMain->send(tcpseg,"ipOut");
  179. }
  180. else
  181. {
  182. // send over IPv6
  183. IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
  184. controlInfo->setProtocol(IP_PROT_TCP);
  185. controlInfo->setSrcAddr(localAddr.get6());
  186. controlInfo->setDestAddr(remoteAddr.get6());
  187. tcpseg->setControlInfo(controlInfo);
  188. tcpMain->send(tcpseg,"ipv6Out");
  189. }
  190. }
  191. void TCPConnection::sendToIP(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest)
  192. {
  193. tcpEV << "Sending: ";
  194. printSegmentBrief(tcpseg);
  195. if (!dest.isIPv6())
  196. {
  197. // send over IPv4
  198. IPControlInfo *controlInfo = new IPControlInfo();
  199. controlInfo->setProtocol(IP_PROT_TCP);
  200. controlInfo->setSrcAddr(src.get4());
  201. controlInfo->setDestAddr(dest.get4());
  202. tcpseg->setControlInfo(controlInfo);
  203. check_and_cast<TCP *>(simulation.getContextModule())->send(tcpseg,"ipOut");
  204. }
  205. else
  206. {
  207. // send over IPv6
  208. IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
  209. controlInfo->setProtocol(IP_PROT_TCP);
  210. controlInfo->setSrcAddr(src.get6());
  211. controlInfo->setDestAddr(dest.get6());
  212. tcpseg->setControlInfo(controlInfo);
  213. check_and_cast<TCP *>(simulation.getContextModule())->send(tcpseg,"ipv6Out");
  214. }
  215. }
  216. TCPSegment *TCPConnection::createTCPSegment(const char *name)
  217. {
  218. return new TCPSegment(name);
  219. }
  220. void TCPConnection::signalConnectionTimeout()
  221. {
  222. sendIndicationToApp(TCP_I_TIMED_OUT);
  223. }
  224. void TCPConnection::sendIndicationToApp(int code)
  225. {
  226. tcpEV << "Notifying app: " << indicationName(code) << "\n";
  227. cMessage *msg = new cMessage(indicationName(code));
  228. msg->setKind(code);
  229. TCPCommand *ind = new TCPCommand();
  230. ind->setConnId(connId);
  231. msg->setControlInfo(ind);
  232. tcpMain->send(msg, "appOut", appGateIndex);
  233. }
  234. void TCPConnection::sendEstabIndicationToApp()
  235. {
  236. tcpEV << "Notifying app: " << indicationName(TCP_I_ESTABLISHED) << "\n";
  237. cMessage *msg = new cMessage(indicationName(TCP_I_ESTABLISHED));
  238. msg->setKind(TCP_I_ESTABLISHED);
  239. TCPConnectInfo *ind = new TCPConnectInfo();
  240. ind->setConnId(connId);
  241. ind->setLocalAddr(localAddr);
  242. ind->setRemoteAddr(remoteAddr);
  243. ind->setLocalPort(localPort);
  244. ind->setRemotePort(remotePort);
  245. msg->setControlInfo(ind);
  246. tcpMain->send(msg, "appOut", appGateIndex);
  247. }
  248. void TCPConnection::sendToApp(cMessage *msg)
  249. {
  250. tcpMain->send(msg, "appOut", appGateIndex);
  251. }
  252. void TCPConnection::initConnection(TCPOpenCommand *openCmd)
  253. {
  254. // create send queue
  255. const char *sendQueueClass = openCmd->getSendQueueClass();
  256. if (!sendQueueClass || !sendQueueClass[0])
  257. sendQueueClass = tcpMain->par("sendQueueClass");
  258. sendQueue = check_and_cast<TCPSendQueue *>(createOne(sendQueueClass));
  259. sendQueue->setConnection(this);
  260. // create receive queue
  261. const char *receiveQueueClass = openCmd->getReceiveQueueClass();
  262. if (!receiveQueueClass || !receiveQueueClass[0])
  263. receiveQueueClass = tcpMain->par("receiveQueueClass");
  264. receiveQueue = check_and_cast<TCPReceiveQueue *>(createOne(receiveQueueClass));
  265. receiveQueue->setConnection(this);
  266. // create SACK retransmit queue
  267. rexmitQueue = new TCPSACKRexmitQueue();
  268. rexmitQueue->setConnection(this);
  269. // create algorithm
  270. const char *tcpAlgorithmClass = openCmd->getTcpAlgorithmClass();
  271. if (!tcpAlgorithmClass || !tcpAlgorithmClass[0])
  272. tcpAlgorithmClass = tcpMain->par("tcpAlgorithmClass");
  273. tcpAlgorithm = check_and_cast<TCPAlgorithm *>(createOne(tcpAlgorithmClass));
  274. tcpAlgorithm->setConnection(this);
  275. // create state block
  276. state = tcpAlgorithm->getStateVariables();
  277. configureStateVariables();
  278. tcpAlgorithm->initialize();
  279. }
  280. void TCPConnection::configureStateVariables()
  281. {
  282. state->delayed_acks_enabled = tcpMain->par("delayedAcksEnabled"); // delayed ACKs enabled/disabled
  283. state->nagle_enabled = tcpMain->par("nagleEnabled"); // Nagle's algorithm enabled/disabled
  284. state->limited_transmit_enabled = tcpMain->par("limitedTransmitEnabled"); // Limited Transmit algorithm (RFC 3042) enabled/disabled
  285. state->increased_IW_enabled = tcpMain->par("increasedIWEnabled"); // increased initial window (=2*SMSS) (RFC 2581) enabled/disabled
  286. state->rcv_wnd = tcpMain->par("advertisedWindow"); // advertisedWindow/maxRcvBuffer is used as initial value for rcv_wnd and rcv_avd
  287. state->rcv_adv = tcpMain->par("advertisedWindow"); // advertisedWindow/maxRcvBuffer is used as initial value for rcv_wnd and rcv_avd
  288. state->maxRcvBuffer = tcpMain->par("advertisedWindow"); // advertisedWindow/maxRcvBuffer is used as initial value for rcv_wnd and rcv_avd
  289. state->snd_mss = tcpMain->par("mss").longValue(); // maximum segment size
  290. state->sack_support = tcpMain->par("sackSupport"); // if set, this means that current host supports SACK (RFC 2018, 2883, 3517)
  291. if (state->sack_support)
  292. {
  293. std::string algorithmName1 = "TCPReno";
  294. std::string algorithmName2 = tcpMain->par("tcpAlgorithmClass");
  295. if (algorithmName1!=algorithmName2) // TODO add additional checks for new SACK supporting algorithms here once they are implemented
  296. {
  297. EV << "If you want to use TCP SACK please set tcpAlgorithmClass to TCPReno" << endl;
  298. ASSERT(false);
  299. }
  300. }
  301. }
  302. void TCPConnection::selectInitialSeqNum()
  303. {
  304. // set the initial send sequence number
  305. state->iss = (unsigned long)fmod(SIMTIME_DBL(simTime())*250000.0, 1.0+(double)(unsigned)0xffffffffUL) & 0xffffffffUL;
  306. state->snd_una = state->snd_nxt = state->snd_max = state->iss;
  307. sendQueue->init(state->iss+1); // +1 is for SYN
  308. rexmitQueue->init(state->iss + 1); // +1 is for SYN
  309. }
  310. bool TCPConnection::isSegmentAcceptable(TCPSegment *tcpseg)
  311. {
  312. // check that segment entirely falls in receive window
  313. // RFC 793, page 69:
  314. // There are four cases for the acceptability test for an incoming segment:
  315. uint32 seg_len = tcpseg->getPayloadLength();
  316. uint32 seqNo = tcpseg->getSequenceNo();
  317. if (seg_len == 0 && state->rcv_wnd == 0) {
  318. return (seqNo == state->rcv_nxt);
  319. }
  320. else if (seg_len == 0 && state->rcv_wnd > 0) {
  321. return (seqLE(state->rcv_nxt, seqNo) && seqLess(seqNo, state->rcv_nxt
  322. + state->rcv_wnd));
  323. }
  324. else if (seg_len > 0 && state->rcv_wnd == 0) {
  325. return false; // not acceptable
  326. }
  327. else if (seg_len > 0 && state->rcv_wnd > 0) {
  328. return ((seqLE(state->rcv_nxt, seqNo) && seqLess(seqNo, state->rcv_nxt
  329. + state->rcv_wnd)) || (seqLE(state->rcv_nxt, seqNo + seg_len
  330. - 1) && seqLess(seqNo + seg_len - 1, state->rcv_nxt
  331. + state->rcv_wnd)));
  332. } else
  333. return false;
  334. }
  335. void TCPConnection::sendSyn()
  336. {
  337. if (remoteAddr.isUnspecified() || remotePort==-1)
  338. opp_error("Error processing command OPEN_ACTIVE: foreign socket unspecified");
  339. if (localPort==-1)
  340. opp_error("Error processing command OPEN_ACTIVE: local port unspecified");
  341. // create segment
  342. TCPSegment *tcpseg = createTCPSegment("SYN");
  343. tcpseg->setSequenceNo(state->iss);
  344. tcpseg->setSynBit(true);
  345. updateRcvWnd();
  346. tcpseg->setWindow(state->rcv_wnd);
  347. if (rcvWndVector)
  348. rcvWndVector->record(state->rcv_wnd);
  349. state->snd_max = state->snd_nxt = state->iss+1;
  350. // write header options
  351. writeHeaderOptions(tcpseg);
  352. // send it
  353. sendToIP(tcpseg);
  354. }
  355. void TCPConnection::sendSynAck()
  356. {
  357. // create segment
  358. TCPSegment *tcpseg = createTCPSegment("SYN+ACK");
  359. tcpseg->setSequenceNo(state->iss);
  360. tcpseg->setAckNo(state->rcv_nxt);
  361. tcpseg->setSynBit(true);
  362. tcpseg->setAckBit(true);
  363. updateRcvWnd();
  364. tcpseg->setWindow(state->rcv_wnd);
  365. if (rcvWndVector)
  366. rcvWndVector->record(state->rcv_wnd);
  367. state->snd_max = state->snd_nxt = state->iss+1;
  368. // write header options
  369. writeHeaderOptions(tcpseg);
  370. // send it
  371. sendToIP(tcpseg);
  372. }
  373. void TCPConnection::sendRst(uint32 seqNo)
  374. {
  375. sendRst(seqNo, localAddr, remoteAddr, localPort, remotePort);
  376. }
  377. void TCPConnection::sendRst(uint32 seq, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort)
  378. {
  379. TCPSegment *tcpseg = createTCPSegment("RST");
  380. tcpseg->setSrcPort(srcPort);
  381. tcpseg->setDestPort(destPort);
  382. tcpseg->setRstBit(true);
  383. tcpseg->setSequenceNo(seq);
  384. // send it
  385. sendToIP(tcpseg, src, dest);
  386. }
  387. void TCPConnection::sendRstAck(uint32 seq, uint32 ack, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort)
  388. {
  389. TCPSegment *tcpseg = createTCPSegment("RST+ACK");
  390. tcpseg->setSrcPort(srcPort);
  391. tcpseg->setDestPort(destPort);
  392. tcpseg->setRstBit(true);
  393. tcpseg->setAckBit(true);
  394. tcpseg->setSequenceNo(seq);
  395. tcpseg->setAckNo(ack);
  396. // send it
  397. sendToIP(tcpseg, src, dest);
  398. }
  399. void TCPConnection::sendAck()
  400. {
  401. TCPSegment *tcpseg = createTCPSegment("ACK");
  402. tcpseg->setAckBit(true);
  403. tcpseg->setSequenceNo(state->snd_nxt);
  404. tcpseg->setAckNo(state->rcv_nxt);
  405. updateRcvWnd();
  406. tcpseg->setWindow(state->rcv_wnd);
  407. if (rcvWndVector)
  408. rcvWndVector->record(state->rcv_wnd);
  409. // write header options
  410. writeHeaderOptions(tcpseg);
  411. // send it
  412. sendToIP(tcpseg);
  413. // notify
  414. tcpAlgorithm->ackSent();
  415. }
  416. void TCPConnection::sendFin()
  417. {
  418. TCPSegment *tcpseg = createTCPSegment("FIN");
  419. // Note: ACK bit *must* be set for both FIN and FIN+ACK. What makes
  420. // the difference for FIN+ACK is that its ackNo acks the remote TCP's FIN.
  421. tcpseg->setFinBit(true);
  422. tcpseg->setAckBit(true);
  423. tcpseg->setAckNo(state->rcv_nxt);
  424. tcpseg->setSequenceNo(state->snd_nxt);
  425. updateRcvWnd();
  426. tcpseg->setWindow(state->rcv_wnd);
  427. if (rcvWndVector)
  428. rcvWndVector->record(state->rcv_wnd);
  429. // send it
  430. sendToIP(tcpseg);
  431. // notify
  432. tcpAlgorithm->ackSent();
  433. }
  434. void TCPConnection::sendSegment(uint32 bytes)
  435. {
  436. if (state->sack_enabled && state->afterRto)
  437. {
  438. // check rexmitQ and try to forward snd_nxt before sending new data
  439. uint32 forward = rexmitQueue->checkRexmitQueueForSackedOrRexmittedSegments(state->snd_nxt);
  440. state->snd_nxt = state->snd_nxt + forward;
  441. }
  442. // send one segment of 'bytes' bytes from snd_nxt, and advance snd_nxt
  443. TCPSegment *tcpseg = sendQueue->createSegmentWithBytes(state->snd_nxt, bytes);
  444. // if sack_enabled copy region of tcpseg to rexmitQueue
  445. if (state->sack_enabled)
  446. rexmitQueue->enqueueSentData(state->snd_nxt, state->snd_nxt+bytes);
  447. tcpseg->setAckNo(state->rcv_nxt);
  448. tcpseg->setAckBit(true);
  449. updateRcvWnd();
  450. tcpseg->setWindow(state->rcv_wnd);
  451. if (rcvWndVector)
  452. rcvWndVector->record(state->rcv_wnd);
  453. // TBD when to set PSH bit?
  454. // TBD set URG bit if needed
  455. ASSERT(bytes==tcpseg->getPayloadLength());
  456. state->snd_nxt += bytes;
  457. // check if afterRto bit can be reset
  458. if (state->afterRto && seqGE(state->snd_nxt, state->snd_max))
  459. state->afterRto = false;
  460. if (state->send_fin && state->snd_nxt==state->snd_fin_seq)
  461. {
  462. tcpEV << "Setting FIN on segment\n";
  463. tcpseg->setFinBit(true);
  464. state->snd_nxt = state->snd_fin_seq+1;
  465. }
  466. sendToIP(tcpseg);
  467. }
  468. bool TCPConnection::sendData(bool fullSegmentsOnly, uint32 congestionWindow) // changed from int congestionWindow to uint32 congestionWindow 2009-08-05 by T.R.
  469. {
  470. if (!state->afterRto)
  471. // we'll start sending from snd_max
  472. state->snd_nxt = state->snd_max;
  473. uint32 old_highRxt = 0;
  474. if (state->sack_enabled)
  475. old_highRxt = rexmitQueue->getHighestRexmittedSeqNum();
  476. // check how many bytes we have
  477. ulong buffered = sendQueue->getBytesAvailable(state->snd_nxt);
  478. if (buffered==0)
  479. return false;
  480. // maxWindow is minimum of snd_wnd and congestionWindow (snd_cwnd)
  481. ulong maxWindow = std::min(state->snd_wnd, congestionWindow);
  482. // effectiveWindow: number of bytes we're allowed to send now
  483. long effectiveWin = maxWindow - (state->snd_nxt - state->snd_una);
  484. if (effectiveWin <= 0)
  485. {
  486. tcpEV << "Effective window is zero (advertised window " << state->snd_wnd <<
  487. ", congestion window " << congestionWindow << "), cannot send.\n";
  488. return false;
  489. }
  490. ulong bytesToSend = effectiveWin;
  491. if (bytesToSend > buffered)
  492. bytesToSend = buffered;
  493. if (fullSegmentsOnly && bytesToSend < state->snd_mss)
  494. {
  495. tcpEV << "Cannot send, not enough data for a full segment (SMSS=" << state->snd_mss
  496. << ", in buffer " << buffered << ")\n";
  497. return false;
  498. }
  499. // start sending 'bytesToSend' bytes
  500. tcpEV << "Will send " << bytesToSend << " bytes (effectiveWindow " << effectiveWin
  501. << ", in buffer " << buffered << " bytes)\n";
  502. uint32 old_snd_nxt = state->snd_nxt;
  503. ASSERT(bytesToSend>0);
  504. #ifdef TCP_SENDFRAGMENTS /* normally undefined */
  505. // make agressive use of the window until the last byte
  506. while (bytesToSend>0)
  507. {
  508. ulong bytes = std::min(bytesToSend, state->snd_mss);
  509. sendSegment(bytes);
  510. bytesToSend -= bytes;
  511. }
  512. #else
  513. // send <MSS segments only if it's the only segment we can send now
  514. // FIXME this should probably obey Nagle's alg -- to be checked
  515. if (bytesToSend <= state->snd_mss)
  516. {
  517. sendSegment(bytesToSend);
  518. }
  519. else
  520. {
  521. // send whole segments only (nagle_enabled)
  522. while (bytesToSend>=state->snd_mss)
  523. {
  524. sendSegment(state->snd_mss);
  525. bytesToSend -= state->snd_mss;
  526. }
  527. if (bytesToSend>0)
  528. tcpEV << bytesToSend << " bytes of space left in effectiveWindow\n";
  529. }
  530. #endif
  531. // remember highest seq sent (snd_nxt may be set back on retransmission,
  532. // but we'll need snd_max to check validity of ACKs -- they must ack
  533. // something we really sent)
  534. state->snd_max = std::max (state->snd_nxt, state->snd_max);
  535. if (unackedVector) unackedVector->record(state->snd_max - state->snd_una);
  536. // notify (once is enough)
  537. tcpAlgorithm->ackSent();
  538. if (state->sack_enabled && state->lossRecovery && old_highRxt != state->highRxt)
  539. {
  540. // Note: Restart of REXMIT timer on retransmission is not part of RFC 2581, however optional in RFC 3517 if sent during recovery.
  541. tcpEV << "Retransmission sent during recovery, restarting REXMIT timer.\n";
  542. tcpAlgorithm->restartRexmitTimer();
  543. }
  544. else // don't measure RTT for retransmitted packets
  545. tcpAlgorithm->dataSent(old_snd_nxt);
  546. return true;
  547. }
  548. bool TCPConnection::sendProbe()
  549. {
  550. // we'll start sending from snd_max
  551. state->snd_nxt = state->snd_max;
  552. // check we have 1 byte to send
  553. if (sendQueue->getBytesAvailable(state->snd_nxt)==0)
  554. {
  555. tcpEV << "Cannot send probe because send buffer is empty\n";
  556. return false;
  557. }
  558. uint32 old_snd_nxt = state->snd_nxt;
  559. tcpEV << "Sending 1 byte as probe, with seq=" << state->snd_nxt << "\n";
  560. sendSegment(1);
  561. // remember highest seq sent (snd_nxt may be set back on retransmission,
  562. // but we'll need snd_max to check validity of ACKs -- they must ack
  563. // something we really sent)
  564. state->snd_max = state->snd_nxt;
  565. if (unackedVector) unackedVector->record(state->snd_max - state->snd_una);
  566. // notify
  567. tcpAlgorithm->ackSent();
  568. tcpAlgorithm->dataSent(old_snd_nxt);
  569. return true;
  570. }
  571. void TCPConnection::retransmitOneSegment()
  572. {
  573. // retransmit one segment at snd_una, and set snd_nxt accordingly
  574. state->snd_nxt = state->snd_una;
  575. ulong bytes = std::min(state->snd_mss, state->snd_max - state->snd_nxt);
  576. ASSERT(bytes!=0);
  577. sendSegment(bytes);
  578. // notify
  579. tcpAlgorithm->ackSent();
  580. if (state->sack_enabled)
  581. {
  582. // RFC 3517, page 7: "(3) Retransmit the first data segment presumed dropped -- the segment
  583. // starting with sequence number HighACK + 1. To prevent repeated
  584. // retransmission of the same data, set HighRxt to the highest
  585. // sequence number in the retransmitted segment."
  586. state->highRxt = rexmitQueue->getHighestRexmittedSeqNum();
  587. }
  588. }
  589. void TCPConnection::retransmitData()
  590. {
  591. // retransmit everything from snd_una
  592. state->snd_nxt = state->snd_una;
  593. ulong bytesToSend = state->snd_max - state->snd_nxt;
  594. ASSERT(bytesToSend!=0);
  595. // TBD - avoid to send more than allowed - check cwnd and rwnd before retransmitting data!
  596. while (bytesToSend>0)
  597. {
  598. ulong bytes = std::min(bytesToSend, (ulong)state->snd_mss);
  599. bytes = std::min(bytes, sendQueue->getBytesAvailable(state->snd_nxt));
  600. sendSegment(bytes);
  601. // Do not send packets after the FIN.
  602. // fixes bug that occurs in examples/inet/bulktransfer at event #64043 T=13.861159213744
  603. if (state->send_fin && state->snd_nxt==state->snd_fin_seq+1)
  604. break;
  605. bytesToSend -= bytes;
  606. }
  607. }
  608. void TCPConnection::readHeaderOptions(TCPSegment *tcpseg)
  609. {
  610. tcpEV << "TCP Header Option(s) received:\n";
  611. for (uint i=0; i<tcpseg->getOptionsArraySize(); i++)
  612. {
  613. TCPOption option = tcpseg->getOptions(i);
  614. short kind = option.getKind();
  615. short length = option.getLength();
  616. tcpEV << "Received option of kind " << kind << " with length " << length << "\n";
  617. bool lengthMatched = false;
  618. switch(kind)
  619. {
  620. case TCPOPTION_END_OF_OPTION_LIST: // EOL=0
  621. {
  622. if (length == 1)
  623. {
  624. lengthMatched = true;
  625. tcpEV << "TCP Header Option EOL received\n";
  626. }
  627. break;
  628. }
  629. case TCPOPTION_NO_OPERATION: // NOP=1
  630. {
  631. if (length == 1)
  632. {
  633. lengthMatched = true;
  634. tcpEV << "TCP Header Option NOP received\n";
  635. }
  636. break;
  637. }
  638. case TCPOPTION_MAXIMUM_SEGMENT_SIZE: // MSS=2
  639. {
  640. if (length == 4)
  641. {
  642. lengthMatched = true;
  643. if (option.getValuesArraySize()!=0)
  644. {
  645. if (fsm.getState() == TCP_S_LISTEN || fsm.getState() == TCP_S_SYN_SENT)
  646. {
  647. // RFC 2581, page 1:
  648. // "The SMSS is the size of the largest segment that the sender can transmit.
  649. // This value can be based on the maximum transmission unit of the network,
  650. // the path MTU discovery [MD90] algorithm, RMSS (see next item), or other
  651. // factors. The size does not include the TCP/IP headers and options."
  652. //
  653. // "The RMSS is the size of the largest segment the receiver is willing to accept.
  654. // This is the value specified in the MSS option sent by the receiver during
  655. // connection startup. Or, if the MSS option is not used, 536 bytes [Bra89].
  656. // The size does not include the TCP/IP headers and options."
  657. //
  658. //
  659. // The value of snd_mss (SMSS) is set to the minimum of snd_mss (local parameter) and
  660. // the value specified in the MSS option received during connection startup.
  661. state->snd_mss = std::min(state->snd_mss, (uint32) option.getValues(0));
  662. if (state->snd_mss==0)
  663. state->snd_mss = 536;
  664. tcpEV << "TCP Header Option MSS received, SMSS is set to: " << state->snd_mss << "\n";
  665. }
  666. else
  667. tcpEV << "ERROR: TCP Header Option MSS received, but in unexpected state\n";
  668. }
  669. else
  670. tcpEV << "ERROR: TCP Header Option MSS received, but no SMSS value present\n";
  671. }
  672. break;
  673. }
  674. case TCPOPTION_SACK_PERMITTED: // SACK_PERMITTED=4
  675. {
  676. if (length == 2)
  677. {
  678. lengthMatched = true;
  679. if (fsm.getState() == TCP_S_LISTEN || fsm.getState() == TCP_S_SYN_SENT)
  680. {
  681. state->rcv_sack_perm = true;
  682. state->sack_enabled = state->sack_support && state->snd_sack_perm && state->rcv_sack_perm;
  683. tcpEV << "TCP Header Option SACK_PERMITTED received, SACK (sack_enabled) is set to: " << state->sack_enabled << "\n";
  684. }
  685. else
  686. tcpEV << "ERROR: TCP Header Option SACK_PERMITTED received, but in unexpected state\n";
  687. }
  688. break;
  689. }
  690. case TCPOPTION_SACK: // SACK=5
  691. {
  692. if (length%8 == 2)
  693. {
  694. lengthMatched = true;
  695. if (state->sack_enabled) // not need to check the state here?
  696. {
  697. // temporary variable
  698. int n = option.getValuesArraySize()/2;
  699. if (n>0) // sacks present?
  700. {
  701. tcpEV << n << " SACK(s) received:\n";
  702. uint count=0;
  703. for (int i=0; i<n; i++)
  704. {
  705. Sack tmp;
  706. tmp.setStart(option.getValues(count));
  707. count++;
  708. tmp.setEnd(option.getValues(count));
  709. count++;
  710. uint32 sack_range = tmp.getEnd() - tmp.getStart();
  711. tcpEV << (i+1) << ". SACK:" << " [" << tmp.getStart() << ".." << tmp.getEnd() << ")\n";
  712. // check for D-SACK
  713. if (i==0 && seqLess(tmp.getEnd(), tcpseg->getAckNo()))
  714. {
  715. // RFC 2883, page 8:
  716. // "In order for the sender to check that the first (D)SACK block of an
  717. // acknowledgement in fact acknowledges duplicate data, the sender
  718. // should compare the sequence space in the first SACK block to the
  719. // cumulative ACK which is carried IN THE SAME PACKET. If the SACK
  720. // sequence space is less than this cumulative ACK, it is an indication
  721. // that the segment identified by the SACK block has been received more
  722. // than once by the receiver. An implementation MUST NOT compare the
  723. // sequence space in the SACK block to the TCP state variable snd.una
  724. // (which carries the total cumulative ACK), as this may result in the
  725. // wrong conclusion if ACK packets are reordered."
  726. tcpEV << "Received D-SACK below cumulative ACK=" << tcpseg->getAckNo() << " D-SACK:" << " [" << tmp.getStart() << ".." << tmp.getEnd() << ")\n";
  727. }
  728. else if (i==0 && seqGE(tmp.getEnd(), tcpseg->getAckNo()) && n>1)
  729. {
  730. // RFC 2883, page 8:
  731. // "If the sequence space in the first SACK block is greater than the
  732. // cumulative ACK, then the sender next compares the sequence space in
  733. // the first SACK block with the sequence space in the second SACK
  734. // block, if there is one. This comparison can determine if the first
  735. // SACK block is reporting duplicate data that lies above the cumulative
  736. // ACK."
  737. Sack tmp2;
  738. tmp2.setStart(option.getValues(2));
  739. tmp2.setEnd(option.getValues(3));
  740. if (seqGE(tmp.getStart(), tmp2.getStart()) && seqLE(tmp.getEnd(), tmp2.getEnd()))
  741. {tcpEV << "Received D-SACK above cumulative ACK=" << tcpseg->getAckNo() << " D-SACK:" << " [" << tmp.getStart() << ".." << tmp.getEnd() << ") SACK:" << " [" << tmp2.getStart() << ".." << tmp2.getEnd() << ")\n";}
  742. }
  743. // splitt sack_range to smss_sized pieces
  744. uint32 tmp_sack_range = sack_range;
  745. uint32 counter = 1; // at least one piece has been received
  746. while (tmp_sack_range > state->snd_mss) // to check how many smss_sized pieces are covered by this single sack_range
  747. {
  748. tmp_sack_range = tmp_sack_range - state->snd_mss;
  749. counter++;
  750. }
  751. // find smss_sized_sack in send queue and set "sacked" bit
  752. uint32 mss_sized_sack = tmp.getStart();
  753. for (uint j=0;j<counter;j++)
  754. {
  755. if (j+1==counter) // the last part does not need to be smss_sized (nagle off)
  756. {
  757. if (seqGE(mss_sized_sack,state->snd_una))
  758. rexmitQueue->setSackedBit(mss_sized_sack,mss_sized_sack+tmp_sack_range);
  759. else
  760. tcpEV << "Received old sack. Sacked segment number is below snd_una\n";
  761. }
  762. else
  763. {
  764. if (seqGE(mss_sized_sack,state->snd_una))
  765. rexmitQueue->setSackedBit(mss_sized_sack,mss_sized_sack+state->snd_mss);
  766. else
  767. tcpEV << "Received old sack. Sacked segment number is below snd_una\n";
  768. }
  769. mss_sized_sack = mss_sized_sack + state->snd_mss;
  770. }
  771. }
  772. state->rcv_sacks = state->rcv_sacks + n; // total counter, no current number
  773. if (rcvSacksVector)
  774. rcvSacksVector->record(state->rcv_sacks);
  775. // update scoreboard
  776. state->sackedBytes_old = state->sackedBytes; // needed for RFC 3042 to check if last dupAck contained new sack information
  777. state->sackedBytes = rexmitQueue->getTotalAmountOfSackedBytes();
  778. if (sackedBytesVector)
  779. sackedBytesVector->record(state->sackedBytes);
  780. }
  781. }
  782. else
  783. tcpEV << "ERROR: " << (length/2) << ". SACK(s) received, but sack_enabled is set to " << state->sack_enabled << "\n";
  784. }
  785. break;
  786. }
  787. // TODO add new TCPOptions here once they are implemented
  788. // TODO delegate to TCPAlgorithm as well -- it may want to recognized additional options
  789. default:
  790. {
  791. lengthMatched = true;
  792. tcpEV << "ERROR: Received option of kind " << kind << " with length " << length << " which is currently not supported\n";
  793. break;
  794. }
  795. }
  796. if (!lengthMatched)
  797. tcpEV << "ERROR: Received option of kind " << kind << " with incorrect length " << length << "\n";
  798. }
  799. }
  800. TCPSegment TCPConnection::writeHeaderOptions(TCPSegment *tcpseg)
  801. {
  802. TCPOption option;
  803. int t = 0;
  804. if (tcpseg->getSynBit() && (fsm.getState() == TCP_S_INIT || fsm.getState() == TCP_S_LISTEN || ((fsm.getState()==TCP_S_SYN_SENT || fsm.getState()==TCP_S_SYN_RCVD) && state->syn_rexmit_count>0))) // SYN flag set and connetion in INIT or LISTEN state (or after synRexmit timeout)
  805. {
  806. // MSS header option
  807. if (state->snd_mss > 0)
  808. {
  809. option.setKind(TCPOPTION_MAXIMUM_SEGMENT_SIZE); // MSS
  810. option.setLength(4);
  811. option.setValuesArraySize(1);
  812. // Update MSS
  813. option.setValues(0,state->snd_mss);
  814. tcpEV << "TCP Header Option MSS(=" << state->snd_mss << ") sent\n";
  815. tcpseg->setOptionsArraySize(tcpseg->getOptionsArraySize()+1);
  816. tcpseg->setOptions(t,option);
  817. t++;
  818. }
  819. // SACK_PERMITTED header option
  820. if (state->sack_support) // Is SACK supported by host?
  821. {
  822. // 2 padding bytes
  823. option.setKind(TCPOPTION_NO_OPERATION); // NOP
  824. option.setLength(1);
  825. option.setValuesArraySize(0);
  826. tcpseg->setOptionsArraySize(tcpseg->getOptionsArraySize()+2);
  827. tcpseg->setOptions(t,option);
  828. t++;
  829. tcpseg->setOptions(t,option);
  830. t++;
  831. option.setKind(TCPOPTION_SACK_PERMITTED);
  832. option.setLength(2);
  833. option.setValuesArraySize(0);
  834. // Update SACK variable
  835. state->snd_sack_perm = true;
  836. state->sack_enabled = state->sack_support && state->snd_sack_perm && state->rcv_sack_perm;
  837. tcpEV << "TCP Header Option SACK_PERMITTED sent, SACK (sack_enabled) is set to: " << state->sack_enabled << "\n";
  838. tcpseg->setOptionsArraySize(tcpseg->getOptionsArraySize()+1);
  839. tcpseg->setOptions(t,option);
  840. t++;
  841. }
  842. // TODO add new TCPOptions here once they are implemented
  843. }
  844. else if (fsm.getState()==TCP_S_SYN_RCVD || fsm.getState()==TCP_S_ESTABLISHED || fsm.getState()==TCP_S_FIN_WAIT_1 || fsm.getState()==TCP_S_FIN_WAIT_2) // connetion is not in INIT or LISTEN state
  845. {
  846. // SACK header option
  847. // RFC 2018, page 4:
  848. // "If sent at all, SACK options SHOULD be included in all ACKs which do
  849. // not ACK the highest sequence number in the data receiver's queue. In
  850. // this situation the network has lost or mis-ordered data, such that
  851. // the receiver holds non-contiguous data in its queue. RFC 1122,
  852. // Section 4.2.2.21, discusses the reasons for the receiver to send ACKs
  853. // in response to additional segments received in this state. The
  854. // receiver SHOULD send an ACK for every valid segment that arrives
  855. // containing new data, and each of these "duplicate" ACKs SHOULD bear a
  856. // SACK option."
  857. if (state->sack_enabled && (state->snd_sack || state->snd_dsack))
  858. {
  859. // 2 padding bytes
  860. option.setKind(TCPOPTION_NO_OPERATION); // NOP
  861. option.setLength(1);
  862. option.setValuesArraySize(0);
  863. tcpseg->setOptionsArraySize(tcpseg->getOptionsArraySize()+2);
  864. tcpseg->setOptions(t,option);
  865. t++;
  866. tcpseg->setOptions(t,option);
  867. t++;
  868. addSacks(tcpseg);
  869. t++;
  870. }
  871. // TODO add new TCPOptions here once they are implemented
  872. // TODO delegate to TCPAlgorithm as well -- it may want to append additional options
  873. }
  874. if (tcpseg->getOptionsArraySize() != 0)
  875. {
  876. uint options_len = 0;
  877. for (uint i=0; i<tcpseg->getOptionsArraySize(); i++)
  878. options_len = options_len + tcpseg->getOptions(i).getLength();
  879. if (options_len <= 40) // Options length allowed? - maximum: 40 Bytes
  880. tcpseg->setHeaderLength(TCP_HEADER_OCTETS+options_len); // TCP_HEADER_OCTETS = 20
  881. else
  882. {
  883. tcpseg->setHeaderLength(TCP_HEADER_OCTETS); // TCP_HEADER_OCTETS = 20
  884. tcpseg->setOptionsArraySize(0); // drop all options
  885. tcpEV << "ERROR: Options length exceeded! Segment will be sent without options" << "\n";
  886. }
  887. }
  888. return *tcpseg;
  889. }
  890. TCPSegment TCPConnection::addSacks(TCPSegment *tcpseg)
  891. {
  892. TCPOption option;
  893. uint options_len = 0;
  894. uint used_options_len = 0;
  895. uint m = 0; // number of sack blocks to be sent in current segment
  896. uint n = 0; // number of sack blocks in sacks_array before sending current segment
  897. bool skip_sacks_array = false; // set if dsack is subsets of a bigger sack block recently reported
  898. bool overlap = false; // set if recently reported sack blocks are subsets of "sacks_array[0]"
  899. uint32 start = state->start_seqno;
  900. uint32 end = state->end_seqno;
  901. ASSERT(start!=0 || end!=0);
  902. // delete old sacks (below rcv_nxt), delete duplicates and print previous status of sacks_array:
  903. tcpEV << "Previous status of sacks_array: \n";
  904. for (int a=0; a<MAX_SACK_BLOCKS; a++) // MAX_SACK_BLOCKS is set to 60
  905. {
  906. if (state->sacks_array[a].getStart()!=0 && seqLE(state->sacks_array[a].getEnd(), state->rcv_nxt))
  907. {
  908. state->sacks_array[a].setStart(0);
  909. state->sacks_array[a].setEnd(0);
  910. }
  911. if (state->sacks_array[a].getStart()!=0 && state->sacks_array[a].getEnd()!=0) // do not print empty entries
  912. tcpEV << "\t" << (a+1) << ". SACK in sacks_array:" << " [" << state->sacks_array[a].getStart() << ".." << state->sacks_array[a].getEnd() << ")\n";
  913. else
  914. break;
  915. }
  916. for (uint a=0; a<MAX_SACK_BLOCKS-1; a++)
  917. {
  918. if (state->sacks_array[a].getStart() != 0)
  919. m++;
  920. else
  921. break;
  922. }
  923. n = m + 1; // +1 for new the new sack block
  924. // 2 padding bytes are prefixed
  925. if (tcpseg->getOptionsArraySize()>0)
  926. {
  927. for (uint i=0; i<tcpseg->getOptionsArraySize(); i++)
  928. used_options_len = used_options_len + tcpseg->getOptions(i).getLength();
  929. if (used_options_len>30)
  930. {
  931. tcpEV << "ERROR: Failed to addSacks - at least 10 free bytes needed for SACK - used_options_len=" << used_options_len << "\n";
  932. //reset flags:
  933. skip_sacks_array = false;
  934. state->snd_sack = false;
  935. state->snd_dsack = false;
  936. state->start_seqno = 0;
  937. state->end_seqno = 0;
  938. return *tcpseg;
  939. }
  940. else
  941. {
  942. n = std::min (n, (((40-used_options_len)-2)/8));
  943. option.setValuesArraySize(n*2);
  944. }
  945. }
  946. else
  947. {
  948. n = std::min (n, MAX_SACK_ENTRIES);
  949. option.setValuesArraySize(n*2);
  950. }
  951. // before adding a new sack move old sacks by one to the right
  952. for (int a=(MAX_SACK_BLOCKS-1); a>=0; a--) // MAX_SACK_BLOCKS is set to 60
  953. state->sacks_array[a+1] = state->sacks_array[a];
  954. if (state->snd_dsack) // SequenceNo < rcv_nxt
  955. {
  956. // RFC 2883, page 3:
  957. // "(3) The left edge of the D-SACK block specifies the first sequence
  958. // number of the duplicate contiguous sequence, and the right edge of
  959. // the D-SACK block specifies the sequence number immediately following
  960. // the last sequence in the duplicate contiguous sequence."
  961. if (seqLess(start, state->rcv_nxt) && seqLess(state->rcv_nxt, end))
  962. end = state->rcv_nxt;
  963. }
  964. else if (start==0 && end==0) // rcv_nxt_old != rcv_nxt
  965. {
  966. // RFC 2018, page 4:
  967. // "* The first SACK block (i.e., the one immediately following the
  968. // kind and length fields in the option) MUST specify the contiguous
  969. // block of data containing the segment which triggered this ACK,
  970. // unless that segment advanced the Acknowledgment Number field in
  971. // the header. This assures that the ACK with the SACK option
  972. // reflects the most recent change in the data receiver's buffer
  973. // queue."
  974. start = state->sacks_array[0].getStart();
  975. end = state->sacks_array[0].getEnd();
  976. }
  977. else // rcv_nxt_old == rcv_nxt or end <= rcv_nxt
  978. {
  979. // RFC 2018, page 4:
  980. // "* The first SACK block (i.e., the one immediately following the
  981. // kind and length fields in the option) MUST specify the contiguous
  982. // block of data containing the segment which triggered this ACK,"
  983. start = receiveQueue->getLE(start);
  984. end = receiveQueue->getRE(end);
  985. }
  986. state->sacks_array[0].setStart(start);
  987. state->sacks_array[0].setEnd(end);
  988. // RFC 2883, page 3:
  989. // "(4) If the D-SACK block reports a duplicate contiguous sequence from
  990. // a (possibly larger) block of data in the receiver's data queue above
  991. // the cumulative acknowledgement, then the second SACK block in that
  992. // SACK option should specify that (possibly larger) block of data.
  993. //
  994. // (5) Following the SACK blocks described above for reporting duplicate
  995. // segments, additional SACK blocks can be used for reporting additional
  996. // blocks of data, as specified in RFC 2018."
  997. if (state->snd_dsack)
  998. {
  999. uint32 start_new = receiveQueue->getLE(start);
  1000. uint32 end_new = receiveQueue->getRE(end);
  1001. if (start_new != start || end_new != end)
  1002. {
  1003. skip_sacks_array = true;
  1004. for (int a=(MAX_SACK_BLOCKS-1); a>=1; a--) // MAX_SACK_BLOCKS is set to 60
  1005. state->sacks_array[a+1] = state->sacks_array[a];
  1006. state->sacks_array[1].setStart(start_new); // specifies larger block of data
  1007. state->sacks_array[1].setEnd(end_new); // specifies larger block of data
  1008. }
  1009. }
  1010. // RFC 2018, page 4:
  1011. // "* The SACK option SHOULD be filled out by repeating the most
  1012. // recently reported SACK blocks (based on first SACK blocks in
  1013. // previous SACK options) that are not subsets of a SACK block
  1014. // already included in the SACK option being constructed."
  1015. // check if recently reported SACK blocks are subsets of "sacks_array[0]"
  1016. for (uint a=0; a<MAX_SACK_BLOCKS-1; a++)
  1017. {
  1018. uint i = 1;
  1019. bool matched = false;
  1020. if (a==0 && skip_sacks_array)
  1021. a = 1;
  1022. if (state->sacks_array[a+i].getStart() == 0)
  1023. break;
  1024. while ((state->sacks_array[a].getStart() == state->sacks_array[a+i].getStart() ||
  1025. state->sacks_array[a].getEnd() == state->sacks_array[a+i].getStart() ||
  1026. state->sacks_array[a].getEnd() == state->sacks_array[a+i].getEnd())
  1027. && a+i < MAX_SACK_BLOCKS && state->sacks_array[a].getStart()!=0) // MAX_SACK_BLOCKS is set to 60
  1028. {
  1029. matched = true;
  1030. i++;
  1031. overlap = true;
  1032. }
  1033. if (matched)
  1034. state->sacks_array[a+1] = state->sacks_array[a+i];
  1035. }
  1036. if (!skip_sacks_array && overlap && m<4)
  1037. n--;
  1038. option.setKind(TCPOPTION_SACK);
  1039. option.setLength(8*n+2);
  1040. option.setValuesArraySize(2*n);
  1041. // write sacks from sacks_array to options
  1042. uint counter = 0;
  1043. for (uint a=0; a<n; a++)
  1044. {
  1045. option.setValues(counter,state->sacks_array[a].getStart());
  1046. counter++;
  1047. option.setValues(counter,state->sacks_array[a].getEnd());
  1048. counter++;
  1049. }
  1050. // independent of "n" we always need 2 padding bytes (NOP) to make: (used_options_len % 4 == 0)
  1051. options_len = used_options_len + 8*n + 2; // 8 bytes for each SACK (n) + 2 bytes for kind&length
  1052. if (options_len <= 40) // Options length allowed? - maximum: 40 Bytes
  1053. {
  1054. tcpseg->setOptionsArraySize(tcpseg->getOptionsArraySize()+1);
  1055. tcpseg->setOptions((tcpseg->getOptionsArraySize()-1),option);
  1056. // update number of sent sacks
  1057. state->snd_sacks = state->snd_sacks+n;
  1058. if (sndSacksVector)
  1059. sndSacksVector->record(state->snd_sacks);
  1060. uint counter = 0;
  1061. tcpEV << n << " SACK(s) added to header:\n";
  1062. for (uint t=0; t<(n*2); t++)
  1063. {
  1064. counter++;
  1065. tcpEV << counter << ". SACK:" << " [" << option.getValues(t);
  1066. t++;
  1067. tcpEV << ".." << option.getValues(t) << ")";
  1068. if (t==1)
  1069. {
  1070. if (state->snd_dsack)
  1071. tcpEV << " (D-SACK)";
  1072. else if (seqLE(option.getValues(t),state->rcv_nxt))
  1073. {
  1074. tcpEV << " (received segment filled out a gap)";
  1075. state->snd_dsack = true; // Note: Set snd_dsack to delete first sack from sacks_array
  1076. }
  1077. }
  1078. tcpEV << "\n";
  1079. }
  1080. }
  1081. else
  1082. tcpEV << "ERROR: Option length exceeded! Segment will be sent without SACK(s)" << "\n";
  1083. // RFC 2883, page 3:
  1084. // "(1) A D-SACK block is only used to report a duplicate contiguous
  1085. // sequence of data received by the receiver in the most recent packet.
  1086. //
  1087. // (2) Each duplicate contiguous sequence of data received is reported
  1088. // in at most one D-SACK block. (I.e., the receiver sends two identical
  1089. // D-SACK blocks in subsequent packets only if the receiver receives two
  1090. // duplicate segments.)//
  1091. //
  1092. // In case of d-sack: delete first sack (d-sack) and move old sacks by one to the left
  1093. if (state->snd_dsack)
  1094. {
  1095. for (int a=1; a<MAX_SACK_BLOCKS; a++) // MAX_SACK_BLOCKS is set to 60
  1096. state->sacks_array[a-1] = state->sacks_array[a];
  1097. // delete/reset last sack to avoid duplicates
  1098. state->sacks_array[MAX_SACK_BLOCKS-1].setStart(0);
  1099. state->sacks_array[MAX_SACK_BLOCKS-1].setEnd(0);
  1100. }
  1101. // reset flags:
  1102. skip_sacks_array = false;
  1103. state->snd_sack = false;
  1104. state->snd_dsack = false;
  1105. state->start_seqno = 0;
  1106. state->end_seqno = 0;
  1107. return *tcpseg;
  1108. }
  1109. void TCPConnection::updateRcvQueueVars()
  1110. {
  1111. // update receive queue related state variables
  1112. state->freeRcvBuffer = receiveQueue->getAmountOfFreeBytes(state->maxRcvBuffer);
  1113. state->usedRcvBuffer = state->maxRcvBuffer - state->freeRcvBuffer;
  1114. // update receive queue related statistics
  1115. if (tcpRcvQueueBytesVector)
  1116. tcpRcvQueueBytesVector->record(state->usedRcvBuffer);
  1117. tcpEV << "receiveQ: receiveQLength=" << receiveQueue->getQueueLength() << " maxRcvBuffer=" << state->maxRcvBuffer << " usedRcvBuffer=" << state->usedRcvBuffer << " freeRcvBuffer=" << state->freeRcvBuffer << "\n";
  1118. }
  1119. void TCPConnection::updateRcvWnd()
  1120. {
  1121. uint32 win = 0;
  1122. // update receive queue related state variables and statistics
  1123. updateRcvQueueVars();
  1124. win = state->freeRcvBuffer;
  1125. // Following lines are based on [Stevens, W.R.: TCP/IP Illustrated, Volume 2, pages 878-879]:
  1126. // Don't advertise less than one full-sized segment to avoid SWS
  1127. if (win < (state->maxRcvBuffer / 4) && win < state->snd_mss)
  1128. win = 0;
  1129. // Do not shrink window
  1130. // (rcv_adv minus rcv_nxt) is the amount of space still available to the sender that was previously advertised
  1131. if (win < state->rcv_adv - state->rcv_nxt)
  1132. win = state->rcv_adv - state->rcv_nxt;
  1133. // Observe upper limit for advertised window on this connection
  1134. if (win > TCP_MAX_WIN) // TCP_MAX_WIN = 65…

Large files files are truncated, but you can click here to view the full file