INET Framework for OMNeT++/OMNEST
inet::ospfv2::DatabaseDescriptionHandler Class Reference

#include <DatabaseDescriptionHandler.h>

Inheritance diagram for inet::ospfv2::DatabaseDescriptionHandler:
inet::ospfv2::IMessageHandler

Public Member Functions

 DatabaseDescriptionHandler (Router *containingRouter)
 
void processPacket (Packet *packet, Ospfv2Interface *intf, Neighbor *neighbor) override
 
- Public Member Functions inherited from inet::ospfv2::IMessageHandler
 IMessageHandler (Router *containingRouter)
 
virtual ~IMessageHandler ()
 

Private Member Functions

bool processDDPacket (const Ospfv2DatabaseDescriptionPacket *ddPacket, Ospfv2Interface *intf, Neighbor *neighbor, bool inExchangeStart)
 

Additional Inherited Members

- Protected Attributes inherited from inet::ospfv2::IMessageHandler
Routerrouter
 

Constructor & Destructor Documentation

◆ DatabaseDescriptionHandler()

inet::ospfv2::DatabaseDescriptionHandler::DatabaseDescriptionHandler ( Router containingRouter)
17  :
18  IMessageHandler(containingRouter)
19 {
20 }

Member Function Documentation

◆ processDDPacket()

bool inet::ospfv2::DatabaseDescriptionHandler::processDDPacket ( const Ospfv2DatabaseDescriptionPacket ddPacket,
Ospfv2Interface intf,
Neighbor neighbor,
bool  inExchangeStart 
)
private
180 {
181  EV_INFO << " Processing packet contents(ddOptions="
182  << ((ddPacket->getDdOptions().I_Init) ? "I " : "_ ")
183  << ((ddPacket->getDdOptions().M_More) ? "M " : "_ ")
184  << ((ddPacket->getDdOptions().MS_MasterSlave) ? "MS" : "__")
185  << "; seqNumber="
186  << ddPacket->getDdSequenceNumber()
187  << "):\n";
188 
189  unsigned int headerCount = ddPacket->getLsaHeadersArraySize();
190 
191  for (unsigned int i = 0; i < headerCount; i++) {
192  const Ospfv2LsaHeader& currentHeader = ddPacket->getLsaHeaders(i);
193  Ospfv2LsaType lsaType = static_cast<Ospfv2LsaType>(currentHeader.getLsType());
194 
195  EV_DETAIL << " " << currentHeader;
196 
197  if ((lsaType < ROUTERLSA_TYPE) || (lsaType > AS_EXTERNAL_LSA_TYPE) ||
198  ((lsaType == AS_EXTERNAL_LSA_TYPE) && (!intf->getArea()->getExternalRoutingCapability())))
199  {
200  EV_ERROR << " Error!\n";
201  neighbor->processEvent(Neighbor::SEQUENCE_NUMBER_MISMATCH);
202  return false;
203  }
204  else {
205  LsaKeyType lsaKey;
206 
207  lsaKey.linkStateID = currentHeader.getLinkStateID();
208  lsaKey.advertisingRouter = currentHeader.getAdvertisingRouter();
209 
210  Ospfv2Lsa *lsaInDatabase = router->findLSA(lsaType, lsaKey, intf->getArea()->getAreaID());
211 
212  // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older)
213  if ((lsaInDatabase == nullptr) || (lsaInDatabase->getHeader() < currentHeader)) {
214  EV_DETAIL << " (newer)";
215  neighbor->addToRequestList(&currentHeader);
216  }
217  }
218  EV_DETAIL << "\n";
219  }
220 
221  if (neighbor->getDatabaseExchangeRelationship() == Neighbor::MASTER) {
222  neighbor->incrementDDSequenceNumber();
223  if ((neighbor->getDatabaseSummaryListCount() == 0) && !ddPacket->getDdOptions().M_More) {
224  neighbor->processEvent(Neighbor::EXCHANGE_DONE); // does nothing in ExchangeStart
225  }
226  else {
227  if (!inExchangeStart) {
228  neighbor->sendDatabaseDescriptionPacket();
229  }
230  }
231  }
232  else {
233  neighbor->setDDSequenceNumber(ddPacket->getDdSequenceNumber());
234  if (!inExchangeStart) {
235  neighbor->sendDatabaseDescriptionPacket();
236  }
237  if (!ddPacket->getDdOptions().M_More &&
238  (neighbor->getDatabaseSummaryListCount() == 0))
239  {
240  neighbor->processEvent(Neighbor::EXCHANGE_DONE); // does nothing in ExchangeStart
241  }
242  }
243  return true;
244 }

Referenced by processPacket().

◆ processPacket()

void inet::ospfv2::DatabaseDescriptionHandler::processPacket ( Packet packet,
Ospfv2Interface intf,
Neighbor neighbor 
)
overridevirtual

Implements inet::ospfv2::IMessageHandler.

