INET Framework for OMNeT++/OMNEST
inet::SctpNatServer Class Reference

#include <SctpNatServer.h>

Inheritance diagram for inet::SctpNatServer:
inet::LifecycleUnsupported inet::ILifecycle

Classes

struct  pathStatus
 

Public Member Functions

void initialize (int stage) override
 
virtual int numInitStages () const override
 
void handleMessage (cMessage *msg) override
 
void finish () override
 
void handleTimer (cMessage *msg)
 
void generateAndSend ()
 
void sendInfo (NatInfo *info)
 
void printNatVector ()
 
- Public Member Functions inherited from inet::LifecycleUnsupported
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Attributes

int32_t notifications
 
uint32_t assocId
 
SctpSocketsocket
 
bool shutdownReceived
 
int64_t bytesSent
 
int32_t packetsSent
 
int32_t packetsRcvd
 
int32_t numSessions
 
int32_t numRequestsToSend
 
bool ordered
 
int32_t outboundStreams
 
int32_t inboundStreams
 
int32_t lastStream
 
int32_t ssn
 

Static Protected Attributes

static NatVector natVector
 

Member Function Documentation

◆ finish()

void inet::SctpNatServer::finish ( )
override
510 {
511  EV << getFullPath() << ": opened " << numSessions << " sessions\n";
512  EV << getFullPath() << ": sent " << bytesSent << " bytes in " << packetsSent << " packets\n";
513 
514  EV << getFullPath() << "Over all " << packetsRcvd << " packets received\n ";
515  EV << getFullPath() << "Over all " << notifications << " notifications received\n ";
516 }

◆ generateAndSend()

void inet::SctpNatServer::generateAndSend ( )
161 {
162  auto cmsg = new Packet("ApplicationPacket", SCTP_C_SEND);
163  auto msg = makeShared<BytesChunk>();
164  int numBytes = par("requestLength");
165  std::vector<uint8_t> vec;
166  vec.resize(numBytes);
167  for (int i = 0; i < numBytes; i++)
168  vec[i] = (numBytes + i) & 0xFF;
169  msg->setBytes(vec);
170  cmsg->insertAtBack(msg);
171 
172  auto cmd = cmsg->addTag<SctpSendReq>();
173  cmd->setSocketId(assocId);
174  cmd->setSendUnordered(ordered ? COMPLETE_MESG_ORDERED : COMPLETE_MESG_UNORDERED);
176  cmd->setSid(lastStream);
177  cmd->setLast(true);
178  packetsSent++;
179  bytesSent += numBytes;
180  send(cmsg, "socketOut");
181 }

◆ handleMessage()

