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 {
33 Ipv6EndPoint* endPoint = *i;
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 }
78 auto endPoint = new Ipv6EndPoint(Ipv6Address::GetAny(), port);
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
102{
103 NS_LOG_FUNCTION(this << boundNetDevice << port);
104
105 return Allocate(boundNetDevice, Ipv6Address::GetAny(), port);
106}
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,
127 Ipv6Address peerAddress,
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,
173 Ipv6Address saddr,
174 uint16_t sport,
175 Ptr<Ipv6Interface> incomingInterface)
176{
177 NS_LOG_FUNCTION(this << daddr << dport << saddr << sport << incomingInterface);
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 {
210 if (!incomingInterface)
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;
229 bool localAddressMatchesAllRouters =
231
232 /* if no match here, keep looking */
233 if (!(localAddressMatchesExact || localAddressMatchesWildCard))
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 */
244 if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
245 {
246 continue;
247 }
248 if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
249 {
250 continue;
251 }
252
253 /* Now figure out which return list to add this one to */
254 if (localAddressMatchesWildCard && remotePeerMatchesWildCard &&
255 remoteAddressMatchesWildCard)
256 { /* Only local port matches exactly */
257 retval1.push_back(endP);
258 }
259 if ((localAddressMatchesExact || (localAddressMatchesAllRouters)) &&
260 remotePeerMatchesWildCard && remoteAddressMatchesWildCard)
261 { /* Only local port and local address matches exactly */
262 retval2.push_back(endP);
263 }
264 if (localAddressMatchesWildCard && remotePeerMatchesExact && remoteAddressMatchesExact)
265 { /* All but local address */
266 retval3.push_back(endP);
267 }
268 if (localAddressMatchesExact && remotePeerMatchesExact && remoteAddressMatchesExact)
269 { /* All 4 match */
270 retval4.push_back(endP);
271 }
272 }
273
274 // Here we find the most exact match
275 EndPoints retval;
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
300Ipv6EndPointDemux::SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
301{
302 uint32_t genericity = 3;
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.
uint16_t GetLocalPort() const
Get the local port.
Ipv6Address GetPeerAddress() const
Get the peer address.
Ipv6Address GetLocalAddress() const
Get the local address.
bool IsRxEnabled() const
Checks if the endpoint can receive packets.
Ptr< NetDevice > GetBoundNetDevice() const
Returns socket's bound netdevice, if any.
uint16_t GetPeerPort() const
Get the peer port.
Smart pointer class similar to boost::intrusive_ptr.
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
Every class exported by the ns3 library is enclosed in the ns3 namespace.