23 {
24  router->getMessageHandler()->printEvent("Database Description packet received", intf, neighbor);
25 
26  const auto& ddPacket = packet->peekAtFront<Ospfv2DatabaseDescriptionPacket>();
27 
28  Neighbor::NeighborStateType neighborState = neighbor->getState();
29 
30  if ((ddPacket->getInterfaceMTU() <= intf->getMtu()) &&
31  (neighborState > Neighbor::ATTEMPT_STATE))
32  {
33  switch (neighborState) {
35  break;
36 
38  neighbor->processEvent(Neighbor::TWOWAY_RECEIVED);
39  break;
40 
42  const Ospfv2DdOptions& ddOptions = ddPacket->getDdOptions();
43 
44  if (ddOptions.I_Init && ddOptions.M_More && ddOptions.MS_MasterSlave &&
45  (ddPacket->getLsaHeadersArraySize() == 0))
46  {
47  if (neighbor->getNeighborID() > router->getRouterID()) {
48  Neighbor::DdPacketId packetID;
49  packetID.ddOptions = ddOptions;
50  packetID.options = ddPacket->getOptions();
51  packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
52 
53  neighbor->setOptions(packetID.options);
54  neighbor->setDatabaseExchangeRelationship(Neighbor::SLAVE);
55  neighbor->setDDSequenceNumber(packetID.sequenceNumber);
56  neighbor->setLastReceivedDDPacket(packetID);
57 
58  if (!processDDPacket(ddPacket.get(), intf, neighbor, true)) {
59  break;
60  }
61 
62  neighbor->processEvent(Neighbor::NEGOTIATION_DONE);
63  if (!neighbor->isLinkStateRequestListEmpty() &&
64  !neighbor->isRequestRetransmissionTimerActive())
65  {
66  neighbor->sendLinkStateRequestPacket();
67  neighbor->clearRequestRetransmissionTimer();
68  neighbor->startRequestRetransmissionTimer();
69  }
70  }
71  else {
72  neighbor->sendDatabaseDescriptionPacket(true);
73  }
74  }
75  if (!ddOptions.I_Init && !ddOptions.MS_MasterSlave &&
76  (ddPacket->getDdSequenceNumber() == neighbor->getDDSequenceNumber()) &&
77  (neighbor->getNeighborID() < router->getRouterID()))
78  {
79  Neighbor::DdPacketId packetID;
80  packetID.ddOptions = ddOptions;
81  packetID.options = ddPacket->getOptions();
82  packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
83 
84  neighbor->setOptions(packetID.options);
85  neighbor->setDatabaseExchangeRelationship(Neighbor::MASTER);
86  neighbor->setLastReceivedDDPacket(packetID);
87 
88  if (!processDDPacket(ddPacket.get(), intf, neighbor, true)) {
89  break;
90  }
91 
92  neighbor->processEvent(Neighbor::NEGOTIATION_DONE);
93  if (!neighbor->isLinkStateRequestListEmpty() &&
94  !neighbor->isRequestRetransmissionTimerActive())
95  {
96  neighbor->sendLinkStateRequestPacket();
97  neighbor->clearRequestRetransmissionTimer();
98  neighbor->startRequestRetransmissionTimer();
99  }
100  }
101  }
102  break;
103 
105  Neighbor::DdPacketId packetID;
106  packetID.ddOptions = ddPacket->getDdOptions();
107  packetID.options = ddPacket->getOptions();
108  packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
109 
110  if (packetID != neighbor->getLastReceivedDDPacket()) {
111  if ((packetID.ddOptions.MS_MasterSlave &&
112  (neighbor->getDatabaseExchangeRelationship() != Neighbor::SLAVE)) ||
113  (!packetID.ddOptions.MS_MasterSlave &&
114  (neighbor->getDatabaseExchangeRelationship() != Neighbor::MASTER)) ||
115  packetID.ddOptions.I_Init ||
116  (packetID.options != neighbor->getLastReceivedDDPacket().options))
117  {
118  neighbor->processEvent(Neighbor::SEQUENCE_NUMBER_MISMATCH);
119  }
120  else {
121  if (((neighbor->getDatabaseExchangeRelationship() == Neighbor::MASTER) &&
122  (packetID.sequenceNumber == neighbor->getDDSequenceNumber())) ||
123  ((neighbor->getDatabaseExchangeRelationship() == Neighbor::SLAVE) &&
124  (packetID.sequenceNumber == (neighbor->getDDSequenceNumber() + 1))))
125  {
126  neighbor->setLastReceivedDDPacket(packetID);
127  if (!processDDPacket(ddPacket.get(), intf, neighbor, false)) {
128  break;
129  }
130  if (!neighbor->isLinkStateRequestListEmpty() &&
131  !neighbor->isRequestRetransmissionTimerActive())
132  {
133  neighbor->sendLinkStateRequestPacket();
134  neighbor->clearRequestRetransmissionTimer();
135  neighbor->startRequestRetransmissionTimer();
136  }
137  }
138  else {
139  neighbor->processEvent(Neighbor::SEQUENCE_NUMBER_MISMATCH);
140  }
141  }
142  }
143  else {
144  if (neighbor->getDatabaseExchangeRelationship() == Neighbor::SLAVE) {
145  neighbor->retransmitDatabaseDescriptionPacket();
146  }
147  }
148  }
149  break;
150 
152  case Neighbor::FULL_STATE: {
153  Neighbor::DdPacketId packetID;
154  packetID.ddOptions = ddPacket->getDdOptions();
155  packetID.options = ddPacket->getOptions();
156  packetID.sequenceNumber = ddPacket->getDdSequenceNumber();
157 
158  if ((packetID != neighbor->getLastReceivedDDPacket()) ||
159  (packetID.ddOptions.I_Init))
160  {
161  neighbor->processEvent(Neighbor::SEQUENCE_NUMBER_MISMATCH);
162  }
163  else {
164  if (neighbor->getDatabaseExchangeRelationship() == Neighbor::SLAVE) {
165  if (!neighbor->retransmitDatabaseDescriptionPacket()) {
166  neighbor->processEvent(Neighbor::SEQUENCE_NUMBER_MISMATCH);
167  }
168  }
169  }
170  }
171  break;
172 
173  default:
174  break;
175  }
176  }
177 }