void inet::SctpNatServer::handleMessage ( cMessage *  msg)
override
184 {
185  int32_t id;
186 
187  if (msg->isSelfMessage()) {
188  handleTimer(msg);
189  }
190  else {
191  EV << "SctpNatServer::handleMessage kind=" << SctpAssociation::indicationName(msg->getKind()) << " (" << msg->getKind() << ")\n";
192  switch (msg->getKind()) {
193  case SCTP_I_PEER_CLOSED:
194  case SCTP_I_ABORT: {
195  Message *message = check_and_cast<Message *>(msg);
196  assocId = message->getTag<SocketInd>()->getSocketId();
197  auto& indtags = message->getTags();
198  const auto& ind = indtags.findTag<SctpCommandReq>();
199 
200  Request *cmsg = new Request("SCTP_C_ABORT", SCTP_C_ABORT);
201  auto& cmd = cmsg->addTag<SctpSendReq>();
202 
203  id = ind->getSocketId();
204  cmd->setSocketId(id);
205  cmd->setSid(ind->getSid());
206  cmd->setNumMsgs(ind->getNumMsgs());
207  delete msg;
208  send(cmsg, "socketOut");
209  break;
210  }
211 
212  case SCTP_I_ESTABLISHED: {
213  Message *message = check_and_cast<Message *>(msg);
214  auto& tags = message->getTags();
215  const auto& connectInfo = tags.findTag<SctpConnectReq>();
216  numSessions++;
217  assocId = connectInfo->getSocketId();
218  id = assocId;
219  inboundStreams = connectInfo->getInboundStreams();
220  outboundStreams = connectInfo->getOutboundStreams();
221 
222  delete msg;
223 
224  break;
225  }
226 
227  case SCTP_I_AVAILABLE: {
228  EV_DETAIL << "SCTP_I_AVAILABLE arrived at server\n";
229  Message *message = check_and_cast<Message *>(msg);
230  int newSockId = message->getTag<SctpAvailableReq>()->getNewSocketId();
231  EV_DETAIL << "new socket id = " << newSockId << endl;
232  Request *cmsg = new Request("SCTP_C_ACCEPT_SOCKET_ID", SCTP_C_ACCEPT_SOCKET_ID);
233  cmsg->addTag<SctpAvailableReq>()->setSocketId(newSockId);
234  cmsg->addTag<DispatchProtocolReq>()->setProtocol(&Protocol::sctp);
235  cmsg->addTag<SocketReq>()->setSocketId(newSockId);
236  EV_INFO << "Sending accept socket id request ..." << endl;
237 
238  send(cmsg, "socketOut");
239  delete msg;
240  break;
241  }
242 
244  EV_DETAIL << "SCTP_I_DATA_NOTIFICATION arrived at server\n";
245  notifications++;
246  Message *message = check_and_cast<Message *>(msg);
247  auto& intags = message->getTags();
248  const auto& ind = intags.findTag<SctpCommandReq>();
249  Request *cmsg = new Request("ReceiveRequest", SCTP_C_RECEIVE);
250  auto cmd = cmsg->addTag<SctpSendReq>();
251  id = ind->getSocketId();
252  cmd->setSocketId(id);
253  cmd->setSid(ind->getSid());
254  cmd->setNumMsgs(ind->getNumMsgs());
255  delete msg;
256  cmsg->addTag<DispatchProtocolReq>()->setProtocol(&Protocol::sctp);
257  cmsg->addTag<SocketReq>()->setSocketId(id);
258  send(cmsg, "socketOut");
259  break;
260  }
261 
262  case SCTP_I_DATA: {
263  EV << "\nData arrived at server: assoc=" << assocId << "\n";
264  printNatVector();
265  Packet *message = check_and_cast<Packet *>(msg);
266  auto& tags = message->getTags();
267  const auto& ind = tags.findTag<SctpRcvReq>();
268  id = ind->getSocketId();
269  const auto& smsg = message->peekDataAsBytes();
270  int bufferlen = B(smsg->getChunkLength()).get();
271  uint8_t buffer[bufferlen];
272  std::vector<uint8_t> vec = smsg->getBytes();
273  for (int i = 0; i < bufferlen; i++) {
274  buffer[i] = vec[i];
275  }
276  struct nat_message *nat = (struct nat_message *)buffer;
277  bool found = false;
278  if (natVector.size() > 0) {
279  for (auto& elem : natVector) {
280  if ((elem)->peer1 == nat->peer1 || (elem)->peer1Assoc == assocId) {
281  EV << "found entry: info: Peer1 = " << nat->peer1 << " peer1Address1=" << nat->peer1Addresses[0] << " peer2=" << nat->peer2 << " peer2Address1=" << nat->peer2Addresses[0] << "\n";
282  if (nat->multi && nat->numAddrPeer1 > 1 && nat->numAddrPeer2 > 1) {
283  EV << " peer1Address2=" << Ipv4Address(nat->peer1Addresses[1]).str() << " peer2Address2=" << Ipv4Address(nat->peer2Addresses[1]).str() << endl;
284  }
285  if ((elem)->peer1 == 0 && !(elem)->peer1Address2.isUnspecified()) {
286  (elem)->peer1 = nat->peer1;
287  (elem)->peer1Address1 = ind->getRemoteAddr();
288  (elem)->peer1Port = nat->portPeer1;
289  if ((elem)->peer2 == 0) {
290  (elem)->peer2 = nat->peer2;
291  }
292  }
293  if (nat->multi && (elem)->peer1Address2.isUnspecified()) {
294  (elem)->peer1Address2 = ind->getRemoteAddr();
295  }
296  if (!(elem)->peer2Address1.isUnspecified() && !(elem)->peer1Address1.isUnspecified()) {
297  if (!(elem)->multi || ((elem)->multi && !(elem)->peer2Address2.isUnspecified() && !(elem)->peer1Address2.isUnspecified())) {
298  EV << "entry now: Peer1=" << (elem)->peer1 << " Peer2=" << (elem)->peer2 << " peer1Address1=" << (elem)->peer1Address1 << " peer1Address2=" << (elem)->peer1Address2 << " peer2Address1=" << (elem)->peer2Address1 << " peer2Address2=" << (elem)->peer2Address2 << " peer2Port=" << (elem)->peer2Port << "\n";
299  sendInfo((elem));
300  }
301  }
302  found = true;
303  break;
304  }
305  if ((elem)->peer2 == nat->peer1 || (elem)->peer2Assoc == assocId) {
306  EV << "opposite way: info: Peer1 = " << nat->peer1 << " peer1Address1=" << Ipv4Address(nat->peer1Addresses[0]).str() << " peer2=" << nat->peer2 << " peer2Address1=" << Ipv4Address(nat->peer2Addresses[0]).str() << "\n";
307  if (nat->multi && nat->numAddrPeer1 > 1 && nat->numAddrPeer2 > 1) {
308  EV << " peer1Address2=" << Ipv4Address(nat->peer1Addresses[1]).str() << " peer2Address2=" << Ipv4Address(nat->peer2Addresses[1]).str() << endl;
309  }
310  if ((elem)->peer2 == 0) {
311  (elem)->peer2 = nat->peer1;
312  }
313  if ((elem)->peer1 == 0) {
314  (elem)->peer1 = nat->peer2;
315  }
316  if ((elem)->peer2Address1.isUnspecified()) {
317  (elem)->peer2Address1 = ind->getRemoteAddr();
318  (elem)->peer2Assoc = assocId;
319  (elem)->peer2Port = nat->portPeer1;
320  (elem)->peer2Gate = ind->getGate();
321  EV << "set peer2Address1=" << ind->getRemoteAddr() << " peer2Assoc=" << assocId << " peer2Port=" << nat->portPeer1 << "\n";
322  }
323  else if ((elem)->multi && !(elem)->peer2Address2.isUnspecified())
324  (elem)->peer2Address2 = ind->getRemoteAddr();
325 
326  if (!(elem)->multi || ((elem)->multi && !(elem)->peer2Address2.isUnspecified() && !(elem)->peer1Address2.isUnspecified()
327  && !(elem)->peer2Address1.isUnspecified() && !(elem)->peer1Address1.isUnspecified()))
328  {
329  EV << "entry now: Peer1=" << (elem)->peer1 << " Peer2=" << (elem)->peer2 << " peer1Address1=" << (elem)->peer1Address1 << " peer1Address2=" << (elem)->peer1Address2 << " peer2Address1=" << (elem)->peer2Address1 << " peer2Address2=" << (elem)->peer2Address2 << " peer1Port=" << (elem)->peer1Port << " peer2Port=" << (elem)->peer2Port << "\n";
330  sendInfo((elem));
331  }
332  found = true;
333  break;
334  }
335  }
336  }
337  if (natVector.size() == 0 || !found) {
338  EV << "make new Info for ";
339  NatInfo *info = new NatInfo();
340  info->peer1 = nat->peer1;
341  EV << info->peer1 << " and assoc " << assocId << "\n";
342  info->multi = nat->multi;
343  info->peer1Address1 = ind->getRemoteAddr();
344  if (info->multi) {
345  info->peer1Address2 = L3Address();
346  info->peer2Address2 = L3Address();
347  }
348  info->peer1Port = nat->portPeer1;
349  info->peer1Assoc = assocId;
350  info->peer1Gate = ind->getGate();
351  info->peer2 = nat->peer2;
352  info->peer2Address1 = L3Address();
353  info->peer2Port = 0;
354  info->peer2Assoc = 0;
355  info->peer2Gate = -1;
356  natVector.push_back(info);
357  EV << "Info: peer1=" << info->peer1 << " peer1Address1=" << info->peer1Address1 << " peer1Address2=" << info->peer1Address2 << " peer1Assoc=" << info->peer1Assoc << "\n peer2=" << info->peer2 << " peer2Address1=" << info->peer2Address1 << " peer2Address2=" << info->peer2Address2 << " peer2Assoc=" << info->peer2Assoc << "\n";
358  }
359  EV << "\n";
360  printNatVector();
361 
362  delete msg;
363  break;
364  }
365 
367  Message *message = check_and_cast<Message *>(msg);
368  id = message->getTag<SocketInd>()->getSocketId();
369  EV << "server: SCTP_I_SHUTDOWN_RECEIVED for assoc " << id << "\n";
370  Request *cmsg = new Request("SCTP_C_NO_OUTSTANDING", SCTP_C_NO_OUTSTANDING);
371  auto& qinfo = cmsg->addTag<SctpCommandReq>();
372  qinfo->setSocketId(id);
373  send(cmsg, "socketOut");
374 
375 // delete command;
376  shutdownReceived = true;
377  delete msg;
378  break;
379  }
380 
383  EV << "Streams have been resetted\n";
384  delete msg;
385  break;
386  }
387 
388  case SCTP_I_CLOSED:
389  delete msg;
390  break;
391 
392  case SCTP_I_ADDRESS_ADDED: {
393  Message *message = check_and_cast<Message *>(msg);
394  auto& intags = message->getTags();
395  const auto& ind = intags.findTag<SctpCommandReq>();
396  bool found = false;
397  printNatVector();
398  EV << " address added: LOCAL=" << ind->getLocalAddr() << ", remote=" << ind->getRemoteAddr() << " assoc=" << assocId << "\n";
399  if (natVector.size() > 0) {
400  for (auto& elem : natVector) {
401  if ((elem)->peer1Assoc == assocId) {
402  EV << "found entry for assoc1 = " << assocId << " Peer1 = " << (elem)->peer1 << " peer1Address1=" << (elem)->peer1Address1 << " peer1Address2=" << (elem)->peer1Address2 << " peer2=" << (elem)->peer2 << " peer2Address1=" << (elem)->peer2Address1 << " peer2Address2=" << (elem)->peer2Address2 << "\n";
403  if ((elem)->multi && (elem)->peer1Address2.isUnspecified()) {
404  (elem)->peer1Address2 = ind->getRemoteAddr();
405  EV << "added peer1Address2=" << ind->getRemoteAddr() << "\n";
406  }
407  if (!(elem)->peer2Address1.isUnspecified()) {
408  if (!(elem)->multi || ((elem)->multi && !(elem)->peer2Address2.isUnspecified() && !(elem)->peer1Address2.isUnspecified())) {
409  EV << "entry now: Peer1=" << (elem)->peer1 << " Peer2=" << (elem)->peer2 << " peer1Address1=" << (elem)->peer1Address1 << " peer1Address2=" << (elem)->peer1Address2 << " peer2Address1=" << (elem)->peer2Address1 << " peer2Address2=" << (elem)->peer2Address2 << " peer2Port=" << (elem)->peer2Port << "\n";
410  sendInfo((elem));
411  }
412  }
413  found = true;
414  break;
415  }
416  else if ((elem)->peer2Assoc == assocId) {
417  EV << "opposite way: found entry for assoc2 = " << assocId << " peer1Address1=" << (elem)->peer1Address1 << " peer1Address2=" << (elem)->peer1Address2 << " peer2Address1=" << (elem)->peer2Address1 << " peer2Address2=" << (elem)->peer2Address2 << "\n";
418  if ((elem)->multi)
419  (elem)->peer2Address2 = ind->getRemoteAddr();
420 
421  if (!(elem)->multi || ((elem)->multi && !(elem)->peer2Address2.isUnspecified() && !(elem)->peer1Address2.isUnspecified())) {
422  EV << "entry now: Peer1=" << (elem)->peer1 << " Peer2=" << (elem)->peer2 << " peer1Address1=" << (elem)->peer1Address1 << " peer1Address2=" << (elem)->peer1Address2 << " peer2Address1=" << (elem)->peer2Address1 << " peer2Address2=" << (elem)->peer2Address2 << " peer1Port=" << (elem)->peer1Port << "peer2Port=" << (elem)->peer2Port << "\n";
423  sendInfo((elem));
424  }
425  found = true;
426  break;
427  }
428  else if ((elem)->peer2Assoc == 0 && ((elem)->multi)) {
429  (elem)->peer2Address2 = ind->getRemoteAddr();
430  (elem)->peer2Assoc = assocId;
431  (elem)->peer2Port = ind->getRemotePort();
432  (elem)->peer2Gate = ind->getGate();
433  EV << "entry now: Peer1=" << (elem)->peer1 << " Peer2=" << (elem)->peer2 << " peer1Address1=" << (elem)->peer1Address1 << " peer1Address2=" << (elem)->peer1Address2 << " peer2Address1=" << (elem)->peer2Address1 << " peer2Address2=" << (elem)->peer2Address2 << " peer1Port=" << (elem)->peer1Port << "peer2Port=" << (elem)->peer2Port << "\n";
434 
435  found = true;
436  }
437  }
438  }
439  else if (natVector.size() == 0 && !found) {
440  EV << "make new Info for ";
441  NatInfo *info = new NatInfo();
442  info->peer1 = 0;
443  info->peer1Assoc = assocId;
444  EV << info->peer1 << " and assoc " << assocId << "\n";
445  info->multi = 1;
446  info->peer1Address1 = L3Address();
447  info->peer1Address2 = ind->getRemoteAddr();
448  info->peer1Port = ind->getRemotePort();
449  info->peer1Gate = ind->getGate();
450  info->peer2 = 0;
451  info->peer2Address1 = L3Address();
452  info->peer2Address2 = L3Address();
453  info->peer2Port = 0;
454  info->peer2Assoc = 0;
455  info->peer2Gate = -1;
456  natVector.push_back(info);
457  EV << "Info: peer1=" << info->peer1 << " peer1Address1=" << info->peer1Address1 << " peer1Address2=" << info->peer1Address2 << " peer1Assoc=" << info->peer1Assoc << "\n peer2=" << info->peer1 << " peer2Address1=" << info->peer2Address1 << " peer2Address2=" << info->peer2Address2 << " peer2Assoc=" << info->peer2Assoc << "\n";
458  }
459  delete msg;
460  printNatVector();
461  break;
462  }
463 
464  default:
465  EV << "Message type " << SctpAssociation::indicationName(msg->getKind()) << " not implemented\n";
466  delete msg;
467  }
468  }
469 }

