A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv6-end-point-demux.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2009 Strasbourg University
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19  */
20 
21 #include "ipv6-end-point-demux.h"
22 #include "ipv6-end-point.h"
23 #include "ns3/log.h"
24 
25 namespace ns3 {
26 
27 NS_LOG_COMPONENT_DEFINE ("Ipv6EndPointDemux")
28  ;
29 
31  : m_ephemeral (49152),
32  m_portFirst (49152),
33  m_portLast (65535)
34 {
36 }
37 
39 {
41  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
42  {
43  Ipv6EndPoint *endPoint = *i;
44  delete endPoint;
45  }
46  m_endPoints.clear ();
47 }
48 
50 {
51  NS_LOG_FUNCTION (this << port);
52  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
53  {
54  if ((*i)->GetLocalPort () == port)
55  {
56  return true;
57  }
58  }
59  return false;
60 }
61 
63 {
64  NS_LOG_FUNCTION (this << addr << port);
65  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
66  {
67  if ((*i)->GetLocalPort () == port
68  && (*i)->GetLocalAddress () == addr)
69  {
70  return true;
71  }
72  }
73  return false;
74 }
75 
77 {
79  uint16_t port = AllocateEphemeralPort ();
80  if (port == 0)
81  {
82  NS_LOG_WARN ("Ephemeral port allocation failed.");
83  return 0;
84  }
85  Ipv6EndPoint *endPoint = new Ipv6EndPoint (Ipv6Address::GetAny (), port);
86  m_endPoints.push_back (endPoint);
87  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
88  return endPoint;
89 }
90 
92 {
93  NS_LOG_FUNCTION (this << address);
94  uint16_t port = AllocateEphemeralPort ();
95  if (port == 0)
96  {
97  NS_LOG_WARN ("Ephemeral port allocation failed.");
98  return 0;
99  }
100  Ipv6EndPoint *endPoint = new Ipv6EndPoint (address, port);
101  m_endPoints.push_back (endPoint);
102  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
103  return endPoint;
104 }
105 
107 {
108  NS_LOG_FUNCTION (this << port);
109 
110  return Allocate (Ipv6Address::GetAny (), port);
111 }
112 
114 {
115  NS_LOG_FUNCTION (this << address << port);
116  if (LookupLocal (address, port))
117  {
118  NS_LOG_WARN ("Duplicate address/port; failing.");
119  return 0;
120  }
121  Ipv6EndPoint *endPoint = new Ipv6EndPoint (address, port);
122  m_endPoints.push_back (endPoint);
123  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
124  return endPoint;
125 }
126 
127 Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address localAddress, uint16_t localPort,
128  Ipv6Address peerAddress, uint16_t peerPort)
129 {
130  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
131  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
132  {
133  if ((*i)->GetLocalPort () == localPort
134  && (*i)->GetLocalAddress () == localAddress
135  && (*i)->GetPeerPort () == peerPort
136  && (*i)->GetPeerAddress () == peerAddress)
137  {
138  NS_LOG_WARN ("No way we can allocate this end-point.");
139  /* no way we can allocate this end-point. */
140  return 0;
141  }
142  }
143  Ipv6EndPoint *endPoint = new Ipv6EndPoint (localAddress, localPort);
144  endPoint->SetPeer (peerAddress, peerPort);
145  m_endPoints.push_back (endPoint);
146 
147  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
148 
149  return endPoint;
150 }
151 
153 {
155  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
156  {
157  if (*i == endPoint)
158  {
159  delete endPoint;
160  m_endPoints.erase (i);
161  break;
162  }
163  }
164 }
165 
166 /*
167  * If we have an exact match, we return it.
168  * Otherwise, if we find a generic match, we return it.
169  * Otherwise, we return 0.
170  */
172  Ipv6Address saddr, uint16_t sport,
173  Ptr<Ipv6Interface> incomingInterface)
174 {
175  NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);
176 
177  EndPoints retval1; /* Matches exact on local port, wildcards on others */
178  EndPoints retval2; /* Matches exact on local port/adder, wildcards on others */
179  EndPoints retval3; /* Matches all but local address */
180  EndPoints retval4; /* Exact match on all 4 */
181 
182  NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
183  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
184  {
185  Ipv6EndPoint* endP = *i;
186  NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
187  << " daddr=" << endP->GetLocalAddress ()
188  << " sport=" << endP->GetPeerPort ()
189  << " saddr=" << endP->GetPeerAddress ());
190  if (endP->GetLocalPort () != dport)
191  {
192  NS_LOG_LOGIC ("Skipping endpoint " << &endP
193  << " because endpoint dport "
194  << endP->GetLocalPort ()
195  << " does not match packet dport " << dport);
196  continue;
197  }
198 
199  if (endP->GetBoundNetDevice ())
200  {
201  if (endP->GetBoundNetDevice () != incomingInterface->GetDevice ())
202  {
203  NS_LOG_LOGIC ("Skipping endpoint " << &endP
204  << " because endpoint is bound to specific device and"
205  << endP->GetBoundNetDevice ()
206  << " does not match packet device " << incomingInterface->GetDevice ());
207  continue;
208  }
209  }
210 
211  /* Ipv6Address incomingInterfaceAddr = incomingInterface->GetAddress (); */
212  NS_LOG_DEBUG ("dest addr " << daddr);
213 
214  bool localAddressMatchesWildCard = endP->GetLocalAddress () == Ipv6Address::GetAny ();
215  bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
216  bool localAddressMatchesAllRouters = endP->GetLocalAddress () == Ipv6Address::GetAllRoutersMulticast ();
217 
218  /* if no match here, keep looking */
219  if (!(localAddressMatchesExact || localAddressMatchesWildCard))
220  {
221  continue;
222  }
223  bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
224  bool remotePeerMatchesWildCard = endP->GetPeerPort () == 0;
225  bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
226  bool remoteAddressMatchesWildCard = endP->GetPeerAddress () == Ipv6Address::GetAny ();
227 
228  /* If remote does not match either with exact or wildcard,i
229  skip this one */
230  if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
231  {
232  continue;
233  }
234  if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
235  {
236  continue;
237  }
238 
239  /* Now figure out which return list to add this one to */
240  if (localAddressMatchesWildCard
241  && remotePeerMatchesWildCard
242  && remoteAddressMatchesWildCard)
243  { /* Only local port matches exactly */
244  retval1.push_back (endP);
245  }
246  if ((localAddressMatchesExact || (localAddressMatchesAllRouters))
247  && remotePeerMatchesWildCard
248  && remoteAddressMatchesWildCard)
249  { /* Only local port and local address matches exactly */
250  retval2.push_back (endP);
251  }
252  if (localAddressMatchesWildCard
253  && remotePeerMatchesExact
254  && remoteAddressMatchesExact)
255  { /* All but local address */
256  retval3.push_back (endP);
257  }
258  if (localAddressMatchesExact
259  && remotePeerMatchesExact
260  && remoteAddressMatchesExact)
261  { /* All 4 match */
262  retval4.push_back (endP);
263  }
264  }
265 
266  /* Here we find the most exact match */
267  if (!retval4.empty ())
268  {
269  return retval4;
270  }
271  if (!retval3.empty ())
272  {
273  return retval3;
274  }
275  if (!retval2.empty ())
276  {
277  return retval2;
278  }
279  return retval1; /* might be empty if no matches */
280 }
281 
282 Ipv6EndPoint* Ipv6EndPointDemux::SimpleLookup (Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
283 {
284  uint32_t genericity = 3;
285  Ipv6EndPoint *generic = 0;
286 
287  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
288  {
289  uint32_t tmp = 0;
290 
291  if ((*i)->GetLocalPort () != dport)
292  {
293  continue;
294  }
295 
296  if ((*i)->GetLocalAddress () == dst && (*i)->GetPeerPort () == sport
297  && (*i)->GetPeerAddress () == src)
298  {
299  /* this is an exact match. */
300  return *i;
301  }
302 
303  if ((*i)->GetLocalAddress () == Ipv6Address::GetAny ())
304  {
305  tmp++;
306  }
307 
308  if ((*i)->GetPeerAddress () == Ipv6Address::GetAny ())
309  {
310  tmp++;
311  }
312 
313  if (tmp < genericity)
314  {
315  generic = (*i);
316  genericity = tmp;
317  }
318  }
319  return generic;
320 }
321 
323 {
325  uint16_t port = m_ephemeral;
326  int count = m_portLast - m_portFirst;
327  do
328  {
329  if (count-- < 0)
330  {
331  return 0;
332  }
333  ++port;
334  if (port < m_portFirst || port > m_portLast)
335  {
336  port = m_portFirst;
337  }
338  }
339  while (LookupPortLocal (port));
340  m_ephemeral = port;
341  return port;
342 }
343 
345 {
346  return m_endPoints;
347 }
348 
349 } /* namespace ns3 */
350 
Ipv6Address GetLocalAddress()
Get the local address.
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
std::list< Ipv6EndPoint * > EndPoints
Container of the IPv6 endpoints.
EndPoints Lookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr< Ipv6Interface > incomingInterface)
lookup for a match with all the parameters.
uint16_t m_ephemeral
The ephemeral port.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
std::list< Ipv6EndPoint * >::iterator EndPointsI
Iterator to the container of the IPv6 endpoints.
EndPoints m_endPoints
A list of IPv6 end points.
bool LookupLocal(Ipv6Address addr, uint16_t port)
Lookup for address and port.
uint16_t port
Definition: dsdv-manet.cc:44
uint16_t GetPeerPort()
Get the peer port.
uint16_t GetLocalPort()
Get the local port.
Ipv6EndPoint * Allocate(void)
Allocate a Ipv6EndPoint.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
uint16_t m_portLast
The last ephemeral port.
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
bool LookupPortLocal(uint16_t port)
Lookup for port local.
Ipv6EndPoint * SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
Simple lookup for a four-tuple match.
uint16_t m_portFirst
The first ephemeral port.
Describes an IPv6 address.
Definition: ipv6-address.h:46
#define NS_LOG_WARN(msg)
Definition: log.h:280
Ipv6Address GetPeerAddress()
Get the peer address.
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
A representation of an internet IPv6 endpoint/connection.
tuple address
Definition: first.py:37
uint16_t AllocateEphemeralPort()
Allocate a ephemeral port.
Ptr< NetDevice > GetBoundNetDevice(void)
Returns socket's bound netdevice, if any.
EndPoints GetEndPoints() const
Get the entire list of end points registered.
void SetPeer(Ipv6Address addr, uint16_t port)
Set the peer informations (address and port).
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.