Referenced by inet::ospfv2::MessageHandler::processPacket().


The documentation for this class was generated from the following files:
inet::ospfv2::Neighbor::INIT_STATE
@ INIT_STATE
Definition: Ospfv2Neighbor.h:52
inet::ospfv2::Neighbor::FULL_STATE
@ FULL_STATE
Definition: Ospfv2Neighbor.h:57
inet::ospfv2::MessageHandler::printEvent
void printEvent(const char *eventString, const Ospfv2Interface *onInterface=nullptr, const Neighbor *forNeighbor=nullptr) const
Definition: MessageHandler.cc:380
inet::ospfv2::Neighbor::NeighborStateType
NeighborStateType
Definition: Ospfv2Neighbor.h:49
inet::ospfv2::Ospfv2LsaType
Ospfv2LsaType
Enum generated from inet/routing/ospfv2/Ospfv2Packet.msg:78 by opp_msgtool.
Definition: Ospfv2Packet_m.h:282
inet::ospfv2::Neighbor::EXCHANGE_DONE
@ EXCHANGE_DONE
Definition: Ospfv2Neighbor.h:34
inet::ospfv2::Neighbor::TWOWAY_STATE
@ TWOWAY_STATE
Definition: Ospfv2Neighbor.h:53
inet::ospfv2::Router::getMessageHandler
MessageHandler * getMessageHandler()
Definition: Ospfv2Router.h:66
inet::ospfv2::ROUTERLSA_TYPE
@ ROUTERLSA_TYPE
Definition: Ospfv2Packet_m.h:283
inet::ospfv2::Neighbor::ATTEMPT_STATE
@ ATTEMPT_STATE
Definition: Ospfv2Neighbor.h:51
inet::ospfv2::Neighbor::NEGOTIATION_DONE
@ NEGOTIATION_DONE
Definition: Ospfv2Neighbor.h:33
inet::ospfv2::AS_EXTERNAL_LSA_TYPE
@ AS_EXTERNAL_LSA_TYPE
Definition: Ospfv2Packet_m.h:287
inet::ospfv2::Neighbor::MASTER
@ MASTER
Definition: Ospfv2Neighbor.h:61
inet::ospfv2::Neighbor::TWOWAY_RECEIVED
@ TWOWAY_RECEIVED
Definition: Ospfv2Neighbor.h:32
inet::ospfv2::Neighbor::EXCHANGE_STATE
@ EXCHANGE_STATE
Definition: Ospfv2Neighbor.h:55
inet::ospfv2::Router::findLSA
Ospfv2Lsa * findLSA(Ospfv2LsaType lsaType, LsaKeyType lsaKey, AreaId areaID)
Find the LSA identified by the input lsaKey in the database.
Definition: Ospfv2Router.cc:226
inet::ospfv2::IMessageHandler::IMessageHandler
IMessageHandler(Router *containingRouter)
Definition: IMessageHandler.h:27
inet::ospfv2::Router::getRouterID
RouterId getRouterID() const
Definition: Ospfv2Router.h:60
inet::ospfv2::Neighbor::EXCHANGE_START_STATE
@ EXCHANGE_START_STATE
Definition: Ospfv2Neighbor.h:54
inet::ospfv2::DatabaseDescriptionHandler::processDDPacket
bool processDDPacket(const Ospfv2DatabaseDescriptionPacket *ddPacket, Ospfv2Interface *intf, Neighbor *neighbor, bool inExchangeStart)
Definition: DatabaseDescriptionHandler.cc:179
inet::ospfv2::Neighbor::SLAVE
@ SLAVE
Definition: Ospfv2Neighbor.h:62
inet::ospfv2::Neighbor::LOADING_STATE
@ LOADING_STATE
Definition: Ospfv2Neighbor.h:56
inet::ospfv2::IMessageHandler::router
Router * router
Definition: IMessageHandler.h:24
inet::ospfv2::Neighbor::SEQUENCE_NUMBER_MISMATCH
@ SEQUENCE_NUMBER_MISMATCH
Definition: Ospfv2Neighbor.h:38