◆ handleTimer()

void inet::SctpNatServer::handleTimer ( cMessage *  msg)
472 {
473  int32_t id;
474 
475  switch (msg->getKind()) {
476  case SCTP_C_SEND:
477  if (numRequestsToSend > 0) {
478  generateAndSend();
480  }
481  break;
482 
483  case SCTP_I_ABORT: {
484  Request *cmsg = new Request("SCTP_C_CLOSE", SCTP_C_CLOSE);
485  auto& cmd = cmsg->addTag<SctpCommandReq>();
486  id = atoi(msg->getName());
487  cmd->setSocketId(id);
488  send(cmsg, "socketOut");
489  break;
490  }
491 
492  case SCTP_C_RECEIVE:
493  send(msg, "socketOut");
494  break;
495 
496  default:
497  break;
498  }
499 }

◆ initialize()

void inet::SctpNatServer::initialize ( int  stage)
override
33 {
35  EV_DEBUG << "initialize SCTP NAT Server stage " << stage << endl;
36 
37  cSimpleModule::initialize(stage);
38  if (stage == INITSTAGE_LOCAL) {
39  WATCH(numSessions);
40  WATCH(packetsSent);
41  WATCH(packetsRcvd);
42  WATCH(bytesSent);
43  WATCH(numRequestsToSend);
44  inboundStreams = par("inboundStreams");
45  outboundStreams = par("outboundStreams");
46  }
47  else if (stage == INITSTAGE_APPLICATION_LAYER) {
48  // parameters
49  const char *addressesString = par("localAddress");
50  AddressVector addresses = L3AddressResolver().resolve(cStringTokenizer(addressesString).asVector());
51  int32_t port = par("localPort");
52 
53  ordered = par("ordered");
54  lastStream = 0;
55 
56  socket = new SctpSocket();
57  socket->setOutputGate(gate("socketOut"));
60 
61  if (addresses.size() == 0)
62  socket->bind(port);
63  else
64  socket->bindx(addresses, port);
65  socket->listen(true, false, par("numPacketsToSendPerClient"));
66  EV << "SctpNatServer::initialized listen port=" << port << "\n";
67 
68  shutdownReceived = false;
69  }
70 }

