servlib/conv_layers/EthConvergenceLayer.h
changeset 0 2b3e5ec03512
equal deleted inserted replaced
-1:000000000000 0:2b3e5ec03512
       
     1 /*
       
     2  *    Copyright 2004-2006 Intel Corporation
       
     3  * 
       
     4  *    Licensed under the Apache License, Version 2.0 (the "License");
       
     5  *    you may not use this file except in compliance with the License.
       
     6  *    You may obtain a copy of the License at
       
     7  * 
       
     8  *        http://www.apache.org/licenses/LICENSE-2.0
       
     9  * 
       
    10  *    Unless required by applicable law or agreed to in writing, software
       
    11  *    distributed under the License is distributed on an "AS IS" BASIS,
       
    12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    13  *    See the License for the specific language governing permissions and
       
    14  *    limitations under the License.
       
    15  */
       
    16 
       
    17 #ifndef _ETH_CONVERGENCE_LAYER_H_
       
    18 #define _ETH_CONVERGENCE_LAYER_H_
       
    19 
       
    20 // Only works on Linux (for now)
       
    21 #ifdef __linux__ 
       
    22 
       
    23 #include <sys/types.h>
       
    24 #include <netinet/in.h>
       
    25 #include <linux/if.h>
       
    26 
       
    27 #include <oasys/thread/Thread.h>
       
    28 #include <oasys/thread/Timer.h>
       
    29 
       
    30 #include "ConvergenceLayer.h"
       
    31 #include "naming/EthernetScheme.h" // for eth_addr_t
       
    32 
       
    33 /** 
       
    34  *   The EthConvergenceLayer provides access to any ethernet interfaces that
       
    35  *  support RAW sockets. It periodically sends beacons out on each interface
       
    36  *  to support neighbor discovery. (this may change later). 
       
    37  *
       
    38  *   To add an ethernet interface in your config file, use:
       
    39  *
       
    40  *   interface add eth string://eth0
       
    41  *
       
    42  *   Theoretically, any router type should work, but so far, the only one I've
       
    43  *   been using is the NeighborhoodRouter. To use this router, add this to dtn.conf
       
    44  *  
       
    45  *   route set type neighborhood
       
    46  *
       
    47  */
       
    48 namespace dtn {
       
    49 
       
    50 class EthConvergenceLayer : public ConvergenceLayer {
       
    51 
       
    52 public:
       
    53     class BeaconTimer;
       
    54 
       
    55     /**
       
    56      * Current version of the protocol.
       
    57      */
       
    58     static const u_int8_t  ETHCL_VERSION = 0x01;
       
    59     static const u_int16_t ETHERTYPE_DTN = 0xd710;
       
    60 
       
    61     static const u_int8_t  ETHCL_BEACON = 0x01;
       
    62     static const u_int8_t  ETHCL_BUNDLE = 0x02;
       
    63 
       
    64     static const u_int32_t ETHCL_BEACON_TIMEOUT_INTERVAL = 2500; // 2.5 seconds
       
    65 
       
    66     static const u_int16_t MAX_ETHER_PACKET = 1518;
       
    67 
       
    68     /**
       
    69      * Maximum bundle size
       
    70      */
       
    71     static const u_int MAX_BUNDLE_LEN = 65507;
       
    72     
       
    73     /**
       
    74      * The basic Eth header structure.
       
    75      */
       
    76     struct EthCLHeader {
       
    77         u_int8_t  version;              ///< ethcl protocol version
       
    78         u_int8_t  type;                 ///< 
       
    79         u_int16_t _padding2;            ///< 
       
    80         u_int32_t bundle_id;            ///< bundle identifier at sender
       
    81     } __attribute__((packed));
       
    82 
       
    83     /**
       
    84      * Data state of a Eth cl
       
    85      *
       
    86      */
       
    87     class EthCLInfo : public CLInfo {
       
    88       public:
       
    89         EthCLInfo(char* if_name) {
       
    90             memset(if_name_,0,IFNAMSIZ);
       
    91             strcpy(if_name_,if_name);
       
    92             timer    = NULL;
       
    93         }
       
    94 
       
    95         ~EthCLInfo() {
       
    96           if(timer)
       
    97               delete timer;
       
    98         }
       
    99 
       
   100         // Name of the device 
       
   101         char if_name_[IFNAMSIZ];
       
   102 
       
   103         BeaconTimer* timer;
       
   104     };
       
   105 
       
   106     /**
       
   107      * Constructor.
       
   108      */
       
   109     EthConvergenceLayer();
       
   110         
       
   111     /**
       
   112      * Bring up a new interface.
       
   113      */
       
   114     bool interface_up(Interface* iface, int argc, const char* argv[]);
       
   115 
       
   116     /**
       
   117      * Bring down the interface.
       
   118      */
       
   119     bool interface_down(Interface* iface);
       
   120 
       
   121     /**
       
   122      * Open the connection to a given contact and send/listen for 
       
   123      * bundles over this contact.
       
   124      */
       
   125     bool open_contact(const ContactRef& contact);
       
   126     
       
   127     /**
       
   128      * Close the connnection to the contact.
       
   129      */
       
   130     bool close_contact(const ContactRef& contact);
       
   131 
       
   132     /**
       
   133      * Delete any CL-specific components of the Link.
       
   134      */
       
   135     void delete_link(const LinkRef& link);
       
   136 
       
   137     /**
       
   138      * Send the bundle to the contact
       
   139      */
       
   140     void bundle_queued(const LinkRef& link, const BundleRef& bundle);
       
   141 
       
   142     /**
       
   143      * Report if the given bundle is queued on the given link.
       
   144      */
       
   145     bool is_queued(const LinkRef& contact, Bundle* bundle);
       
   146     
       
   147     /**
       
   148      * Tunable parameter structure.
       
   149      *
       
   150      * Per-link and per-interface settings are configurable via
       
   151      * arguments to the 'link add' and 'interface add' commands.
       
   152      *
       
   153      * The parameters are stored in each Link's CLInfo slot, as well
       
   154      * as part of the Receiver helper class.
       
   155      */
       
   156     class Params : public CLInfo {
       
   157     public:
       
   158         u_int32_t beacon_interval_;       ///< Beacon Interval
       
   159     };
       
   160     
       
   161     /**
       
   162      * Default parameters.
       
   163      */
       
   164     static Params defaults_;
       
   165     
       
   166     /**
       
   167      * Helper class (and thread) that listens on a registered
       
   168      * interface for incoming data.
       
   169      */
       
   170     class Receiver : public CLInfo,
       
   171                      public oasys::Logger,
       
   172                      public oasys::Thread
       
   173     {
       
   174     public:
       
   175         /**
       
   176          * Constructor.
       
   177          */
       
   178         Receiver(const char *if_name, EthConvergenceLayer::Params* params);
       
   179 
       
   180         /**
       
   181          * Destructor.
       
   182          */
       
   183         virtual ~Receiver() {}
       
   184         
       
   185         /**
       
   186          * Loop forever, issuing blocking calls to IPSocket::recvfrom(),
       
   187          * then calling the process_data function when new data does
       
   188          * arrive
       
   189          * 
       
   190          * Note that unlike in the Thread base class, this run() method is
       
   191          * public in case we don't want to actually create a new thread
       
   192          * for this guy, but instead just want to run the main loop.
       
   193          */
       
   194         void run();
       
   195         
       
   196     protected:
       
   197         /**
       
   198          * Handler to process an arrived packet.
       
   199          */
       
   200         void process_data(u_char* bp, size_t len);
       
   201         char if_name_[IFNAMSIZ];
       
   202     };
       
   203 
       
   204 
       
   205 
       
   206     /**
       
   207      * Helper class (and thread) that manages an "established"
       
   208      * connection with a peer daemon (virtual connection in the
       
   209      * case of Eth).
       
   210      *
       
   211      * Only the sender side of the connection needs to initiate
       
   212      * a connection. The receiver will just receive data. Therefore,
       
   213      * we don't need a passive side of a connection
       
   214      */
       
   215     class Sender : public CLInfo,
       
   216                    public oasys::Logger
       
   217     {
       
   218     public:
       
   219         /**
       
   220          * Constructor for the active connection side of a connection.
       
   221          */
       
   222         Sender(char* if_name, const ContactRef& contact);
       
   223 
       
   224         /**
       
   225          * Destructor.
       
   226          */
       
   227         virtual ~Sender() {}
       
   228         
       
   229     protected:
       
   230         friend class EthConvergenceLayer;
       
   231         
       
   232         /**
       
   233          * Send one bundle.
       
   234          */
       
   235         bool send_bundle(const BundleRef& bundle);
       
   236 
       
   237         /// The contact that we're representing
       
   238         ContactRef contact_;
       
   239         
       
   240         /// Socket identifier
       
   241         int sock_;
       
   242 
       
   243         /// MAC address of the interface used for this contact
       
   244         eth_addr_t src_hw_addr_;
       
   245         eth_addr_t dst_hw_addr_; 
       
   246 
       
   247         /// The name of the interface the next_hop is behind
       
   248         char if_name_[IFNAMSIZ]; 
       
   249         
       
   250         char canary_[7];
       
   251 
       
   252        /**
       
   253         * Temporary buffer for formatting bundles. Note that the
       
   254         * fixed-length buffer is big enough since UDP packets can't
       
   255         * be any bigger than that.
       
   256         */
       
   257         u_char buf_[EthConvergenceLayer::MAX_BUNDLE_LEN];
       
   258     };
       
   259 
       
   260     /** 
       
   261      *  helper class (and thread) that periodically sends beacon messages
       
   262      *  over the specified ethernet interface.
       
   263      */
       
   264     class Beacon : public oasys::Logger,
       
   265                    public oasys::Thread
       
   266     {
       
   267     public:
       
   268         Beacon(const char* if_name, unsigned int beacon_interval);
       
   269 
       
   270         virtual ~Beacon() {};
       
   271 
       
   272     private:
       
   273         virtual void run();
       
   274         char if_name_[IFNAMSIZ];
       
   275         unsigned int beacon_interval_;
       
   276     };
       
   277 
       
   278     class BeaconTimer : public oasys::Logger, public oasys::Timer, public CLInfo {
       
   279     public:
       
   280         char * next_hop_;
       
   281 
       
   282         BeaconTimer(char * next_hop);
       
   283         ~BeaconTimer();
       
   284 
       
   285         void timeout(const struct timeval& now);
       
   286 
       
   287         Timer* copy();
       
   288     };    
       
   289 
       
   290 protected:
       
   291     /**
       
   292      * Parses parameters during EthConvegenceLayer initialization
       
   293      */
       
   294     bool parse_params(Params* params, int argc, const char** argv,
       
   295                       const char** invalidp);
       
   296 
       
   297 private:
       
   298     Beacon *if_beacon_;
       
   299 };
       
   300 
       
   301 
       
   302 } // namespace dtn
       
   303 
       
   304 #endif // __linux
       
   305 
       
   306 #endif /* _ETH_CONVERGENCE_LAYER_H_ */