A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-end-point-demux.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007-2009 Strasbourg University
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
7 */
8
10
11#include "ipv6-end-point.h"
12
13#include "ns3/log.h"
14
15namespace ns3
16{
17
18NS_LOG_COMPONENT_DEFINE("Ipv6EndPointDemux");
19
21 : m_ephemeral(49152),
22 m_portFirst(49152),
23 m_portLast(65535)
24{
25 NS_LOG_FUNCTION(this);
26}
27
29{
30 NS_LOG_FUNCTION(this);
31 for (auto i = m_endPoints.begin(); i != m_endPoints.end(); i++)
32 {
34 delete endPoint;
35 }
36 m_endPoints.clear();
37}
38
39bool
41{
42 NS_LOG_FUNCTION(this << port);
43 for (auto i = m_endPoints.begin(); i != m_endPoints.end(); i++)
44 {
45 if ((*i)->GetLocalPort() == port)
46 {
47 return true;
48 }
49 }
50 return false;
51}
52
53bool
55{
56 NS_LOG_FUNCTION(this << addr << port);
57 for (auto i = m_endPoints.begin(); i != m_endPoints.end(); i++)
58 {
59 if ((*i)->GetLocalPort() == port && (*i)->GetLocalAddress() == addr &&
60 (*i)->GetBoundNetDevice() == boundNetDevice)
61 {
62 return true;
63 }
64 }
65 return false;
66}
67
70{
71 NS_LOG_FUNCTION(this);
72 uint16_t port = AllocateEphemeralPort();
73 if (port == 0)
74 {
75 NS_LOG_WARN("Ephemeral port allocation failed.");
76 return nullptr;
77 }
79 m_endPoints.push_back(endPoint);
80 NS_LOG_DEBUG("Now have >>" << m_endPoints.size() << "<< endpoints.");
81 return endPoint;
82}
83
86{
87 NS_LOG_FUNCTION(this << address);
88 uint16_t port = AllocateEphemeralPort();
89 if (port == 0)
90 {
91 NS_LOG_WARN("Ephemeral port allocation failed.");
92 return nullptr;
93 }
94 auto endPoint = new Ipv6EndPoint(address, port);
95 m_endPoints.push_back(endPoint);
96 NS_LOG_DEBUG("Now have >>" << m_endPoints.size() << "<< endpoints.");
97 return endPoint;
98}
99
107
110{
111 NS_LOG_FUNCTION(this << boundNetDevice << address << port);
112 if (LookupLocal(boundNetDevice, address, port) || LookupLocal(nullptr, address, port))
113 {
114 NS_LOG_WARN("Duplicated endpoint.");
115 return nullptr;
116 }
117 auto endPoint = new Ipv6EndPoint(address, port);
118 m_endPoints.push_back(endPoint);
119 NS_LOG_DEBUG("Now have >>" << m_endPoints.size() << "<< endpoints.");
120 return endPoint;
121}
122
125 Ipv6Address localAddress,
126 uint16_t localPort,
128 uint16_t peerPort)
129{
130 NS_LOG_FUNCTION(this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
131 for (auto i = m_endPoints.begin(); i != m_endPoints.end(); i++)
132 {
133 if ((*i)->GetLocalPort() == localPort && (*i)->GetLocalAddress() == localAddress &&
134 (*i)->GetPeerPort() == peerPort && (*i)->GetPeerAddress() == peerAddress &&
135 ((*i)->GetBoundNetDevice() == boundNetDevice || !(*i)->GetBoundNetDevice()))
136 {
137 NS_LOG_WARN("Duplicated endpoint.");
138 return nullptr;
139 }
140 }
141 auto endPoint = new Ipv6EndPoint(localAddress, localPort);
142 endPoint->SetPeer(peerAddress, peerPort);
143 m_endPoints.push_back(endPoint);
144
145 NS_LOG_DEBUG("Now have >>" << m_endPoints.size() << "<< endpoints.");
146
147 return endPoint;
148}
149
150void
152{
153 NS_LOG_FUNCTION(this);
154 for (auto i = m_endPoints.begin(); i != m_endPoints.end(); i++)
155 {
156 if (*i == endPoint)
157 {
158 delete endPoint;
159 m_endPoints.erase(i);
160 break;
161 }
162 }
163}
164
165/*
166 * If we have an exact match, we return it.
167 * Otherwise, if we find a generic match, we return it.
168 * Otherwise, we return 0.
169 */
172 uint16_t dport,
174 uint16_t sport,
176{
178
179 EndPoints retval1; /* Matches exact on local port, wildcards on others */
180 EndPoints retval2; /* Matches exact on local port/adder, wildcards on others */
181 EndPoints retval3; /* Matches all but local address */
182 EndPoints retval4; /* Exact match on all 4 */
183
184 NS_LOG_DEBUG("Looking up endpoint for destination address " << daddr);
185 for (auto i = m_endPoints.begin(); i != m_endPoints.end(); i++)
186 {
187 Ipv6EndPoint* endP = *i;
188
189 NS_LOG_DEBUG("Looking at endpoint dport="
190 << endP->GetLocalPort() << " daddr=" << endP->GetLocalAddress()
191 << " sport=" << endP->GetPeerPort() << " saddr=" << endP->GetPeerAddress());
192
193 if (!endP->IsRxEnabled())
194 {
195 NS_LOG_LOGIC("Skipping endpoint " << &endP
196 << " because endpoint can not receive packets");
197 continue;
198 }
199
200 if (endP->GetLocalPort() != dport)
201 {
202 NS_LOG_LOGIC("Skipping endpoint " << &endP << " because endpoint dport "
203 << endP->GetLocalPort()
204 << " does not match packet dport " << dport);
205 continue;
206 }
207
208 if (endP->GetBoundNetDevice())
209 {
211 {
212 continue;
213 }
214 if (endP->GetBoundNetDevice() != incomingInterface->GetDevice())
215 {
216 NS_LOG_LOGIC("Skipping endpoint "
217 << &endP << " because endpoint is bound to specific device and"
218 << endP->GetBoundNetDevice() << " does not match packet device "
219 << incomingInterface->GetDevice());
220 continue;
221 }
222 }
223
224 /* Ipv6Address incomingInterfaceAddr = incomingInterface->GetAddress (); */
225 NS_LOG_DEBUG("dest addr " << daddr);
226
227 bool localAddressMatchesWildCard = endP->GetLocalAddress() == Ipv6Address::GetAny();
228 bool localAddressMatchesExact = endP->GetLocalAddress() == daddr;
230 endP->GetLocalAddress() == Ipv6Address::GetAllRoutersMulticast();
231
232 /* if no match here, keep looking */
234 {
235 continue;
236 }
237 bool remotePeerMatchesExact = endP->GetPeerPort() == sport;
238 bool remotePeerMatchesWildCard = endP->GetPeerPort() == 0;
239 bool remoteAddressMatchesExact = endP->GetPeerAddress() == saddr;
240 bool remoteAddressMatchesWildCard = endP->GetPeerAddress() == Ipv6Address::GetAny();
241
242 /* If remote does not match either with exact or wildcard,i
243 skip this one */
245 {
246 continue;
247 }
249 {
250 continue;
251 }
252
253 /* Now figure out which return list to add this one to */
256 { /* Only local port matches exactly */
257 retval1.push_back(endP);
258 }
261 { /* Only local port and local address matches exactly */
262 retval2.push_back(endP);
263 }
265 { /* All but local address */
266 retval3.push_back(endP);
267 }
269 { /* All 4 match */
270 retval4.push_back(endP);
271 }
272 }
273
274 // Here we find the most exact match
276 if (!retval4.empty())
277 {
278 retval = retval4;
279 }
280 else if (!retval3.empty())
281 {
282 retval = retval3;
283 }
284 else if (!retval2.empty())
285 {
286 retval = retval2;
287 }
288 else
289 {
290 retval = retval1;
291 }
292
293 NS_ABORT_MSG_IF(retval.size() > 1,
294 "Too many endpoints - perhaps you created too many sockets without binding "
295 "them to different NetDevices.");
296 return retval; // might be empty if no matches
297}
298
301{
303 Ipv6EndPoint* generic = nullptr;
304
305 for (auto i = m_endPoints.begin(); i != m_endPoints.end(); i++)
306 {
307 uint32_t tmp = 0;
308
309 if ((*i)->GetLocalPort() != dport)
310 {
311 continue;
312 }
313
314 if ((*i)->GetLocalAddress() == dst && (*i)->GetPeerPort() == sport &&
315 (*i)->GetPeerAddress() == src)
316 {
317 /* this is an exact match. */
318 return *i;
319 }
320
321 if ((*i)->GetLocalAddress() == Ipv6Address::GetAny())
322 {
323 tmp++;
324 }
325
326 if ((*i)->GetPeerAddress() == Ipv6Address::GetAny())
327 {
328 tmp++;
329 }
330
331 if (tmp < genericity)
332 {
333 generic = (*i);
334 genericity = tmp;
335 }
336 }
337 return generic;
338}
339
340uint16_t
342{
343 NS_LOG_FUNCTION(this);
344 uint16_t port = m_ephemeral;
345 int count = m_portLast - m_portFirst;
346 do
347 {
348 if (count-- < 0)
349 {
350 return 0;
351 }
352 ++port;
354 {
356 }
357 } while (LookupPortLocal(port));
359 return port;
360}
361
364{
365 return m_endPoints;
366}
367
368} /* namespace ns3 */
Describes an IPv6 address.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
EndPoints Lookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr< Ipv6Interface > incomingInterface)
lookup for a match with all the parameters.
Ipv6EndPoint * Allocate()
Allocate a Ipv6EndPoint.
bool LookupLocal(Ptr< NetDevice > boundNetDevice, Ipv6Address addr, uint16_t port)
Lookup for address and port.
EndPoints m_endPoints
A list of IPv6 end points.
uint16_t m_ephemeral
The ephemeral port.
EndPoints GetEndPoints() const
Get the entire list of end points registered.
Ipv6EndPoint * SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
Simple lookup for a four-tuple match.
bool LookupPortLocal(uint16_t port)
Lookup for port local.
uint16_t AllocateEphemeralPort()
Allocate a ephemeral port.
uint16_t m_portFirst
The first ephemeral port.
uint16_t m_portLast
The last ephemeral port.
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
std::list< Ipv6EndPoint * > EndPoints
Container of the IPv6 endpoints.
A representation of an IPv6 endpoint/connection.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
uint16_t port
Definition dsdv-manet.cc:33
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Every class exported by the ns3 library is enclosed in the ns3 namespace.