39 #include "IPDatagram_m.h"
40 #include "TCPSegment.h"
42 #include "TCPCommand_m.h"
43 #include "IPControlInfo.h"
44 #include "IPv6ControlInfo.h"
45 #include "ICMPMessage_m.h"
46 #include "ICMPv6Message_m.h"
47 #include "IPAddressResolver.h"
48 #include "TCPSendQueue.h"
49 #include "TCPSACKRexmitQueue.h"
50 #include "TCPReceiveQueue.h"
51 #include "TCPAlgorithm.h"
53 #define EPHEMERAL_PORTRANGE_START 1024
54 #define EPHEMERAL_PORTRANGE_END 5000
60 static std::ostream&
operator<<(std::ostream& os,
const TCP::SockPair& sp)
62 os <<
"loc=" << IPvXAddress(sp.localAddr) <<
":" << sp.localPort <<
" "
63 <<
"rem=" << IPvXAddress(sp.remoteAddr) <<
":" << sp.remotePort;
67 static std::ostream&
operator<<(std::ostream& os,
const TCP::AppConnKey& app)
69 os <<
"connId=" << app.connId <<
" appGateIndex=" << app.appGateIndex;
73 static std::ostream&
operator<<(std::ostream& os,
const TCPConnection& conn)
75 os <<
"connId=" << conn.connId <<
" " << TCPConnection::stateName(conn.getFsmState())
76 <<
" state={" << const_cast<TCPConnection&>(conn).getState()->info() <<
"}";
84 WATCH(lastEphemeralPort);
86 WATCH_PTRMAP(tcpConnMap);
87 WATCH_PTRMAP(tcpAppConnMap);
89 recordStatistics = par(
"recordStats");
91 cModule *netw = simulation.getSystemModule();
92 testing = netw->hasPar(
"testing") && netw->par(
"testing").boolValue();
93 logverbose = !testing && netw->hasPar(
"logverbose") && netw->par(
"logverbose").boolValue();
145 if (msg->isSelfMessage())
148 bool ret = conn->processTimer(msg);
150 removeConnection(conn);
152 else if (msg->arrivedOn(
"ipIn") || msg->arrivedOn(
"ipv6In"))
154 if (dynamic_cast<ICMPMessage *>(msg) ||
dynamic_cast<ICMPv6Message *
>(msg))
156 tcpEV <<
"ICMP error received -- discarding\n";
162 TCPSegment *tcpseg = check_and_cast<TCPSegment *>(msg);
165 IPvXAddress srcAddr, destAddr;
166 if (dynamic_cast<IPControlInfo *>(tcpseg->getControlInfo())!=NULL)
168 IPControlInfo *controlInfo = (IPControlInfo *)tcpseg->removeControlInfo();
169 srcAddr = controlInfo->getSrcAddr();
170 destAddr = controlInfo->getDestAddr();
173 else if (dynamic_cast<IPv6ControlInfo *>(tcpseg->getControlInfo())!=NULL)
175 IPv6ControlInfo *controlInfo = (IPv6ControlInfo *)tcpseg->removeControlInfo();
176 srcAddr = controlInfo->getSrcAddr();
177 destAddr = controlInfo->getDestAddr();
182 error(
"(%s)%s arrived without control info", tcpseg->getClassName(), tcpseg->getName());
190 bool ret = conn->processTCPSegment(tcpseg, srcAddr, destAddr);
192 removeConnection(conn);
202 TCPCommand *controlInfo = check_and_cast<TCPCommand *>(msg->getControlInfo());
203 int appGateIndex = msg->getArrivalGate()->getIndex();
204 int connId = controlInfo->getConnId();
215 key.appGateIndex = appGateIndex;
217 tcpAppConnMap[key] = conn;
219 tcpEV <<
"TCP connection created for " << msg <<
"\n";
221 bool ret = conn->processAppCommand(msg);
223 removeConnection(conn);
227 updateDisplayString();
243 tmp->segmentArrivalWhileClosed(tcpseg, srcAddr, destAddr);
253 const char *sendQueueClass = sendQueue->getClassName();
254 conn->sendQueue = check_and_cast<TCPSendQueue *>(createOne(sendQueueClass));
255 conn->sendQueue->setConnection(conn);
257 const char *receiveQueueClass = receiveQueue->getClassName();
258 conn->receiveQueue = check_and_cast<TCPReceiveQueue *>(createOne(receiveQueueClass));
259 conn->receiveQueue->setConnection(conn);
262 rexmitQueue =
new TCPSACKRexmitQueue();
263 rexmitQueue->setConnection(
this);
265 const char *tcpAlgorithmClass = tcpAlgorithm->getClassName();
266 conn->tcpAlgorithm = check_and_cast<TCPAlgorithm *>(createOne(tcpAlgorithmClass));
267 conn->tcpAlgorithm->setConnection(conn);
269 conn->state = conn->tcpAlgorithm->getStateVariables();
270 configureStateVariables();
271 conn->tcpAlgorithm->initialize();
274 conn->state->active =
false;
275 conn->state->fork =
true;
276 conn->localAddr = localAddr;
277 conn->localPort = localPort;
278 FSM_Goto(conn->fsm, TCP_S_LISTEN);
286 TCPSegment *tcpseg = createTCPSegment(
"RST");
288 tcpseg->setSrcPort(srcPort);
289 tcpseg->setDestPort(destPort);
291 tcpseg->setRstBit(
true);
292 tcpseg->setSequenceNo(seq);
300 TCPSegment *tcpseg = createTCPSegment(
"RST+ACK");
302 tcpseg->setSrcPort(srcPort);
303 tcpseg->setDestPort(destPort);
305 tcpseg->setRstBit(
true);
306 tcpseg->setAckBit(
true);
307 tcpseg->setSequenceNo(seq);
308 tcpseg->setAckNo(ack);
318 if (sndNxtVector && tcpseg->getPayloadLength()!=0)
319 sndNxtVector->record(tcpseg->getSequenceNo());
321 sndAckVector->record(tcpseg->getAckNo());
324 tcpseg->setSrcPort(localPort);
325 tcpseg->setDestPort(remotePort);
326 ASSERT(tcpseg->getHeaderLength() >= TCP_HEADER_OCTETS);
327 ASSERT(tcpseg->getHeaderLength() <= TCP_MAX_HEADER_OCTETS);
330 int ipHeaderBytes = 0;
331 if (remoteAddr.isIPv6()) {
334 ipHeaderBytes = IP_HEADER_BYTES;
336 tcpseg->setByteLength(tcpseg->getHeaderLength() +
337 tcpseg->getPayloadLength() + ipHeaderBytes);
339 tcpEV <<
"Sending: ";
340 printSegmentBrief(tcpseg);
347 const IPvXAddress& src = IPAddressResolver().addressOf(tcpMain->getParentModule());
349 const IPvXAddress& dest = remoteAddr;
355 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
356 <<
" No route to host " << dest
367 simtime_t totalDelay = 0;
380 }
else if (temp.second ==
false) {
381 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
382 <<
" Send queue full: packet " << tcpseg <<
" dropped"
388 totalDelay = temp.first;
395 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
397 <<
" is not connected"
409 double temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.
jitter);
410 while (temp == INFINITY || temp != temp) {
411 std::cerr <<
"\n******* SimpleTCPConnection: truncnormal() -> inf !!\n"
413 temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.
jitter);
421 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
422 <<
" Packet " << tcpseg <<
" sent with delay = " << totalDelay
430 if (!remoteAddr.isIPv6())
433 IPControlInfo *controlInfo =
new IPControlInfo();
434 controlInfo->setProtocol(IP_PROT_TCP);
435 controlInfo->setSrcAddr(src.get4());
436 controlInfo->setDestAddr(dest.get4());
437 tcpseg->setControlInfo(controlInfo);
439 tcpMain->sendDirect(tcpseg, totalDelay, 0, destEntry->
getTcpIPv4Gate());
444 IPv6ControlInfo *controlInfo =
new IPv6ControlInfo();
445 controlInfo->setProtocol(IP_PROT_TCP);
446 controlInfo->setSrcAddr(src.get6());
447 controlInfo->setDestAddr(dest.get6());
448 tcpseg->setControlInfo(controlInfo);
450 tcpMain->sendDirect(tcpseg, totalDelay, 0, destEntry->
getTcpIPv6Gate());
464 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
465 <<
" No route to host " << dest
476 simtime_t totalDelay = 0;
489 }
else if (temp.second ==
false) {
490 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
491 <<
" Send queue full: packet " << tcpseg <<
" dropped"
497 totalDelay = temp.first;
504 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
506 <<
" is not connected"
518 double temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.
jitter);
519 while (temp == INFINITY || temp != temp) {
520 std::cerr <<
"\n******* SimpleTCPConnection: truncnormal() -> inf !!\n"
522 temp = truncnormal(0, SIMTIME_DBL(totalDelay) * sad.
jitter);
530 EV <<
"[SimpleTCPConnection::sendToIP() @ " << src <<
"]\n"
531 <<
" Packet " << tcpseg <<
" sent with delay = " << totalDelay
539 tcpEV <<
"Sending: ";
540 printSegmentBrief(tcpseg);
545 IPControlInfo *controlInfo =
new IPControlInfo();
546 controlInfo->setProtocol(IP_PROT_TCP);
547 controlInfo->setSrcAddr(src.get4());
548 controlInfo->setDestAddr(dest.get4());
549 tcpseg->setControlInfo(controlInfo);
551 check_and_cast<TCP *>(simulation.getContextModule())->sendDirect(tcpseg, totalDelay, 0, destEntry->
getTcpIPv4Gate());
556 IPv6ControlInfo *controlInfo =
new IPv6ControlInfo();
557 controlInfo->setProtocol(IP_PROT_TCP);
558 controlInfo->setSrcAddr(src.get6());
559 controlInfo->setDestAddr(dest.get6());
560 tcpseg->setControlInfo(controlInfo);
562 check_and_cast<TCP *>(simulation.getContextModule())->sendDirect(tcpseg, totalDelay, 0, destEntry->
getTcpIPv6Gate());