src/node/ipv4-end-point-demux.h
changeset 238 2f09fd9cf32e
child 240 7da682f99bf9
equal deleted inserted replaced
237:6562b2679455 238:2f09fd9cf32e
       
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2005 INRIA
       
     4  * All rights reserved.
       
     5  *
       
     6  * This program is free software; you can redistribute it and/or modify
       
     7  * it under the terms of the GNU General Public License version 2 as
       
     8  * published by the Free Software Foundation;
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13  * GNU General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License
       
    16  * along with this program; if not, write to the Free Software
       
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    18  *
       
    19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
       
    20  */
       
    21 
       
    22 #ifndef IPV4_END_POINT_DEMUX_H
       
    23 #define IPV4_END_POINT_DEMUX_H
       
    24 
       
    25 #include <stdint.h>
       
    26 #include <list>
       
    27 #include "ns3/ipv4-address.h"
       
    28 
       
    29 namespace ns3 {
       
    30 
       
    31 class Ipv4EndPoint;
       
    32 
       
    33 template <typename T>
       
    34 class Ipv4EndPointDemux {
       
    35 public:
       
    36   Ipv4EndPointDemux ();
       
    37   ~Ipv4EndPointDemux ();
       
    38 
       
    39   bool LookupPortLocal (uint16_t port);
       
    40   bool LookupLocal (Ipv4Address addr, uint16_t port);
       
    41   T *Lookup (Ipv4Address daddr, 
       
    42              uint16_t dport, 
       
    43              Ipv4Address saddr, 
       
    44              uint16_t sport);
       
    45 
       
    46   T *Allocate (void);
       
    47   T *Allocate (Ipv4Address address);
       
    48   T *Allocate (Ipv4Address address, uint16_t port);
       
    49   T *Allocate (Ipv4Address localAddress, 
       
    50                uint16_t localPort,
       
    51                Ipv4Address peerAddress, 
       
    52                uint16_t peerPort);
       
    53 
       
    54  private:
       
    55   uint16_t AllocateEphemeralPort (void);
       
    56   typedef std::list<T *> EndPoints;
       
    57   typedef std::list<T *>::iterator EndPointsI;
       
    58 
       
    59   uint16_t m_ephemeral;
       
    60   EndPoints m_endPoints;
       
    61 };
       
    62 
       
    63 }; // namespace ns3
       
    64 
       
    65 namespace ns3{
       
    66 
       
    67 template <typename T>
       
    68 Ipv4EndPointDemux<T>::Ipv4EndPointDemux ()
       
    69   : m_ephemeral (1025)
       
    70 {}
       
    71 
       
    72 template <typename T>
       
    73 Ipv4EndPointDemux<T>::~Ipv4EndPointDemux ()
       
    74 {}
       
    75 
       
    76 template <typename T>
       
    77 bool
       
    78 Ipv4EndPointDemux<T>::LookupPortLocal (uint16_t port)
       
    79 {
       
    80   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
       
    81     {
       
    82       if ((*i)->GetLocalPort  () == port) 
       
    83         {
       
    84           return true;
       
    85         }
       
    86     }
       
    87   return false;
       
    88 }
       
    89 
       
    90 template <typename T>
       
    91 bool
       
    92 Ipv4EndPointDemux<T>::LookupLocal (Ipv4Address addr, uint16_t port)
       
    93 {
       
    94   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
       
    95     {
       
    96       if ((*i)->GetLocalPort () == port &&
       
    97           (*i)->GetLocalAddress () == addr) 
       
    98         {
       
    99           return true;
       
   100         }
       
   101     }
       
   102   return false;
       
   103 }
       
   104 
       
   105 template <typename T>
       
   106 T *
       
   107 Ipv4EndPointDemux<T>::Allocate (void)
       
   108 {
       
   109   uint16_t port = AllocateEphemeralPort ();
       
   110   if (port == 0) 
       
   111     {
       
   112       return 0;
       
   113     }
       
   114   T *endPoint = new T (Ipv4Address::GetAny (), port);
       
   115   m_endPoints.push_back (endPoint);
       
   116   return endPoint;
       
   117 }
       
   118 template <typename T>
       
   119 T *
       
   120 Ipv4EndPointDemux<T>::Allocate (Ipv4Address address)
       
   121 {
       
   122   uint16_t port = AllocateEphemeralPort ();
       
   123   if (port == 0) 
       
   124     {
       
   125       return 0;
       
   126     }
       
   127   T *endPoint = new T (address, port);
       
   128   endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this));
       
   129   m_endPoints.push_back (endPoint);
       
   130   return endPoint;
       
   131 }
       
   132 template <typename T>
       
   133 T *
       
   134 Ipv4EndPointDemux<T>::Allocate (Ipv4Address address, uint16_t port)
       
   135 {
       
   136   if (LookupLocal (address, port)) 
       
   137     {
       
   138       return 0;
       
   139     }
       
   140   T *endPoint = new T (address, port);
       
   141   endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this));
       
   142   m_endPoints.push_back (endPoint);
       
   143   return endPoint;
       
   144 }
       
   145 
       
   146 template <typename T>
       
   147 T *
       
   148 Ipv4EndPointDemux<T>::Allocate (Ipv4Address localAddress, uint16_t localPort,
       
   149                                 Ipv4Address peerAddress, uint16_t peerPort)
       
   150 {
       
   151   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
       
   152     {
       
   153       if ((*i)->GetLocalPort () == localPort &&
       
   154           (*i)->GetLocalAddress () == localAddress &&
       
   155           (*i)->GetPeerPort () == peerPort &&
       
   156           (*i)->GetPeerAddress () == peerAddress) 
       
   157         {
       
   158           /* no way we can allocate this end-point. */
       
   159           return 0;
       
   160         }
       
   161     }
       
   162   T *endPoint = new T (localAddress, localPort);
       
   163   endPoint->SetPeer (peerAddress, peerPort);
       
   164   endPoint->SetDestroyCallback (MakeCallback (&Ipv4EndPointDemux::DestroyEndPoint, this));
       
   165   m_endPoints.push_back (endPoint);
       
   166   return endPoint;
       
   167 }
       
   168 
       
   169 
       
   170 /*
       
   171  * If we have an exact match, we return it.
       
   172  * Otherwise, if we find a generic match, we return it.
       
   173  * Otherwise, we return 0.
       
   174  */
       
   175 template <typename T>
       
   176 T *
       
   177 Ipv4EndPointDemux<T>::Lookup (Ipv4Address daddr, uint16_t dport, 
       
   178                               Ipv4Address saddr, uint16_t sport)
       
   179 {
       
   180   uint32_t genericity = 3;
       
   181   T *generic = 0;
       
   182   //TRACE ("lookup " << daddr << ":" << dport << " " << saddr << ":" << sport);
       
   183   for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
       
   184     {
       
   185 #if 0
       
   186       TRACE ("against " << 
       
   187              (*i)->GetLocalAddress ()
       
   188              << ":" << 
       
   189              (*i)->GetLocalPort () 
       
   190              << " " << 
       
   191              (*i)->GetPeerAddress () 
       
   192              << ":" 
       
   193              << (*i)->GetPeerPort ());
       
   194 #endif
       
   195       if ((*i)->GetLocalPort () != dport) 
       
   196         {
       
   197           continue;
       
   198         }
       
   199       if ((*i)->GetLocalAddress () == daddr &&
       
   200           (*i)->GetPeerPort () == sport &&
       
   201           (*i)->GetPeerAddress () == saddr) 
       
   202         {
       
   203           /* this is an exact match. */
       
   204           return *i;
       
   205         }
       
   206       uint32_t tmp = 0;
       
   207       if ((*i)->GetLocalAddress () == Ipv4Address::GetAny ()) 
       
   208         {
       
   209           tmp ++;
       
   210         }
       
   211       if ((*i)->GetPeerAddress () == Ipv4Address::GetAny ()) 
       
   212         {
       
   213           tmp ++;
       
   214         }
       
   215       if (tmp < genericity) 
       
   216         {
       
   217           generic = (*i);
       
   218           genericity = tmp;
       
   219         }
       
   220     }
       
   221   return generic;
       
   222 }
       
   223 
       
   224 template <typename T>
       
   225 uint16_t
       
   226 Ipv4EndPointDemux<T>::AllocateEphemeralPort (void)
       
   227 {
       
   228   uint16_t port = m_ephemeral;
       
   229   do 
       
   230     {
       
   231       port++;
       
   232       if (port > 5000) 
       
   233         {
       
   234           port = 1024;
       
   235         }
       
   236       if (!LookupPortLocal (port)) 
       
   237         {
       
   238           return port;
       
   239         }
       
   240   } while (port != m_ephemeral);
       
   241   return 0;
       
   242 }
       
   243 
       
   244 
       
   245 
       
   246 }//namespace ns3
       
   247 
       
   248 
       
   249 #endif /* IPV4_END_POINTS_H */