◆ numInitStages()

virtual int inet::SctpNatServer::numInitStages ( ) const
inlineoverridevirtual
69 { return NUM_INIT_STAGES; }

◆ printNatVector()

void inet::SctpNatServer::printNatVector ( )
502 {
503  for (auto& elem : natVector) {
504  EV << "Peer1: " << (elem)->peer1 << " Assoc: " << (elem)->peer1Assoc << " Address1: " << (elem)->peer1Address1 << " Address2: " << (elem)->peer1Address2 << "Port: " << (elem)->peer1Port << endl;
505  EV << "Peer2: " << (elem)->peer2 << " Assoc: " << (elem)->peer2Assoc << " Address1: " << (elem)->peer2Address1 << " Address2: " << (elem)->peer2Address2 << "Port: " << (elem)->peer2Port << endl;
506  }
507 }

◆ sendInfo()

void inet::SctpNatServer::sendInfo ( NatInfo info)
73 {
74  uint8_t buffer[100], buffer2[100];
75  int buflen = 16;
76  struct nat_message *nat = (struct nat_message *)(buffer);
77  nat->peer1 = info->peer1;
78  nat->peer2 = info->peer2;
79  nat->portPeer1 = info->peer1Port;
80  nat->portPeer2 = info->peer2Port;
81  nat->numAddrPeer1 = 2;
82  nat->numAddrPeer2 = 2;
83  nat->multi = info->multi;
84  buflen = ADD_PADDING(buflen + 4 * (nat->numAddrPeer1 + nat->numAddrPeer2));
85  nat->peer1Addresses[0] = info->peer1Address1.toIpv4().getInt();
86  nat->peer1Addresses[1] = info->peer1Address2.toIpv4().getInt();
87  nat->peer2Addresses[0] = info->peer2Address1.toIpv4().getInt();
88  nat->peer2Addresses[1] = info->peer2Address2.toIpv4().getInt();
89 
90  EV << "Info for peer1: peer1-1=" << Ipv4Address(nat->peer1Addresses[0]).str() << " peer2-1=" << Ipv4Address(nat->peer2Addresses[0]).str() << "\n";
91  if (info->multi)
92  EV << " peer1-2=" << Ipv4Address(nat->peer1Addresses[1]).str() << " peer2-2=" << Ipv4Address(nat->peer2Addresses[1]).str() << endl;
93 
94  auto applicationData = makeShared<BytesChunk>(buffer, buflen);
95  applicationData->addTag<CreationTimeTag>()->setCreationTime(simTime());
96  auto applicationPacket = new Packet("ApplicationPacket", SCTP_C_SEND_ORDERED);
97  applicationPacket->insertAtBack(applicationData);
98  auto sctpSendReq = applicationPacket->addTag<SctpSendReq>();
99  sctpSendReq->setLast(true);
100  sctpSendReq->setPrMethod(0);
101  sctpSendReq->setPrValue(0);
102  sctpSendReq->setSid(0);
103  applicationPacket->addTag<DispatchProtocolReq>()->setProtocol(&Protocol::sctp);
104  applicationPacket->addTag<SocketReq>()->setSocketId(info->peer1Assoc);
105  send(applicationPacket, "socketOut");
106  EV << "info sent to peer1\n";
107 
108  EV << "SctpNatServer::shutdown peer1\n";
109 
110  Request *msg = new Request("SHUTDOWN", SCTP_C_SHUTDOWN);
111  auto& cmd = msg->addTag<SctpCommandReq>();
112  cmd->setSocketId(info->peer1Assoc);
113  msg->addTag<DispatchProtocolReq>()->setProtocol(&Protocol::sctp);
114  msg->addTag<SocketReq>()->setSocketId(info->peer1Assoc);
115  send(msg, "socketOut");
116  EV << "abortMsg sent to peer1\n";
117 
118  struct nat_message *nat2 = (struct nat_message *)(buffer2);
119  buflen = 16;
120  nat2->peer1 = info->peer2;
121  nat2->peer2 = info->peer1;
122  nat2->portPeer1 = info->peer2Port;
123  nat2->portPeer2 = info->peer1Port;
124  nat2->numAddrPeer1 = 2;
125  nat2->numAddrPeer2 = 2;
126  nat2->multi = info->multi;
127  buflen = ADD_PADDING(buflen + 4 * (nat2->numAddrPeer1 + nat2->numAddrPeer2));
128  nat2->peer1Addresses[0] = info->peer2Address1.toIpv4().getInt();
129  nat2->peer1Addresses[1] = info->peer2Address2.toIpv4().getInt();
130  nat2->peer2Addresses[0] = info->peer1Address1.toIpv4().getInt();
131  nat2->peer2Addresses[1] = info->peer1Address2.toIpv4().getInt();
132 
133  EV << "Info for peer2: peer1-1=" << Ipv4Address(nat2->peer1Addresses[0]).str() << " peer2-1=" << Ipv4Address(nat2->peer2Addresses[0]).str() << "\n";
134 
135  auto applicationData2 = makeShared<BytesChunk>(buffer2, buflen);
136  applicationData2->addTag<CreationTimeTag>()->setCreationTime(simTime());
137  auto applicationPacket2 = new Packet("ApplicationPacket", SCTP_C_SEND_ORDERED);
138  applicationPacket2->insertAtBack(applicationData2);
139  auto sctpSendReq2 = applicationPacket2->addTag<SctpSendReq>();
140  sctpSendReq2->setLast(true);
141  sctpSendReq2->setPrMethod(0);
142  sctpSendReq2->setPrValue(0);
143  sctpSendReq2->setSid(0);
144  applicationPacket2->addTag<DispatchProtocolReq>()->setProtocol(&Protocol::sctp);
145  applicationPacket2->addTag<SocketReq>()->setSocketId(info->peer2Assoc);
146  send(applicationPacket2, "socketOut");
147  EV << "info sent to peer2\n";
148 
149  EV << "SctpNatServer::shutdown peer2\n";
150 
151  Request *msg2 = new Request("SHUTDOWN", SCTP_C_SHUTDOWN);
152  auto& cmd2 = msg2->addTag<SctpCommandReq>();
153  cmd2->setSocketId(info->peer2Assoc);
154  msg2->addTag<DispatchProtocolReq>()->setProtocol(&Protocol::sctp);
155  msg2->addTag<SocketReq>()->setSocketId(info->peer2Assoc);
156  send(msg2, "socketOut");
157  EV << "abortMsg sent to peer2\n";
158 }

