NSIS-ka
A free C++ implementation of NSIS protocols

Changeset 4147


Ignore:
Timestamp:
Jul 21, 2009, 6:02:36 PM (8 years ago)
Author:
bless
Message:
  • merged in changes from current trunk, reverted changes from r3121 and r3185, compiles at least
Location:
ntlp/branches/20081127-merge-mobility-mk3
Files:
2 deleted
53 edited
5 copied

Legend:

Unmodified
Added
Removed
  • ntlp/branches/20081127-merge-mobility-mk3

  • ntlp/branches/20081127-merge-mobility-mk3/Changelog

    r2956 r4147  
     1gist-ka-0.97 (rxxxx):
     2=====================
     3        - upgrade to draft -20: now using C-Flag in common header to
     4          indicate Query encapsulation (was introduced in draft -17)
     5        - Invalid C Flag error handling
     6        - added check for reception of own Query, there will be a warning and it will be ignored
     7        - added additional consistency check for stack configuration data and stack profile
     8        - modified tp_queryencap to also intercept packets that have no RAO set, if the new option
     9          intercept-requires-rao==false
     10        - tp_queryencap will check for the C-Flag if intercept-requires-rao==false
     11          (otherwise normal Confirm and Data Packets in C-mode will be captured by
     12          tp_queryencap, too)
     13        - use of configpar class for configuration parameters:
     14          consistent naming of parameters at command line, config file,
     15          and interactive console
     16        - improved GISTConsole to set all available GIST parameters
     17        - implemented NAT traversal (early stage)
     18        - improved responder cookie mechanism to carry transparent data, too
     19        - cleaned up code for setting the RAO (Micha Lenk)
     20        - several smaller bug fixes
     21       
     22
    123gist-ka-0.96 (r2957):
    224=====================
  • ntlp/branches/20081127-merge-mobility-mk3/GIST-KA-RELEASE

    r2963 r4147  
    11GIST_VERSION=0
    2 GIST_PATCHLEVEL=96
    3 GIST_SUBLEVEL=1
     2GIST_PATCHLEVEL=97
     3GIST_SUBLEVEL=0
    44GIST_EXTRAVERSION=
    55ifdef GIST_SUBLEVEL
  • ntlp/branches/20081127-merge-mobility-mk3/gist

    r2520 r4147  
    1 #! /bin/sh
     1#!/bin/bash
    22
    33LOGDIR=testing/logs
     
    55if [ \! -d $LOGDIR ]; then   mkdir $LOGDIR; fi
    66
     7# define a signal handler function
     8handle_sigint()
     9{
     10        true
     11}
     12
    713# load kernel modules
    814./loadmodules
     15# activate the signal handler
     16# This signal handler is called after all child processes (i.e. gist)
     17# have been signaled SIGINT and have terminated and gives control back
     18# to the script
     19trap handle_sigint SIGINT
    920
    10 src/gistka $* 2>&1 | tee $LOGDIR/test-`date +"%F-%T"`-`hostname`-$$
     21src/gistka --config ../nsis-ka.conf $* 2>&1 | tee $LOGDIR/test-`date +"%F-%T"`-`hostname`-$$
    1122
    1223./flush
  • ntlp/branches/20081127-merge-mobility-mk3/include/apimessage.h

    r3565 r4147  
    223223        void set_sendmessage(nslpdata* data, msghandle_t nslpmsghandle, uint32 nslpid, sessionid* sid, mri* mr, tx_attr_t tx_attr, uint32 timeout, uint16 ip_ttl, uint32 ghc);
    224224
    225         // XXXMOB: replace if_index by an address
    226         void set_recvmessage(nslpdata* data, uint32 nslpid, sessionid* sid, mri* mr, bool adjacency_check, uint32 sii_handle, tx_attr_t tx_attr, uint16 ip_ttl, uint16 ip_distance, uint32 ghc);
    227         void set_recvmessage(nslpdata* data, appladdress *own_addr, uint32 nslpid, sessionid* sid, mri* mr, bool adjacency_check, uint32 sii_handle, tx_attr_t tx_attr, uint16 ip_ttl, uint16 ip_distance, uint32 ghc);
     225        void set_recvmessage(nslpdata* data, uint32 nslpid, sessionid* sid, mri* mr, bool adjacency_check, uint32 sii_handle, tx_attr_t tx_attr, uint16 ip_ttl, uint16 ip_distance, uint32 ghc, uint16 inbound_if_index= 0);
     226        void set_recvmessage(nslpdata* data, appladdress *own_addr, uint32 nslpid, sessionid* sid, mri* mr, bool adjacency_check, uint32 sii_handle, tx_attr_t tx_attr, uint16 ip_ttl, uint16 ip_distance, uint32 ghc, uint16 inbound_if_index= 0);
    228227        void set_recvmessageanswer(uint32 nslpid, sessionid* sid, mri* mr, nslpdata* data, status_t directive);
    229228        void set_messagestatus(uint32 nslpid, sessionid* sid, msghandle_t nslpmsghandle, tx_attr_t tx_attr, error_t error);
     
    328327        void set_local_addr(hostaddress *ls) {local_addr = ls;}
    329328
     329        /// inbound interface index
     330        void set_inbound_ifidx(uint16 if_index) { inbound_if_index= if_index; }
     331
     332        /// returns inbound interface index (that of the incoming query)
     333        uint16 get_inbound_ifidx() const { return inbound_if_index; }
     334        /// is the inbound interface an internal i/f? (inside NAT)
     335        uint16 is_inbound_if_internal() const { return inbound_if_internal; }
     336
    330337private:
    331338        subtype_t subtype;
     
    392399        /// The local source this message should be sent from
    393400        hostaddress *local_addr;
     401
     402        /// interface index on which the message was received
     403        uint16 inbound_if_index;
     404        /// inbound interface location (internal/external)
     405        bool inbound_if_internal;
    394406
    395407        static const char* const error_t_str[];
  • ntlp/branches/20081127-merge-mobility-mk3/include/mri.h

    r3489 r4147  
    7070        virtual appladdress* determine_dest_address() const = 0;
    7171
     72        /// returns the appropriate local outgoing interface for the flow
     73        virtual uint16 get_local_if() const = 0;
     74   
    7275        /// returns the IP Version
    7376        virtual uint8 get_ip_version() const = 0;
  • ntlp/branches/20081127-merge-mobility-mk3/include/mri_est.h

    r3489 r4147  
    114114        virtual appladdress* determine_dest_address() const { return new appladdress(dest_signaling_addr,prot_udp,GIST_default_port); }
    115115
     116        // Returns the appropriate local outgoing interface for the flow
     117        virtual uint16 get_local_if() const { return mri_pc.get_local_if(); }
     118   
    116119        // Returns the IP Version
    117120        virtual uint8 get_ip_version() const { return mri_pc.get_ip_version(); }
  • ntlp/branches/20081127-merge-mobility-mk3/include/mri_le.h

    r3489 r4147  
    7878
    7979        virtual appladdress* determine_dest_address() const;
     80        virtual uint16 get_local_if() const;
    8081        virtual void invertDirection();
    8182
  • ntlp/branches/20081127-merge-mobility-mk3/include/mri_pc.h

    r3489 r4147  
    9494
    9595        virtual appladdress* determine_dest_address() const;
     96        virtual uint16 get_local_if() const;
    9697
    9798
  • ntlp/branches/20081127-merge-mobility-mk3/include/ntlp_ie.h

    r2886 r4147  
    154154                error_gist_invalid_r_flag,
    155155                error_gist_invalid_e_flag,
     156                error_gist_invalid_c_flag,
    156157                error_gist_missing_magic_number,
    157158                error_gist_no_routing_state,
     
    440441
    441442
     443// Invalid C flag  object
     444class GIST_InvalidCFlag : public GIST_Error {
     445public:
     446    /// constructor
     447    GIST_InvalidCFlag(IE::coding_t cod, uint8 version, uint8 hops, uint16 length, uint16 nslpid, uint8 type, uint8 flags);
     448    const IE::coding_t coding;
     449    const uint8 version;
     450    const uint8 hops;
     451    const uint16 length;
     452    const uint16 nslpid;
     453    const uint8 type;
     454    const uint8 flags;
     455
     456  gist_error_code_t errorcode() const { return error_gist_invalid_c_flag; }
     457  const char*getdescription() const { return "Invalid C Flag"; }
     458}; // end class InvalidCFlag
     459
     460
    442461
    443462//@}
  • ntlp/branches/20081127-merge-mobility-mk3/include/ntlp_object.h

    r2949 r4147  
    175175protected:
    176176        /// constructor
    177     known_ntlp_object(type_t t,  action_t a = Mandatory);
    178     known_ntlp_object(type_t t, subtype_t st, action_t a = Mandatory);
     177        known_ntlp_object(type_t t,  action_t a = Mandatory);
     178        known_ntlp_object(type_t t, subtype_t st, action_t a = Mandatory);
    179179        /// copy constructor
    180180        known_ntlp_object(const known_ntlp_object& n);
     
    182182        known_ntlp_object& operator=(const known_ntlp_object& n);
    183183public:
     184        virtual known_ntlp_object* copy() const = 0;
     185
    184186        /// get type
    185187        virtual uint16 get_type() const;
  • ntlp/branches/20081127-merge-mobility-mk3/include/ntlp_starter.h

    r3314 r4147  
    4343    using std::list;
    4444
    45 /// global variables
    46 
    47 // handle to access config parameters
    4845extern class NTLPStarter* global_ntlpstarterthread_p;
    49 
    5046
    5147/// starter module parameters
    5248struct NTLPStarterParam : public ThreadParam {
    53     NTLPStarterParam(uint16 udpport= GIST_default_port,                    ///< port on which to start TPoverUDP
    54                      uint16 tcpport= GIST_default_port,                    ///< port on which to start TPoverTCP (currently also hardcoded in some secret places...to be fixed)
    55                      uint16 tlsport= GIST_default_port+1,
    56                      uint16 sctpport= GIST_default_port,
    57                      uint32 retrylimit = retrylimit_default,   ///< retry upper limit for exponential backoffs
    58                      uint32 retryperiod = retryperiod_default, ///< Initial retry period in msec
    59                      float retryfactor = retryfactor_default,  ///< This factor is used to calculate local timeout values from peer's timeout values ~0.8?
    60                      uint32 rs_validity_time = rs_validity_time_default, ///< how long to keep state open, will be told to the peer, so he can calculate refresh period
    61                      uint32 refreshtime = refreshtime_default, ///< upper Boundary for Refresh Period -> small: better route change detection
    62                      uint32 ma_hold_time = ma_hold_time_default, ///< keep MA slightly longer than Upper Refresh Period boundary (makes no sense otherwise)
    63                      uint32 secrets_refreshtime = secrets_refreshtime_default,  ///< Secrets Roll-Over Time
    64                      uint32 secrets_count = secrets_count_default,      ///< count of local secrets hold at one time
    65                      uint32 secrets_length = secrets_length_default,    ///< length of local secrets in bit
    66                      bool latestate = latestate_default,                ///< is Late State Installation to be used?
    67                      bool confirmrequired = confirmrequired_default,    ///< always perform a full handshake?
    68                      bool senddatainquery = senddatainquery_default,    ///< send data in query?
    69                      bool reqhelloecho    = reqhelloecho_default,       ///< require to echo MA-Hellos?
    70                      bool sctpenable      = sctpenable_default,         ///< advertise SCTP in negotiation?
    71                      AddressList *addresses = NULL,
    72                      Flowinfo *fi_service = NULL,
    73                      const char *intercept_cmd = "./intercept",
    74                      bool debug_tp = false);
     49        AddressList *addresses;
     50        Flowinfo *fi_service;
    7551
    76     uint16 udpport;
    77     uint16 tcpport;
    78     uint16 tlsport;
    79     uint16 sctpport;
    80     AddressList *addresses;
    81     Flowinfo *fi_service;
    82     uint32 retrylimit;
    83     uint32 retryperiod;
    84     float retryfactor;
    85     uint32 rs_validity_time;
    86     uint32 refreshtime;
    87     uint32 ma_hold_time;
    88     uint32 secrets_refreshtime;
    89     uint32 secrets_count;
    90     uint32 secrets_length;
    91     bool latestate;
    92     bool confirmrequired;
    93     bool senddatainquery;
    94     bool reqhelloecho;
    95     bool sctpenable;
    96     const char *intercept_cmd;
    97     bool debug_tp;              // enable debugging output on TP level
    98 
    99   string to_string() const;
     52                NTLPStarterParam()   : ThreadParam(ThreadParam::default_sleep_time, "GIST Starter"), addresses(0), fi_service(0) {}
    10053}; // end NTLPStarterParam
    10154
  • ntlp/branches/20081127-merge-mobility-mk3/src/GISTConsole.cpp

    r3701 r4147  
    88// ===========================================================
    99//                     
    10 // Copyright (C) 2005-2007, all rights reserved by
     10// Copyright (C) 2005-2009, all rights reserved by
    1111// - Institute of Telematics, Universitaet Karlsruhe (TH)
    1212//
     
    4444#include "logfile.h"
    4545#include "apimessage.h"
    46 
     46#include "configfile.h"
    4747
    4848#include "GISTConsole.h"
    4949#include "ntlp_starter.h"
    5050#include "ntlp_statemodule.h"
     51#include "gist_conf.h"
    5152
    5253#include "mri_est.h"
     
    5455using namespace protlib::log;
    5556using namespace protlib;
     57using namespace ntlp;
    5658
    5759extern Thread* global_ntlpthread_p;
    5860
    5961namespace ntlp {
    60 
    6162const char *GISTConsoleDefaultPort= "40023";
     63}
    6264
    6365struct apiargs_t {
     
    108110  ostringstream os;
    109111  os << " APIargs" << endl
    110      << " handle:" << apiargs.nslpmsghandle << endl
    111      << " nslpid:" << apiargs.nslpid << endl
    112      << " sid:" << apiargs.mysid << endl
     112     << " handle: " << apiargs.nslpmsghandle << endl
     113     << " nslpid: " << apiargs.nslpid << endl
     114     << " sid: " << apiargs.mysid << endl
     115     << " flow src: " << apiargs.sourceaddress << endl
     116     << " flow dst: " << apiargs.destaddress << endl
     117     << " direction: " << (apiargs.downstream ? "downstream" : "upstream") << endl
    113118     << " pc mri:" << apiargs.pc_mri << endl
    114119     << " est mri:" << apiargs.est_mri << endl
    115120     << " sii handle:" << apiargs.siihandle << endl
    116      << (apiargs.tx_attr.reliable ? " reliable" : " unreliable") << endl
    117      << (apiargs.tx_attr.secure ? " secure" : " not secure") << endl
    118      << " timeout: " << apiargs.timeout << endl
    119      << "  IP ttl: " << apiargs.ip_ttl << endl
    120      << "  Gist Hop Count:" << apiargs.ghc << endl;
     121     << " transfer attributes: " << (apiargs.tx_attr.reliable ? " reliable" : " unreliable") << ", "
     122                                 << (apiargs.tx_attr.secure ? " secure" : " not secure") << endl
     123     << " timeout: " << dec << apiargs.timeout << endl
     124     << " IP ttl: " << apiargs.ip_ttl << endl
     125     << " Gist Hop Count:" << apiargs.ghc << endl
     126     << " Data:" << apiargs.nslpdata << endl;
    121127  return os.str();
    122128}
     
    145151        commands["set"] = &GISTConsole::set;
    146152        commands["show"] = &GISTConsole::show;
     153        commands["setpar"] = &GISTConsole::setpar;
     154        commands["showpar"] = &GISTConsole::showpar;
    147155        commands["sh"] = &GISTConsole::show;
    148156        commands["quit"] = &GISTConsole::quit;
     
    152160        commands["shutdown"] = &GISTConsole::shutdown;
    153161        commands["kill"] = &GISTConsole::shutdown;
     162        commands["saveconfig"]= &GISTConsole::saveconfig;
    154163
    155164        send_pdu_template = false;
    156165
    157166        QueueManager::instance()->register_queue(get_fqueue(), p.source);
     167
     168        // assumes that the configpar_repository is already created and initialized
     169        collectParNames();
     170
    158171        Log(DEBUG_LOG, LOG_NORMAL, "GISTConsole", "created");
     172}
     173
     174
     175void
     176GISTConsole::collectParNames()
     177{
     178        unsigned int max_pars= configpar_repository::instance()->getRealmSize(gist_realm);
     179        configparBase* cfgpar= NULL;
     180        for (unsigned int i= 0; i < max_pars; i++) {
     181                try {
     182                        // get config par with id i
     183                        cfgpar= configpar_repository::instance()->getConfigPar(gist_realm, i);
     184                        // store mapping from configpar name to parameter id i
     185                        if (cfgpar)
     186                                parname_map[cfgpar->getName()]= i;
     187                } // end try
     188                catch (configParExceptionParNotRegistered) {
     189                        cfgpar= NULL;
     190                        continue;
     191                } // end catch
     192                catch (...) {
     193                  throw;
     194                }
     195        } // end for
    159196}
    160197
     
    194231        (void) setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
    195232        if (bind(sockfd, res->ai_addr, res->ai_addrlen) == -1) {
    196                 Log(ERROR_LOG, LOG_ALERT, "GISTConsole", "bind: " << strerror(errno));
     233                ERRLog("GISTConsole", "bind: " << strerror(errno));
    197234                return;
    198235        }
    199236        if (listen(sockfd, 1) == -1) {
    200                 Log(ERROR_LOG, LOG_ALERT, "GISTConsole", "listen: " << strerror(errno));
     237                ERRLog("GISTConsole", "listen: " << strerror(errno));
    201238                return;
    202239        }
     
    206243        socklen_t clientaddr_len = sizeof(clientaddr);
    207244
    208         Log(DEBUG_LOG, LOG_NORMAL, "GISTConsole", "waiting for client to connect");
     245        DLog("GISTConsole", "waiting for client to connect");
    209246        while (get_state()==STATE_RUN) {
    210247                poll_fd.fd = sockfd;
     
    280317                                typedef map<string, cmd_func_t>::iterator CI;
    281318                                pair<CI,CI> cr = commands.equal_range(args.front());
     319                                if (cr.first == commands.end())
     320                                { // nothing found
     321                                        out_buf = "# Unknown command '" + args.front() + "', try 'help'.\n";
     322                                        send();
     323                                        ret = ERROR;
     324                                        break;
     325                                                                               
     326                                }
    282327                                if (cr.first == cr.second) {
    283                                         out_buf = "# Did you mean '" + (*cr.first).first + "'?\n";
     328                                        out_buf = "# Did you mean '" + (cr.first)->first + "'?\n";
    284329                                        send();
    285330                                        ret = OK;
    286331                                        break;
    287332                                }
    288                                 if ((*cr.first).first != args.front()) {
    289                                         out_buf = "# Unknown command '" + (*cr.first).first + "', try 'help'.";
     333                                if ((cr.first)->first != args.front()) {
     334                                        out_buf = "# Unknown command '" + (cr.first)->first + "', try 'help'.\n";
    290335                                        send();
     336                                        ret = ERROR;
     337                                        break;
    291338                                }
    292                                 ret = (this->*((*cr.first).second))();
     339                                // exact match
     340                                // call the assigned function for the given command name
     341                                ret = (this->*((cr.first)->second))();
    293342                                break;
    294343                        }
     
    349398GISTConsole::usage()
    350399{
     400  list<string>::const_iterator aa = args.begin();
     401
     402  out_buf="# ";
     403  bool emptyarg= (++aa == args.end()) ? true : false;
     404  if (emptyarg)
     405  {
    351406        map<string, cmd_func_t>::const_iterator ci = commands.begin();
    352407
    353         out_buf = "# ";
     408        out_buf = "# available commands\n# ";
    354409
    355410        while(ci != commands.end()) {
     
    357412                ci++;
    358413        }
    359         out_buf += "\n";
    360         send();
    361 
    362         return OK;
     414  }
     415  else
     416  {
     417          string parhelp= helppar(*aa);
     418          //  check for command or parameter name
     419          if (parhelp.empty() == false)
     420          {
     421                  out_buf += parhelp;
     422          }
     423          else
     424          {
     425                out_buf += "nothing special known about " + *aa + ", sorry can't help you any further";
     426          }
     427  }
     428  out_buf += "\n";
     429  send();
     430
     431  return OK;
    363432}
    364433
     
    417486}
    418487
     488
     489GISTConsole::cmd_return
     490GISTConsole::set_template(list<string>::const_iterator& aa)
     491{
     492        static const char *arg_names[] = {
     493          "nslpid",
     494          "src [ip]",
     495          "dest [ip]",
     496          "reliable [yes/no]",
     497          "secure [yes/no]",
     498                NULL
     499        };
     500        int i = 0;
     501
     502        out_buf = "# setting template ";
     503
     504        send_pdu_template = false;
     505
     506        NEXT_ARG();                             // nslpid
     507        apiargs.nslpid = atoi((*aa).c_str());
     508
     509
     510        NEXT_ARG();                             // src_ip
     511        if (!src_a.set_ip((*aa).c_str()))
     512                ARG_ERROR();
     513        else
     514          apiargs.sourceaddress=src_a;
     515
     516        NEXT_ARG();                             // dest_ip
     517        if (!dest_a.set_ip((*aa).c_str()))
     518                ARG_ERROR();
     519        else
     520          apiargs.destaddress=dest_a;
     521       
     522        NEXT_ARG();                             // reliable
     523        if (string("yes").find((*aa)) != string::npos) {
     524                apiargs.tx_attr.reliable = true;
     525        } else if (string("no").find((*aa)) != string::npos) {
     526                apiargs.tx_attr.reliable = false ;
     527        } else
     528                ARG_ERROR();
     529
     530        NEXT_ARG();                             // secure
     531        if (string("yes").find((*aa)) != string::npos) {
     532                apiargs.tx_attr.secure = true;
     533        } else if (string("no").find((*aa)) != string::npos) {
     534                apiargs.tx_attr.secure = false ;
     535        } else
     536                ARG_ERROR();
     537
     538        out_buf+= "\n";
     539        send();
     540        send_pdu_template = true;
     541
     542        return OK;
     543}
     544
     545
    419546GISTConsole::cmd_return
    420547GISTConsole::send_pdu()
     
    592719    {
    593720      out_buf = "# showing global config parameters:\n";
    594       out_buf += global_ntlpstarterthread_p->get_param().to_string();
     721      out_buf += gconf.to_string();
    595722    }
    596723    else
     
    633760
    634761GISTConsole::cmd_return
    635 GISTConsole::setsid(list<string>::const_iterator aa)
    636 {
    637   if (++aa != args.end())
     762GISTConsole::setsid(list<string>::const_iterator& aa)
     763{
     764  if (aa != args.end())
    638765  {
    639766    if (*aa == "new")
    640767    {
    641768      apiargs.mysid.generate_random();
    642       aa++;
    643769    }
    644770    else
     
    649775    }
    650776  }
     777  else
     778  {
     779          out_buf="# missing argument: either specify 'new' or a session id value";
     780          return MORE_ARGS;
     781  }
     782
    651783  return OK;
    652784}
     
    669801    "upstream",
    670802    "downstream",
     803    "reliable",
     804    "unreliable",
     805    "secure",
     806    "unsecure",
     807    "template",
    671808    NULL
    672809  };
     
    676813  bool unknownarg= (++aa == args.end()) ? true : false;
    677814
    678   out_buf += "# setting ";
     815  out_buf= "# setting ";
    679816
    680817  while (aa != args.end())
     
    682819    if (*aa == "sid")
    683820    {
    684       setsid(aa);
    685       out_buf += "sid to " + apiargs.mysid.to_string();
     821      aa++;
     822      if (aa != args.end())
     823      {
     824              setsid(aa);
     825              out_buf += "sid to " + apiargs.mysid.to_string();
     826      }
     827      else
     828      {
     829              out_buf += "sid failed, missing value ";
     830              break;
     831      }
    686832    }
    687833    else
     
    696842      else
    697843      {
    698         break;
     844              out_buf += " nslpid failed, missing value ";
     845              break;
    699846      }
    700847    }
     
    708855      }
    709856      else
     857      {
    710858        apiargs.sourceaddress=src_a;
     859        out_buf += "flowsrc to ";
     860        out_buf += apiargs.sourceaddress.get_ip_str();
     861      }
    711862    }
    712863    else
     
    719870      }
    720871      else
     872      {
    721873        apiargs.destaddress=dest_a;
     874        out_buf += "flowdst to ";
     875        out_buf+= apiargs.destaddress.get_ip_str();
     876      }
    722877    }
    723878    else
     
    731886        break;
    732887      }
    733       else
     888      else
     889      {
    734890        apiargs.est_mri.set_origin_sig_address(sigorigin);
     891        out_buf += "sigsrc to ";
     892        out_buf += sigorigin.get_ip_str();
     893      }
    735894    }
    736895    else
     
    745904      }
    746905      else
     906      {
    747907        apiargs.est_mri.set_dest_sig_address(sigdest);
     908        out_buf += "sigdst to ";
     909        out_buf += sigdest.get_ip_str();
     910      }
    748911    }
    749912    else
     
    759922      out_buf += "MRI direction to downstream";
    760923    }
     924    else
     925    if (*aa == "reliable")
     926    {   
     927            apiargs.tx_attr.reliable= true;
     928            out_buf += "transfer mode to reliable";
     929    }
     930    else
     931    if (*aa == "unreliable")
     932    {   
     933            apiargs.tx_attr.reliable= false;
     934            out_buf += "transfer mode to unreliable";
     935    }
     936    else
     937    if (*aa == "secure")
     938    {   
     939            apiargs.tx_attr.secure= true;
     940            out_buf += "transfer mode to secure";
     941    }
     942    else
     943    if (*aa == "unsecure")
     944    {   
     945            apiargs.tx_attr.secure= false;
     946            out_buf += "transfer mode to unsecure";
     947    }
     948    else
     949    if (*aa == "template")
     950    {   
     951            return set_template(aa);
     952    }
     953    else
     954    {
     955            out_buf= "# I don't know how to set this: " + *aa;
     956            unknownarg= true;
     957    }
    761958    aa++;
    762959  }
     
    764961  if (unknownarg)
    765962  {
    766     out_buf +="\n possible parameters to set:";
     963    out_buf +="# possible parameters to set:";
    767964    unsigned int i= 0;
    768965    while (alt_arg_names[i] != NULL)
     
    778975
    779976  return OK;
     977}
     978
     979
     980std::string
     981GISTConsole::parnamelist() const
     982{
     983        string parnames;
     984        for (parname_map_t::const_iterator cit= parname_map.begin(); cit !=  parname_map.end(); cit++)
     985        {
     986                if (parnames.length() > 0)
     987                        parnames+= ", ";
     988                parnames+= cit->first;
     989        } // end for
     990        return parnames;
     991}
     992
     993
     994std::string
     995GISTConsole::helppar(string parname)
     996{
     997        string helppartext;
     998        typedef parname_map_t::const_iterator PNI;
     999        pair<PNI,PNI> pn_pair_cit = parname_map.equal_range(parname);
     1000
     1001        configpar_id_t configparid= 0;
     1002        if ( pn_pair_cit.first != parname_map.end() ) // found entry for parameter
     1003        {
     1004                if (pn_pair_cit.first->first != parname)
     1005                {
     1006                        helppartext+= "nearest match, ";
     1007                }
     1008                configparid= (pn_pair_cit.first)->second;
     1009                configparBase* cfgpar= configpar_repository::instance()->getConfigPar(gist_realm, configparid);
     1010                helppartext+= "help for parameter `";
     1011                helppartext+= cfgpar->getName();
     1012                helppartext+= "': " + cfgpar->getDescription();
     1013        }
     1014        return helppartext;
     1015}
     1016
     1017
     1018GISTConsole::cmd_return
     1019GISTConsole::setpar()
     1020{
     1021  list<string>::const_iterator aa = args.begin();
     1022 
     1023  out_buf="# ";
     1024  bool emptyarg= (++aa == args.end()) ? true : false;
     1025  if (emptyarg)
     1026  {
     1027          out_buf+= "parameter name missing\n";
     1028          out_buf+= "# available parameters: " + GISTConsole::parnamelist() + '\n';
     1029          send();
     1030          return ERROR;
     1031  }
     1032
     1033  // aa now points to the token following setpar
     1034  string key= *aa;
     1035
     1036  // lookup parameter name
     1037  parname_map_t::const_iterator cit= parname_map.find(key);
     1038  configpar_id_t configparid= 0;
     1039  if ( cit == parname_map.end() )
     1040  {
     1041          out_buf+= "invalid/unknown parameter name `" + key + "'\n";
     1042          out_buf+= "# available parameters: " + GISTConsole::parnamelist();
     1043  }
     1044  else
     1045  {
     1046          // parameter name was found
     1047          configparid= cit->second;
     1048         
     1049          // treat rest of the input as parameter value(s)
     1050          aa++;
     1051          string parvaluestring;
     1052          // next argument(s) should be the parameter value(s), so collect them
     1053          while (aa != args.end())
     1054          {
     1055                  parvaluestring += *aa;
     1056                  aa++;
     1057                  if (aa != args.end())
     1058                          parvaluestring += ' ';
     1059          } // end while any more arguments
     1060
     1061          istringstream valinput(parvaluestring);
     1062          // read in the value
     1063          try {
     1064                  // get parameter from config repository
     1065                  configparBase* cfgpar= configpar_repository::instance()->getConfigPar(gist_realm, configparid);
     1066                  if (cfgpar->isChangeableWhileRunning())
     1067                  {
     1068                          cfgpar->readVal(valinput);
     1069                          out_buf+= "setting value for ";
     1070                          out_buf+= cfgpar->getName();
     1071                          out_buf+= ": ";
     1072                          ostringstream outstr;
     1073                          cfgpar->writeVal(outstr);
     1074                          out_buf+= outstr.str();
     1075                  }
     1076                  else
     1077                  {
     1078                          out_buf+= "refused to set parameter " + cfgpar->getName() + " while running! Value unchanged.";
     1079                  }
     1080          }
     1081          catch ( configParExceptionParseError &e ) {
     1082                  configparBase* cfgpar= configpar_repository::instance()->getConfigPar(gist_realm, configparid);
     1083                 
     1084                  out_buf+= "invalid value, parse error.\n Hint: `" + cfgpar->getName() + "' ";
     1085                  out_buf+= cfgpar->getDescription();
     1086          } // end catch parse exception
     1087  } // end else
     1088
     1089
     1090  out_buf +="\n";
     1091  send();
     1092
     1093  return OK;
     1094}
     1095
     1096GISTConsole::cmd_return
     1097GISTConsole::showpar()
     1098{
     1099  list<string>::const_iterator aa = args.begin();
     1100 
     1101  out_buf="# ";
     1102  bool emptyarg= (++aa == args.end()) ? true : false;
     1103  if (emptyarg)
     1104  {
     1105          out_buf+= "parameter name missing\n";
     1106          out_buf+= "# available parameters: " + GISTConsole::parnamelist() + '\n';
     1107          send();
     1108          return ERROR;
     1109  }
     1110
     1111  string key= *aa;
     1112
     1113  while (aa != args.end())
     1114  {
     1115          key= *aa;
     1116          parname_map_t::const_iterator cit= parname_map.find(key);
     1117          configpar_id_t configparid= 0;
     1118          if ( cit == parname_map.end() )
     1119          {
     1120                  out_buf+= "invalid/unknown parameter name `" + key + "'\n";
     1121                  out_buf+= "# available parameters: " + GISTConsole::parnamelist() + '\n';
     1122                  send();
     1123                  break;
     1124          }
     1125          else
     1126          {
     1127                  configparid= cit->second;
     1128
     1129                  // get parameter from config repository
     1130                  configparBase* cfgpar= configpar_repository::instance()->getConfigPar(gist_realm, configparid);
     1131
     1132                  out_buf+= "value of `";
     1133                  out_buf+= cfgpar->getName();
     1134                  out_buf+= "': ";
     1135                  ostringstream outstr;
     1136                  cfgpar->writeVal(outstr);
     1137                  out_buf+= outstr.str();
     1138                  out_buf +="\n";
     1139                  send();
     1140                  return OK;
     1141          }
     1142  }
     1143  return ERROR;
    7801144}
    7811145
     
    8101174
    8111175        if (!send_pdu_template) {
    812                 out_buf += "Set a template first!\n";
     1176                out_buf += "Set a template first by using the `set template' command!\n";
    8131177                send();
    8141178                return ERROR;
     
    8301194        samesid = atoi((*aa).c_str());
    8311195
    832         uint128 sid;
    833 
    834         out_buf = "# Sending ...\n";
    835         send();
    836         if (samesid) {
    837                 sid= apiargs.mysid;
    838         }
     1196        ostringstream outstr;
    8391197
    8401198        for (int i = 0; i < count; i++) {
     
    8421200                  apiargs.mysid.generate_random();
    8431201                }
    844                 out_buf = "# SID = 0x";
    845                 out_buf += apiargs.mysid.to_string();
    846                 out_buf += "\n";
     1202
     1203                outstr.clear();
     1204                outstr << "# Sending message #" << i << apiargs.mysid.to_string() << '\n';
     1205                out_buf = outstr.str();
    8471206                send();
    8481207
    849                 create_api_msg(sid)->send_to(message::qaddr_coordination);
    850 
     1208                apiargs.pc_mri.set_sourceaddress(apiargs.sourceaddress);
     1209                apiargs.pc_mri.set_destaddress(apiargs.destaddress);
     1210
     1211                create_api_msg(apiargs.mysid)->send_to(message::qaddr_coordination);
     1212
     1213                outstr.clear();
     1214                outstr << "# sleeping " << delay << " ms ...\n";
     1215                out_buf = outstr.str();
     1216                send();
     1217                               
    8511218                if (delay)
    8521219                        usleep(delay * 1000);
    8531220        }
     1221        out_buf = "# Multi send done.\n";
     1222        send();
    8541223
    8551224        return OK;
     
    8711240}
    8721241
    873 }
     1242
     1243GISTConsole::cmd_return
     1244GISTConsole::saveconfig()
     1245{
     1246  list<string>::const_iterator aa= args.begin();
     1247
     1248  if (++aa != args.end())
     1249  {
     1250            configfile save_cfgfile(configpar_repository::instance());
     1251            try {
     1252                    save_cfgfile.save(*aa);
     1253                    out_buf="# saved config to ";
     1254                    out_buf+= *aa + "\n";   
     1255            }
     1256            catch ( configfile_error &e ) {
     1257                    out_buf="# an error occured during saving the file:";
     1258                    out_buf+= e.what();
     1259                    out_buf+="\n";
     1260            }
     1261            catch ( ... ) {
     1262                    out_buf="# an error occured during saving the file.";
     1263            }
     1264            send();
     1265
     1266  }
     1267  else
     1268  {
     1269          out_buf="# missing argument: must specify a file name for saving the config\n";
     1270          send();
     1271          return ERROR;
     1272  }
     1273
     1274  return OK;
     1275       
     1276}
     1277
  • ntlp/branches/20081127-merge-mobility-mk3/src/GISTConsole.h

    r2949 r4147  
    77#include "logfile.h"
    88#include "address.h"
     9#include "gist_conf.h"
    910
    1011using namespace protlib::log;
     
    4748        list<string> args;
    4849
     50        typedef map<std::string, configpar_id_t> parname_map_t;
     51        parname_map_t parname_map;
     52
    4953        const GISTConsoleParam param;
    5054        int sockfd, clientfd;
     
    5761        cmd_return usage();
    5862
     63        void collectParNames();
     64
     65        // returns a string containing parameter names
     66        string parnamelist() const;
     67
     68        // returns descriptive help text for a parameter
     69        string helppar(string parname);
     70
    5971        hostaddress src_a, dest_a;
    6072        //known_nslp_pdu::type_t pdu_format;
    6173        bool send_pdu_template;
    6274        APIMsg* create_api_msg(uint128 sid, bool use_est_MRI= false);
    63         cmd_return setsid(list<string>::const_iterator aa);
     75        cmd_return setsid(list<string>::const_iterator& aa);
    6476
    6577        cmd_return set();
     78
     79        cmd_return set_template(list<string>::const_iterator& aa);
    6680
    6781        cmd_return send_pdu();
     
    7084
    7185        cmd_return multi_send();
     86       
     87        cmd_return saveconfig();
    7288
    7389        cmd_return show();
     90
     91        cmd_return setpar();
     92
     93        cmd_return showpar();
    7494
    7595        cmd_return shutdown();
  • ntlp/branches/20081127-merge-mobility-mk3/src/Makefile

    r3701 r4147  
    7777CFLAGS += $(FLOWINFO_CFLAGS)
    7878endif
    79 NTLP_OBJS=  $(patsubst %.cpp,%.o,$(NTLP_SRCS))
     79NTLP_ALLOBJS=  $(patsubst %.cpp,%.o,$(NTLP_SRCS))
     80NTLP_OBJS=  $(filter-out $(NTLP_MAIN_OBJ),$(NTLP_ALLOBJS))
     81
    8082
    8183DEPENDFILE := $(wildcard dependfile)
     
    127129PDU_INC         = ./pdu
    128130INCLUDE         = -I. -I$(PDU_INC) -I$(API_INC) -I$(PROTLIB_INC) -I$(FQUEUE_INC) $(SCTP_INCLUDE) $(GUI_INCLUDE)
    129 LIBDIRS         = $(SCTP_LIBSEARCH) $(GUI_LIBSEARCH)
     131LIBDIRS                = -L$(FQUEUE_SRC) -L$(PROTLIB_SRC) $(SCTP_LIBSEARCH) $(GUI_LIBSEARCH)
    130132
    131133SUBDIRS = $(PROTLIB_SRC)
     
    156158        test -x simpleclient && su -c 'chown root simpleclient ; chmod u+s simpleclient' ; true
    157159
    158 $(NTLPEXE):   ntlp_main.o $(GISTLIB) $(LIBS)
    159         $(CPP) $(CFLAGS) -o $@ ntlp_main.o -L . -lGIST $(LIBDIRS) $(SHLIBS) $(STATIC_LIBS)
     160$(NTLPEXE):   $(NTLP_MAIN_OBJ) $(GISTLIB) $(LIBS)
     161        $(CPP) $(CFLAGS) -o $@ $(NTLP_MAIN_OBJ) -L . -lGIST $(LIBDIRS) $(SHLIBS) $(STATIC_LIBS)
    160162
    161163$(GISTLIB): $(NTLP_OBJS)
     
    261263
    262264TAGS:
    263         - etags --language=c++ $(INC)/*.h $(NTLP_SRCS) $(PROTLIB_INC)/*.h $(PROTLIB_SRC)/*.cpp
     265        - etags --language-force=c++ $(INC)/*.h $(NTLP_SRCS) $(PROTLIB_INC)/*.h $(PROTLIB_SRC)/*.cpp
    264266
    265267
     
    285287           moc $< -o $@
    286288
    287 
    288 .PHONY: clean distclean dellogs clobber setperms TAGS depend dependfile
     289conftypecheck:
     290        grep -h getconfigpar $(NTLP_SRCS) ../include/*.h | perl -pe 's/.*getconfigpar.*<\s*([^\s]+[^>]+>?)\s*>\(([^)]+)\).*/\2 \1/' | sort | uniq
     291
     292.PHONY: clean distclean dellogs clobber setperms TAGS depend dependfile conftypecheck
    289293
    290294### DO NOT DELETE THIS LINE -- make depend depends on it.
  • ntlp/branches/20081127-merge-mobility-mk3/src/apimessage.cpp

    r3420 r4147  
    104104        payload_status(good),
    105105        payload_urgent(false),
    106         local_addr(0)
    107     {
     106        local_addr(0),
     107        inbound_if_index(0),
     108        inbound_if_internal(false)
     109{
    108110        payload_tx_attr.reliable=false;
    109111        payload_tx_attr.secure=false;
     
    212214                mri* mr, bool adjacency_check, uint32 sii_handle,
    213215                tx_attr_t tx_attr, uint16 ip_ttl, uint16 ip_distance,
    214                                  uint32 ghc) {
     216                                 uint32 ghc, uint16 inbound_if_idx) {
    215217
    216218            set_recvmessage(data, NULL, nslpid, sid, mr, adjacency_check,
    217                             sii_handle, tx_attr, ip_ttl, ip_distance, ghc);
    218     }
    219 
    220     void APIMsg::set_recvmessage(nslpdata* data, appladdress *own_addr, uint32 nslpid, sessionid* sid, mri* mr, bool adjacency_check, uint32 sii_handle, tx_attr_t tx_attr, uint16 ip_ttl, uint16 ip_distance, uint32 ghc){
     219                            sii_handle, tx_attr, ip_ttl, ip_distance, ghc, inbound_if_idx);
     220    }
     221
     222    void APIMsg::set_recvmessage(nslpdata* data, appladdress *own_addr, uint32 nslpid, sessionid* sid, mri* mr, bool adjacency_check, uint32 sii_handle, tx_attr_t tx_attr, uint16 ip_ttl, uint16 ip_distance, uint32 ghc, uint16 inbound_if_idx){
    221223
    222224
     
    239241        payload_ghc=ghc;
    240242
     243        inbound_if_index= inbound_if_idx;
    241244    }
    242245
  • ntlp/branches/20081127-merge-mobility-mk3/src/capability.cpp

    r2766 r4147  
    2929#include "capability.h"
    3030
    31 #include "ntlp_starter.h" // required to to access to config parameters (global_ntlpstarterthread_p)
    32 
    33 namespace ntlp {
     31#include "gist_conf.h" // required to to access to config parameters
     32
     33  using namespace ntlp;
    3434  using namespace protlib;
    3535  using namespace protlib::log;
     
    5555#ifdef _USE_SCTP
    5656  // 1st: SCTP @ port tcpport ( "3" == SCTP )
    57   if (global_ntlpstarterthread_p->get_param().sctpenable)
    58   {
    59     stackprofile_tmp=new stackprofile;
    60     stackprofile_tmp->addprotocol(stackprofile::MA_Protocol_ID_SCTP);
    61     stackprops.push_back(stackprofile_tmp);
    62     maopt_tmp=new ma_protocol_option(stackprofile::MA_Protocol_ID_SCTP,profindex,false);
    63     query_maopt_tmp=new ma_protocol_option(*maopt_tmp);
    64     querystackconfs.push_back(query_maopt_tmp); // omit options data for query
    65     maopt_tmp->add16(sctpport); // add port number for response
    66     stackconfs.push_back(maopt_tmp);
    67     profindex++;
    68   }
     57  stackprofile_tmp=new stackprofile;
     58  stackprofile_tmp->addprotocol(stackprofile::MA_Protocol_ID_SCTP);
     59  stackprops.push_back(stackprofile_tmp);
     60  maopt_tmp=new ma_protocol_option(stackprofile::MA_Protocol_ID_SCTP,profindex,false);
     61  query_maopt_tmp=new ma_protocol_option(*maopt_tmp);
     62  querystackconfs.push_back(query_maopt_tmp); // omit options data for query
     63  maopt_tmp->add16(sctpport); // add port number for response
     64  stackconfs.push_back(maopt_tmp);
     65  profindex++;
    6966#endif
    7067
     
    126123
    127124#ifdef _USE_SCTP
    128   // SCTP
    129   if (global_ntlpstarterthread_p->get_param().sctpenable)
    130   {
    131     reliableprotocols.push_back(prot_sctp);
    132   }
     125  reliableprotocols.push_back(prot_sctp);
    133126#endif
    134127
     
    155148  if (!secure)
    156149  {
    157     // if SCTP enabled, use it
    158     if (global_ntlpstarterthread_p->get_param().sctpenable)
     150    // if SCTP enabled and allowed to advertise, use it
     151    if (gconf.getpar<bool>(gistconf_advertise_sctp))
    159152    {
    160153      if (sp->find_profile(stackprofile::MA_Protocol_ID_SCTP, index))
     
    307300    for (unsigned int i = 0; i<stackprops.size();i++)
    308301    {
    309       if (stackprops[i])
    310         sp->add_profile(*stackprops[i]);
     302            if (stackprops[i])
     303            {
     304                    // only add SCTP if configured
     305                    if ( stackprops[i]->prof_vec[0] == stackprofile::MA_Protocol_ID_SCTP )
     306                    {
     307                            if (gconf.getpar<bool>(gistconf_advertise_sctp))
     308                            {
     309                                    //DLog("capability", "query_stackprop(): including SCTP");
     310                                    sp->add_profile(*stackprops[i]);
     311                            }
     312                            else
     313                            {
     314                                    //DLog("capability", "query_stackprop(): excluding SCTP, because advertising disabled by config");
     315                            }
     316                    }
     317                    else
     318                    { // no restrictions on other protocols so far
     319                            sp->add_profile(*stackprops[i]);
     320                    }
     321            }
    311322    } // end for
    312323  }
     
    336347    {
    337348      if (querystackconfs[i])
    338         sc->add_protoption(*querystackconfs[i]);
     349      {
     350              if (querystackconfs[i]->get_protocol() == stackprofile::MA_Protocol_ID_SCTP)
     351              {
     352                      if (gconf.getpar<bool>(gistconf_advertise_sctp))
     353                      {
     354                              sc->add_protoption(*querystackconfs[i]);
     355                      }
     356                      else
     357                      {
     358                              //DLog("capability", "query_stackconf(): excluding SCTP, because advertising disabled by config");
     359                      }
     360              }
     361              else
     362              {
     363                      sc->add_protoption(*querystackconfs[i]);
     364              }
     365      }
    339366    } // endfor
    340367  }
     
    349376  }
    350377
    351   sc->set_ma_hold_time(global_ntlpstarterthread_p->get_param().ma_hold_time); // ma_hold_time par is in ms
     378  sc->set_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time)); // ma_hold_time par is in ms
    352379  return sc;
    353380 
     
    367394    {
    368395      if (stackprops[i])
    369         sp2->add_profile(*stackprops[i]);
    370     }
     396      {
     397              // only add SCTP if configured
     398              if ( stackprops[i]->prof_vec[0] == stackprofile::MA_Protocol_ID_SCTP )
     399              {
     400                      if (gconf.getpar<bool>(gistconf_advertise_sctp))
     401                              sp2->add_profile(*stackprops[i]);                     
     402              }
     403              else
     404              { // no restrictions on other protocols so far
     405                      sp2->add_profile(*stackprops[i]);
     406              }
     407      }
     408    } // end for
    371409  }
    372410  else
     
    381419}
    382420
     421// create responder stack configuration data
     422// @param sc existing stack configuration data which is used to put the result in
     423//           may be NULL (then a new one is allocated)
    383424stack_conf_data*
    384425capability::resp_stackconf(stack_conf_data* sc, bool secure) const
     
    390431    for (unsigned int i = 0; i<stackconfs.size(); i++)
    391432    {
    392       if (stackconfs[i])
    393         sc2->add_protoption(*stackconfs[i]);
    394     }
     433            if (stackconfs[i])
     434            {
     435                    if (stackconfs[i]->get_protocol() == stackprofile::MA_Protocol_ID_SCTP)
     436                    {
     437                            if (gconf.getpar<bool>(gistconf_advertise_sctp))
     438                            {
     439                                    sc2->add_protoption(*stackconfs[i]);
     440                            }
     441                    }
     442                    else
     443                    {
     444                            sc2->add_protoption(*stackconfs[i]);
     445                    }
     446                   
     447            }
     448    } // end for
    395449  }
    396450  else
     
    403457  }
    404458
    405   sc2->set_ma_hold_time(global_ntlpstarterthread_p->get_param().ma_hold_time); // ma_hold_time par is in ms
     459  sc2->set_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time)); // ma_hold_time par is in ms
    406460  return sc2;
    407461 
     
    462516}
    463517
    464 
    465 } // end namespace
     518// compares a stack profile and stack configuration data
     519// and checks for consistency
     520bool
     521capability::is_consistent(const stackprop* sp, const stack_conf_data* sc) const
     522{
     523    if ( sp == NULL || sc == NULL )
     524                return true;
     525
     526    const ma_protocol_option* ma_prot_opt= NULL;
     527    const stackprofile* stackprof= NULL;
     528    uint8 profile_index= 0;
     529    // the following checks whether protocols at the
     530    // stack conf and stack profile are the same at the same index
     531    for (unsigned int i = 0; i<sc->length(); i++)
     532    {
     533            ma_prot_opt= sc->get_protoption(i);
     534            if ( ma_prot_opt )
     535            {
     536                    profile_index= ma_prot_opt->get_profile();
     537                    if (profile_index > 0)
     538                    {
     539                            stackprof= sp->get_profile(profile_index-1);
     540                            bool found_protid= false;
     541                            for (unsigned int j= 0; j<stackprof->prof_vec.size(); j++)
     542                                    if ( stackprof && ma_prot_opt->get_protocol() == stackprof->prof_vec.at(j) )
     543                                    {
     544                                            found_protid= true;
     545                                    }
     546                            if (!found_protid) // protocol mismatch at the profile index
     547                                    return false;
     548                    }
     549            }
     550    } // end for
     551    return true;
     552}
     553
  • ntlp/branches/20081127-merge-mobility-mk3/src/capability.h

    r2949 r4147  
    7474  bool accept_proposal(const stackprop* sp, bool secure = false) const;
    7575 
     76  bool is_consistent(const stackprop* sp, const stack_conf_data* sc) const;
     77 
    7678private:
    7779 
  • ntlp/branches/20081127-merge-mobility-mk3/src/gist_exceptions.h

    r2548 r4147  
    104104                sc_unknown_type         = 1,
    105105                sc_invalid_r_flag       = 2,
    106                 sc_incorrect_msg_length = 3
     106                sc_incorrect_msg_length = 3,
     107                sc_invalid_e_flag       = 4,
     108                sc_invalid_c_flag       = 5
    107109        };
    108110
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_main.cpp

    r3324 r4147  
    77// ===========================================================
    88//                     
    9 // Copyright (C) 2005-2007, all rights reserved by
     9// Copyright (C) 2005-2009, all rights reserved by
    1010// - Institute of Telematics, Universitaet Karlsruhe (TH)
    1111//
     
    7373#include "ntlp_starter.h"
    7474
     75#include "gist_conf.h"
     76#include "configfile.h"
     77
    7578#include "GISTConsole.h"
    7679
     
    8083#include <openssl/evp.h>
    8184
    82 
    8385using namespace ntlp;
    8486using namespace protlib;
     
    9799Thread* global_ntlpthread_p= 0;
    98100
    99 ///config array
     101namespace ntlp {
     102// configuration class
     103gistconf gconf;
     104}
     105
     106/// config array
    100107map<std::string, std::string> config;
    101108
     
    186193
    187194
    188 /** read in the config from config file
    189  *  @returns true if file was read, false if file could not be opened
    190  */
    191 bool
    192 read_config()
    193 {
    194     string temp;
    195     const unsigned short maxlinelen = 128;
    196 
    197     ifstream configfile;
    198     char line[maxlinelen];
    199 
    200     configfile.open(gist_configfilename, std::ios::in);
    201     if ( configfile.is_open() )
    202     {
    203       Log(DEBUG_LOG,LOG_NORMAL,"read_config()","Reading in Configuration file " << gist_configfilename);
    204     }
    205     else
    206     {
    207       Log(ERROR_LOG,LOG_CRIT,"read_config()","Reading Configuration file " << gist_configfilename << " failed.");
    208       return false;
    209     }
    210 
    211 
    212     while (!configfile.eof())
    213     {
    214       configfile.getline(line, maxlinelen);
    215       //std::cout<<line;
    216 
    217       temp = string(line);
    218 
    219       std::string::size_type pos  = std::string::npos;
    220        
    221       pos = temp.find_first_of("=", 0);
    222 
    223       if (pos)
    224       { // found =
    225         config[temp.substr(0, pos)] = temp.substr(pos + 1, temp.length());
    226       }
    227     }
    228 
    229     return true;
    230 }
    231195
    232196/// print the usage help
     
    244208        << "  display this help text" << endl
    245209
    246         << "  --ipv4-address <addr>         "
    247         << "  override the local IPv4 address" << endl
    248 
    249         << "  --ipv6-address <addr>         "
    250         << "  override the local IPv6 address" << endl
    251 
    252         << "  --udp-port <port>             "
    253         << "  the UDP port to use" << endl
    254 
    255         << "  --tcp-port <port>             "
    256         << "  the TCP port to use" << endl
    257 
    258         << "  --tls-port <port>             "
    259         << "  the TCP port to use for TLS over TCP" << endl
    260 
    261         << "  --retry-limit <num>           "
    262         << "  the upper retry limit (ms)" << endl
    263 
    264         << "  --retry-period <num>          "
    265         << "  the initial retry period (ms)" << endl
    266 
    267         << "  --refresh-limit <num>         "
    268         << "  the upper refresh period limit (ms)" << endl
    269 
    270         << "  --ma-hold-time <ms>           "
    271         << "  the hold time for message associations" << endl
    272 
    273         << "  --timing-factor <num>         "
    274         << "  for calculating local refresh timers" << endl
    275 
    276         << "  --lifetime <ms>               "
    277         << "  the life time of routing state" << endl
    278 
    279         << "  --secrets-count <num>         "
    280         << "  the secrets count" << endl
    281 
    282         << "  --secrets-length <num>        "
    283         << "  the secrets length in bits" << endl
    284 
    285         << "  --secrets-rollover-time <ms>  "
    286         << "  the secrets rollover time" << endl
    287 
    288         << "  --latestate <on|off>          "
    289         << "  use late state installation on responder" << endl
    290 
    291         << "  --reqconfirm <on|off>          "
    292         << "  require the full handshake even in D-Mode" << endl
    293         << "                                "
    294         << "  (and thus use cookie authentication)" << endl
    295 
    296         << "  --datainquery <on|off>          "
    297         << "  send NSLP data already in Query" << endl
    298 
    299 
    300         << "  --debug-tp                    "
    301         << "  enable debugging on TP level" << endl
     210        << "  --" << gconf.parname(gistconf_conffilename) << " <filename> "
     211        << "\t\t" << gconf.getDescription(gistconf_conffilename) << endl
     212
     213        << "  --" << gconf.parname(gistconf_localaddrv4) << " <addr> "
     214        << "\t\t" << gconf.getDescription(gistconf_localaddrv4) << endl
     215
     216        << "  --" << gconf.parname(gistconf_localaddrv6) << " <addr> "
     217        << "\t\t" << gconf.getDescription(gistconf_localaddrv6) << endl
     218
     219        << "  --" << gconf.parname(gistconf_udpport) << " <port> "
     220        << "\t\t" << gconf.getDescription(gistconf_udpport) << endl
     221
     222        << "  --" << gconf.parname(gistconf_tcpport) << " <port> "
     223        << "\t\t" << gconf.getDescription(gistconf_tcpport) << endl
     224
     225        << "  --" << gconf.parname(gistconf_tlsport) << " <port> "
     226        << "\t\t" << gconf.getDescription(gistconf_tlsport) << endl
     227
     228        << "  --" << gconf.parname(gistconf_retrylimit) << " <time> "
     229        << "\t\t" << gconf.getDescription(gistconf_retrylimit) << endl
     230
     231        << "  --" << gconf.parname(gistconf_retryperiod) << " <time> "
     232        << "\t\t" << gconf.getDescription(gistconf_retryperiod) << endl
     233
     234        << "  --" << gconf.parname(gistconf_retryfactor) << " <real> "
     235        << "\t\t" << gconf.getDescription(gistconf_retryfactor) << endl
     236
     237        << "  --" << gconf.parname(gistconf_ma_hold_time) << " <time> "
     238        << "\t\t" << gconf.getDescription(gistconf_ma_hold_time) << endl
     239
     240        << "  --" << gconf.parname(gistconf_refresh_limit) << " <time> "
     241        << "\t\t" << gconf.getDescription(gistconf_refresh_limit) << endl
     242
     243        << "  --" << gconf.parname(gistconf_rs_validity_time) << " <time> "
     244        << "\t\t" << gconf.getDescription(gistconf_rs_validity_time) << endl
     245
     246        << "  --" << gconf.parname(gistconf_secrets_count) << " <number> "
     247        << "\t\t" << gconf.getDescription(gistconf_secrets_count) << endl
     248
     249        << "  --" << gconf.parname(gistconf_secrets_length) << " <number> "
     250        << "\t\t" << gconf.getDescription(gistconf_secrets_length) << endl
     251
     252        << "  --" << gconf.parname(gistconf_secrets_refreshtime) << " <time> "
     253        << "\t\t" << gconf.getDescription(gistconf_secrets_refreshtime) << endl
     254
     255        << "  --" << gconf.parname(gistconf_latestate) << " <on/off> "
     256        << "\t\t" << gconf.getDescription(gistconf_latestate) << endl
     257
     258        << "  --" << gconf.parname(gistconf_confirmrequired) << " <on/off> "
     259        << "\t\t" << gconf.getDescription(gistconf_confirmrequired) << endl
     260
     261        << "  --" << gconf.parname(gistconf_senddatainquery) << " <on/off> "
     262        << "\t\t" << gconf.getDescription(gistconf_senddatainquery) << endl
     263
     264        << "  --" << gconf.parname(gistconf_reqhelloecho) << " <on/off> "
     265        << "\t\t" << gconf.getDescription(gistconf_reqhelloecho) << endl
     266
     267        << "  --" << gconf.parname(gistconf_advertise_sctp) << " <on/off> "
     268        << "\t\t" << gconf.getDescription(gistconf_advertise_sctp) << endl
     269
     270        << "  --" << gconf.parname(gistconf_debug_tp) << " <on/off> "
     271        << "\t\t" << gconf.getDescription(gistconf_debug_tp) << endl
     272
     273        << "  --" << gconf.parname(gistconf_intercept_cmd) << " <filename> "
     274        << "\t\t" << gconf.getDescription(gistconf_intercept_cmd) << endl
    302275
    303276        << "  --echo <nslpid>               "
    304277        << "  make this node listen to RAO <nslpid>, " << endl
    305278        << "  NSLPID <nslpid> and accept connections on " << endl
    306         << "  it (for testing)" << endl
    307 
    308         << "  --reqechohello <on|off>" << endl
    309         << "  request from peer to answer MA-Hellos, " << endl;
     279        << "  it (for testing)" << endl;
    310280}
    311281
    312 
    313 /*
    314  * A list of all valid command line options.
    315  */
    316 static char short_opts[] = "h";
    317 static struct option long_opts[] = {
    318         { "help",                       0, NULL, 'h' },
    319         { "latestate",                  1, NULL, 'l' },
    320         { "datainquery",                1, NULL, 'D' },
    321         { "echo",                       1, NULL, 'e' },
    322         { "reqconfirm",                 1, NULL, 'C' },
    323         { "reqhelloecho",               1, NULL, 'H' },
    324         { "ipv4-address",               1, NULL, 'a' },
    325         { "ipv6-address",               1, NULL, 'A' },
    326         { "udp-port",                   1, NULL, 'u' },
    327         { "tcp-port",                   1, NULL, 't' },
    328         { "tls-port",                   1, NULL, 'T' },
    329         { "sctp-port",                  1, NULL, 'S' },
    330         { "retry-limit",                1, NULL, 'r' },
    331         { "retry-period",               1, NULL, 'p' },
    332         { "timing-factor",              1, NULL, 'f' },
    333         { "lifetime",                   1, NULL, 'L' },
    334         { "refresh-limit",              1, NULL, 'R' },
    335         { "ma-hold-time",               1, NULL, 'm' },
    336         { "secrets-count",              1, NULL, 'c' },
    337         { "secrets-length",             1, NULL, 'n' },
    338         { "secrets-rollover-time",      1, NULL, 'o' },
    339         { "debug-tp",                   0, NULL, 'd' },
    340         { NULL,                         0, NULL, 0 },
    341 };
    342282
    343283
     
    349289static bool read_cmdline(int argc, char* argv[])
    350290{
     291/*
     292 * A list of all valid command line options.
     293 */
     294  char short_opts[] = "h";
     295  struct option long_opts[] = {
     296        { "help",                       0, NULL, 'h' },
     297        { gconf.parname(gistconf_conffilename).c_str(),    1, NULL, 'c' },
     298        { gconf.parname(gistconf_latestate).c_str(),       1, NULL, 'l' },
     299        { gconf.parname(gistconf_senddatainquery).c_str(), 1, NULL, 'D' },
     300        { "echo",                                                   1, NULL, 'e' },
     301        { gconf.parname(gistconf_confirmrequired).c_str(), 1, NULL, 'C' },
     302        { gconf.parname(gistconf_reqhelloecho).c_str(),    1, NULL, 'H' },
     303        { gconf.parname(gistconf_localaddrv4).c_str(),      1, NULL, 'a' },
     304        { gconf.parname(gistconf_localaddrv6).c_str(),      1, NULL, 'A' },
     305        { gconf.parname(gistconf_udpport).c_str(),          1, NULL, 'u' },
     306        { gconf.parname(gistconf_tcpport).c_str(),          1, NULL, 't' },
     307        { gconf.parname(gistconf_tlsport).c_str(),          1, NULL, 'T' },
     308        { gconf.parname(gistconf_sctpport).c_str(),         1, NULL, 'S' },
     309        { gconf.parname(gistconf_retrylimit).c_str(),       1, NULL, 'r' },
     310        { gconf.parname(gistconf_retryperiod).c_str(),      1, NULL, 'p' },
     311        { gconf.parname(gistconf_retryfactor).c_str(),      1, NULL, 'f' },
     312        { gconf.parname(gistconf_rs_validity_time).c_str(),1, NULL, 'L' },
     313        { gconf.parname(gistconf_refresh_limit).c_str(),    1, NULL, 'R' },
     314        { gconf.parname(gistconf_ma_hold_time).c_str(),    1, NULL, 'm' },
     315        { gconf.parname(gistconf_secrets_count).c_str(),   1, NULL, 's' },
     316        { gconf.parname(gistconf_secrets_length).c_str(),  1, NULL, 'n' },
     317        { gconf.parname(gistconf_secrets_refreshtime).c_str(),  1, NULL, 'o' },
     318        { gconf.parname(gistconf_debug_tp).c_str(),             0, NULL, 'd' },
     319        { NULL,                         0, NULL, 0 },
     320  };
     321
    351322  int c, opt_index;
    352323
     
    358329    switch ( c ) {
    359330      case 'h': printhelp(); exit(0); break;
    360       case 'l': config["LATE_STATE"] = optarg; break;
     331      case 'c': config[gconf.parname(gistconf_conffilename)] = optarg;
     332              gconf.setpar(gistconf_conffilename, string(optarg));
     333                break;
     334      case 'l': config[gconf.parname(gistconf_latestate)] = optarg; break;
    361335      case 'e': echo_nslpid = StringToInt(optarg);
    362336        startapimsgchecker = true;
    363337        break;
    364       case 'd': config["DEBUG_TP"] = optarg; break;
    365       case 'C': config["REQUIRE_CONFIRM"] = optarg; break;
    366       case 'H': config["REQUIRE_HELLOECHO"] = optarg; break;
    367       case 'D': config["DATA_IN_QUERY"] = optarg; break;
    368       case 'a': config["IPV4_ADDR"] = optarg; break;
    369       case 'A': config["IPV6_ADDR"] = optarg; break;
    370       case 'u': config["UDP_PORT"] = optarg; break;
    371       case 't': config["TCP_PORT"] = optarg; break;
    372       case 'T': config["TLS_PORT"] = optarg; break;
    373       case 'S': config["SCTP_PORT"] = optarg; break;
    374       case 'r': config["RETRY_LIMIT"] = optarg; break;
    375       case 'p': config["RETRY_PERIOD"] = optarg; break;
    376       case 'f': config["TIMING_FACTOR"] = optarg; break;
    377       case 'L': config["STATE_LIFETIME"] = optarg; break;
    378       case 'R': config["REFRESH_LIMIT"] = optarg; break;
    379       case 'm': config["MA_HOLD_TIME"] = optarg; break;
    380       case 'c': config["SECRETS_COUNT"] = optarg; break;
    381       case 'n': config["SECRETS_LENGTH"] = optarg; break;
    382       case 'o': config["SECRETS_ROLLOVER_TIME"] = optarg; break;
     338      case 'd': config[gconf.parname(gistconf_debug_tp)] = optarg; break;
     339      case 'C': config[gconf.parname(gistconf_confirmrequired)] = optarg; break;
     340      case 'H': config[gconf.parname(gistconf_reqhelloecho)] = optarg; break;
     341      case 'D': config[gconf.parname(gistconf_senddatainquery)] = optarg; break;
     342      case 'a': config[gconf.parname(gistconf_localaddrv4)] = optarg; break;
     343      case 'A': config[gconf.parname(gistconf_localaddrv6)] = optarg; break;
     344      case 'u': config[gconf.parname(gistconf_udpport)] = optarg; break;
     345      case 't': config[gconf.parname(gistconf_tcpport)] = optarg; break;
     346      case 'T': config[gconf.parname(gistconf_tlsport)] = optarg; break;
     347      case 'S': config[gconf.parname(gistconf_sctpport)] = optarg; break;
     348      case 'r': config[gconf.parname(gistconf_retrylimit)] = optarg; break;
     349      case 'p': config[gconf.parname(gistconf_retryperiod)] = optarg; break;
     350      case 'f': config[gconf.parname(gistconf_retryfactor)] = optarg; break;
     351      case 'L': config[gconf.parname(gistconf_rs_validity_time)] = optarg; break;
     352      case 'R': config[gconf.parname(gistconf_refresh_limit)] = optarg; break;
     353      case 'm': config[gconf.parname(gistconf_ma_hold_time)] = optarg; break;
     354      case 's': config[gconf.parname(gistconf_secrets_count)] = optarg; break;
     355      case 'n': config[gconf.parname(gistconf_secrets_length)] = optarg; break;
     356      case 'o': config[gconf.parname(gistconf_secrets_refreshtime)] = optarg; break;
    383357       
    384       default:  std::cerr << "Illegal chararacter "
    385                           << c << std::endl;
     358    default:    std::cerr << "Unknown option '" << (char) c << "'" << std::endl;
    386359        return false;
    387360        break;
     
    489462test(const char* logname)
    490463{
    491     list<hostaddress> ntlpv4addr;
    492     list<hostaddress> ntlpv6addr;
    493 
    494     if (config["IPV4_ADDR"]!="query") {
    495         std::stringstream in(config["IPV4_ADDR"]);
    496 
    497         while ( in ) {
    498                 bool success;
    499                 std::string token;
    500                 in >> token;
    501 
    502                 hostaddress addr(token.c_str(), &success);
    503 
    504                 if ( success && addr.is_ipv4() )
    505                         ntlpv4addr.push_back(addr);
    506         }
    507     }
    508 
    509     if (config["IPV6_ADDR"]!="query") {
    510         std::stringstream in(config["IPV6_ADDR"]);
    511 
    512         while ( in ) {
    513                 bool success;
    514                 std::string token;
    515                 in >> token;
    516 
    517                 hostaddress addr(token.c_str(), &success);
    518 
    519                 if ( success && addr.is_ipv6() )
    520                         ntlpv6addr.push_back(addr);
    521         }
    522     }
     464  hostaddresslist_t& ntlpv4addr= gconf.getparref< hostaddresslist_t >(gistconf_localaddrv4);
     465  hostaddresslist_t& ntlpv6addr= gconf.getparref< hostaddresslist_t >(gistconf_localaddrv6);
     466
     467  // check whether all addresses are really pure IPv4
     468  if (ntlpv4addr.empty() == false) {
     469    hostaddresslist_t::iterator it= ntlpv4addr.begin();
     470    while (it != ntlpv4addr.end())
     471    {
     472      if ( !it->is_ipv4() )
     473      {
     474        WLog("main", "Detected non IPv4 address, removing " << *it );
     475        it= ntlpv4addr.erase(it);
     476      }
     477      else
     478        it++;
     479    } // end while
     480  }
     481
     482  // check whether all addresses are really pure IPv6
     483  if (ntlpv6addr.empty() == false) {
     484    hostaddresslist_t::iterator it= ntlpv6addr.begin();
     485    while (it != ntlpv6addr.end())
     486    {
     487      if ( !it->is_ipv6() )
     488      {
     489        WLog("main", "Detected non-IPv6 address, removing " << *it );
     490        it= ntlpv6addr.erase(it);
     491      }
     492      else
     493        it++;
     494    } // end while
     495  }
    523496
    524497    // this will set default values
     
    531504   
    532505    if (ntlpv4addr.size() != 0) {
    533         list<hostaddress>::iterator it;
     506        hostaddresslist_t::iterator it;
    534507        for (it = ntlpv4addr.begin(); it != ntlpv4addr.end(); it++)
    535508            addresses->add_property(dynamic_cast<netaddress &>(*it));
     
    537510
    538511    if (ntlpv6addr.size() != 0) {
    539         list<hostaddress>::iterator it;
     512        hostaddresslist_t::iterator it;
    540513        for (it = ntlpv6addr.begin(); it != ntlpv6addr.end(); it++)
    541514            addresses->add_property(dynamic_cast<netaddress &>(*it));
     
    547520    // fill the parameters from configfile or command line
    548521    // (parameters given by command line will override these)
    549     if (config["UDP_PORT"].empty() == false)  ntlppar.udpport = StringToInt(config["UDP_PORT"]);
    550     if (config["TCP_PORT"].empty() == false)  ntlppar.tcpport = StringToInt(config["TCP_PORT"]);
    551     if (config["SCTP_PORT"].empty() == false) ntlppar.sctpport= StringToInt(config["SCTP_PORT"]);
    552     if (config["TLS_PORT"].empty() == false)  ntlppar.tlsport = StringToInt(config["TLS_PORT"]);
     522    if (config[gconf.parname(gistconf_udpport)].empty() == false)  gconf.setpar(gistconf_udpport, (uint16) StringToInt(config[gconf.parname(gistconf_udpport)]));
     523    if (config[gconf.parname(gistconf_tcpport)].empty() == false)  gconf.setpar(gistconf_tcpport, (uint16) StringToInt(config[gconf.parname(gistconf_tcpport)]));
     524    if (config[gconf.parname(gistconf_sctpport)].empty() == false) gconf.setpar(gistconf_sctpport, (uint16) StringToInt(config[gconf.parname(gistconf_sctpport)]));
     525    if (config[gconf.parname(gistconf_tlsport)].empty() == false)  gconf.setpar(gistconf_tlsport, (uint16) StringToInt(config[gconf.parname(gistconf_tlsport)]));
    553526   
    554     if (config["RETRY_LIMIT"          ].empty() == false) ntlppar.retrylimit    =    StringToInt(config[ "RETRY_LIMIT"          ]);
    555     if (config["RETRY_PERIOD"         ].empty() == false) ntlppar.retryperiod   =    StringToInt(config[ "RETRY_PERIOD"         ]);
    556     if (config["TIMING_FACTOR"        ].empty() == false) ntlppar.retryfactor   = StringToDouble(config[ "TIMING_FACTOR"        ]);
    557     if (config["STATE_LIFETIME"       ].empty() == false) ntlppar.rs_validity_time = StringToInt(config[ "STATE_LIFETIME"       ]);
    558     if (config["REFRESH_LIMIT"        ].empty() == false) ntlppar.refreshtime   =    StringToInt(config[ "REFRESH_LIMIT"        ]);
    559     if (config["MA_HOLD_TIME"         ].empty() == false) ntlppar.ma_hold_time    =  StringToInt(config[ "MA_HOLD_TIME"         ]);
    560     if (config["SECRETS_ROLLOVER_TIME"].empty() == false) ntlppar.secrets_refreshtime = StringToInt(config[ "SECRETS_ROLLOVER_TIME"]);
    561     if (config["SECRETS_COUNT"        ].empty() == false) ntlppar.secrets_count  =   StringToInt(config[ "SECRETS_COUNT"        ]);
    562     if (config["SECRETS_LENGTH"       ].empty() == false) ntlppar.secrets_length =   StringToInt(config[ "SECRETS_LENGTH"       ]);
    563     if (config["LATE_STATE"           ].empty() == false) ntlppar.latestate     =   StringToBool(config[ "LATE_STATE"           ]);
    564     if (config["DATA_IN_QUERY"        ].empty() == false) ntlppar.senddatainquery=  StringToBool(config[ "DATA_IN_QUERY"        ]);
    565     if (config["REQUIRE_CONFIRM"      ].empty() == false) ntlppar.confirmrequired=  StringToBool(config[ "REQUIRE_CONFIRM"    ]);
    566     if (config["REQUIRE_HELLOECHO"    ].empty() == false) ntlppar.reqhelloecho  =   StringToBool(config[ "REQUIRE_HELLOECHO"    ]);
    567     if (config["ADVERTISE_SCTP"       ].empty() == false) ntlppar.sctpenable    =   StringToBool(config[ "ADVERTISE_SCTP"       ]);
    568     if (config["DEBUG_TP"             ].empty() == false) ntlppar.debug_tp      =   StringToBool(config[ "DEBUG_TP"             ]);
     527    if (config[gconf.parname(gistconf_retrylimit)].empty() == false) gconf.setpar(gistconf_retrylimit, (uint32) StringToInt(config[ gconf.parname(gistconf_retrylimit)]));
     528    if (config[gconf.parname(gistconf_retryperiod)].empty() == false) gconf.setpar(gistconf_retryperiod, (uint32) StringToInt(config[ gconf.parname(gistconf_retryperiod)]));
     529    if (config[gconf.parname(gistconf_retryfactor)].empty() == false) gconf.setpar(gistconf_retryfactor, StringToDouble(config[ gconf.parname(gistconf_retryfactor)]));
     530    if (config[gconf.parname(gistconf_rs_validity_time)].empty() == false) gconf.setpar(gistconf_rs_validity_time, (uint32) StringToInt(config[ gconf.parname(gistconf_rs_validity_time)]));
     531    if (config[gconf.parname(gistconf_refresh_limit)].empty() == false) gconf.setpar(gistconf_refresh_limit, (uint32) StringToInt(config[ gconf.parname(gistconf_refresh_limit)]));
     532    if (config[gconf.parname(gistconf_ma_hold_time)].empty() == false) gconf.setpar(gistconf_ma_hold_time, (uint32) StringToInt(config[ gconf.parname(gistconf_ma_hold_time)]));
     533    if (config[gconf.parname(gistconf_secrets_refreshtime)].empty() == false) gconf.setpar(gistconf_secrets_refreshtime, (uint32) StringToInt(config[ gconf.parname(gistconf_secrets_refreshtime)]));
     534    if (config[gconf.parname(gistconf_secrets_count)].empty() == false) gconf.setpar(gistconf_secrets_count, (uint32) StringToInt(config[ gconf.parname(gistconf_secrets_count)]));
     535    if (config[gconf.parname(gistconf_secrets_length)].empty() == false) gconf.setpar(gistconf_secrets_length, (uint16) StringToInt(config[ gconf.parname(gistconf_secrets_length)]));
     536    if (config[gconf.parname(gistconf_latestate)].empty() == false) gconf.setpar(gistconf_latestate, StringToBool(config[ gconf.parname(gistconf_latestate)]));
     537    if (config[gconf.parname(gistconf_senddatainquery)].empty() == false) gconf.setpar(gistconf_senddatainquery, StringToBool(config[ gconf.parname(gistconf_senddatainquery)]));
     538    if (config[gconf.parname(gistconf_confirmrequired)].empty() == false) gconf.setpar(gistconf_confirmrequired, StringToBool(config[ gconf.parname(gistconf_confirmrequired)]));
     539    if (config[gconf.parname(gistconf_reqhelloecho)].empty() == false) gconf.setpar(gistconf_reqhelloecho, StringToBool(config[ gconf.parname(gistconf_reqhelloecho)]));
     540    if (config[gconf.parname(gistconf_advertise_sctp)].empty() == false) gconf.setpar(gistconf_advertise_sctp, StringToBool(config[ gconf.parname(gistconf_advertise_sctp)]));
     541    if (config[gconf.parname(gistconf_verbose_error_responses)].empty() == false) gconf.setpar(gistconf_verbose_error_responses, StringToBool(config[ gconf.parname(gistconf_verbose_error_responses)]));
     542    if (config[gconf.parname(gistconf_debug_tp)].empty() == false) gconf.setpar(gistconf_debug_tp, StringToBool(config[ gconf.parname(gistconf_debug_tp)]));
    569543
    570544#ifdef USE_FLOWINFO
     
    639613  logname<<argv[0]<<"."<<getpid()<<".log";
    640614
    641   // read configuration from config file
    642   if (read_config() == false)
    643   {
    644     // it's not that critical since we will use default values otherwise
    645   }
     615  // init gist configuration parameters
     616  gconf.repository_init();
     617  gconf.setRepository();
    646618
    647619  // process command line options, they should override the config file values, exit on error
     620  // it's not that critical since we will use default values otherwise
    648621  if ( read_cmdline(argc, argv) == false )
    649622        return 1;
     623
     624  // read configuration from config file
     625  configfile read_cfgfile(configpar_repository::instance());
     626
     627  // read in the config file
     628  read_cfgfile.load(gconf.getpar<string>(gistconf_conffilename));
     629
    650630
    651631  tsdb::init(true);
     
    655635  SSL_library_init();
    656636  OpenSSL_add_ssl_algorithms();
     637  // 2nd: load in all digests from OpenSSL
     638  OpenSSL_add_all_digests();
    657639  SSL_load_error_strings();
    658640
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_proto.cpp

    r3701 r4147  
    211211  if (pdu->get_type()==known_ntlp_pdu::Query)
    212212  {
    213     // Query must be sent via Query Encapsulation
    214     if (peeraddr.get_protocol() != prot_query_encap)
     213    // Query must be sent via Query Encapsulation (check for C-flag set)
     214    if ( pdu->get_C() == false )
    215215    {
    216216      //BINGO! This Query was coming to us accidentally. Tell the sender, he is doing somethin WEIRD
     
    241241    {
    242242      // check for NLI transport match
    243       if ((peeraddr.is_ipv4() && pdu->get_mri()->get_ip_version()!=4)
    244           ||
    245           (peeraddr.is_ipv6() && !peeraddr.is_mapped_ip() && pdu->get_mri()->get_ip_version()!=6))
    246 
     243      if (
     244           (peeraddr.is_ipv4() && pdu->get_mri()->get_ip_version()!=4)
     245           ||
     246           (peeraddr.is_ipv6() && !peeraddr.is_mapped_ip() && pdu->get_mri()->get_ip_version()!=6)
     247         )
    247248      {
    248249        ERRLog(NTLP::modname, "MRI IP version ("<< (int) pdu->get_mri()->get_ip_version() 
     
    265266  else
    266267  { // not a QUERY message
    267     if ((peeraddr.get_protocol() == prot_query_encap) && (pdu->get_type()!=known_ntlp_pdu::Data))
     268    if ( pdu->get_C() && (pdu->get_type()!=known_ntlp_pdu::Data))
    268269    {
    269270      //This is always NOT OUR FAULT, no one should send something other than a QUERY in QE mode
     
    444445
    445446  bool dgram = (peer.get_protocol() == prot_query_encap) || (peer.get_protocol() == tsdb::get_udp_id());
    446   bool qe = (peer.get_protocol() == prot_query_encap);
     447  bool qe = (peer.get_protocol() == prot_query_encap) || pdu->get_C();
    447448
    448449  //DLog(NTLP::modname,"generateErrorPdu() - entered, dgram:" << dgram << "query encap:" << qe); 
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_proto.h

    r3022 r4147  
    4343#include "logfile.h"
    4444
    45 #include <pthread.h>
    46 
     45#ifndef NSIS_OMNETPP_SIM
     46  // don't want this in the OMNet++ simulation
     47  #include <pthread.h>
     48#endif
    4749
    4850namespace ntlp {
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_starter.cpp

    r3701 r4147  
    8383#include "mri_est.h"
    8484
     85#include "gist_conf.h"
     86
    8587namespace ntlp {
    8688    using namespace protlib;
    8789    using namespace protlib::log;
    8890
    89   // global handle to access config parameters (initialized by constructor)
     91  // global handle to access state module object (initialized by constructor)
    9092  NTLPStarter* global_ntlpstarterthread_p= 0;
    91 
    92 /**
    93  *
    94  * NTLP Starter Module
    95  *
    96  *
    97  * Takes the following parameters (defaults are available, see ntlp_global_constants.h):
    98  *
    99  * @param udpport                  Choose a Signaling Port. Usually, this is the IANA-defined GIST port
    100  * @param tcpport                  Choose a Listening Port for TCP. Feel free to choose.
    101  * @param tlsport                  Choose a Listening Port for TCP/TLS. Feel free to choose.
    102  * @param sctpport                 Choose a Listening Port for SCTP. Feel free to choose.
    103  * @param addresses                The list of (local) addresses.
    104  * @param retrylimit               How many retries are performed? Upper limit (T2=64s) Note: exponential backoff!
    105  * @param retryperiod              Initial retry period in milliseconds
    106  * @param retryfactor              This factor is used to calculate the refresh period from peers timers
    107  * @param rs_validity_time         How many milliseconds should routing state be valid by default
    108  * @param refreshtime              Trigger GIST probing (refresh) every x milliseconds
    109  * @param ma_hold_time             Keep an inactive Messaging Association open for x milliseconds
    110  * @param secrets_refreshtime      Local secrets rollover time in seconds
    111  * @param secrets_count            Amount of local secrets
    112  * @param secrets_length           Length of local secrets in bit
    113  * @param latestate                  Use Late State Installation. Will not work in a NATed environment
    114  * @param confirmrequired            Require a full handshake at any time
    115  * @param senddatainquery            Send NSLP data also in query
    116  * @param reqhelloecho               Request a reply to an MA-hello
    117  * @param sctpenable                 Use SCTP in stack configuration if available
    118  * @param intercept_cmd              string that contains the name of the RAO interception script to be called
    119  * @param debug_tp                   debugging transport: if enabled each received or sent message is printed as hexdump
    120  */
    121 NTLPStarterParam::NTLPStarterParam(uint16 udpport,
    122                                    uint16 tcpport,
    123                                    uint16 tlsport,
    124                                    uint16 sctpport,
    125                                    uint32 retrylimit,
    126                                    uint32 retryperiod,
    127                                    float retryfactor,
    128                                    uint32 rs_validity_time,
    129                                    uint32 refreshtime,
    130                                    uint32 ma_hold_time,
    131                                    uint32 secrets_refreshtime,
    132                                    uint32 secrets_count,
    133                                    uint32 secrets_length,
    134                                    bool latestate,
    135                                    bool confirmrequired,
    136                                    bool senddatainquery,
    137                                    bool reqhelloecho,
    138                                    bool sctpenable,
    139                                    AddressList *addresses,
    140                                    Flowinfo *fi_service,
    141                                    const char *intercept_cmd,
    142                                    bool debug_tp)
    143   : ThreadParam(ThreadParam::default_sleep_time, "GIST Starter"),
    144     udpport(udpport),
    145     tcpport(tcpport),
    146     tlsport(tlsport),
    147     sctpport(sctpport),
    148     addresses(addresses),
    149     fi_service(fi_service),
    150     retrylimit(retrylimit),
    151     retryperiod(retryperiod),
    152     retryfactor(retryfactor),
    153     rs_validity_time(rs_validity_time),
    154     refreshtime(refreshtime),
    155     ma_hold_time(ma_hold_time),
    156     secrets_refreshtime(secrets_refreshtime),
    157     secrets_count(secrets_count),
    158     secrets_length(secrets_length),
    159     latestate(latestate),
    160     confirmrequired(confirmrequired),
    161     senddatainquery(senddatainquery),
    162     reqhelloecho(reqhelloecho),
    163     sctpenable(sctpenable),
    164     intercept_cmd(intercept_cmd),
    165     debug_tp(debug_tp)
    166 {
    167 }
    168 
    169 
    170 string
    171 NTLPStarterParam::to_string() const
    172 {
    173   ostringstream os;
    174 
    175   os << "UDP Port:                     " << udpport << endl;
    176   os << "TCP Port:                     " << tcpport << endl;
    177   os << "SCTP Port:                    " << sctpport << endl;
    178   os << "SCTP advertisment:            " << (sctpenable ? "enabled" : "disabled") << endl;
    179   typedef std::list<hostaddress>::const_iterator addr_iter;
    180  
    181 /*
    182  * XXXMOB:
    183   os << "Specified Local IPv4 addresses: {";
    184   for ( addr_iter i = localaddrv4.begin();
    185         i != localaddrv4.end(); i++ )
    186     os << " " << *i;
    187  
    188   os << " }" << endl;
    189  
    190   os << "Specified Local IPv6 addresses: {";
    191   for ( addr_iter i = localaddrv6.begin();
    192         i != localaddrv6.end(); i++ )
    193     os << " " << *i;
    194  
    195   os << " }" << endl;
    196 */
    197  
    198   os << "Retry Limit:                    " << retrylimit << " msec" << endl;
    199   os << "Initial Retry Period:           " << retryperiod << " msec" << endl;
    200   os << "Security Timing Factor:         " << retryfactor << endl;
    201   os << "Default Routing State Lifetime: " << rs_validity_time << " ms" << endl;
    202   os << "Maximum Upper Refresh Limit:    " << refreshtime << " ms" << endl;
    203   os << "MA Hold Time:                   " << ma_hold_time << " ms" << endl;
    204   os << "Secrets Rollover Time:          " << secrets_refreshtime <<"sec"<<endl;
    205   os << "Count of local secrets:         " << secrets_count << endl;
    206   os << "Length of local secrets:        " << secrets_length << endl;
    207   os << "Late State Installation:        " << latestate << endl;
    208   os << "Send NSLP Data in Query:        " << senddatainquery << endl;
    209   os << "Require Handshake:              " << confirmrequired << endl;
    210   os << "Debugging on TP level:          " << debug_tp << endl;
    211  
    212   return os.str();
    213 }
    214 
    21593
    21694
     
    235113{
    236114#ifndef _USE_SCTP
    237   param.sctpenable= false;
     115  // sctp cannot be used if not compiled
     116  gconf.setpar(gistconf_advertise_sctp, false);
    238117#endif
    239 
    240118  cout << color[blue] << gist_name << " v" << gist_releasestring
    241        << " ($Rev$ - development build) (C) 2005-2008 Universitaet Karlsruhe (TH)" << color[off] << endl;
     119       << " ($Rev$ - development build) (C) 2005-2009 Universitaet Karlsruhe (TH)" << color[off] << endl;
    242120  cout << endl;
    243121  cout << "Parameters:" << endl;
    244122  cout << "-----------------------------------------------------------------" << endl;
    245   cout << param.to_string();
    246   cout << "Digest Function:                " << "SHA1 by OpenSSL" << endl;
     123  cout << gconf.to_string();
    247124  cout << "-----------------------------------------------------------------" << endl;
    248125  cout << endl;
    249  
    250126 
    251127  // Register IEs
     
    301177  TPoverSCTPParam sctppar(ntlp_pdu::common_header_length,
    302178                          ntlp_pdu::decode_common_header_ntlpv1_clen,
    303                           (port_t) param.sctpport);
     179                          gconf.getpar<uint16>(gistconf_sctpport));
    304180 
    305181  ThreadStarter<TPoverSCTP,TPoverSCTPParam> sctptpthread(1,sctppar);
     
    313189  TPoverTCPParam tcppar(ntlp_pdu::common_header_length,
    314190                        ntlp_pdu::decode_common_header_ntlpv1_clen,
    315                         (port_t) param.tcpport,"TPoverTCP", 5000UL,
    316                         param.debug_tp);
     191                        (port_t) gconf.getpar<uint16>(gistconf_tcpport),"TPoverTCP", 5000UL,
     192                        gconf.getpar<bool>(gistconf_debug_tp));
    317193 
    318194 
     
    324200 
    325201 
    326   //start TPoverTLS
    327   TPoverTLS_TCPParam tlspar("client_cert.pem",
    328                             "client_privkey.pem",
    329                             "root_cert.pem",
     202  // start TPoverTLS
     203  TPoverTLS_TCPParam tlspar(gconf.getpar<string>(gistconf_tls_client_cert).c_str(),
     204                            gconf.getpar<string>(gistconf_tls_client_privkey).c_str(),
     205                            gconf.getpar<string>(gistconf_tls_cacert).c_str(),
    330206                            ntlp_pdu::common_header_length,
    331207                            ntlp_pdu::decode_common_header_ntlpv1_clen,
    332                             param.tlsport,"TPoverTLS_TCP", 5000UL,
    333                             param.debug_tp);
     208                            gconf.getpar<uint16>(gistconf_tlsport),"TPoverTLS_TCP", 5000UL,
     209                            gconf.getpar<bool>(gistconf_debug_tp));
    334210 
    335211 
     
    346222  TPoverUDPParam udppar(ntlp_pdu::common_header_length,
    347223                        ntlp_pdu::decode_common_header_ntlpv1_clen,
    348                         param.udpport,"TPoverUDP",5000UL, param.debug_tp);
     224                        gconf.getpar<uint16>(gistconf_udpport),
     225                        "TPoverUDP",
     226                        5000UL,
     227                        gconf.getpar<bool>(gistconf_debug_tp));
    349228 
    350229  ThreadStarter<TPoverUDP,TPoverUDPParam> udptpthread(1,udppar);
     
    364243  TPqueryEncapParam qepar(ntlp_pdu::common_header_length,
    365244                          ntlp_pdu::decode_common_header_ntlpv1_clen,
    366                           (port_t) param.udpport,
     245                          (port_t) gconf.getpar<uint16>(gistconf_udpport),
    367246                          raovec,
    368247                          udpproto,
     248                          gconf.getparref<bool>(gistconf_strict_rao),
    369249                          GIST_magic_number,
    370                           5000UL, param.debug_tp);
     250                          5000UL,
     251                          gconf.getpar<bool>(gistconf_debug_tp));
    371252 
    372253  ThreadStarter<TPqueryEncap,TPqueryEncapParam> qetpthread(1,qepar);
     
    378259 
    379260  DLog(param.name, "ports used: "
    380        << param.udpport << " (UDP), "
    381        << param.tcpport << " (TCP), "
    382        << param.sctpport << " (SCTP), "
    383        << param.tlsport << " (TLS over TCP)");
     261       << gconf.getpar<uint16>(gistconf_udpport) << " (UDP), "
     262       << gconf.getpar<uint16>(gistconf_tcpport) << " (TCP), "
     263       << gconf.getpar<uint16>(gistconf_sctpport) << " (SCTP), "
     264       << gconf.getpar<uint16>(gistconf_tlsport) << " (TLS over TCP)");
    384265 
    385266 
     
    407288 
    408289  @ Routing Table Object
    409   @ initial retry period (in msec) for exponential backoff retransmissions
    410   @ retry limit period for retransmissions
    411   @ retry factor: Multiplicate with rs_validity_time to get Refresh_QNode timer value (e.g. "0.8", "0.9")
    412   @ rs_validity_time: Default local state validity time in seconds
    413   @ refreshtime: Maximum local refrsh period (refresh based on peer rs_validity_time, if it is less than this parameter)
    414   @ MA-Hold-Time: The time Messaging Associations will be kept open -> Don't exceed the specific TP mod. timeout!!
    415290  @ Secretmanager Object
    416291  @ nslptable hashmap
     
    425300  */
    426301 
    427   secretmanager secrets(param.secrets_count, param.secrets_length);
     302  secretmanager secrets(gconf.getpar<uint32>(gistconf_secrets_count),
     303                        gconf.getpar<uint16>(gistconf_secrets_length));
    428304   
    429305  // PI
     
    436312  // ================================================================================================
    437313
    438   AddressList *addresses;
     314  AddressList *addresses= NULL;
    439315  if (param.addresses == 0) {
    440316    addresses = new AddressList();
    441317    addresses->add_host_prop(NULL, AddressList::ConfiguredAddr_P);
    442   } else {
    443     addresses = param.addresses;
     318  }
     319  else {
     320          addresses = param.addresses;
    444321  }
    445322
     
    454331  delete alist;
    455332
     333
    456334#ifdef USE_FLOWINFO
    457335  if (param.fi_service == NULL) {
     
    459337    abort();
    460338  }
    461 #endif
    462 
     339#endif 
     340 
    463341  DLog(param.name,
    464342       "NLI initialisation, IP TTL is set to 0 (unspecified)");
     
    467345
    468346  netaddress na;
    469   nli nli_tmpl(ttl, param.rs_validity_time, mypi, na);
     347  nli nli_tmpl(ttl, gconf.getpar<uint32>(gistconf_rs_validity_time), mypi, na);
    470348 
    471349  DLog(param.name, "Startup phase 4: Starting Processing Module");
     
    476354  // =====================================================================
    477355 
    478   StatemoduleParam smpar(rt,
     356  StatemoduleParam smpar(rt, 
    479357                         nli_tmpl,
    480358                         *addresses,
    481359                         *param.fi_service,
    482                          param.retrylimit,
    483                          param.retryperiod,
    484                          param.retryfactor,
    485                          param.rs_validity_time,
    486                          param.refreshtime,
    487                          param.ma_hold_time,
    488360                         secrets,
    489361                         nslptable,
    490362                         raovec,
    491                          param.secrets_refreshtime,
    492                          10, // default sleep time
    493                          param.udpport,
    494                          param.tcpport,
    495                          param.tlsport,
    496                          param.sctpport,
    497                          param.latestate,
    498                          param.confirmrequired,
    499                          param.senddatainquery,
    500                          param.reqhelloecho,
    501                          param.sctpenable);
     363                         10 // default sleep time
     364                        );
    502365
    503366  ThreadStarter<Statemodule,StatemoduleParam> smthread(1,smpar);
     
    539402
    540403       
    541   SignalingNTLPParam sigpar(pm, nli_tmpl, *addresses, *param.fi_service, nslptable, param.udpport);
     404  SignalingNTLPParam sigpar(pm,  nli_tmpl, *addresses, *param.fi_service, nslptable, gconf.getpar<uint16>(gistconf_udpport));
    542405  ThreadStarter<SignalingNTLP,SignalingNTLPParam> signaling(1,sigpar); 
    543406       
     
    558421  DLog(param.name, "Startup phase 9: Enabling Packet Interception");
    559422
    560   if ( param.intercept_cmd == NULL )
     423  if ( gconf.getpar<string>(gistconf_intercept_cmd).length() == 0 )
    561424    DLog(param.name, "NOT enabling packet interception, as requested");
    562425  else {
    563     if ( system(param.intercept_cmd) != 0 ) {
     426    if ( system(gconf.getpar<string>(gistconf_intercept_cmd).c_str()) != 0 ) {
    564427      ERRLog(param.name,
    565428             "Packet interception could not be enabled. Aborting");
     
    631494       
    632495  pm.clear();
     496
     497  DLog(param.name, "Shutdown phase 5: Cleaning Up");
     498
     499  delete mypi;
     500
    633501}
    634502
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_statemodule.h

    r3405 r4147  
    6666
    6767/// typedef transfert_t
    68 enum transfer_t {
     68typedef enum transfer_t_enum {
    6969  tx_queryencap,
    7070  tx_dmode,
    7171  tx_cmode,
    7272  tx_cmode_sec
    73 };
     73} transfer_t;
    7474 
    7575/// statemodule parameters
     
    7979                   AddressList &addresses,
    8080                   Flowinfo &fi_service,
    81                    uint32 retrylimit,
    82                    uint32 retryperiod,
    83                    float retryfactor,
    84                    uint32 rs_validity_time,
    85                    uint32 refreshtime,
    86                    uint32 ma_hold_time,
    8781                   secretmanager& secrets,
    8882                   NSLPtable& nslptable,
    8983                   vector<uint32>& raovec,
    90                    uint32 secrets_refresh,
    91                    uint32 sleep = ThreadParam::default_sleep_time,
    92                    uint16 udpport = 4,
    93                    uint16 tcpport = 4,
    94                    uint16 tlsport = 4444,
    95                    uint16 sctpport = 4,
    96                    bool latestate = false,
    97                    bool confirmrequired = false,
    98                    bool senddatainquery= true,
    99                    bool reqechohello = false,
    100                    bool sctpenable = true,
    101                    bool verbose_error_responses = true
     84                   uint32 sleep = ThreadParam::default_sleep_time
    10285                   );
    10386  const message::qaddr_t qaddr_ext;
     
    11497  uint32 ma_hold_time;
    11598  secretmanager& secrets;
    116   uint32 secrets_refresh;
    117   uint16 wkp;
    118   uint16 tcpport;
    119   uint16 tlsport;
    120   uint16 sctpport;
    121   bool latestate;
    122   bool confirmrequired;
    123   bool senddatainquery;
    124   bool reqhelloecho;
    125   bool sctpenable;
    126   bool verbose_error_responses;
    12799
    128100  NSLPtable& nslptable;
     
    153125
    154126  /// fill a query cookie, use local secrets and OpenSSL hash function
    155   respcookie* create_resp_cookie(const nli* querier_nli, const routingkey* r_key, uint32 gennumber, uint16 if_index);
     127  respcookie* create_resp_cookie(const nli* querier_nli, const routingkey* r_key, uint32 gennumber, uint16 if_index, const NetMsg* transparent_data);
     128
     129  /// check a responder cookie, use local secrets and resp_cookie generation function
     130  bool evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* resp);
    156131
    157132  ///calculation of refresh times. Give maximum time allowed and the factor to apply
     
    175150       
    176151  /// module parameters
    177   const StatemoduleParam param;
     152  const StatemoduleParam& param;
    178153  /// additional queue
    179154  FastQueue* external_fq;
    180155  //@{ message processing
    181156
     157protected:
     158  /// process internal messages
     159  void handleInternalMessage(message* msg);
     160 
     161  /// process timouts
     162  void handleTimeout();
     163
     164private:
    182165  /// get messages from queue
    183166  void process_queue(uint32 nr);
     
    256239  /// check if a stackprofile is applicable
    257240  bool profile_valid(stackprop* proposal, stackprofile* profile);
    258        
    259   /// check a responder cookie, use local secrets and resp_cookie generation function
    260   bool evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* resp);
    261241
    262242  /// check a responder cookie, use local secrets and resp_cookie generation function
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_statemodule_api.cpp

    r3544 r4147  
    3838#include <sstream>
    3939
     40#include "gist_conf.h"
     41
    4042namespace ntlp {
    4143
     
    243245  }
    244246
    245   msg->set_recvmessage(senddata, own_addr->copy(), pdu->get_nslpid(), new sessionid(*(pdu->get_sessionid())), mymr, false, sii_handle, myattr, ip_ttl, ip_distance, pdu->get_hops());
     247  msg->set_recvmessage(senddata, own_addr->copy(), pdu->get_nslpid(), new sessionid(*(pdu->get_sessionid())), mymr, false, sii_handle, myattr, ip_ttl, ip_distance, pdu->get_hops(), r_entry ? r_entry->get_incoming_if() : 0 );
    246248   
    247249  msg->send_to(param.nslptable.get_address(pdu->get_nslpid()));
     
    259261 * @param own_addr -- the IP address of the interface we received the data on
    260262 * @param pdu -- the pdu containing the data (may NOT be NULL)
    261  * @param r_entry -- the routing entry itself (may NOT be NULL)
     263 * @param r_entry -- the routing entry itself
    262264 */
    263265void
     
    268270  nslpdata* mydata = pdu->get_nslpdata();
    269271
    270   assert( pdu->get_mri() != NULL );
    271   mri* mymr=pdu->get_mri()->copy();
     272 
     273  if( pdu->get_mri() == NULL )
     274  {
     275          // at this stage it is not possible that an MRI in the PDU is missing since it should have
     276          // been checked twice, i.e., during parsing and in ntlp_statemodule_main
     277          ERRCLog("statemodule","deliver_adjacency_flag(): PDU contains no MRI, which is required though. This should not happen and is an internal error.");
     278          return;
     279  }
     280 
     281  nattraversal* nattravobj= pdu->get_nattraversal(); 
     282  mri* pdumri= pdu->get_mri()->copy();
     283  // use MRI from NTO if present
     284  mri* ntomri= nattravobj ? nattravobj->get_embedded_mri()->copy() : 0;
    272285       
    273286  tx_attr_t myattr;
     
    282295  }
    283296
    284   // same as in Statemodule::deliver()
    285   if ( mymr->get_downstream() )
    286     myattr.final_hop = is_local_address(mymr->get_destaddress());
     297  // check for final hop, same as in Statemodule::deliver()
     298  // this must be done using the outer flow destination address
     299  if ( pdumri->get_downstream() )
     300    myattr.final_hop = is_local_address(pdumri->get_destaddress());
    287301  else
    288     myattr.final_hop = is_local_address(mymr->get_sourceaddress());
     302    myattr.final_hop = is_local_address(pdumri->get_sourceaddress());
    289303
    290304  DLog("statemodule", "GIST node is the final hop: " << myattr.final_hop);
     
    295309
    296310  uint8 ip_distance = 0;
    297   //if we can do distance calculation, yeah, DO IT!
     311  // if we can do distance calculation, DO IT!
    298312  if (peer->get_ip_ttl()) {
    299313    if (pdu->get_nli()) {
     
    303317
    304318  // TODO: for MA setup only
    305   msg->set_recvmessage(senddata, own_addr->copy(), pdu->get_nslpid(), new sessionid(*(pdu->get_sessionid())), mymr, true, 0, myattr, pdu->get_nli()->get_ip_ttl(), ip_distance, pdu->get_hops());
     319  msg->set_recvmessage(senddata, own_addr->copy(),
     320                       pdu->get_nslpid(),
     321                       pdu->get_sessionid()->copy(),
     322                       ntomri ? ntomri : pdumri,  // use MRI from NAT traversal object if present
     323                       true, 0, myattr,
     324                       pdu->get_nli()->get_ip_ttl(),
     325                       ip_distance,
     326                       pdu->get_hops(),
     327                       r_entry ? r_entry->get_incoming_if() : 0 );
    306328   
    307329  msg->send_to(param.nslptable.get_address(pdu->get_nslpid()));
     
    524546     
    525547      // set local default RS_Validity Time
    526       r_entry->rs_validity_time=param.rs_validity_time;
     548      r_entry->rs_validity_time= gconf.getpar<uint32>(gistconf_rs_validity_time);
    527549     
    528550      // initiate sending the Query
     
    564586
    565587      // set local Default RS_Validity Time
    566       r_entry->rs_validity_time= param.rs_validity_time;
     588      r_entry->rs_validity_time= gconf.getpar<uint32>(gistconf_rs_validity_time);;
    567589           
    568590      // send a Query requesting handshake, this will NOT transfer data payload!
     
    743765  if (!r_entry)
    744766  {
    745     ERRCLog(param.name, "RecvMessageAnswer while no state. Discarding API call.");
    746     delete apimsg;
     767    ERRCLog(param.name, "Cannot find routing state for RecvMessageAnswer. Ignoring API call.");
     768    // apimsg will be deleted in calling method anyway
    747769    return;
    748770  }
     
    782804           
    783805      // do we enforce late state installation?
    784       if (param.latestate)
     806      if ( gconf.getpar<bool>(gistconf_latestate) )
    785807      {
    786808        DLog(param.name, "Late state installation configured, no state is saved");                 
     
    794816        DLog(param.name, "Immediate state installation configured, set up state");
    795817               
    796         r_entry->rs_validity_time = param.rs_validity_time;
     818        r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    797819       
    798820        // put in state "rn_established"
    799         if (!param.confirmrequired)
     821        if ( gconf.getpar<bool>(gistconf_confirmrequired) == false )
    800822        {
    801823          DLog(param.name, "No full handshake is configured, state set up");
     
    857879        ERRCLog(param.name, "NSLP told us to relay, but we are the end");
    858880        ERRCLog(param.name, "Sending Error Message is redundant, as we would send it to ourself.");
     881        // apimsg will be deleted in calling method anyway
    859882       
    860883        if (r_entry)
     
    870893      DLog(param.name, "Set RAO value to the one of the NSLP (we know it for sure)");
    871894           
    872       /*
    873        * XXXMOB: The outgoing interface doesn't mean all that much to us,
    874        *         we really need the source addreess.
    875        *
    876895      uint16 outgoinginterface = mymri->get_local_if();
    877896           
     
    885904        DLog(param.name, "Set request for outgoing interface index " << outgoinginterface << " for GIST Query");
    886905      }
    887        */
    888906
    889907
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_statemodule_data.cpp

    r3420 r4147  
    3737#include "data.h"
    3838
     39#include "gist_conf.h"
     40
    3941namespace ntlp {
    4042
     
    7173  }
    7274
    73   appladdress* peer = new appladdress(destnli->get_if_address(), param.udp, param.wkp);
     75  appladdress* peer = new appladdress(destnli->get_if_address(), param.udp, gconf.getpar<uint16>(gistconf_udpport));
    7476
    7577  SignalingMsgNTLP* sigmsg = new SignalingMsgNTLP();
     
    146148  r_entry->msg_id=msghandle;
    147149 
    148   appladdress* peer=new appladdress;
    149   peer->set_port(param.wkp);
     150  appladdress* peer= new appladdress;
     151  peer->set_port( gconf.getpar<uint16>(gistconf_udpport) );
    150152  peer->set_protocol(param.udp);
    151153 
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_statemodule_main.cpp

    r3568 r4147  
    5454#include <list>
    5555
     56#include "gist_conf.h"
     57
    5658using namespace protlib;
    5759using namespace protlib::log;
     
    7577                                   AddressList &addresses,
    7678                                   Flowinfo &fi_service,
    77                                    uint32 retrylimit,
    78                                    uint32 retryperiod,
    79                                    float retryfactor,
    80                                    uint32 rs_validity_time,
    81                                    uint32 refreshtime,
    82                                    uint32 ma_hold_time,
    8379                                   secretmanager& secrets,
    8480                                   NSLPtable& nslptable,
    8581                                   vector<uint32>& raovec,
    86                                    uint32 secrets_refresh,
    87                                    uint32 sleep,
    88                                    uint16 udpport,
    89                                    uint16 tcpport,
    90                                    uint16 tlsport,
    91                                    uint16 sctpport,
    92                                    bool latestate,
    93                                    bool confirmrequired,
    94                                    bool senddatainquery,
    95                                    bool reqhelloecho,
    96                                    bool sctpenable,
    97                                    bool verbose_error_responses)
     82                                   uint32 sleep)
    9883  : ThreadParam(sleep,"GIST Processing",2),       ///< common thread parameter
    9984    qaddr_ext(message::qaddr_coordination),          ///< queue for messages to coordinator
     
    10388    addresses(addresses),
    10489    fi_service(fi_service),
    105     retrylimit(retrylimit),                ///< Upper limit (time) for Query/Response retransmits?
    106     retryperiod(retryperiod),              ///< The timespan between retransmissions
    107     retryfactor(retryfactor),
    108     rs_validity_time(rs_validity_time),
    109     refreshtime(refreshtime),
    110     ma_hold_time(ma_hold_time),
    11190    secrets(secrets),
    112     secrets_refresh(secrets_refresh),      ///< Secrets Refresh Time in Seconds
    113     wkp(udpport),                          ///< Well-Known Port for Datagram Mode
    114     tcpport(tcpport),
    115     tlsport(tlsport),
    116     sctpport(sctpport),
    117     latestate(latestate),                  ///< Are we running late-state-installation?
    118     confirmrequired(confirmrequired),      ///< Are we requesting full handshakes?
    119     senddatainquery(senddatainquery),      ///< send NSLP data also in a query?
    120     reqhelloecho(reqhelloecho),
    121     sctpenable(sctpenable),
    122     verbose_error_responses(verbose_error_responses), ///< send back error in certain cases (e.g., resp cookie mismatch)
    12391    nslptable(nslptable),
    12492    raovec(raovec),
     
    132100  sctp = tsdb::getprotobyname("sctp");
    133101           
    134   rt.set_own_ma_hold_time(ma_hold_time);
     102  rt.set_own_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time));
    135103
    136104  // show RAOs that will be intercepted
     
    148116Statemodule::Statemodule(const StatemoduleParam& p)
    149117  : Thread(p),
    150     cap(p.wkp, p.tcpport, p.tlsport, p.sctpport),
     118    cap(gconf.getpar<uint16>(gistconf_udpport), gconf.getpar<uint16>(gistconf_tcpport), gconf.getpar<uint16>(gistconf_tlsport), gconf.getpar<uint16>(gistconf_sctpport)),
    151119    param(p),
    152120    external_fq(new FastQueue(message::get_qaddr_name(p.qaddr_ext),true))
     
    177145Statemodule::main_loop(uint32 nr)
    178146{
    179   Log(INFO_LOG,LOG_NORMAL, param.name, "Starting " << param.name << " module thread #" << nr <<", ");
     147  ILog(param.name, "Starting " << param.name << " module thread #" << nr <<", ");
    180148
    181149  // Initially starting timer for secret refresh, only Task #1 will do this!!
     
    187155    *timer_type = refresh_secrets;
    188156
    189     msg->start_relative(param.secrets_refresh, 0, (void*)timer_type, NULL);
     157    msg->start_relative(gconf.getpar<uint32>(gistconf_secrets_refreshtime), 0, (void*)timer_type, NULL);
    190158   
    191159    msg->send_to(message::qaddr_timer);
    192     Log(INFO_LOG,LOG_NORMAL, param.name, "Secrets Refresh Timer activated, refreshing every " << param.secrets_refresh << " seconds");     
     160    Log(INFO_LOG,LOG_NORMAL, param.name, "Secrets Refresh Timer activated, refreshing every " << gconf.getpar<uint32>(gistconf_secrets_refreshtime) << " seconds");     
    193161
    194162  }
     
    197165  process_queue(nr);
    198166
    199   Log(INFO_LOG,LOG_NORMAL, param.name, "Module thread #" << nr << " stopped");
     167  ILog(param.name, "Module thread #" << nr << " stopped");
    200168       
    201169} // end main_loop
    202170
     171
     172
     173
     174/**
     175 *  called to process message
     176 */
     177void Statemodule::handleInternalMessage(message *msg)
     178{
     179    switch (msg->get_type())
     180    {
     181    // internal message from signaling (message from IP network)
     182        case message::type_signaling:
     183         // -----------------------
     184         {
     185          SignalingMsgNTLP* sigmsg= dynamic_cast<SignalingMsgNTLP*>(msg);
     186          if (sigmsg)
     187          {
     188            // =====================================================
     189            process_sig_msg(sigmsg); ///< process signaling messages
     190            // =====================================================
     191          }
     192          else
     193          {
     194            Log(ERROR_LOG,LOG_ALERT, param.name,
     195                "Cannot cast message from "
     196                << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to SignalingMsgNTLP");
     197           
     198            delete msg;
     199          } // end if sigmsg
     200         } break;
     201
     202        // internal message from API
     203        case message::type_API:
     204         // -----------------------
     205         {
     206          APIMsg* apimsg= dynamic_cast<APIMsg*>(msg);
     207          if (apimsg)
     208          {
     209            // =====================================================
     210            process_api_msg(apimsg); ///< process API messages
     211            // =====================================================
     212          }
     213          else
     214          {
     215            Log(ERROR_LOG,LOG_ALERT, param.name,
     216                "Cannot cast message from "
     217                << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to APIMsg");
     218           
     219            delete msg;
     220          } // end if sigmsg
     221         } break;
     222
     223        // internal message from timer module
     224        case message::type_timer:
     225         // -----------------------
     226         {
     227          TimerMsg* timermsg= dynamic_cast<TimerMsg*>(msg);
     228          if (timermsg)
     229          {
     230            // =====================================================
     231            process_timer_msg(timermsg); ///< process timer messages
     232            // =====================================================
     233          }
     234          else
     235          {
     236            Log(ERROR_LOG,LOG_ALERT, param.name,
     237                "Cannot cast message from "
     238                << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to TimerMsg");
     239           
     240            delete msg;
     241          } // end if timermsg
     242         } break;
     243
     244#ifdef USE_FLOWINFO
     245        case message::type_mobility:
     246          // -----------------------
     247          MobilityMsg *mobmsg= dynamic_cast<MobilityMsg*>(msg);
     248          if (mobmsg)
     249          {
     250            // =====================================================
     251            process_mobility_msg(mobmsg); ///< process timer messages
     252            // =====================================================
     253          }
     254          else
     255          {
     256            Log(ERROR_LOG,LOG_ALERT, param.name,
     257                "Cannot cast message from "
     258                << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to MobilityMsg");
     259           
     260            delete msg;
     261          } // end if mobmsg
     262          break;
     263#endif
     264
     265        // everything else is handled by default
     266        default:
     267          ERRLog(param.name, "Received a message from " << msg->get_qaddr_name()
     268                             << " that cannot be processed here: " << msg->get_type_name());
     269                               
     270          delete msg;
     271    } // end switch message type
     272}
     273
     274
     275/**
     276 * called if Timeout happened by dequeue_timedwait()
     277 */
     278void Statemodule::handleTimeout()
     279{
     280        //nothing to do
     281}
    203282
    204283/**
     
    218297  if (!fq)
    219298  {
    220     Log(ERROR_LOG,LOG_ALERT, param.name, "Cannot find input queue");
     299    ERRCLog(param.name, "Cannot find input queue");
    221300   
    222301    return;
     
    224303
    225304  message* msg = NULL;
    226   SignalingMsgNTLP* sigmsg = NULL;
    227   TimerMsg* timermsg = NULL;
    228   APIMsg* apimsg = NULL;
    229 #ifdef USE_FLOWINFO
    230   MobilityMsg *mobmsg = NULL;
    231 #endif
    232305  // maximum wait period (in ms) at queue
    233306  uint32 wait= param.sleep_time;
     
    239312    if (msg)
    240313    {
    241       switch (msg->get_type())
    242       {
    243 
    244         // internal message from signaling (message from IP network)
    245         case message::type_signaling:
    246           // -----------------------
    247           sigmsg= dynamic_cast<SignalingMsgNTLP*>(msg);
    248           if (sigmsg)
    249           {
    250             // =====================================================
    251             process_sig_msg(sigmsg); ///< process signaling messages
    252             // =====================================================
    253           }
    254           else
    255           {
    256             Log(ERROR_LOG,LOG_ALERT, param.name,
    257                 "Cannot cast message from "
    258                 << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to SignalingMsgNTLP");
    259            
    260             delete msg;
    261           } // end if sigmsg
    262           break;
    263 
    264         // internal message from API
    265         case message::type_API:
    266           // -----------------------
    267           apimsg= dynamic_cast<APIMsg*>(msg);
    268           if (apimsg)
    269           {
    270             // =====================================================
    271             process_api_msg(apimsg); ///< process API messages
    272             // =====================================================
    273           }
    274           else
    275           {
    276             Log(ERROR_LOG,LOG_ALERT, param.name,
    277                 "Cannot cast message from "
    278                 << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to APIMsg");
    279            
    280             delete msg;
    281           } // end if sigmsg
    282           break;
    283 
    284         // internal message from timer module
    285         case message::type_timer:
    286           // -----------------------
    287           timermsg= dynamic_cast<TimerMsg*>(msg);
    288           if (timermsg)
    289           {
    290             // =====================================================
    291             process_timer_msg(timermsg); ///< process timer messages
    292             // =====================================================
    293           }
    294           else
    295           {
    296             Log(ERROR_LOG,LOG_ALERT, param.name,
    297                 "Cannot cast message from "
    298                 << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to TimerMsg");
    299            
    300             delete msg;
    301           } // end if timermsg
    302           break;
    303 
    304 #ifdef USE_FLOWINFO
    305         case message::type_mobility:
    306           // -----------------------
    307           mobmsg= dynamic_cast<MobilityMsg*>(msg);
    308           if (mobmsg)
    309           {
    310             // =====================================================
    311             process_mobility_msg(mobmsg); ///< process timer messages
    312             // =====================================================
    313           }
    314           else
    315           {
    316             Log(ERROR_LOG,LOG_ALERT, param.name,
    317                 "Cannot cast message from "
    318                 << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to MobilityMsg");
    319            
    320             delete msg;
    321           } // end if mobmsg
    322           break;
    323 #endif
    324 
    325         // everything else is handled by default
    326         default:
    327           ERRLog(param.name, "Received a message from " << msg->get_qaddr_name()
    328                              << " that cannot be processed here: " << msg->get_type_name());
    329                                
    330           delete msg;
    331       } // end switch message type
     314        handleInternalMessage(msg);
    332315    }  // end if msg
    333 
     316        else handleTimeout();
     317       
    334318    sched_yield();
    335319  } // end while running
    336320} // end process_queue
     321
     322
    337323
    338324
     
    501487{
    502488  nli *mynl;
     489  uint32 rs_validity_time= re ? re->rs_validity_time : gconf.getpar<uint32>(gistconf_rs_validity_time);
    503490
    504491  if (re) {
    505492    mynl = param.nli_tmpl.copy2(*re->local_src);
    506     mynl->set_rs_validity_time(re->rs_validity_time);
     493    mynl->set_rs_validity_time(rs_validity_time);
    507494  } else {
    508495    uint32_t pref = IPV6_PREFER_SRC_COA;
     
    510497    mynl = param.nli_tmpl.copy2(*src);
    511498  }
     499
    512500
    513501  return mynl;
     
    648636  } // endif error PDU
    649637
    650   // check for untranslated mandatory NATed objects
    651   if (incoming_pdu->get_nattraversal())
    652   {
    653     // if the NAT Traversal object does NOT indicate NLI and stack_conf_data to be translated, sppol error.
    654     nattraversal* nattrav = incoming_pdu->get_nattraversal();
    655        
     638  // check for NAT Traversal object (NTO) and any untranslated mandatory NATed objects
     639  // NTOs are only present in Queries or Responses, but we want to use
     640  nattraversal* nattravobj = incoming_pdu->get_nattraversal();
     641  if ( nattravobj )
     642  {
     643    // if the NAT Traversal object does NOT indicate NLI and stack_conf_data to be translated,
     644    // send back an error.
    656645    bool nli_found = false;
    657646    bool stackconf_found = false;
    658647       
    659648    uint16 tmp_trans;
    660     for (unsigned int i = 0; i < nattrav->get_translations().size(); i++)
    661     {
    662       tmp_trans= nattrav->get_translations()[i];
     649    for (unsigned int i = 0; i < nattravobj->get_translations().size(); i++)
     650    {
     651      tmp_trans= nattravobj->get_translations()[i];
    663652
    664653      if (tmp_trans == known_ntlp_object::NLI) nli_found=true;
     
    688677  } // end checking for untranslated NAT Objects
    689678
    690   // if it is a response carrying a NAT Traversal object, we ought to use the MRI from it instead the one from the PDU
    691   if (incoming_pdu->is_response() && incoming_pdu->get_nattraversal())
    692   {
    693     DLog(param.name, "GIST Response carrying a NAT Traversal object, taking MRI from it");
    694     r_key->mr=incoming_pdu->get_nattraversal()->get_embedded_mri()->copy();
     679  // if it is a query/response carrying a NAT Traversal object,
     680  // we ought to use the MRI from it instead the one from the PDU
     681  // because all later messages use untranslated the local querier addresses in MRI/NLI
     682  if (nattravobj)
     683  {
     684    DLog(param.name, "GIST Message carrying a NAT Traversal object, taking MRI from it");
     685    r_key->mr= nattravobj->get_embedded_mri()->copy();
     686    // must invert the direction since original MRI will have
     687    // the D-bit set, but not the Embedded MRI in the NTO
     688    // since code below assumes that D is set, we have to do it explicitly here
     689    if (incoming_pdu->is_response())
     690            r_key->mr->invertDirection();
    695691  }
    696692  else
     
    705701  r_key->nslpid=incoming_pdu->get_nslpid();
    706702
     703  // MRI and SessionID are mandatoy in Query, Response, and Data messages
     704  // Error and Hellos are processed earlier
    707705  if (!r_key->mr)
    708706  {
    709707    ERRCLog(param.name, "No MRI in message, this will not be processed");
    710     // TODO: throw ERROR msg?
     708    senderror(incoming_pdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::MRI);
    711709    return;
    712710  }
     
    715713  {
    716714    ERRCLog(param.name, "No SessionID in message, this will not be processed");
    717     // TODO: Throw ERROR msg?
     715    senderror(incoming_pdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::SessionID);
    718716    return;
    719717  }
     
    784782        {
    785783          // if Data came via Q-Mode we should deliver it to the application and indicate that no routing state exists
    786           if (generic_sigmsg->get_source() == message::qaddr_tp_queryencap)
     784          // since draft -17 we have to check for the C flag
     785          if (incoming_pdu->get_C())
    787786          {
    788787            DLog(param.name, " Data PDU via Q-Mode, simply deliver DATA to NSLP");
     
    12881287    if (pdu->get_nli()) {
    12891288      DLog(param.name, "IP Source is NOT last GIST hop, sending to GIST denoted by NLI");
    1290       target = new appladdress(pdu->get_nli()->get_if_address(), param.udp, param.wkp);
     1289      target = new appladdress(pdu->get_nli()->get_if_address(), param.udp, gconf.getpar<uint16>(gistconf_udpport));
    12911290           
    12921291           
     
    13001299    target = new appladdress(*peer);
    13011300    if (target->get_protocol()== param.qenc) target->set_protocol(param.udp);
    1302     if (target->get_protocol()== param.udp) target->set_port(param.wkp);
     1301    if (target->get_protocol()== param.udp) target->set_port(gconf.getpar<uint16>(gistconf_udpport));
    13031302  }
    13041303   
     
    14581457  *timer_type=refresh_secrets;
    14591458 
    1460   msg->start_relative(param.secrets_refresh, 0, (void*)timer_type, NULL);
     1459  msg->start_relative(gconf.getpar<uint32>(gistconf_secrets_refreshtime), 0, (void*)timer_type, NULL);
    14611460 
    14621461  msg->send_to(message::qaddr_timer);
     
    15221521      EVLog(param.name, "Route Flapping occured, restarting refresh_qnode timer for downstream path");
    15231522           
    1524       starttimer(&tmpkey, tmpentry, refresh_qnode, 0, randomized(tmpentry->nl->get_rs_validity_time(), param.retryfactor));
     1523      starttimer(&tmpkey, tmpentry, refresh_qnode, 0, randomized(tmpentry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    15251524    }
    15261525  }
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_statemodule_querier.cpp

    r3564 r4147  
    4141#include <sstream>
    4242
     43#include "gist_conf.h"
     44
    4345namespace ntlp {
    4446
     
    121123  else
    122124  {
    123     // set RAO value on peer address
    124     peer->set_rao(param.rt.get_rao(r_key->nslpid));
    125     DLog(param.name, "Set request for RAO value of " << param.rt.get_rao(r_key->nslpid) << " for GIST Query");
     125    if ( gconf.getpar<bool>(gistconf_send_rao) )
     126    {
     127            // set RAO value on peer address
     128            peer->set_rao(param.rt.get_rao(r_key->nslpid));
     129            DLog(param.name, "Set request for RAO value of " << param.rt.get_rao(r_key->nslpid) << " for GIST Query");
     130    }
    126131
    127132/*
     
    164169
    165170  // set well-known-port for GIST and dummy prot_query_encap protocol to force the message to tp_queryencap
    166   peer->set_port(param.wkp);
     171  peer->set_port( gconf.getpar<uint16>(gistconf_udpport) );
    167172  peer->set_protocol(refmri->get_mrm() == mri::mri_t_explicitsigtarget ? param.udp : param.qenc);
    168173
     
    184189      if (apimsg->get_data())
    185190      {
    186         if (param.senddatainquery)
     191        if (gconf.getpar<bool>(gistconf_senddatainquery))
    187192        {
    188193          data= new nslpdata(*(apimsg->get_data()));
     
    248253    sp= cap.query_stackprop(secure);
    249254    sc= cap.query_stackconf(secure);
    250     sc->set_ma_hold_time(param.ma_hold_time);
    251  
    252     DLog(param.name, "Constructed Stack Proposal/Stack Configuration data for C-Mode handshake");
     255    sc->set_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time));
     256
     257    if (cap.is_consistent(sp,sc))
     258    {
     259        DLog(param.name, "Successfully constructed Stack Proposal/Stack Configuration data for C-Mode handshake");
     260    }
     261    else
     262    {
     263      ERRCLog(param.name, "Constructed inconsistent Stack Proposal/Stack Configuration data for C-Mode handshake, not sending any query. Programming error, please fix the code.");
     264      delete mysid;
     265      delete mymri;
     266      delete data;
     267      delete mynli;
     268      delete sp;
     269      delete sc;
     270      return;
     271    }
    253272  }
    254273
     
    385404
    386405    r_entry->state=qn_established;             
    387     r_entry->rs_validity_time = param.rs_validity_time;
     406    r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    388407
    389408    // create/reuse and store SII handle for this peer
     
    402421               
    403422    // start Refresh_QNode timer on timer slot #2
    404     starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), param.retryfactor));
     423    starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    405424
    406425    // check whether other side did MA re-use and promoted our D-mode setup to C-mode
     
    594613
    595614  // (re)Start refresh_QNode timer
    596   starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), param.retryfactor));
     615  starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    597616
    598617  // Start inactive_QNode timer if not running
     
    628647           
    629648  // start Refresh_QNode again
    630   starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), param.retryfactor));
     649  starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    631650
    632651  // Inactive_QNode should be running already (was probably restarted by incoming piggybacked NSLP data earlier)
     
    696715  // construct target address
    697716  appladdress* target= new appladdress;
    698   target->set_port(param.wkp);
     717  target->set_port(gconf.getpar<uint16>(gistconf_udpport));
    699718  if (!r_entry->nl) {
    700719    ERRCLog(param.name, "No NLI saved locally for this peer. Cannot proceed.");
     
    755774  // construct target address for sending back any error messages
    756775  appladdress*  errortarget= new appladdress;
    757   errortarget->set_port(param.wkp);
     776  errortarget->set_port( gconf.getpar<uint16>(gistconf_udpport) );
    758777  if (!r_entry->nl) {
    759778    ERRCLog(param.name, "No NLI saved locally for this peer. Cannot proceed.");
     
    837856  // but this is only required for the very first confirmation message during
    838857  // initial MA setup
    839   stack_conf_data* mysc = (ma_reuse == false)  ? new stack_conf_data(param.ma_hold_time) : NULL;
     858  stack_conf_data* mysc = (ma_reuse == false)  ? new stack_conf_data(gconf.getpar<uint32>(gistconf_ma_hold_time)) : NULL;
    840859   
    841860  // echo responder cookie
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_statemodule_responder.cpp

    r3701 r4147  
    4444#include "authorized_peer_db.h"
    4545
     46#include "gist_conf.h"
     47
    4648extern "C"
    4749{
     
    6769  // the response is sent (late state installation) or that will persist until
    6870  // a confirm is received
    69 
    70   //EVLog(param.name, "Delivering Payload to NSLP");
    71   deliver_adjacency_flag(peer, own_addr, query_pdu);
    7271
    7372  DLog(param.name, "Initial GIST Query received");
     
    8382  r_entry->set_local_src(*src->copy());
    8483
    85   // save eventual NAT Traversal payload in routing entry
     84  // save potentially present NAT Traversal payload in routing entry
    8685  if (nattraversal* nattrav = query_pdu->get_nattraversal())
    8786  {
    8887    EVLog(param.name, color[green]<< "This message traversed a NAT, saving NAT information locally" << color[off]);
    8988
    90     r_entry->nattrav=nattrav->copy();
     89    // NTO contains the original (local to the Querier) MRI, NLI and SCD
     90    r_entry->nattrav= nattrav->copy();
    9191  }
    9292       
    9393  // set our RS_Validity time
    94   r_entry->rs_validity_time = param.rs_validity_time;
     94  r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    9595         
    9696  // save Query Cookie for Response retries
    9797  r_entry->qrc=new querycookie(*(query_pdu->get_querycookie()));
    9898
    99   // save NLI and SII handle in the entry
    100   r_entry->nl=new nli(*query_pdu->get_nli());
     99  // if we have a NAT traversal object, use information from it
     100  // for cookie generation etc. otherwise the cookie cannot be validated
     101  // properly
     102  if (r_entry->nattrav)
     103  {
     104          const nli* nto_nli= r_entry->nattrav->get_nli();
     105          // save a copy of the NLI carried in the NAT Traversal object
     106          if ( nto_nli )
     107          {
     108                r_entry->nl= new nli( *nto_nli );
     109                DLog(param.name, "Using NLI from NAT traversal object, i/f address: " << nto_nli->get_if_address());
     110          }
     111  }
     112  else
     113  { // use NLI from the PDU
     114          // save NLI
     115          r_entry->nl= new nli(*query_pdu->get_nli());
     116  }
     117
     118  // check whether this is our own query by comparing the Peer ID
     119  if (r_entry->nl)
     120  {
     121          const peer_identity* pid= r_entry->nl->get_pi();
     122          if ( pid && (*pid == *(param.nli_tmpl.get_pi())) )
     123          { // peer id from query nli is the same as ours, this is usually an error
     124                  WLog(param.name,"Detected Query coming from myself, will be ignored and dropped to avoid loopback to myself.");
     125                  delete r_entry;
     126                  return;
     127          }
     128                 
     129  }
     130
     131  // SII handle in the entry
    101132  r_entry->sii_handle= param.rt.generate_sii_handle(r_entry->nl);
    102133  DLog(param.name, "Saved NLI, SII handle = " << r_entry->sii_handle);
     
    157188  r_entry->tmppeer = peer->copy();
    158189
    159 // XXXMOB: store own_address instead of if_index
    160 //  // remember incoming interface for query
    161 //  r_entry->set_incoming_if(peer->get_if_index());
    162 //  DLog(param.name, "Saved incoming interface index " << r_entry->get_incoming_if());
     190  // remember incoming interface for query
     191  r_entry->set_incoming_if(peer->get_if_index());
     192  DLog(param.name, "Saved incoming interface index " << r_entry->get_incoming_if());
    163193 
    164194  // set up temporary state
     
    168198 
    169199  DLog(param.name, "Prepared for State setup");
     200
     201  EVLog(param.name, "Notifying NSLP of initial Query requesting to peer");
     202  deliver_adjacency_flag(peer, own_addr, query_pdu, r_entry);
     203
    170204}
    171205
     
    222256  }
    223257                   
    224   if (param.confirmrequired)
     258  if (gconf.getpar<bool>(gistconf_confirmrequired))
    225259  {
    226260    DLog(param.name, "Full handshake configured, waiting for GIST Confirm");
     
    295329  if (echoed_resp_cookie && (respcookie_matched= evaluate_resp_cookie(cnfpdu->get_nli(), r_key, echoed_resp_cookie)) == false)
    296330  {
    297     DLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
     331    WLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
    298332    // send back error
    299333    // but only during initial deployment or debugging, because
    300334    // sending the error in general makes a node a source of backscatter
    301     if (param.verbose_error_responses)
     335    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    302336      senderror(cnfpdu, peer, GIST_Error::error_gist_invalid_rcookie);
    303337
     
    310344      DLog(param.name, "Responder Cookie matched, processing GIST Confirm");
    311345
    312 // XXXMOB: replace with local address
    313 //
    314 //      if (echoed_resp_cookie->get_if_index() != r_entry->get_incoming_if())
    315 //      {
    316 //      WLog(param.name, "Found inconsistency: Responder Cookie indicated that Query used a different interface: old idx="
    317 //           << r_entry->get_incoming_if() << " new idx=" << echoed_resp_cookie->get_if_index());
    318 //      }
     346      if (echoed_resp_cookie->get_if_index() != r_entry->get_incoming_if())
     347      {
     348        ILog(param.name, "Responder Cookie indicated that Query used a different interface: old idx="
     349             << r_entry->get_incoming_if() << " new idx=" << echoed_resp_cookie->get_if_index());
     350      }
    319351    }
    320352
     
    410442      // since we already ensured by the responder cookie that this is not a blind attacker
    411443      // chances are high that this is a broken implementation and not an adversary
    412       if (param.verbose_error_responses)
     444      if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    413445        senderror(cnfpdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::NLI);
    414446    }
     
    490522  DLog(param.name, "GIST Confirm while no Routing State - Assuming Late State Installation");
    491523
     524  const respcookie* responder_cookie= cnfpdu->get_respcookie();
    492525  // check whether Responder Cookie is present (we should have sent one, but is it echoed?)
    493   if (cnfpdu->get_respcookie() == NULL)
     526  if (responder_cookie == NULL)
    494527  {
    495528    ERRCLog(param.name,"Confirm in Late State installation: Responder Cookie missing in Confirm, although we sent one for sure.");
    496529    // send back error for missing responder cookie
    497     if (param.verbose_error_responses)
     530    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    498531      senderror(cnfpdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::RespCookie);
    499532
     
    501534  }
    502535
     536  // MUST CHECK with different NLI and r_key if NTO is present...
    503537  // evaluate Responder Cookie in CONFIRM
    504   bool rsp_cookie_matched = evaluate_resp_cookie(cnfpdu->get_nli(), r_key, cnfpdu->get_respcookie());
     538  bool rsp_cookie_matched = evaluate_resp_cookie(cnfpdu->get_nli(), r_key, responder_cookie);
    505539
    506540  // is Responder Cookie valid?
    507541  if (rsp_cookie_matched == false)
    508542  {
    509     DLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
     543    WLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
    510544
    511545    // send back error if enabled
    512     if (param.verbose_error_responses)
     546    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    513547      senderror(cnfpdu, peer, GIST_Error::error_gist_invalid_rcookie);
    514548
     
    525559  // we got a valid confirm, we must set up routing state and begin in "established"
    526560  // as we ignored the Query to the Confirm and did nothing
    527                
     561 
    528562  routingentry* r_entry= new routingentry(true);
    529563  const hostaddress *src = dynamic_cast<const hostaddress *>(own_addr);
     
    585619    // since we already ensured by the responder cookie that this is not a blind attacker
    586620    // chances are high that this is a broken implementation and not an adversary
    587     if (param.verbose_error_responses)
     621    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    588622      senderror(cnfpdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::NLI);
    589623  }
    590624
    591 // XXXMOB: Replace with local address
    592 //
    593 //  // record incoming interface (is contained in Responder Cookie that we sent back on receiving the query)
    594 //  r_entry->set_incoming_if(cnfpdu->get_respcookie()->get_if_index());
    595 //  DLog(param.name, "saved incoming interface index " << r_entry->get_incoming_if());
     625  // record incoming interface (is contained in Responder Cookie that we sent back on receiving the query)
     626  r_entry->set_incoming_if(responder_cookie->get_if_index());
     627  DLog(param.name, "saved incoming interface index " << r_entry->get_incoming_if());
     628
     629  // save any NAT traversal object that comes with the responder_cookie
     630  // since cookie data was protected by our HMAC and found to be correct
     631  // we can be sure, that the NTO is unmodified and correct
     632  if (responder_cookie->get_transparent_data())
     633  {
     634          uint32 bytes_read= 0;
     635          IEErrorList errorlist;
     636          nattraversal* nat_trav_obj= new nattraversal;
     637          NetMsg* tmpbuf= new NetMsg(responder_cookie->get_transparent_data(),
     638                                     responder_cookie->get_transparent_data_len(),
     639                                     false);
     640          nat_trav_obj->deserialize(*tmpbuf, IE::protocol_v1, errorlist, bytes_read, false);
     641          if (errorlist.is_empty() == false)
     642          {
     643                  ERRLog(param.name,"parse error while getting NTO from responder cookie - this is an implementation error");
     644          }
     645          else
     646          {
     647                  // save the nat traversal object
     648                  r_entry->nattrav= nat_trav_obj;
     649          }
     650          delete tmpbuf;
     651  }
    596652
    597653  // set our RS_Validity time
    598   r_entry->rs_validity_time = param.rs_validity_time;
     654  r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    599655
    600656  // what we want is in the echoed response stack proposal
     
    799855    if (rsp_cookie_matched == false)
    800856    {
    801       DLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
     857      WLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
    802858
    803859      // send back error if enabled
    804       if (param.verbose_error_responses)
     860      if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    805861        senderror(cnfpdu, peer, GIST_Error::error_gist_invalid_rcookie);
    806862
     
    9551011  // - include NLI describing OURSELF
    9561012  // - store responder locally in routing data table for checking later
    957   // - cookie is only sent when setting up a connection
     1013  // - cookie is only sent when setting up routing state
    9581014  // - set R-Flag if latestate or C-Mode is requested
    9591015 
     
    9771033  // we don't need a confirm only in case of a refresh
    9781034
    979   bool requestconfirm= ( ((r_entry->state == rn_established) && !param.confirmrequired) ) ? false : true;
     1035  bool requestconfirm= ( (r_entry->state == rn_established) && !gconf.getpar<bool>(gistconf_confirmrequired) ) ? false: true;
     1036
    9801037  // if initial handshake and late state installation required, we need a confirm back
    981   if ( (r_entry->state == rn_querynslp) && param.latestate )
     1038  if ( (r_entry->state == rn_querynslp) && gconf.getpar<bool>(gistconf_latestate) )
    9821039    requestconfirm= true;
    9831040
     
    10291086      own_sc = cap.resp_stackconf(NULL, false);
    10301087     
    1031       own_sc->set_ma_hold_time(param.ma_hold_time);
     1088      own_sc->set_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time));
    10321089     
     1090      if (cap.is_consistent(own_sp,own_sc))
     1091      {
     1092              DLog(param.name, "Successfully constructed Stack Proposal/Stack Configuration data for C-Mode handshake");
     1093      }
     1094      else
     1095      {
     1096              ERRCLog(param.name, "Constructed inconsistent Stack Proposal/Stack Configuration data for C-Mode handshake, not sending any query. Programming error, please fix the code.");
     1097      }
     1098
    10331099      // save them for retries
    10341100      delete (r_entry->sp);
     
    10741140  appladdress* response_dest=NULL;
    10751141  // answer goes back to source port or well known port (wkp)
    1076   port_t response_port= peer ? peer->get_port() : param.wkp;
    1077 
    1078 // XXXMOB: replace with local address
    1079 //  // interface index from query
    1080 //  uint16 if_index= peer ? peer->get_if_index() : 0;
    1081   uint16 if_index= 0;
     1142  port_t response_port= peer ? peer->get_port() : gconf.getpar<uint16>(gistconf_udpport);
     1143
     1144  // interface index from query
     1145  uint16 if_index= peer ? peer->get_if_index() : 0;
    10821146
    10831147  // *********** Messaging Association Re-Use ****************************************
     
    10881152  // this is ususally the case only when we have stored state and no_confirm timer went off
    10891153  nli* qnli= pdu ? pdu->get_nli() : r_entry->nl;
     1154
     1155  // override in case of NAT traversal, use info from NAT traversal object
     1156  if (r_entry->nattrav)
     1157          qnli= r_entry->nl;
    10901158  if (qnli)
    10911159  {
     
    11631231  nli* nl = build_local_nli(mr->get_ip_version(), na, r_entry);
    11641232
     1233  // test if we have a saved nat traversal object (NTO)
     1234  nattraversal* nto = dynamic_cast<nattraversal*>(r_entry->nattrav);
     1235  NetMsg* ntobuf_p= NULL;
     1236  // put NTO as transparent data into hash if present
     1237  if (nto)
     1238  {
     1239          uint32 ntobuf_size= nto->get_serialized_size(IE::protocol_v1);
     1240          ntobuf_p= new NetMsg(ntobuf_size);
     1241          // should be serialized including the common object header
     1242          uint32 written= 0;
     1243          nto->serialize(*ntobuf_p, IE::protocol_v1, written);
     1244  }
     1245
    11651246  // generate a new responder cookie and include it
    11661247  // but only if MA re-use is not possible or we want late state installation
    1167   respcookie* rc = ( (ma_requested && ma_reuse == false) || requestconfirm ) ? create_resp_cookie(qnli, r_key, 0, if_index) : NULL;
     1248  respcookie* rc = ( (ma_requested && ma_reuse == false) || requestconfirm ) ? create_resp_cookie(qnli, r_key, 0, if_index, ntobuf_p) : NULL;
     1249 
     1250  // ntobuf not required anymore
     1251  delete ntobuf_p;
    11681252 
    11691253  // confirm MUST be requested if responder cookie is present
     
    11801264  if (r_entry->mod_data)
    11811265  {
    1182     if ((param.latestate) || (!param.confirmrequired))
     1266    if (gconf.getpar<bool>(gistconf_latestate) || (!gconf.getpar<bool>(gistconf_confirmrequired)))
    11831267    {
    11841268      DLog(param.name, "There will be no repetitions of this Response, cleaning replacement NSLP data");
     
    11971281  response* rsp = new response(mr, sid, nl, qc, rc, own_sp, own_sc, mydata);
    11981282
    1199   nattraversal* nt = NULL;
    1200    
    1201   // test if we have a saved nat traversal object
    1202   nt = dynamic_cast<nattraversal*>(r_entry->nattrav);
    1203  
    1204   if (nt) {
     1283 
     1284  if (nto) {
    12051285        EVLog(param.name, color[green] << "Included NAT traversal object in GIST Response" << color[off]);
    1206         rsp->add_nat(nt);
     1286        rsp->add_nat(nto);
    12071287  }
    12081288 
     
    12361316 * Our cookie is currently constructed as follows:
    12371317 * Secret generation number(32 bit) +
    1238  * Hash(Q-Node Peer-ID, Q-Node i/f address, MRI, Session-ID, NSLPID, generation number, secret)
     1318 * query receiving interface index +
     1319 * MAC Data Offset +
     1320 * MAC Data= Hash(Q-Node Peer-ID, Q-Node i/f address, MRI, Session-ID, NSLPID, generation number, secret)
    12391321 *
    12401322 * @param querier_nli -- the nli (peer-id, ip address) of the querier
     
    12421324 * @param gennumber -- the generation number to use, if 0 use the current generation number
    12431325 * @param if_index -- interface index
     1326 * @param transparent_data -- e.g., nattraversal object if used, this must be included in the responder cookie if present
    12441327 * @return responder cookie or NULL if secret not available (wrong generation number)
    12451328 */
    12461329respcookie*
    1247 Statemodule::create_resp_cookie(const nli* querier_nli, const routingkey* key, uint32 gennumber, uint16 if_index)
     1330Statemodule::create_resp_cookie(const nli* querier_nli, const routingkey* key, uint32 gennumber, uint16 if_index, const NetMsg* transparent_data)
    12481331{
    12491332
     
    12731356
    12741357
    1275   //============================================
    1276   // Now put our input data into a byte buffer
    1277   //============================================
     1358  //===================================================================
     1359  // Now put our input data into a byte buffer for calculating the hash
     1360  //===================================================================
    12781361 
    12791362         mri* mr= key->mr;
     
    12811364   uint16 nslpid= key->nslpid;
    12821365   uint8  pi_len= querier_nli->get_pi()->get_length();
    1283   // compute size needed for data in NetMsg
     1366   uint16 transparent_data_len= (transparent_data && transparent_data->get_buffer()) ? transparent_data->get_size() : 0;
     1367
     1368  // compute size needed for data in NetMsg (note: just used for computing the hash)
    12841369
    12851370  // generation number (4 byte) in clear text (not hashed)
    12861371   uint32 buffersize = sizeof(generationnumber);
    12871372
    1288   // put the interface index directly after the generation number
    12891373  buffersize+= sizeof(if_index);
    12901374
     
    13011385  // SessionID without header
    13021386  buffersize+= sid->get_serialized_size(IE::protocol_v1)-4;
     1387
    13031388  // NSLPID
    13041389  buffersize+=sizeof(nslpid);
     
    13091394  // secret
    13101395  buffersize+=secretsize;
     1396
     1397  // if any transparent data given
     1398  buffersize+= transparent_data_len;
    13111399   
    13121400  // build NetMsg of sufficient size -> used for calculating the hash
     
    13211409  msg->copy_from(querier_nli->get_pi()->get_buffer(), msg->get_pos(), pi_len);
    13221410  msg->set_pos_r(pi_len);
    1323   written= pi_len;
     1411  written+= pi_len;
    13241412
    13251413  // serialize IP address
     
    13481436  // serialize MRI into NetMsg buffer
    13491437  mr->serializeNoHead(*msg, IE::protocol_v1, written);
    1350    
     1438
    13511439  // serialize SessionID into NetMsg buffer
    13521440  sid->serializeNoHead(*msg, IE::protocol_v1, written);
     
    13591447  msg->copy_from(secret, msg->get_pos(), secretsize);
    13601448  msg->set_pos_r(secretsize);
     1449
     1450  // put transparent_data into hash if present
     1451  if (transparent_data_len > 0)
     1452  {
     1453          memcpy(msg->get_buffer()+msg->get_pos(), transparent_data->get_buffer(), transparent_data_len);
     1454  }
     1455
    13611456   
    13621457  //============================================
     
    13691464  unsigned char md_value[EVP_MAX_MD_SIZE];
    13701465  unsigned int md_len;
    1371  
    1372   // 2nd: load in all digests from OpenSSL
    1373   OpenSSL_add_all_digests();
    1374  
    1375   // 3rd: We want SHA1 (maybe we make this a command line option)
    1376   md = EVP_get_digestbyname("SHA1");
     1466   
     1467  // 2nd: We want SHA1 (maybe we make this a command line option)
     1468  md = EVP_get_digestbyname(gconf.getparref<string>(gistconf_cookie_digest).c_str());
    13771469 
    13781470  if(!md) {
    1379     ERRCLog(param.name, "Hasher SHA-1 not available. Please update your OpenSSL library!");
     1471          ERRCLog(param.name, "Hash algorithm " << gconf.getparref<string>(gistconf_cookie_digest) << " not available. Please update your OpenSSL library!");
    13801472    abort();
    13811473  }
    13821474 
    1383   // 4th: Initialize hasher
     1475  // 3rd: Initialize hasher
    13841476  EVP_MD_CTX_init(&mdctx);
    13851477  EVP_DigestInit_ex(&mdctx, md, NULL);
    1386   // 5th: give input to hasher
     1478  // 4th: give input to hasher
    13871479  EVP_DigestUpdate(&mdctx, msg->get_buffer(), msg->get_size());
    13881480   
    1389   // 6th: Finalize message digest
     1481  // 5th: Finalize message digest
    13901482  EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
    13911483
    1392   // 7th: Cleanup datastructures
     1484  // 6th: Cleanup datastructures
    13931485  EVP_MD_CTX_cleanup(&mdctx);
    13941486
     1487  //==============================================
     1488  // From here on we put the cookie value together
     1489  //==============================================
     1490
     1491  // 7.1: Put together result buffer
     1492  uint16 totallen= sizeof(generationnumber) + 2*sizeof(uint16) + transparent_data_len + md_len;
     1493  uchar* buf = new uchar[totallen];
     1494  uchar* pbuf= buf;
     1495
     1496  // 7.2: Put in Generation Number first
     1497  *((uint32*)pbuf) = htonl(generationnumber);
     1498  pbuf+= sizeof(generationnumber);
     1499
     1500  // 7.3: interface index next (16 bit)
     1501  *((uint16*)pbuf) = htons(if_index);
     1502  pbuf+= sizeof(uint16);
     1503
     1504  // 7.4: byte offset pointing to HMAC data behind optional NTO
     1505  *((uint16*)pbuf) = htons( transparent_data_len );
     1506  pbuf+= sizeof(uint16);
     1507
     1508  // put transparent data into buffer if present, currently it could be the NAT traversal object
     1509  if (transparent_data && transparent_data->get_buffer() && transparent_data_len > 0)
     1510  {
     1511          memcpy(pbuf, transparent_data->get_buffer(), transparent_data_len);
     1512          pbuf+= transparent_data_len;
     1513  }
     1514
     1515  // 7.4th: Copy Resulting Hash/MD into buffer
     1516  memcpy(pbuf, md_value, md_len);
     1517 
     1518  // 8th: Put into Responder Cookie
     1519  respcookie* cookie = new respcookie(buf, totallen);
     1520
     1521  DLog(param.name, "Computed Responder Cookie, length "<< totallen*8 << " Bit: " << cookie->to_str());
     1522
     1523  // delete temporary buffer now
     1524  delete buf;
    13951525  // delete netmsg buffer
    13961526  delete msg;
    1397 
    1398   // 7.1th: Put together result buffer
    1399   uint16 totallen= sizeof(generationnumber) + sizeof(uint32) + md_len;
    1400   uchar* buf = new uchar[totallen];
    1401   uchar* pbuf= buf;
    1402 
    1403   // 7.2th: Put in Generation Number first
    1404   *((uint32*)pbuf) = htonl(generationnumber);
    1405   pbuf+= sizeof(generationnumber);
    1406  
    1407   // 7.3th: Put interface index next (has been hashed)
    1408   // note: fill up to 32bit word due to alignment requirements
    1409   *((uint32*)pbuf) = htonl( (uint32) if_index);
    1410   pbuf+= sizeof(uint32);
    1411 
    1412   // 7.4th: Copy Resulting Hash/MD into buffer
    1413   memcpy(pbuf, md_value, md_len);
    1414    
    1415   // 8th: Put into Responder Cookie
    1416   respcookie* cookie = new respcookie(buf, totallen);
    1417 
    1418   DLog(param.name, "Computed Responder Cookie, length "<< totallen*8 << " Bit: " << cookie->to_str());
    1419 
    1420   // delete temporary buffer now
    1421   delete buf;
    14221527
    14231528  return cookie;
     
    14321537 */
    14331538bool
    1434 Statemodule::evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* responder_cookie) 
     1539Statemodule::evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* responder_cookie)
    14351540{
    14361541  // if any argument is missing (probably in incoming pdu, we cannot recalc the responder cookie, so it is invalid)
     
    14411546 
    14421547  uint32 generationnumber= responder_cookie->get_generationnumber();
    1443   // decode interface id (actually 16bit, but sent as 32 bit word)
    1444   uint32 if_index= responder_cookie->get_if_index();
    1445   if (if_index >> 16)
    1446   {
    1447     // in this case the highest bits were set but they shouldn't be
    1448     // someone messed with the cookie
    1449     DLog(param.name, "Validation failed: Interface ID is not 16bit!: 0x" << hex << if_index << dec);
    1450     return false;
    1451   }
     1548
     1549  // decode interface id (16bit)
     1550  uint16 if_index= responder_cookie->get_if_index();
     1551
     1552  uint16 td_len= responder_cookie->get_transparent_data_len();
     1553  // check for any transparent objects carried in the responder cookie
     1554  // and make sure that we don't read behind the end of the buffer
     1555  NetMsg* transparent_data_msgbuf= ( (td_len > 0) && ( (uint32)(td_len+4+2+2) < responder_cookie->get_size()) ) ?
     1556          new NetMsg(responder_cookie->get_transparent_data(), td_len, false) : NULL;
    14521557
    14531558  // Now generate fitting cookie with decoded generation number of secret
    1454   const respcookie* ourcookie= create_resp_cookie(querier_nli, r_key, generationnumber, if_index);
     1559  const respcookie* ourcookie= create_resp_cookie(querier_nli, r_key, generationnumber, if_index, transparent_data_msgbuf);
     1560  delete transparent_data_msgbuf;
    14551561 
    14561562  if (ourcookie==NULL)
     
    14621568
    14631569  DLog(param.name, "Given Responder Cookie, length "<< responder_cookie->get_size()*8 << " Bit: " << responder_cookie->to_str());
     1570
     1571  // perform actual comparison
    14641572  if (*responder_cookie != *ourcookie) {
    14651573      DLog(param.name, color[red] << "Responder Cookie did not match!" << color[off]);
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/mri_le.cpp

    r3022 r4147  
    114114    nat_flag = msg.decode8() >> 7;
    115115
    116     Log(ERROR_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded MRM, position: " << msg.get_pos());   
     116    Log(DEBUG_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded MRM, position: " << msg.get_pos());   
    117117    // decode the bit field containing ip_version, flags and reserved bits
    118118    flagfield = msg.decode16();
    119     Log(ERROR_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded Flags, position: " << msg.get_pos());   
     119    Log(DEBUG_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded Flags, position: " << msg.get_pos());   
    120120    ip_version= flagfield >> 12;
    121121   
     
    129129        msg.decode(tempaddr4);
    130130        destaddress.set_ip(tempaddr4);
    131         Log(ERROR_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded IPv4, position: " << msg.get_pos());         
     131        Log(DEBUG_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded IPv4, position: " << msg.get_pos());         
    132132    } else {
    133133        msg.decode(tempaddr6);
     
    135135        msg.decode(tempaddr6);
    136136        destaddress.set_ip(tempaddr6);
    137         Log(ERROR_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded IPv6, position: " << msg.get_pos()); 
     137        Log(DEBUG_LOG, LOG_NORMAL, "mri_looseend::deserialize()", "Decoded IPv6, position: " << msg.get_pos()); 
    138138    }
    139139
     
    312312
    313313
     314//virtual function which allows each MRI subtype to return a local interface address
     315uint16
     316mri_looseend::get_local_if() const
     317{
     318
     319    // a local IF number of '0' will cause the Framework not to try to bind to a specific interface - unnecessary here!
     320     return 0;
     321   
     322}
     323
     324
     325
     326
    314327//virtual function inverting direction flag, Responder nodes stores MRI with inverted direction
    315328void mri_looseend::invertDirection() {
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/mri_pc.cpp

    r3022 r4147  
    3232#include <string>
    3333#include <cerrno>
    34 #include <net/if.h>
    35 #include <linux/types.h> // in case that this one is not included in netlink.h
    36 #include <linux/netlink.h>
    37 #include <linux/rtnetlink.h>
     34
     35#ifndef NSIS_OMNETPP_SIM
     36// this will NOT be included in the OMNeT++ simulation, but otherwise
     37  #include <net/if.h>
     38  #include <linux/types.h> // in case that this one is not included in netlink.h
     39  #include <linux/netlink.h>
     40  #include <linux/rtnetlink.h>
     41#endif // end ifndef NSIS_OMNETPP_SIM
    3842
    3943#include "logfile.h"
     
    607611
    608612
     613#ifndef NSIS_OMNETPP_SIM
     614
     615/**
     616 * Returns the interface number the kernel would use for this MRI.
     617 *
     618 * This depends on the Direction flag (upstream/downstream).
     619 *
     620 * TODO: Review and cleanup necessary.
     621 */
     622uint16
     623mri_pathcoupled::get_local_if() const
     624{
     625    //#######################################################################
     626    //
     627    // Query the kernel via RTNetlink socket with RTM_GET_ROUTE
     628    //
     629    // currently, this fails for IPv4, no idea as to why
     630    //
     631    //#######################################################################
     632
     633    // Buffer for error messages, used by the strerror_r() calls below.
     634    char msg_buf[1024];
     635
     636    // We must decide whether IPv4 or IPv6 is used
     637    bool ipv6 = destaddress.is_ipv6();
     638
     639
     640    // 2 sockaddr_in6?
     641    struct in6_addr dstaddr, srcaddr;
     642    struct in_addr dstaddr4, srcaddr4;
     643   
     644    // Netlink Message header plus RTNetlink Message Header plus 1024byte data
     645    struct {
     646        struct nlmsghdr n;
     647        struct rtmsg r;
     648        char data[1024];
     649    } req;
     650
     651    // Struct rtattr
     652    struct rtattr *attr;
     653    struct rtattr *attr2;
     654
     655   
     656    // int outgoinginterface
     657    uint16 outgoinginterface = 0;
     658
     659   
     660    // enable this routine here
     661    if (true) {
     662
     663        // OPEN a RTNETLINK SOCKET
     664       
     665        int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
     666        if (sock < 0) {
     667            strerror_r(errno, msg_buf, sizeof msg_buf);
     668            ERRCLog("mri_pathcoupled::get_local_if()",
     669                        "error opening Netlink socket: " << msg_buf);
     670        }       
     671
     672        // if IPv6
     673
     674        if (ipv6) {
     675
     676            if (flags & Direction) {
     677                sourceaddress.get_ip(dstaddr);
     678                destaddress.get_ip(srcaddr);
     679            } else {
     680                destaddress.get_ip(dstaddr);
     681                sourceaddress.get_ip(srcaddr);
     682            }           
     683
     684            memset(&req, 0, sizeof(req));
     685            req.n.nlmsg_len =
     686                NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r))) +
     687                RTA_LENGTH(sizeof(dstaddr)) + RTA_LENGTH(sizeof(srcaddr));
     688            req.n.nlmsg_flags = NLM_F_REQUEST;
     689            req.n.nlmsg_type = RTM_GETROUTE;
     690            req.r.rtm_family = AF_INET6;
     691            req.r.rtm_dst_len = 128;
     692            req.r.rtm_src_len = 128;
     693
     694            attr = (rtattr*) (((char *) &req) + NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r))));
     695            attr->rta_type = RTA_DST;
     696            attr->rta_len = RTA_LENGTH(sizeof(dstaddr));
     697
     698            memcpy(RTA_DATA(attr), &dstaddr, sizeof(dstaddr));
     699
     700
     701            attr2 = (rtattr*) (((char*) &req) + NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r))) + attr->rta_len);
     702            attr2->rta_type = RTA_SRC;
     703            attr2->rta_len = RTA_LENGTH(sizeof(srcaddr));
     704
     705
     706            memcpy(RTA_DATA(attr2), &srcaddr, sizeof(srcaddr));
     707
     708
     709            // Send to Kernel
     710
     711             /*Send the message*/
     712
     713            if (send(sock, &req, req.n.nlmsg_len, 0) < 0) {
     714                strerror_r(errno, msg_buf, sizeof msg_buf);
     715                ERRCLog("mri_pathcoupled::get_local_if()",
     716                        "error sending Netlink message: " << msg_buf);
     717                close(sock);
     718            }
     719
     720            char* returnbuf = new char[NL_BUFSIZE];
     721
     722            int read = readnl(sock, returnbuf);
     723
     724            if (read < 0) return 0;
     725
     726            nlmsghdr* nlhdrp = (struct nlmsghdr *)returnbuf;
     727
     728            rtmsg* rtmsg = (struct rtmsg*)NLMSG_DATA(nlhdrp);
     729           
     730
     731            // Iterate through data area serachin
     732
     733            rtattr* attrp = RTM_RTA(rtmsg);
     734            uint32 attrlen = RTM_PAYLOAD(nlhdrp);
     735
     736            for( ; RTA_OK(attrp, attrlen); attrp = RTA_NEXT(attrp, attrlen) ){
     737
     738               
     739                if ((attrp->rta_type) == RTA_OIF) {
     740                   
     741                    char* ifname= new char[IF_NAMESIZE];
     742                    if_indextoname(*(int *)RTA_DATA(attrp), ifname);
     743
     744                    Log(EVENT_LOG, LOG_NORMAL, "mri_pathcoupled",  "Kernel decided the outgoing interface index should be " << *(int *)RTA_DATA(attrp) << ", interface Name " << ifname);
     745               
     746                    outgoinginterface=*(int *)RTA_DATA(attrp);
     747                    delete ifname;
     748                }
     749
     750
     751            }
     752
     753
     754
     755
     756        } //end if IPv6
     757        else
     758        {
     759
     760
     761            //cout << "IPv4 used, query for IPv4" << endl;
     762
     763
     764            if (flags & Direction) {
     765
     766            sourceaddress.get_ip(dstaddr4);
     767            destaddress.get_ip(srcaddr4);
     768
     769            } else {
     770
     771            destaddress.get_ip(dstaddr4);
     772            sourceaddress.get_ip(srcaddr4);
     773
     774            }
     775
     776            //cout << "Got socket addresses from data structures" << endl;
     777           
     778            memset(&req, 0, sizeof(req));
     779            req.n.nlmsg_len =
     780                NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r))) +
     781                RTA_LENGTH(sizeof(dstaddr4)) + RTA_LENGTH(sizeof(srcaddr4));
     782            req.n.nlmsg_flags = NLM_F_REQUEST;
     783            req.n.nlmsg_type = RTM_GETROUTE;
     784            req.r.rtm_family = AF_INET;
     785            req.r.rtm_dst_len = 12;
     786            req.r.rtm_src_len = 12;
     787
     788            attr = (rtattr*) (((char *) &req) + NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r))));
     789            attr->rta_type = RTA_DST;
     790            attr->rta_len = RTA_LENGTH(sizeof(dstaddr4));
     791
     792            memcpy(RTA_DATA(attr), &dstaddr4, sizeof(dstaddr4));
     793
     794            attr2 = (rtattr*) (((char*) &req) + NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.r))) + RTA_LENGTH(sizeof(dstaddr4)));
     795            attr2->rta_type = RTA_SRC;
     796            attr2->rta_len = RTA_LENGTH(sizeof(srcaddr4));
     797
     798
     799            memcpy(RTA_DATA(attr2), &srcaddr4, sizeof(srcaddr4));
     800
     801
     802            // Send to Kernel
     803
     804            if (send(sock, &req, req.n.nlmsg_len, 0) < 0) {
     805                strerror_r(errno, msg_buf, sizeof msg_buf);
     806                ERRCLog("mri_pathcoupled::get_local_if()",
     807                        "error sending Netlink message: " << msg_buf);
     808                close(sock);
     809            }
     810
     811            char* returnbuf = new char[NL_BUFSIZE];
     812
     813            int read = readnl(sock, returnbuf);
     814
     815            if (read <0 ) return 0;
     816
     817            nlmsghdr* nlhdrp = (struct nlmsghdr *)returnbuf;
     818
     819            rtmsg* rtmsg = (struct rtmsg*)NLMSG_DATA(nlhdrp);
     820           
     821            // Iterate through data area serachin
     822            rtattr* attrp = RTM_RTA(rtmsg);
     823            uint32 attrlen = RTM_PAYLOAD(nlhdrp);
     824
     825            for( ; RTA_OK(attrp, attrlen); attrp = RTA_NEXT(attrp, attrlen) ){
     826
     827                if ((attrp->rta_type) == RTA_OIF) {
     828                   
     829                    char* ifname= new char[IF_NAMESIZE];
     830                    if_indextoname(*(int *)RTA_DATA(attrp), ifname);
     831
     832                    Log(EVENT_LOG, LOG_NORMAL, "mri_pathcoupled",  "Linux Kernel decided the outgoing interface index should be " << *(int *)RTA_DATA(attrp) << ", interface Name " << ifname);
     833               
     834                    outgoinginterface=*(int *)RTA_DATA(attrp);
     835                    delete ifname;
     836                }
     837
     838
     839            }
     840
     841            if (returnbuf) delete returnbuf;
     842            close(sock);
     843
     844            if (!outgoinginterface) {
     845               
     846                Log(EVENT_LOG, LOG_NORMAL, "mri_pathcoupled", "Linux Kernel was unable to provide a outgoing interface for this flow, taking default route.");
     847
     848            }
     849        }
     850    }
     851   
     852    return outgoinginterface;
     853}
     854
     855#else
     856// this is only included in the OMNeT++ Simulation
     857uint16
     858mri_pathcoupled::get_local_if() const
     859{
     860  return 0; // not really relevant yet
     861}
     862
     863#endif // ifndef NSIS_OMNETPP_SIM
     864
     865
    609866// Invert direction flag; responder nodes stores MRI with inverted direction
    610867void mri_pathcoupled::invertDirection() {
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/nattraversal.cpp

    r2926 r4147  
    4747 */
    4848
    49 /***** class singlehandle *****/
     49void
     50natinfo::clear() {
     51        for (translated_object_list_t::iterator cit= translated_object_list.begin(); cit != translated_object_list.end(); cit++)
     52        {
     53                delete (*cit);
     54        };
     55        translated_object_list.clear();
     56}
     57
     58
     59natinfo::natinfo(const natinfo& nat_info) {
     60        for (translated_object_list_t::const_iterator cit= nat_info.translated_object_list.begin();
     61             cit != nat_info.translated_object_list.end(); cit++)
     62        {
     63                if (*cit)
     64                        add(*(*cit)); // add copies the object
     65        };
     66}
     67
     68
     69natinfo&
     70natinfo::operator=(const natinfo& nat_info)
     71{
     72        clear();
     73        for (translated_object_list_t::const_iterator cit= nat_info.translated_object_list.begin();
     74             cit != nat_info.translated_object_list.end(); cit++)
     75        {
     76                if (*cit)
     77                        add(*(*cit)); // add copies the object
     78        };
     79        return *this;
     80}
     81
     82bool
     83natinfo::operator==(const natinfo& ni) const
     84{
     85        if (count() != ni.count())
     86                return false;
     87
     88        for (int i= 0; i<count(); i++)
     89        {
     90                if ( translated_object_list[i]==NULL || ni.translated_object_list[i]==NULL
     91                     ||
     92                     *translated_object_list[i] != *(ni.translated_object_list[i]) )
     93                        return false;
     94        }
     95        return true;
     96}
     97
     98
     99uint16
     100natinfo::length() const
     101{
     102        uint16 len= 0;
     103        for (translated_object_list_t::const_iterator cit= translated_object_list.begin();
     104             cit != translated_object_list.end();
     105             cit++)
     106        {
     107                len += (*cit)->get_serialized_size(IE::protocol_v1);
     108        }
     109        return len;
     110}
     111
     112
     113const nli*
     114natinfo::get_nli() const
     115{
     116        for (translated_object_list_t::const_iterator cit= translated_object_list.begin(); cit != translated_object_list.end(); cit++)
     117        {
     118                if (*cit)
     119                {
     120                        if ( (*cit)->is_nli() )
     121                                return reinterpret_cast<const ntlp::nli*>(*cit);
     122                }
     123        }
     124        return NULL;
     125}
     126
    50127
    51128/***** IE name *****/
     
    59136/***** inherited from IE *****/
    60137
    61 nattraversal* nattraversal::new_instance() const {
     138
     139nattraversal*
     140nattraversal::new_instance() const {
    62141        nattraversal* sh = NULL;
    63142        catch_bad_alloc(sh = new nattraversal());
     
    65144} // end new_instance
    66145
    67 nattraversal* nattraversal::copy() const {
     146nattraversal*
     147nattraversal::copy() const {
    68148        nattraversal* sh = NULL;
    69149        catch_bad_alloc(sh =  new nattraversal(*this));
     
    71151} // end copy
    72152
     153
    73154nattraversal*
    74155nattraversal::deserialize(NetMsg& msg, coding_t cod, IEErrorList& errorlist, uint32& bread, bool skip) {
    75        
     156        const char *const methodname= "nattraversal::deserialize()";
    76157    uint16 len = 0;
    77158    uint32 ielen = 0;
     
    79160    uint32 resume = 0;
    80161   
     162/**
     163 *
     164 *  0                   1                   2                   3
     165    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     166   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     167   | MRI-Length    | Type-Count    |  NAT-Count    |  Reserved     |
     168   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     169   //            Original Message-Routing-Information             //
     170   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     171   //                 List of translated objects                  //
     172   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     173   | Length of opaque information  |                               |
     174   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                              //
     175   //                Information replaced by NAT #1                |
     176   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     177   :                                                               :
     178   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     179   | Length of opaque information  |                               |
     180   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                              //
     181   //                Information replaced by NAT #N                |
     182   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     183
     184   **
     185   */
    81186
    82187    // check arguments
     
    87192        return NULL;
    88193
    89     //get mri length (read to nowhere)
    90     msg.decode8();
    91     //uint mri_length=msg.decode8();
    92 
    93     //get type count
    94     uint type_count=msg.decode8();
    95 
    96     //get nat count
    97     uint nat_count=msg.decode8();
    98 
    99     //read reserved bits to "nowhere"
    100     uint tmp=msg.decode8();
    101 
    102 
    103 
    104  
    105     uint i=0;
    106     uint count=0;
    107     uint j=0;
    108     uint f=0;
    109 
     194    // get mri length (is given in 32 words), object header is missing
     195    uint16 mri_length= msg.decode8()*4;
     196    DLog(methodname, "MRI length: " << mri_length << " bytes");
     197
     198    // get type count
     199    uint type_count= msg.decode8();
     200    DLog(methodname, "type count: " << type_count);
     201
     202    // get nat count
     203    uint nat_count= msg.decode8();
     204    DLog(methodname, "NAT count: " << nat_count);
     205
     206    // read reserved bits to "nowhere"
     207    uint tmp= msg.decode8();
    110208
    111209    // read mri
     
    113211    // read MRM and instantiate correct MRI subclass
    114212
    115     uint mrm = msg.decode16(false);
    116 
    117     if (mrm == 0) {
     213    uint mrm_type= msg.decode16(false);
     214
     215    DLog(methodname, "Reading MRI of type " << mrm_type);
     216
     217    if (mrm_type == 0) {
    118218
    119219        embedded_mri = new mri_pathcoupled;
    120220        dynamic_cast<mri_pathcoupled*>(embedded_mri)->deserializeNoHead(msg, cod, errorlist, bread, skip);
    121221    }
    122 
    123     if (mrm == 1) {
     222    else
     223    if (mrm_type == 1) {
    124224
    125225        embedded_mri = new mri_looseend;
    126226        dynamic_cast<mri_looseend*>(embedded_mri)->deserializeNoHead(msg, cod, errorlist, bread, skip);
    127227    }
    128 
    129  
    130 
    131 
     228    else
     229    {
     230            WLog(methodname, "NAT traversal contains unknown MRM type " << mrm_type << ", skipping");
     231            // should skip over this object
     232            msg.set_pos_r(mri_length);
     233    }
     234
     235
     236    DLog(methodname, "Reading translated objects.");
    132237    // read translated objects
    133 
     238    uint i= 0;
    134239    for (i=0; i<type_count; i++) {
    135 
    136         translated_objects.push_back(msg.decode16());
    137         tmp=msg.decode16();
    138 
    139     }
     240        translated_object_types.push_back(msg.decode16());
     241    }
     242    // skip padding with 2 NULL bytes if necessary
     243    if (translated_object_types.size() % 2)
     244        tmp= msg.decode16();
    140245
    141246
    142247    // read NLI infos
    143248   
    144     natinfo temp;
    145 
    146     // iterate over profile_count to read whole profiles
     249    natinfo nat_info_temp;
     250
     251    // iterate over profile_count to read whole NAT information
    147252    for (i=0; i<nat_count; i++) {
    148         temp.clear();
    149 
    150         //read count of fields:
    151         count=msg.decode16();
    152 
    153         //iterate through Higher Level Information
    154         for (j=0; j<count; j++) {
    155 
    156             temp.add(msg.decode8());
    157 
     253        nat_info_temp.clear();
     254
     255        // read length of total opaque information fields of NAT i:
     256        len = msg.decode16();
     257        //      uint count = 1;
     258        uint32 objbread = 0;
     259        uint32 tmpbread = 1;
     260        uint32 objpos = msg.get_pos();
     261       
     262       
     263        IE* tmpie = NULL;
     264        ntlp_object* tmpobj = NULL;
     265        known_ntlp_object* tmpknown = NULL;
     266
     267        // iterate through Higher Level Information
     268        while ((objbread<len) && (tmpbread!=0) && (msg.get_pos() < ielen)) {
     269         
     270                // deserialize next NTLP object
     271                tmpie = NTLP_IEManager::instance()->deserialize(msg,cat_known_pdu_object,cod,errorlist,tmpbread,false); //skip == false??
     272                objbread += tmpbread;
     273               
     274                if (tmpie) 
     275                        tmpobj = dynamic_cast<ntlp_object*>(tmpie);
     276                else {
     277                        tmpobj = NULL;
     278                        ERRCLog(methodname, "could not cast to ntlp_object");
     279                }
     280
     281                if (tmpobj) {
     282                        tmpknown = dynamic_cast<known_ntlp_object*>(tmpobj);
     283                        if (tmpknown) {
     284                                nat_info_temp.add(*tmpknown);
     285                        }
     286                        else {
     287                                DLog(methodname, "unknown object in opaque information list, ignoring");
     288                        } // end if tmpknown
     289                }
     290                else {         
     291                        // TODO: for further extension, if the opaque information
     292                        // is not the ntlp_obj, it should be skip anyway
     293                       
     294                        if (tmpie) delete tmpie;
     295                        // do logging and recover
     296                        ERRLog(methodname, "no NTLP object deserialized from IE");
     297                        if (!skip) {
     298                                msg.set_pos(resume);
     299                                return this;
     300                        } // end if not skip
     301                } // end if tmpobj
     302                // setting position of next object
     303                objpos += tmpbread;             
     304        } // end while objbread<len
     305
     306        // handle padding, initial length field of NAT info is 16-bit
     307        uint8 padbytes= (2+len) % 4;
     308        while(padbytes > 0)
     309        {
     310                msg.decode8();
     311                padbytes--;
    158312        }
    159 
    160         //read padding
    161         for (f=0; f<(round_up4(count+2)-(count+2));f++) tmp=msg.decode8();
    162 
    163 
    164         add_profile(temp);
    165     }
    166 
    167 
    168     // There is no padding.
     313       
     314        push_natinfo(nat_info_temp);
     315    } // end for iterating over NAT info objects
     316
     317
     318    // There is no further padding.
    169319    bread = ielen;
    170320    return this;
     
    181331// special serialization function with the ability to omit the TLV header
    182332void nattraversal::serializeEXT(NetMsg& msg, coding_t cod, uint32& wbytes, bool header) const {
    183     uint32 ielen = get_serialized_size(cod); //+header_length;
    184     Log(ERROR_LOG,LOG_NORMAL, "nattraversal::serialize()","should be of length" << ielen);
    185         // check arguments and IE state
    186         check_ser_args(cod,wbytes);
    187         Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "Bytes left in NetMsg: " << msg.get_bytes_left());
    188         // calculate length and encode header
    189         encode_header_ntlpv1(msg,get_serialized_size(cod));
    190         Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "Header encoded, 4byte, bytes left in NetMsg: " << msg.get_bytes_left());
    191         Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "Begin of actual serilization");
    192        
    193         //encode mri length (get_serialized_size currently returns byte size INCLUDING TLV header, we must subtract 1 word = 4 byte)
    194         msg.encode8(embedded_mri->get_serialized_size(cod)-4);
    195        
    196         Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "MRI length encoded, 1byte, bytes left in NetMsg: " << msg.get_bytes_left());
    197 
    198         //encode type count
    199         msg.encode8(translated_objects.size());
    200        
    201         Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "translated object count encoded, 1byte, bytes left in NetMsg: " << msg.get_bytes_left());
    202        
    203         //encode nat_count
    204         msg.encode8(informations.size());
    205        
    206         Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "NAT count encoded, 1byte, bytes left in NetMsg: " << msg.get_bytes_left());
    207 
    208         //reserved
    209         msg.encode8(0);
    210        
    211        
    212         uint idx=0;
    213         uint j=0;
    214         uint i=0;
    215 
    216         uint32 written=0;
    217         //encode MRI (ugly way, I could not get it right using virtual functions in mri superclass..linker would not link it :-/
    218         if (embedded_mri->get_mrm()==0) dynamic_cast<mri_pathcoupled*>(embedded_mri)->serializeNoHead(msg, cod, written);
    219         if (embedded_mri->get_mrm()==1) dynamic_cast<mri_looseend*>(embedded_mri)->serializeNoHead(msg, cod, written);
    220 
    221 Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "MRI encoded, "<< (embedded_mri->get_serialized_size(cod))*4 << "bytes, bytes left in NetMsg: " << msg.get_bytes_left());
    222 
    223 
    224         //iterate translated objects
    225         for (i=0; i<translated_objects.size(); i++) {
    226             //encode 16bit type numbers
    227             msg.encode16(translated_objects[i]);
    228             //padding of 2bytes
    229             msg.encode16(0);
    230         }
    231 
    232 Log(ERROR_LOG, LOG_NORMAL, "nattraversal::serialize()", "Translated objects encoded, "<< translated_objects.size()*4 << "bytes, bytes left in NetMsg: " << msg.get_bytes_left());
    233 
    234 
    235         //iterate profiles, 
    236         for (i=0; i<informations.size(); i++) {
    237             idx=0;
    238 
    239             //encode NLI info length ( !!!! byte length here < as not stated otherwise in DRAFT > !!!! )
    240             msg.encode16(informations[i].prof_vec.size());
    241             idx=2;
     333        const char *const methodname= "nattraversal::serialize()";
     334
     335        uint32 nto_length = get_serialized_size(cod) - (header ? 0 : header_length); // includes object header
     336    DLog(methodname,"should be of length " << nto_length);
     337    // check arguments and IE state
     338    check_ser_args(cod,wbytes);
     339    DLog(methodname, "Bytes left in NetMsg: " << msg.get_bytes_left());
     340    // calculate length and encode header
     341    if (header)
     342    {
     343            encode_header_ntlpv1(msg, nto_length - header_length);
     344            DLog(methodname, "Header encoded, 4 byte, bytes left in NetMsg: " << msg.get_bytes_left());
     345    }
     346    DLog(methodname, "Begin of actual serialization");
     347       
     348    // encode mri length (get_serialized_size currently returns byte size INCLUDING TLV header, we must subtract 1 word = 4 byte)
     349    uint32 mri_len= embedded_mri->get_serialized_size(cod);
     350    // MRI length is given in number of 32-bit words
     351    msg.encode8((mri_len/4)-1);
     352       
     353    DLog(methodname, "MRI length (" << mri_len-4 << " bytes) encoded in 1 byte, bytes left in NetMsg: " << msg.get_bytes_left());
     354
     355    // encode type count
     356    msg.encode8(translated_object_types.size());
     357       
     358    DLog(methodname, "translated object count (" <<  translated_object_types.size() << ") encoded, 1 byte, bytes left in NetMsg: " << msg.get_bytes_left());
     359       
     360    // encode nat_count
     361    msg.encode8(nat_information.size());
     362       
     363    DLog(methodname, "NAT count (" << nat_information.size() << ") encoded, 1 byte, bytes left in NetMsg: " << msg.get_bytes_left());
     364
     365    // reserved
     366    msg.encode8(0);
     367    DLog(methodname, "Reserved byte encoded, 1 byte, bytes left in NetMsg: " << msg.get_bytes_left());
     368   
     369    uint i=0;
     370    uint32 written=0;
     371    // encode MRI (ugly way, I could not get it right using virtual functions in mri superclass..linker would not link it :-/
     372    if (embedded_mri->get_mrm()==0) dynamic_cast<mri_pathcoupled*>(embedded_mri)->serializeNoHead(msg, cod, written);
     373    if (embedded_mri->get_mrm()==1) dynamic_cast<mri_looseend*>(embedded_mri)->serializeNoHead(msg, cod, written);
     374   
     375    DLog(methodname, "MRI encoded, "<< mri_len-4 << " bytes, bytes left in NetMsg: " << msg.get_bytes_left());
     376   
     377   
     378    // iterate translated objects
     379    for (i=0; i<translated_object_types.size(); i++) {
     380            // encode 16bit type numbers
     381            msg.encode16(translated_object_types[i]);
     382    }
     383    // pad with 2 NULL bytes if necessary
     384    if (translated_object_types.size() % 2)
     385    {
     386      msg.encode16(0);
     387    }
     388
     389
     390    DLog(methodname, "Translated objects encoded, "<< translated_object_types.size()*2 + (translated_object_types.size() % 2)*2 << " bytes, bytes left in NetMsg: " << msg.get_bytes_left());
     391
     392
     393    // iterate over NAT info, 
     394    for (i=0; i<nat_information.size(); i++) {
     395            // The length fields for each opaque payload are byte counts, not
     396            // including the 2 bytes of the length field itself.
     397            uint16 info_len = nat_information[i].length();
     398            msg.encode16(info_len);
    242399           
    243 
    244             for (j=0; j<informations[i].prof_vec.size(); j++) {
    245 
    246                 msg.encode8(informations[i].prof_vec[j]);
    247                 idx++;
     400            uint32 tmp_wbytes = 0;
     401            for (uint16 j=0; j<nat_information[i].size(); j++) {
     402                    if (nat_information[i].get(j))
     403                    {
     404                            try
     405                            {
     406                                    nat_information[i].get(j)->serialize(msg,cod,tmp_wbytes);
     407                            }
     408                            catch (IEError& e)
     409                            {
     410                                    ERRCLog(methodname,"while processing " << nat_information[i].get(j)->get_ie_name() << ":" << e.getstr());
     411                            }
     412                            catch(...)
     413                            {
     414                                    throw;
     415                            }
     416                    } // end if
     417
     418                    // encode padding: each opaque information field is zero-padded
     419                    // to the next 32-bit word boundary if necessary.
     420           
     421            } // end for j
     422
     423            // must pad two length bytes + NAT info part to a 32-bit boundary
     424            uint8 padbytes= (2 + info_len) % 4;
     425            while(padbytes>0)
     426            {
     427                    msg.encode8(0);
     428                    padbytes--;
    248429            }
    249430
    250             // padding
    251             if (idx % 4) {
    252                 if (idx%4==3) msg.encode8(0);
    253                 if (idx%4==2) msg.encode16(0);
    254                 if (idx%4==1) { msg.encode16(0); msg.encode8(0); }
    255             }
    256 
    257 
    258 
    259         }
    260 
    261 
    262 
    263         wbytes = ielen;
    264        
    265     ostringstream tmpostr;
    266     msg.hexdump(tmpostr,0,wbytes);
    267     Log(DEBUG_LOG,LOG_NORMAL, "nattraversal_serialize", "netmsg pos:" << msg.get_pos() << " netmsg:" << tmpostr.str().c_str());
     431    } //end for NAT info #i
     432
     433    DLog(methodname, "Translated opaque information encoded, bytes left in NetMsg: " << msg.get_bytes_left());
     434
     435    wbytes = nto_length;
     436   
     437    //ostringstream tmpostr;
     438    //msg.hexdump(tmpostr,0,wbytes);
     439    //DLog(methodname, "netmsg pos:" << msg.get_pos() << " netmsg:" << tmpostr.str());
     440
    268441    return;
    269442} // end serialize
     
    273446} // end check
    274447
    275 size_t nattraversal::get_serialized_size(coding_t cod) const {
     448
     449// returns the object size in bytes, including the common object header
     450size_t
     451nattraversal::get_serialized_size(coding_t cod) const {
    276452    uint size;
    277453
     
    279455    if (!supports_coding(cod)) throw IEError(IEError::ERROR_CODING);
    280456   
    281     //Prof-Count field and reserved, 1 word
    282     size=32;
    283 
    284     //MRI length in 8 = bit length - 4 byte
    285     size+=((embedded_mri->get_serialized_size(cod))*8)-32;
    286 
    287     //translations list, 1 word each item
    288     size+=(translated_objects.size())*32;
    289 
    290     //iterate profiles, add their sizes, round each up to word boundary
    291     for (i=0; i<informations.size(); i++) {
    292     size+=(round_up4(informations[i].prof_vec.size()+2))*8;
    293     }
    294 
    295  
    296     return (size/8)+header_length;
    297 
     457    // MRI-Count, Type-Count, NAT-Count field and reserved, 1 32-bit word
     458    size= 32;
     459
     460    // MRI length in byte length - 4 byte object header
     461    size+= (embedded_mri->get_serialized_size(cod)*8)-32;
     462
     463    // translations list, 1 16-word each item and padding of 16 bit if necessary
     464    size+= (translated_object_types.size() + (translated_object_types.size() % 2)) * 16;
     465
     466    //uint32 to_size=size; // only for debugging
     467    // iterate over translated information of different NATs, add their sizes, round each up to word boundary
     468    for (i=0; i<nat_information.size(); i++) {
     469            // length info for all translated info of NAT #i
     470            size+= 16;
     471            uint16 natinfosize= 0;
     472            // translated objects of NAT#i
     473            for (uint16 j= 0; j<nat_information[i].size(); j++)
     474            {
     475                    // the length of opaque information and the padding to a 32bit alignment
     476                    natinfosize= nat_information[i].get(j)->get_serialized_size(cod);
     477                    size+= natinfosize * 8;
     478            }
     479            // add padding if necessary
     480            // starting from length field, padding up to the next 32-bit boundary
     481            size+= ((2 + natinfosize)%4) *8;
     482    } // end for NAT info #i
     483    //DLog("nattraversal::get_serialized_size()","nat info objects use " << (size-to_size) / 8 << " bytes");
     484
     485    // include header length
     486    return (size/8) + header_length;
    298487} // end get_serialized_size
    299488
    300 bool nattraversal::operator==(const IE& ie) const {
    301     // const nattraversal* sh = dynamic_cast<const nattraversal*>(&ie);
    302         //if (sh) return ((subtype==sh->subtype) && (handle==sh->handle));
     489
     490bool
     491nattraversal::operator==(const IE& ie) const {
     492    const nattraversal* nto = dynamic_cast<const nattraversal*>(&ie);
     493
     494        if (nto)
     495        {
     496                //DLog("nattraversal::operator==","dynamic cast successful.");
     497
     498                if (embedded_mri != NULL && nto != NULL)
     499                {
     500                        if ( *embedded_mri != *(nto->get_embedded_mri()) )
     501                        {
     502                                return false;
     503                        }
     504                }
     505                //DLog("nattraversal::operator==","MRI ok.");
     506
     507                if (translated_object_types.size() != nto->translated_object_types.size())
     508                        return false;
     509                //DLog("nattraversal::operator==","no of translated objects ok.");
     510
     511                for (uint32 i=0; i<translated_object_types.size(); i++) {
     512                        if (translated_object_types[i] != nto->translated_object_types[i])
     513                                return false;
     514                }
     515                //DLog("nattraversal::operator==","translated objects ok.");
     516
     517                if (nat_information.size() != nto->nat_information.size())
     518                        return false;
     519
     520                //DLog("nattraversal::operator==","No of NAT info ok.");
     521
     522                const known_ntlp_object* ni1;
     523                const known_ntlp_object* ni2;
     524
     525                for (uint32 i=0; i<nat_information.size(); i++) {
     526                        // translated objects of NAT#i
     527                        if (nat_information[i].size() != nto->nat_information[i].size())
     528                                return false;
     529
     530                        for (uint16 j= 0; j<nat_information[i].size(); j++)
     531                        {
     532                                ni1= nat_information[i].get(j);
     533                                ni2= nto->nat_information[i].get(j);
     534                                if (ni1 == NULL || ni2 == NULL || *ni1 != *ni2)
     535                                        return false;
     536                               
     537                        } // end for
     538                } // end for NAT info #i
     539
     540                return true;
     541        }
     542        else
    303543        return false;
    304544} // end operator==
     
    309549{
    310550    os<<setw(level*indent)<<"";
    311         if (name && (*name!=0)) os<<name<<"\n";
    312 
    313         uint j=0;
    314         uint i=0;
    315 
    316 
    317         os << "MRI-Length:   " << (int) embedded_mri->get_serialized_size(protocol_v1)-4 << "\n";
    318 
    319         os << "Type-Count:   " << (int) translated_objects.size() << "\n";
    320 
    321         os << "NAT Count:    " << (int) informations.size() << "\n";
    322 
    323         os << "Embedded MRI: ";
    324         // print MRI
    325        
    326         embedded_mri->print(os, level, indent);
    327 
    328 
    329 
    330         os << "Translated objects:\n";
    331        
    332         //iterate translated_objects
    333         for (i=0; i<translated_objects.size(); i++) {
    334 
    335             os << (int) translated_objects[i] << "\n";
     551    if (name && (*name!=0)) os<<name<< endl;
     552
     553    uint j=0;
     554    uint i=0;
     555       
     556
     557    os << "MRI-Length:   " << (int) embedded_mri->get_serialized_size(protocol_v1)-4 << " bytes" << endl;
     558   
     559    os << "Type-Count:   " << (int) translated_object_types.size() << endl;
     560   
     561    os << "NAT Count:    " << (int) nat_information.size() << endl;
     562   
     563    os << "Embedded MRI: ";
     564    // print MRI
     565   
     566    embedded_mri->print(os, level, indent);
     567   
     568    os << "Translated object types: ";
     569   
     570    // iterate translated_object_types
     571    for (i=0; i<translated_object_types.size(); i++) {
    336572           
    337         }
    338 
    339         //iterate informations, 
    340         for (i=0; i<informations.size(); i++) {
    341 
    342             for (j=0; j<informations[i].prof_vec.size(); j++) {
    343 
    344                 os << "<" << (int) informations[i].prof_vec[j] << "> ";
     573      os << hex << (uint16) translated_object_types[i] << ":" << dec;
     574    }
     575    os << endl;
     576   
     577    // iterate nat_information, 
     578    for (i=0; i<nat_information.size(); i++) {
     579           
     580            for (j=0; j<nat_information[i].size(); j++) {
     581                    nat_information[i].get(j)->print(os,level,indent);
    345582            }
    346         os <<"\n";
    347         }
    348        
    349 
    350 
    351         return os;
     583            os << endl;
     584    }
     585   
     586    return os;
    352587} // end print
    353588 
    354589istream& nattraversal::input(istream& is, bool istty, uint32 level, const uint32 indent, const char* name) {
    355     //ntlp_object* tmp;
     590        //ntlp_object* tmp;
    356591        string s;
    357592        if (istty) cout<<""<<"hostaddress: ";
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/nattraversal.h

    r2548 r4147  
    3131#include "protlib_types.h"
    3232#include "mri.h"
    33 
     33#include "nli.h"
     34#include "ie.h"
    3435
    3536
     
    4445
    4546
    46 
     47/**
     48 * list of translated NTLP objects / information per NAT
     49 **/
    4750class natinfo {
    4851 public:
    49     std::vector <uint8> prof_vec;
    50  
    51 inline
    52 void
    53     add(uint8 field) {
    54             prof_vec.push_back(field);
    55 
    56             };
    57 
    58 inline
    59 void
    60 clear() {
    61    prof_vec.clear();
     52        /// constructor
     53        natinfo() {};
     54        /// copy constructor
     55        natinfo(const natinfo& nat_info);
     56        /// destructor
     57        ~natinfo() { clear(); }
     58
     59        // assignment operator
     60        natinfo& operator=(const natinfo& nat_info);
     61
     62        bool operator==(const natinfo& ni) const;
     63
     64        /// add a copy of of the NTLP object to the translated NAT information
     65        void add(const known_ntlp_object& obj) { translated_object_list.push_back( obj.copy() ); };
     66
     67        /// get NAT info object at certain index
     68        const known_ntlp_object* get(unsigned int index) const { return translated_object_list.at(index); };
     69
     70        /// get back number of NAT info objects
     71        unsigned int size() const { return translated_object_list.size(); };
     72
     73        /// remove all objects from list
     74        void clear();
     75
     76        uint16 count() const { return translated_object_list.size(); };
     77
     78        /// get back NLI object if exists, NULL otherwise
     79        const nli* get_nli() const;
     80
     81        uint16 length() const;
     82
     83private:
     84        typedef std::vector<known_ntlp_object *> translated_object_list_t;
     85
     86        translated_object_list_t translated_object_list;
     87
    6288};
    6389
    64 inline
    65     natinfo() {
    66 };
    67 
    68 inline
    69 uint16
    70     length() {
    71     return prof_vec.size();
    72 };
    73 
    74 
    75 inline
    76     ~natinfo() {
    77 
    78 };
    79 
    80 };
    81 
    82 
     90/**
     91 *
     92 *  0                   1                   2                   3
     93    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     94   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     95   | MRI-Length    | Type-Count    |  NAT-Count    |  Reserved     |
     96   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     97   //            Original Message-Routing-Information             //
     98   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     99   //                 List of translated objects                  //
     100   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     101   | Length of opaque information  |                               |
     102   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                              //
     103   //                Information replaced by NAT #1                |
     104   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     105   :                                                               :
     106   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     107   | Length of opaque information  |                               |
     108   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                              //
     109   //                Information replaced by NAT #N                |
     110   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     111
     112   MRI-Length (8 bits):  The length of the included MRI payload in 32-
     113      bit words.
     114
     115   Original Message-Routing-Information (variable):  The MRI data from
     116      when the message was first sent, not including the object header.
     117
     118   Type-Count (8 bits):  The number of objects in the 'List of
     119      translated objects' field.
     120
     121   List of translated objects (variable):  This field lists the types of
     122      the objects that were translated by every NAT through which the
     123      message has passed.  Each element in the list is a 16-bit field
     124      containing the first 16 bits of the object TLV header, including
     125      the AB extensibility flags, two reserved bits, and 12 bit object
     126      type.  The list is initialised by the first NAT on the path;
     127      subsequent NATs may delete elements in the list.  Padded with 2
     128      null bytes if necessary.
     129
     130   NAT-Count (8 bits):  The number of NATs traversed by the message, and
     131      the number of opaque payloads at the end of the object.  The
     132      length fields for each opaque payload are byte counts, not
     133      including the 2 bytes of the length field itself.  Note that each
     134      opaque information field is zero-padded to the next 32-bit word
     135      boundary if necessary.
     136*
     137**/
    83138
    84139class nattraversal : public known_ntlp_object {
    85 
    86140
    87141/***** inherited from IE ****/
     
    100154/***** new members *****/
    101155
    102         const mri* get_embedded_mri() { return embedded_mri; }
     156        const mri* get_embedded_mri() const { return embedded_mri; }
     157        const nli* get_nli() const {
     158                if (!nat_information.empty())
     159                        return nat_information.front().get_nli();
     160                else
     161                        return NULL;
     162        }
    103163
    104164
    105165 private:
    106         // the vector holding NLI informations
    107         std::vector <natinfo> informations;
     166        typedef std::vector<natinfo> nat_information_t;
     167
     168        // the vector holding NLI information (one information object per traversed NAT)
     169        nat_information_t nat_information;
    108170       
    109         // the vector holding our list of translated objects
    110         std::vector <uint16> translated_objects;
    111        
    112         //MRI length
    113         uint8 mri_length;
    114 
    115 
    116         //Reserved
    117         uint8 reserved;
    118        
    119         //MRI
     171        // the vector holding our list of translated object types
     172        std::vector <uint16> translated_object_types;
     173
     174
     175        // MRI
    120176        mri* embedded_mri;
    121177
    122         // any more fields are not necessary, as we can get the length of the vectors via their functions
     178        // mri length will be derived from embedded_mri
     179        // any further fields are not necessary, as we can get the length of the vectors via their functions
    123180
    124181   
     
    128185public:   
    129186
    130 
    131 
    132 
    133 
    134 // add a profile
    135 inline
    136 void
    137     add_profile(natinfo info) {
    138     informations.push_back(info);
     187        // add information that have been translated by a NAT
     188        void push_natinfo(const natinfo& info) { nat_information.push_back(info); };
     189
     190        // clear profiles
     191        inline void clear() { nat_information.clear(); };
     192
     193        // add a translated object
     194        inline void add_translation(uint16 type) { translated_object_types.push_back(type); }
     195
     196        // clear translated objects
     197        inline void clear_translations() { translated_object_types.clear(); }
     198
     199        // get translated objects
     200        inline const vector<uint16> get_translations() const { return translated_object_types; }
     201
     202        // stupid constructor, still, it is needed by NTLP_IE's "new_instance()" method, for deserialization (??)
     203        inline nattraversal () : known_ntlp_object(NatTraversal, Mandatory),
     204                                 embedded_mri(0)
     205                {
     206                        nat_information.clear();
     207                };
     208
     209
     210        // This is the one mighty constructor, via which the object SHOULD be built programmatically!
     211        inline
     212        nattraversal (const mri* mr, std::vector <natinfo> nat_information, std::vector <uint16> translated_object_types):
     213                known_ntlp_object(NatTraversal, Mandatory),
     214                nat_information(nat_information),
     215                translated_object_types(translated_object_types),
     216                embedded_mri(mr ? mr->copy() : 0)
     217                {};
     218
     219
     220        // Copy constructor
     221        inline
     222        nattraversal(const nattraversal& n) :
     223                known_ntlp_object(NatTraversal, Mandatory),
     224                nat_information(n.nat_information),
     225                translated_object_types(n.translated_object_types),
     226                embedded_mri(n.embedded_mri ? n.embedded_mri->copy() : NULL)
     227                {
     228                }
     229       
     230
     231        inline
     232        nattraversal& operator=(const nattraversal& n)
     233        {
     234                nat_information.clear();
     235                nat_information= n.nat_information;
     236                translated_object_types.clear();
     237                translated_object_types=n.translated_object_types;
     238                delete embedded_mri;
     239                embedded_mri= n.embedded_mri ? n.embedded_mri->copy() : NULL;
     240               
     241                return *this;
     242        }
     243
     244        virtual inline ~nattraversal() { delete embedded_mri; }
     245
    139246};
    140247
    141 // clear profiles
    142 inline
    143 void
    144     clear() {
    145     informations.clear();
    146 };
    147 
    148 
    149 // add a translated object
    150 inline
    151 void
    152     add_translation(uint16 type) {
    153     translated_objects.push_back(type);
    154248}
    155249
    156 // clear translated objects
    157 inline
    158 void
    159     clear_translations() {
    160     translated_objects.clear();
    161 }
    162 
    163 // get translated objects
    164 inline
    165     const vector<uint16> get_translations() const {
    166     return translated_objects;
    167 }
    168 
    169 // stupid constructor, still, it is needed by NTLP_IE's "new_instance()" method, for deserialization (??)
    170 inline
    171     nattraversal () :
    172     known_ntlp_object(NatTraversal, Mandatory)
    173 
    174     {
    175         informations.clear();
    176 };
    177 
    178 
    179 //This is the one mighty constructor, via which the object SHOULD be built programmatically!
    180 inline
    181     nattraversal (mri* mr, std::vector <natinfo> informations, std::vector <uint16> translated_objects):
    182     known_ntlp_object(NatTraversal, Mandatory),
    183     informations(informations),
    184     translated_objects(translated_objects),
    185     embedded_mri(mr)
    186     {};
    187 
    188 
    189 //Copy constructor
    190 inline
    191     nattraversal(const nattraversal& n) :
    192         known_ntlp_object(NatTraversal, Mandatory){
    193     informations=n.informations;
    194     translated_objects=n.translated_objects;
    195     embedded_mri=n.embedded_mri->copy();
    196 
    197 }
    198 
    199 
    200 
    201 
    202 
    203 virtual
    204 inline
    205     ~nattraversal()
    206     {
    207 
    208     }
    209 
    210 };
    211 
    212 }
    213 
    214250
    215251#endif
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/nli.h

    r3025 r4147  
    161161  void set_ip_ttl(uint8 ttl);
    162162  const netaddress& get_if_address() const { return if_address; }
     163#ifdef NSIS_OMNETPP_SIM
     164  // this is for the OMNeT++ Simulation and is not included otherwise
     165  // need to set this after the constructor is called (in initialize())
     166  void set_if_address(const hostaddress& ha) { if_address=ha; }
     167#endif
    163168}; // end class nli
    164169
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/ntlp_errorobject.h

    r3701 r4147  
    7676    errsub_IncorrectMsgLength= 3,
    7777    errsub_InvalidEFlag      = 4,
     78    errsub_InvalidCFlag      = 5,
    7879    // subtypes for err_ObjectTypeError
    7980    errsub_DuplicateObject              = 0,
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/ntlp_ie.cpp

    r2887 r4147  
    164164        uint16 nslpid;
    165165        uint8 flags;
     166        bool  c_flag= false;
    166167        uint8 hops;
    167168        IE* ie = NULL;
     
    176177        } // end if bleft<common_header_length
    177178        try {
    178                 ntlp_pdu::decode_common_header_ntlpv1(msg,vers,hops, len, nslpid, type, flags, errorlist);
     179                ntlp_pdu::decode_common_header_ntlpv1(msg,vers,hops, len, nslpid, type, flags, c_flag, errorlist);
    179180        } catch(IEError& ignored) {
    180181                catch_bad_alloc(iee = new IETooBigForImpl(coding,cat,saved_pos));
     
    633634
    634635
     636/***** class GIST_InvalidCFlag *****/
     637GIST_InvalidCFlag::GIST_InvalidCFlag(IE::coding_t cod, uint8 version, uint8 hops, uint16 length, uint16 nslpid, uint8 type, uint8 flags)
     638        : coding(cod),
     639          version(version),
     640          hops(hops),
     641          length(length),
     642          nslpid(nslpid),
     643          type(type),
     644          flags(flags)
     645{
     646    ERRCLog("GIST Error" , IEError::getstr() << " version: " << (int) version);
     647} // end constructor
     648
    635649
    636650} // end namespace protlib
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/ntlp_object.cpp

    r2928 r4147  
    216216 * @note Arguments are NOT checked.
    217217 * @param msg network message
    218  * @param len ntlp_object content length
     218 * @param len ntlp_object content length (in bytes, excluding this header, 0 means no value present)
    219219 */
    220220void known_ntlp_object::encode_header_ntlpv1(NetMsg& msg, uint16 len) const {
    221   register uint32 objlen = round_up4(len); //+header_length;
    222 
    223   // check if len is devidable by 4
     221  register uint32 objlen = round_up4(len); // including padding
     222
     223  // check if len is dividable by 4
    224224  if (len%4)
    225225  {
    226226    IEWrongLength err(protocol_v1,category,type,255,msg.get_pos());
    227227    Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::encode_header_ntlpv1(): IE " << get_ie_name()
    228                                              << ", error " << err.getstr() << ", length " << len);
     228        << ", error " << err.getstr() << ", length " << len << ", object is not aligned to 32-bit word boundary");
    229229    throw err;
    230230  } // end if len mod 4
    231231
    232232  // Is msg big enough?
    233   if ( msg.get_bytes_left() < (objlen/8) )
     233  if ( msg.get_bytes_left() < objlen )
    234234  {
    235235    IEMsgTooShort err(protocol_v1,category,msg.get_pos());
    236236    Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::encode_header_ntlpv1(): IE " << get_ie_name()
    237                               << ", error " << err.getstr() << ", required " << objlen << "available: " << msg.get_bytes_left());
     237        << ", error " << err.getstr() << ", required: " << objlen << " bytes, available: " << msg.get_bytes_left() << " bytes");
    238238    throw err;
    239239  } // end if not enough memory
     
    241241  // encode common object header
    242242  msg.encode16(type | (action << 14));
     243  // length: length of value given in no of 32-bit words
    243244  msg.encode16((len)/4);
    244245  return;
    245246} // end encode_header_ntlpv1
     247
    246248
    247249/** set catgory as well as object type and action.
     
    409411
    410412
    411 /** Get size of this object in serialized form in bytes.
    412  * @param c coding sheme for which the size is calculated.
     413/** Get size of this object in serialized form in bytes, including the common object header
     414 * @param c coding scheme for which the size is calculated.
     415 * @note the returned value includes the header_length and returns the number of bytes
    413416 */
    414417size_t raw_ntlp_object::get_serialized_size(IE::coding_t c) const {
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/ntlp_pdu.cpp

    r2973 r4147  
    9191        // decode common PDU header
    9292        try {
    93           decode_common_header_ntlpv1(msg,v, h, len, s, t, f, errorlist);
    94           flags=f;
     93          decode_common_header_ntlpv1(msg,v, h, len, s, t, f, c_flag, errorlist);
     94          flags= f;
    9595          nslpid = s;
    9696          ntlp_hops = h;
     
    289289  msg.encode16(len/4);
    290290  msg.encode16(nslpid);
    291   msg.encode8(type);
     291  // clear C-Flag by default
     292  uint8 cflag_and_type= type & 0x7F;
     293  if (type == known_ntlp_pdu::Query)
     294         cflag_and_type= 0x80 | type;
     295  msg.encode8(cflag_and_type);
    292296  msg.encode8(flags);
    293297 
     
    429433
    430434/** Decode common header without doing any sanity checks. */
    431 void ntlp_pdu::decode_common_header_ntlpv1(NetMsg& msg, uint8& ver, uint8& hops, uint16& clen_bytes, uint16& nslpid, uint8& type, uint8& flags, IEErrorList& errorlist) {
     435void ntlp_pdu::decode_common_header_ntlpv1(NetMsg& msg, uint8& ver, uint8& hops, uint16& clen_bytes, uint16& nslpid, uint8& type, uint8& flags, bool& c_flag, IEErrorList& errorlist) {
    432436        uint32 tmpclen = 0;
    433437        ver = msg.decode8();
     
    436440        nslpid = msg.decode16();
    437441        type = msg.decode8();
     442        // get C-Flag from upper bit
     443        c_flag= type & 0x80;
     444        // finally clear the C-Flag from type
     445        type = type & 0x7F;
    438446        flags = msg.decode8();
    439447       
     
    455463        if ((type == known_ntlp_pdu::Error) && (flags & R_Flag)) {
    456464            errorlist.put(new GIST_InvalidRFlag(protocol_v1, ver, hops, tmpclen, nslpid, type, flags));
     465        }
     466        // 5: Invalid C-flag:  The C flag was set on something other than a
     467        // Query message or Q-mode Data message, or was clear on a Query
     468        // message.
     469        if ( (!c_flag) && ((type == known_ntlp_pdu::Query))
     470            ||
     471             ( c_flag && (type != known_ntlp_pdu::Query) && (type != known_ntlp_pdu::Data) )
     472           )
     473        {
     474            errorlist.put(new GIST_InvalidCFlag(protocol_v1, ver, hops, tmpclen, nslpid, type, flags));
    457475        }
    458476
     
    478496      type(t),
    479497      flags(0),
     498      c_flag(false),
    480499      nattrav_ptr(0),
    481500      mri_ptr(0),
     
    499518                                        type(n.type),
    500519                                        flags(0),
     520                                        c_flag(n.c_flag),
    501521                                        //take over the NTLP object pointers from the other object
    502522                                        nattrav_ptr(n.