Member Data Documentation

◆ assocId

uint32_t inet::SctpNatServer::assocId
protected

◆ bytesSent

int64_t inet::SctpNatServer::bytesSent
protected

◆ inboundStreams

int32_t inet::SctpNatServer::inboundStreams
protected

◆ lastStream

int32_t inet::SctpNatServer::lastStream
protected

◆ natVector

NatVector inet::SctpNatServer::natVector
staticprotected

◆ notifications

int32_t inet::SctpNatServer::notifications
protected

◆ numRequestsToSend

int32_t inet::SctpNatServer::numRequestsToSend
protected

◆ numSessions

int32_t inet::SctpNatServer::numSessions
protected

◆ ordered

bool inet::SctpNatServer::ordered
protected

◆ outboundStreams

int32_t inet::SctpNatServer::outboundStreams
protected

◆ packetsRcvd

int32_t inet::SctpNatServer::packetsRcvd
protected

◆ packetsSent

int32_t inet::SctpNatServer::packetsSent
protected

◆ shutdownReceived

bool inet::SctpNatServer::shutdownReceived
protected

◆ socket

SctpSocket* inet::SctpNatServer::socket
protected

◆ ssn

int32_t inet::SctpNatServer::ssn
protected

The documentation for this class was generated from the following files:
inet::SCTP_I_RCV_STREAMS_RESETTED
@ SCTP_I_RCV_STREAMS_RESETTED
Definition: SctpCommand_m.h:214
inet::SctpNatServer::handleTimer
void handleTimer(cMessage *msg)
Definition: SctpNatServer.cc:471
inet::SctpNatServer::natVector
static NatVector natVector
Definition: SctpNatServer.h:57
inet::SctpNatServer::bytesSent
int64_t bytesSent
Definition: SctpNatServer.h:47
inet::SctpNatServer::packetsRcvd
int32_t packetsRcvd
Definition: SctpNatServer.h:49
inet::AddressVector
std::vector< L3Address > AddressVector
Definition: SctpCommand_m.h:70
inet::SctpSocket::setOutputGate
void setOutputGate(cGate *toSctp)
Sets the gate on which to send to SCTP.
Definition: SctpSocket.h:174
inet::sctp::SctpAssociation::indicationName
static const char * indicationName(int32_t code)
Utility: returns name of SCTP_I_xxx constants.
Definition: SctpAssociationUtil.cc:205
inet::SCTP_I_CLOSED
@ SCTP_I_CLOSED
Definition: SctpCommand_m.h:201
inet::SctpNatServer::numSessions
int32_t numSessions
Definition: SctpNatServer.h:50
inet::NatInfo
struct inet::natInfo NatInfo
Accepts any number of incoming connections, and sends back whatever arrives on them.
inet::SctpNatServer::socket
SctpSocket * socket
Definition: SctpNatServer.h:45
DispatchProtocolReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DispatchProtocolReq
Definition: IUdp-gates.txt:25
inet::SCTP_C_SEND
@ SCTP_C_SEND
Definition: SctpCommand_m.h:132
inet::SctpNatServer::packetsSent
int32_t packetsSent
Definition: SctpNatServer.h:48
inet::SCTP_C_SHUTDOWN
@ SCTP_C_SHUTDOWN
Definition: SctpCommand_m.h:142
inet::SCTP_I_SEND_STREAMS_RESETTED
@ SCTP_I_SEND_STREAMS_RESETTED
Definition: SctpCommand_m.h:213
inet::SCTP_C_ACCEPT_SOCKET_ID
@ SCTP_C_ACCEPT_SOCKET_ID
Definition: SctpCommand_m.h:153
inet::SctpNatServer::ordered
bool ordered
Definition: SctpNatServer.h:52
inet::SCTP_C_RECEIVE
@ SCTP_C_RECEIVE
Definition: SctpCommand_m.h:136
inet::SCTP_I_DATA
@ SCTP_I_DATA
Definition: SctpCommand_m.h:197
inet::SCTP_C_ABORT
@ SCTP_C_ABORT
Definition: SctpCommand_m.h:134
inet::SctpNatServer::printNatVector
void printNatVector()
Definition: SctpNatServer.cc:501
inet::SCTP_I_ESTABLISHED
@ SCTP_I_ESTABLISHED
Definition: SctpCommand_m.h:199
inet::SctpNatServer::numRequestsToSend
int32_t numRequestsToSend
Definition: SctpNatServer.h:51
inet::SctpNatServer::lastStream
int32_t lastStream
Definition: SctpNatServer.h:55
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::SctpSocket::listen
void listen(bool fork=true, bool streamReset=false, uint32_t requests=0, uint32_t messagesToPush=0)
Initiates passive OPEN.
Definition: SctpSocket.cc:183
inet::SctpNatServer::outboundStreams
int32_t outboundStreams
Definition: SctpNatServer.h:53
inet::SCTP_C_SEND_ORDERED
@ SCTP_C_SEND_ORDERED
Definition: SctpCommand_m.h:137
inet::SctpSocket::setOutboundStreams
void setOutboundStreams(int streams)
Setter and getter methods for socket and API Parameters.
Definition: SctpSocket.h:179
ADD_PADDING
#define ADD_PADDING(x)
Definition: SctpAssociation.h:252
inet::SctpNatServer::generateAndSend
void generateAndSend()
Definition: SctpNatServer.cc:160
if
if(cwndVector) cwndVector -> record(state->snd_cwnd)
inet::SCTP_I_SHUTDOWN_RECEIVED
@ SCTP_I_SHUTDOWN_RECEIVED
Definition: SctpCommand_m.h:209
inet::SCTP_C_NO_OUTSTANDING
@ SCTP_C_NO_OUTSTANDING
Definition: SctpCommand_m.h:143
inet::SCTP_I_PEER_CLOSED
@ SCTP_I_PEER_CLOSED
Definition: SctpCommand_m.h:200
inet::SctpSocket::bindx
void bindx(AddressVector localAddr, int localPort)
Definition: SctpSocket.cc:171
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::SctpNatServer::inboundStreams
int32_t inboundStreams
Definition: SctpNatServer.h:54
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::SCTP_I_DATA_NOTIFICATION
@ SCTP_I_DATA_NOTIFICATION
Definition: SctpCommand_m.h:198
inet::INITSTAGE_APPLICATION_LAYER
INET_API InitStage INITSTAGE_APPLICATION_LAYER
Initialization of applications.
inet::COMPLETE_MESG_ORDERED
@ COMPLETE_MESG_ORDERED
Definition: SctpCommand_m.h:236
inet::SCTP_I_ABORT
@ SCTP_I_ABORT
Definition: SctpCommand_m.h:206
inet::Protocol::sctp
static const Protocol sctp
Definition: Protocol.h:108
inet::COMPLETE_MESG_UNORDERED
@ COMPLETE_MESG_UNORDERED
Definition: SctpCommand_m.h:235
tags
* tags
Definition: IUdp-gates.txt:3
inet::SctpNatServer::shutdownReceived
bool shutdownReceived
Definition: SctpNatServer.h:46
inet::SctpNatServer::sendInfo
void sendInfo(NatInfo *info)
Definition: SctpNatServer.cc:72
inet::SctpSocket::bind
void bind(int localPort)
Bind the socket to a local port number.
Definition: SctpSocket.cc:142
inet::SCTP_C_CLOSE
@ SCTP_C_CLOSE
Definition: SctpCommand_m.h:133
inet::SCTP_I_ADDRESS_ADDED
@ SCTP_I_ADDRESS_ADDED
Definition: SctpCommand_m.h:216
inet::SctpSocket::setInboundStreams
void setInboundStreams(int streams)
Definition: SctpSocket.h:180
inet::SCTP_I_AVAILABLE
@ SCTP_I_AVAILABLE
Definition: SctpCommand_m.h:218
inet::SctpNatServer::assocId
uint32_t assocId
Definition: SctpNatServer.h:44
inet::SctpNatServer::notifications
int32_t notifications
Definition: SctpNatServer.h:43