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

Changeset 4108


Ignore:
Timestamp:
Jul 16, 2009, 3:58:50 PM (8 years ago)
Author:
bless
Message:

merged in changes from https://svn.ipv6.tm.uka.de/nsis/ntlp/branches/20080820-configpar until r4106

Location:
ntlp/trunk
Files:
1 deleted
45 edited
4 copied

Legend:

Unmodified
Added
Removed
  • ntlp/trunk

  • ntlp/trunk/GIST-KA-RELEASE

    r2963 r4108  
    11GIST_VERSION=0
    2 GIST_PATCHLEVEL=96
    3 GIST_SUBLEVEL=1
     2GIST_PATCHLEVEL=97
     3GIST_SUBLEVEL=0
    44GIST_EXTRAVERSION=
    55ifdef GIST_SUBLEVEL
  • ntlp/trunk/gist

    r2520 r4108  
    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/trunk/include/apimessage.h

    r3674 r4108  
    133133   
    134134  /// transfer attributes
    135   typedef struct tx_attr_t {
     135  struct tx_attr_t {
    136136    tx_attr_t() :
    137137      reliable(false), // rcv and snd
  • ntlp/trunk/include/ntlp_ie.h

    r2886 r4108  
    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/trunk/include/ntlp_object.h

    r2949 r4108  
    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/trunk/include/ntlp_starter.h

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

    r3437 r4108  
    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/trunk/src/GISTConsole.h

    r2949 r4108  
    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/trunk/src/Makefile

    r3674 r4108  
    6565NTLP_PDUOBJS := $(patsubst %.cpp,%.o,$(NTLP_PDUSRC))
    6666
     67NTLP_MAIN_OBJ = ntlp_main.o
    6768NTLP_SRCS =  $(wildcard *.cpp) $(NTLP_PDUSRC)
    68 NTLP_OBJS=  $(patsubst %.cpp,%.o,$(NTLP_SRCS))
     69NTLP_ALLOBJS=  $(patsubst %.cpp,%.o,$(NTLP_SRCS))
     70NTLP_OBJS=  $(filter-out $(NTLP_MAIN_OBJ),$(NTLP_ALLOBJS))
     71
    6972
    7073DEPENDFILE := $(wildcard dependfile)
     
    119122PDU_INC         = ./pdu
    120123INCLUDE         = -I. -I$(PDU_INC) -I$(API_INC) -I$(PROTLIB_INC) -I$(FQUEUE_INC) $(SCTP_INCLUDE) $(GUI_INCLUDE)
    121 LIBDIRS         = $(SCTP_LIBSEARCH) $(GUI_LIBSEARCH)
     124LIBDIRS                = -L$(FQUEUE_SRC) -L$(PROTLIB_SRC) $(SCTP_LIBSEARCH) $(GUI_LIBSEARCH)
    122125
    123126SUBDIRS = $(PROTLIB_SRC)
     
    148151        test -x simpleclient && su -c 'chown root simpleclient ; chmod u+s simpleclient' ; true
    149152
    150 $(NTLPEXE):   ntlp_main.o $(GISTLIB) $(LIBS)
    151         $(CPP) $(CFLAGS) -o $@ ntlp_main.o -L . -lGIST $(LIBDIRS) $(SHLIBS) $(STATIC_LIBS)
     153$(NTLPEXE):   $(NTLP_MAIN_OBJ) $(GISTLIB) $(LIBS)
     154        $(CPP) $(CFLAGS) -o $@ $(NTLP_MAIN_OBJ) -L . -lGIST $(LIBDIRS) $(SHLIBS) $(STATIC_LIBS)
    152155
    153156$(GISTLIB): $(NTLP_OBJS)
     
    250253
    251254TAGS:
    252         - etags --language=c++ $(INC)/*.h $(NTLP_SRCS) $(PROTLIB_INC)/*.h $(PROTLIB_SRC)/*.cpp
     255        - etags --language-force=c++ $(INC)/*.h $(NTLP_SRCS) $(PROTLIB_INC)/*.h $(PROTLIB_SRC)/*.cpp
    253256
    254257
     
    274277           moc $< -o $@
    275278
    276 
    277 .PHONY: clean distclean dellogs clobber setperms TAGS depend dependfile
     279conftypecheck:
     280        grep -h getconfigpar $(NTLP_SRCS) ../include/*.h | perl -pe 's/.*getconfigpar.*<\s*([^\s]+[^>]+>?)\s*>\(([^)]+)\).*/\2 \1/' | sort | uniq
     281
     282.PHONY: clean distclean dellogs clobber setperms TAGS depend dependfile conftypecheck
    278283
    279284### DO NOT DELETE THIS LINE -- make depend depends on it.
  • ntlp/trunk/src/capability.cpp

    r2766 r4108  
    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/trunk/src/capability.h

    r2949 r4108  
    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/trunk/src/gist_exceptions.h

    r2548 r4108  
    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/trunk/src/ntlp_main.cpp

    r3674 r4108  
    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//
     
    7272#include "ntlp_starter.h"
    7373
     74#include "gist_conf.h"
     75#include "configfile.h"
     76
    7477#include "GISTConsole.h"
    7578
     
    7982#include <openssl/evp.h>
    8083
    81 
    8284using namespace ntlp;
    8385using namespace protlib;
     
    9698Thread* global_ntlpthread_p= 0;
    9799
    98 ///config array
     100namespace ntlp {
     101// configuration class
     102gistconf gconf;
     103}
     104
     105/// config array
    99106map<std::string, std::string> config;
    100107
     
    185192
    186193
    187 /** read in the config from config file
    188  *  @returns true if file was read, false if file could not be opened
    189  */
    190 bool
    191 read_config()
    192 {
    193     string temp;
    194     const unsigned short maxlinelen = 128;
    195 
    196     ifstream configfile;
    197     char line[maxlinelen];
    198 
    199     configfile.open(gist_configfilename, std::ios::in);
    200     if ( configfile.is_open() )
    201     {
    202       Log(DEBUG_LOG,LOG_NORMAL,"read_config()","Reading in Configuration file " << gist_configfilename);
    203     }
    204     else
    205     {
    206       Log(ERROR_LOG,LOG_CRIT,"read_config()","Reading Configuration file " << gist_configfilename << " failed.");
    207       return false;
    208     }
    209 
    210 
    211     while (!configfile.eof())
    212     {
    213       configfile.getline(line, maxlinelen);
    214       //std::cout<<line;
    215 
    216       temp = string(line);
    217 
    218       std::string::size_type pos  = std::string::npos;
    219        
    220       pos = temp.find_first_of("=", 0);
    221 
    222       if (pos)
    223       { // found =
    224         config[temp.substr(0, pos)] = temp.substr(pos + 1, temp.length());
    225       }
    226     }
    227 
    228     return true;
    229 }
    230194
    231195/// print the usage help
     
    243207        << "  display this help text" << endl
    244208
    245         << "  --ipv4-address <addr>         "
    246         << "  override the local IPv4 address" << endl
    247 
    248         << "  --ipv6-address <addr>         "
    249         << "  override the local IPv6 address" << endl
    250 
    251         << "  --udp-port <port>             "
    252         << "  the UDP port to use" << endl
    253 
    254         << "  --tcp-port <port>             "
    255         << "  the TCP port to use" << endl
    256 
    257         << "  --tls-port <port>             "
    258         << "  the TCP port to use for TLS over TCP" << endl
    259 
    260         << "  --retry-limit <num>           "
    261         << "  the upper retry limit (ms)" << endl
    262 
    263         << "  --retry-period <num>          "
    264         << "  the initial retry period (ms)" << endl
    265 
    266         << "  --refresh-limit <num>         "
    267         << "  the upper refresh period limit (ms)" << endl
    268 
    269         << "  --ma-hold-time <ms>           "
    270         << "  the hold time for message associations" << endl
    271 
    272         << "  --timing-factor <num>         "
    273         << "  for calculating local refresh timers" << endl
    274 
    275         << "  --lifetime <ms>               "
    276         << "  the life time of routing state" << endl
    277 
    278         << "  --secrets-count <num>         "
    279         << "  the secrets count" << endl
    280 
    281         << "  --secrets-length <num>        "
    282         << "  the secrets length in bits" << endl
    283 
    284         << "  --secrets-rollover-time <ms>  "
    285         << "  the secrets rollover time" << endl
    286 
    287         << "  --latestate <on|off>          "
    288         << "  use late state installation on responder" << endl
    289 
    290         << "  --reqconfirm <on|off>          "
    291         << "  require the full handshake even in D-Mode" << endl
    292         << "                                "
    293         << "  (and thus use cookie authentication)" << endl
    294 
    295         << "  --datainquery <on|off>          "
    296         << "  send NSLP data already in Query" << endl
    297 
    298 
    299         << "  --debug-tp                    "
    300         << "  enable debugging on TP level" << endl
     209        << "  --" << gconf.parname(gistconf_conffilename) << " <filename> "
     210        << "\t\t" << gconf.getDescription(gistconf_conffilename) << endl
     211
     212        << "  --" << gconf.parname(gistconf_localaddrv4) << " <addr> "
     213        << "\t\t" << gconf.getDescription(gistconf_localaddrv4) << endl
     214
     215        << "  --" << gconf.parname(gistconf_localaddrv6) << " <addr> "
     216        << "\t\t" << gconf.getDescription(gistconf_localaddrv6) << endl
     217
     218        << "  --" << gconf.parname(gistconf_udpport) << " <port> "
     219        << "\t\t" << gconf.getDescription(gistconf_udpport) << endl
     220
     221        << "  --" << gconf.parname(gistconf_tcpport) << " <port> "
     222        << "\t\t" << gconf.getDescription(gistconf_tcpport) << endl
     223
     224        << "  --" << gconf.parname(gistconf_tlsport) << " <port> "
     225        << "\t\t" << gconf.getDescription(gistconf_tlsport) << endl
     226
     227        << "  --" << gconf.parname(gistconf_retrylimit) << " <time> "
     228        << "\t\t" << gconf.getDescription(gistconf_retrylimit) << endl
     229
     230        << "  --" << gconf.parname(gistconf_retryperiod) << " <time> "
     231        << "\t\t" << gconf.getDescription(gistconf_retryperiod) << endl
     232
     233        << "  --" << gconf.parname(gistconf_retryfactor) << " <real> "
     234        << "\t\t" << gconf.getDescription(gistconf_retryfactor) << endl
     235
     236        << "  --" << gconf.parname(gistconf_ma_hold_time) << " <time> "
     237        << "\t\t" << gconf.getDescription(gistconf_ma_hold_time) << endl
     238
     239        << "  --" << gconf.parname(gistconf_refresh_limit) << " <time> "
     240        << "\t\t" << gconf.getDescription(gistconf_refresh_limit) << endl
     241
     242        << "  --" << gconf.parname(gistconf_rs_validity_time) << " <time> "
     243        << "\t\t" << gconf.getDescription(gistconf_rs_validity_time) << endl
     244
     245        << "  --" << gconf.parname(gistconf_secrets_count) << " <number> "
     246        << "\t\t" << gconf.getDescription(gistconf_secrets_count) << endl
     247
     248        << "  --" << gconf.parname(gistconf_secrets_length) << " <number> "
     249        << "\t\t" << gconf.getDescription(gistconf_secrets_length) << endl
     250
     251        << "  --" << gconf.parname(gistconf_secrets_refreshtime) << " <time> "
     252        << "\t\t" << gconf.getDescription(gistconf_secrets_refreshtime) << endl
     253
     254        << "  --" << gconf.parname(gistconf_latestate) << " <on/off> "
     255        << "\t\t" << gconf.getDescription(gistconf_latestate) << endl
     256
     257        << "  --" << gconf.parname(gistconf_confirmrequired) << " <on/off> "
     258        << "\t\t" << gconf.getDescription(gistconf_confirmrequired) << endl
     259
     260        << "  --" << gconf.parname(gistconf_senddatainquery) << " <on/off> "
     261        << "\t\t" << gconf.getDescription(gistconf_senddatainquery) << endl
     262
     263        << "  --" << gconf.parname(gistconf_reqhelloecho) << " <on/off> "
     264        << "\t\t" << gconf.getDescription(gistconf_reqhelloecho) << endl
     265
     266        << "  --" << gconf.parname(gistconf_advertise_sctp) << " <on/off> "
     267        << "\t\t" << gconf.getDescription(gistconf_advertise_sctp) << endl
     268
     269        << "  --" << gconf.parname(gistconf_debug_tp) << " <on/off> "
     270        << "\t\t" << gconf.getDescription(gistconf_debug_tp) << endl
     271
     272        << "  --" << gconf.parname(gistconf_intercept_cmd) << " <filename> "
     273        << "\t\t" << gconf.getDescription(gistconf_intercept_cmd) << endl
    301274
    302275        << "  --echo <nslpid>               "
    303276        << "  make this node listen to RAO <nslpid>, " << endl
    304277        << "  NSLPID <nslpid> and accept connections on " << endl
    305         << "  it (for testing)" << endl
    306 
    307         << "  --reqechohello <on|off>" << endl
    308         << "  request from peer to answer MA-Hellos, " << endl;
     278        << "  it (for testing)" << endl;
    309279}
    310280
    311 
    312 /*
    313  * A list of all valid command line options.
    314  */
    315 static char short_opts[] = "h";
    316 static struct option long_opts[] = {
    317         { "help",                       0, NULL, 'h' },
    318         { "latestate",                  1, NULL, 'l' },
    319         { "datainquery",                1, NULL, 'D' },
    320         { "echo",                       1, NULL, 'e' },
    321         { "reqconfirm",                 1, NULL, 'C' },
    322         { "reqhelloecho",               1, NULL, 'H' },
    323         { "ipv4-address",               1, NULL, 'a' },
    324         { "ipv6-address",               1, NULL, 'A' },
    325         { "udp-port",                   1, NULL, 'u' },
    326         { "tcp-port",                   1, NULL, 't' },
    327         { "tls-port",                   1, NULL, 'T' },
    328         { "sctp-port",                  1, NULL, 'S' },
    329         { "retry-limit",                1, NULL, 'r' },
    330         { "retry-period",               1, NULL, 'p' },
    331         { "timing-factor",              1, NULL, 'f' },
    332         { "lifetime",                   1, NULL, 'L' },
    333         { "refresh-limit",              1, NULL, 'R' },
    334         { "ma-hold-time",               1, NULL, 'm' },
    335         { "secrets-count",              1, NULL, 'c' },
    336         { "secrets-length",             1, NULL, 'n' },
    337         { "secrets-rollover-time",      1, NULL, 'o' },
    338         { "debug-tp",                   0, NULL, 'd' },
    339         { NULL,                         0, NULL, 0 },
    340 };
    341281
    342282
     
    348288static bool read_cmdline(int argc, char* argv[])
    349289{
     290/*
     291 * A list of all valid command line options.
     292 */
     293  char short_opts[] = "h";
     294  struct option long_opts[] = {
     295        { "help",                       0, NULL, 'h' },
     296        { gconf.parname(gistconf_conffilename).c_str(),    1, NULL, 'c' },
     297        { gconf.parname(gistconf_latestate).c_str(),       1, NULL, 'l' },
     298        { gconf.parname(gistconf_senddatainquery).c_str(), 1, NULL, 'D' },
     299        { "echo",                                                   1, NULL, 'e' },
     300        { gconf.parname(gistconf_confirmrequired).c_str(), 1, NULL, 'C' },
     301        { gconf.parname(gistconf_reqhelloecho).c_str(),    1, NULL, 'H' },
     302        { gconf.parname(gistconf_localaddrv4).c_str(),      1, NULL, 'a' },
     303        { gconf.parname(gistconf_localaddrv6).c_str(),      1, NULL, 'A' },
     304        { gconf.parname(gistconf_udpport).c_str(),          1, NULL, 'u' },
     305        { gconf.parname(gistconf_tcpport).c_str(),          1, NULL, 't' },
     306        { gconf.parname(gistconf_tlsport).c_str(),          1, NULL, 'T' },
     307        { gconf.parname(gistconf_sctpport).c_str(),         1, NULL, 'S' },
     308        { gconf.parname(gistconf_retrylimit).c_str(),       1, NULL, 'r' },
     309        { gconf.parname(gistconf_retryperiod).c_str(),      1, NULL, 'p' },
     310        { gconf.parname(gistconf_retryfactor).c_str(),      1, NULL, 'f' },
     311        { gconf.parname(gistconf_rs_validity_time).c_str(),1, NULL, 'L' },
     312        { gconf.parname(gistconf_refresh_limit).c_str(),    1, NULL, 'R' },
     313        { gconf.parname(gistconf_ma_hold_time).c_str(),    1, NULL, 'm' },
     314        { gconf.parname(gistconf_secrets_count).c_str(),   1, NULL, 's' },
     315        { gconf.parname(gistconf_secrets_length).c_str(),  1, NULL, 'n' },
     316        { gconf.parname(gistconf_secrets_refreshtime).c_str(),  1, NULL, 'o' },
     317        { gconf.parname(gistconf_debug_tp).c_str(),             0, NULL, 'd' },
     318        { NULL,                         0, NULL, 0 },
     319  };
     320
    350321  int c, opt_index;
    351322
     
    357328    switch ( c ) {
    358329      case 'h': printhelp(); exit(0); break;
    359       case 'l': config["LATE_STATE"] = optarg; break;
     330      case 'c': config[gconf.parname(gistconf_conffilename)] = optarg;
     331              gconf.setpar(gistconf_conffilename, string(optarg));
     332                break;
     333      case 'l': config[gconf.parname(gistconf_latestate)] = optarg; break;
    360334      case 'e': echo_nslpid = StringToInt(optarg);
    361335        startapimsgchecker = true;
    362336        break;
    363       case 'd': config["DEBUG_TP"] = optarg; break;
    364       case 'C': config["REQUIRE_CONFIRM"] = optarg; break;
    365       case 'H': config["REQUIRE_HELLOECHO"] = optarg; break;
    366       case 'D': config["DATA_IN_QUERY"] = optarg; break;
    367       case 'a': config["IPV4_ADDR"] = optarg; break;
    368       case 'A': config["IPV6_ADDR"] = optarg; break;
    369       case 'u': config["UDP_PORT"] = optarg; break;
    370       case 't': config["TCP_PORT"] = optarg; break;
    371       case 'T': config["TLS_PORT"] = optarg; break;
    372       case 'S': config["SCTP_PORT"] = optarg; break;
    373       case 'r': config["RETRY_LIMIT"] = optarg; break;
    374       case 'p': config["RETRY_PERIOD"] = optarg; break;
    375       case 'f': config["TIMING_FACTOR"] = optarg; break;
    376       case 'L': config["STATE_LIFETIME"] = optarg; break;
    377       case 'R': config["REFRESH_LIMIT"] = optarg; break;
    378       case 'm': config["MA_HOLD_TIME"] = optarg; break;
    379       case 'c': config["SECRETS_COUNT"] = optarg; break;
    380       case 'n': config["SECRETS_LENGTH"] = optarg; break;
    381       case 'o': config["SECRETS_ROLLOVER_TIME"] = optarg; break;
     337      case 'd': config[gconf.parname(gistconf_debug_tp)] = optarg; break;
     338      case 'C': config[gconf.parname(gistconf_confirmrequired)] = optarg; break;
     339      case 'H': config[gconf.parname(gistconf_reqhelloecho)] = optarg; break;
     340      case 'D': config[gconf.parname(gistconf_senddatainquery)] = optarg; break;
     341      case 'a': config[gconf.parname(gistconf_localaddrv4)] = optarg; break;
     342      case 'A': config[gconf.parname(gistconf_localaddrv6)] = optarg; break;
     343      case 'u': config[gconf.parname(gistconf_udpport)] = optarg; break;
     344      case 't': config[gconf.parname(gistconf_tcpport)] = optarg; break;
     345      case 'T': config[gconf.parname(gistconf_tlsport)] = optarg; break;
     346      case 'S': config[gconf.parname(gistconf_sctpport)] = optarg; break;
     347      case 'r': config[gconf.parname(gistconf_retrylimit)] = optarg; break;
     348      case 'p': config[gconf.parname(gistconf_retryperiod)] = optarg; break;
     349      case 'f': config[gconf.parname(gistconf_retryfactor)] = optarg; break;
     350      case 'L': config[gconf.parname(gistconf_rs_validity_time)] = optarg; break;
     351      case 'R': config[gconf.parname(gistconf_refresh_limit)] = optarg; break;
     352      case 'm': config[gconf.parname(gistconf_ma_hold_time)] = optarg; break;
     353      case 's': config[gconf.parname(gistconf_secrets_count)] = optarg; break;
     354      case 'n': config[gconf.parname(gistconf_secrets_length)] = optarg; break;
     355      case 'o': config[gconf.parname(gistconf_secrets_refreshtime)] = optarg; break;
    382356       
    383       default:  std::cerr << "Illegal chararacter "
    384                           << c << std::endl;
     357    default:    std::cerr << "Unknown option '" << (char) c << "'" << std::endl;
    385358        return false;
    386359        break;
     
    488461test(const char* logname)
    489462{
    490     list<hostaddress> ntlpv4addr;
    491     list<hostaddress> ntlpv6addr;
    492 
    493     if (config["IPV4_ADDR"]!="query") {
    494         std::stringstream in(config["IPV4_ADDR"]);
    495 
    496         while ( in ) {
    497                 bool success;
    498                 std::string token;
    499                 in >> token;
    500 
    501                 hostaddress addr(token.c_str(), &success);
    502 
    503                 if ( success && addr.is_ipv4() )
    504                         ntlpv4addr.push_back(addr);
    505         }
    506     }
    507 
    508     if (config["IPV6_ADDR"]!="query") {
    509         std::stringstream in(config["IPV6_ADDR"]);
    510 
    511         while ( in ) {
    512                 bool success;
    513                 std::string token;
    514                 in >> token;
    515 
    516                 hostaddress addr(token.c_str(), &success);
    517 
    518                 if ( success && addr.is_ipv6() )
    519                         ntlpv6addr.push_back(addr);
    520         }
    521     }
    522 
    523     // this will set default values
    524     NTLPStarterParam ntlppar;
    525 
    526     // set specified IP addresses
    527     ntlppar.localaddrv4= ntlpv4addr;
    528     ntlppar.localaddrv6= ntlpv6addr;
    529    
     463  hostaddresslist_t& ntlpv4addr= gconf.getparref< hostaddresslist_t >(gistconf_localaddrv4);
     464  hostaddresslist_t& ntlpv6addr= gconf.getparref< hostaddresslist_t >(gistconf_localaddrv6);
     465
     466  // check whether all addresses are really pure IPv4
     467  if (ntlpv4addr.empty() == false) {
     468    hostaddresslist_t::iterator it= ntlpv4addr.begin();
     469    while (it != ntlpv4addr.end())
     470    {
     471      if ( !it->is_ipv4() )
     472      {
     473        WLog("main", "Detected non IPv4 address, removing " << *it );
     474        it= ntlpv4addr.erase(it);
     475      }
     476      else
     477        it++;
     478    } // end while
     479  }
     480
     481  // check whether all addresses are really pure IPv6
     482  if (ntlpv6addr.empty() == false) {
     483    hostaddresslist_t::iterator it= ntlpv6addr.begin();
     484    while (it != ntlpv6addr.end())
     485    {
     486      if ( !it->is_ipv6() )
     487      {
     488        WLog("main", "Detected non-IPv6 address, removing " << *it );
     489        it= ntlpv6addr.erase(it);
     490      }
     491      else
     492        it++;
     493    } // end while
     494  }
     495
    530496    // fill the parameters from configfile or command line
    531497    // (parameters given by command line will override these)
    532     if (config["UDP_PORT"].empty() == false)  ntlppar.udpport = StringToInt(config["UDP_PORT"]);
    533     if (config["TCP_PORT"].empty() == false)  ntlppar.tcpport = StringToInt(config["TCP_PORT"]);
    534     if (config["SCTP_PORT"].empty() == false) ntlppar.sctpport= StringToInt(config["SCTP_PORT"]);
    535     if (config["TLS_PORT"].empty() == false)  ntlppar.tlsport = StringToInt(config["TLS_PORT"]);
     498    if (config[gconf.parname(gistconf_udpport)].empty() == false)  gconf.setpar(gistconf_udpport, (uint16) StringToInt(config[gconf.parname(gistconf_udpport)]));
     499    if (config[gconf.parname(gistconf_tcpport)].empty() == false)  gconf.setpar(gistconf_tcpport, (uint16) StringToInt(config[gconf.parname(gistconf_tcpport)]));
     500    if (config[gconf.parname(gistconf_sctpport)].empty() == false) gconf.setpar(gistconf_sctpport, (uint16) StringToInt(config[gconf.parname(gistconf_sctpport)]));
     501    if (config[gconf.parname(gistconf_tlsport)].empty() == false)  gconf.setpar(gistconf_tlsport, (uint16) StringToInt(config[gconf.parname(gistconf_tlsport)]));
    536502   
    537     if (config["RETRY_LIMIT"          ].empty() == false) ntlppar.retrylimit    =    StringToInt(config[ "RETRY_LIMIT"          ]);
    538     if (config["RETRY_PERIOD"         ].empty() == false) ntlppar.retryperiod   =    StringToInt(config[ "RETRY_PERIOD"         ]);
    539     if (config["TIMING_FACTOR"        ].empty() == false) ntlppar.retryfactor   = StringToDouble(config[ "TIMING_FACTOR"        ]);
    540     if (config["STATE_LIFETIME"       ].empty() == false) ntlppar.rs_validity_time = StringToInt(config[ "STATE_LIFETIME"       ]);
    541     if (config["REFRESH_LIMIT"        ].empty() == false) ntlppar.refreshtime   =    StringToInt(config[ "REFRESH_LIMIT"        ]);
    542     if (config["MA_HOLD_TIME"         ].empty() == false) ntlppar.ma_hold_time    =  StringToInt(config[ "MA_HOLD_TIME"         ]);
    543     if (config["SECRETS_ROLLOVER_TIME"].empty() == false) ntlppar.secrets_refreshtime = StringToInt(config[ "SECRETS_ROLLOVER_TIME"]);
    544     if (config["SECRETS_COUNT"        ].empty() == false) ntlppar.secrets_count  =   StringToInt(config[ "SECRETS_COUNT"        ]);
    545     if (config["SECRETS_LENGTH"       ].empty() == false) ntlppar.secrets_length =   StringToInt(config[ "SECRETS_LENGTH"       ]);
    546     if (config["LATE_STATE"           ].empty() == false) ntlppar.latestate     =   StringToBool(config[ "LATE_STATE"           ]);
    547     if (config["DATA_IN_QUERY"        ].empty() == false) ntlppar.senddatainquery=  StringToBool(config[ "DATA_IN_QUERY"        ]);
    548     if (config["REQUIRE_CONFIRM"      ].empty() == false) ntlppar.confirmrequired=  StringToBool(config[ "REQUIRE_CONFIRM"    ]);
    549     if (config["REQUIRE_HELLOECHO"    ].empty() == false) ntlppar.reqhelloecho  =   StringToBool(config[ "REQUIRE_HELLOECHO"    ]);
    550     if (config["ADVERTISE_SCTP"       ].empty() == false) ntlppar.sctpenable    =   StringToBool(config[ "ADVERTISE_SCTP"       ]);
    551     if (config["DEBUG_TP"             ].empty() == false) ntlppar.debug_tp      =   StringToBool(config[ "DEBUG_TP"             ]);
     503    if (config[gconf.parname(gistconf_retrylimit)].empty() == false) gconf.setpar(gistconf_retrylimit, (uint32) StringToInt(config[ gconf.parname(gistconf_retrylimit)]));
     504    if (config[gconf.parname(gistconf_retryperiod)].empty() == false) gconf.setpar(gistconf_retryperiod, (uint32) StringToInt(config[ gconf.parname(gistconf_retryperiod)]));
     505    if (config[gconf.parname(gistconf_retryfactor)].empty() == false) gconf.setpar(gistconf_retryfactor, StringToDouble(config[ gconf.parname(gistconf_retryfactor)]));
     506    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)]));
     507    if (config[gconf.parname(gistconf_refresh_limit)].empty() == false) gconf.setpar(gistconf_refresh_limit, (uint32) StringToInt(config[ gconf.parname(gistconf_refresh_limit)]));
     508    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)]));
     509    if (config[gconf.parname(gistconf_secrets_refreshtime)].empty() == false) gconf.setpar(gistconf_secrets_refreshtime, (uint32) StringToInt(config[ gconf.parname(gistconf_secrets_refreshtime)]));
     510    if (config[gconf.parname(gistconf_secrets_count)].empty() == false) gconf.setpar(gistconf_secrets_count, (uint32) StringToInt(config[ gconf.parname(gistconf_secrets_count)]));
     511    if (config[gconf.parname(gistconf_secrets_length)].empty() == false) gconf.setpar(gistconf_secrets_length, (uint16) StringToInt(config[ gconf.parname(gistconf_secrets_length)]));
     512    if (config[gconf.parname(gistconf_latestate)].empty() == false) gconf.setpar(gistconf_latestate, StringToBool(config[ gconf.parname(gistconf_latestate)]));
     513    if (config[gconf.parname(gistconf_senddatainquery)].empty() == false) gconf.setpar(gistconf_senddatainquery, StringToBool(config[ gconf.parname(gistconf_senddatainquery)]));
     514    if (config[gconf.parname(gistconf_confirmrequired)].empty() == false) gconf.setpar(gistconf_confirmrequired, StringToBool(config[ gconf.parname(gistconf_confirmrequired)]));
     515    if (config[gconf.parname(gistconf_reqhelloecho)].empty() == false) gconf.setpar(gistconf_reqhelloecho, StringToBool(config[ gconf.parname(gistconf_reqhelloecho)]));
     516    if (config[gconf.parname(gistconf_advertise_sctp)].empty() == false) gconf.setpar(gistconf_advertise_sctp, StringToBool(config[ gconf.parname(gistconf_advertise_sctp)]));
     517    if (config[gconf.parname(gistconf_verbose_error_responses)].empty() == false) gconf.setpar(gistconf_verbose_error_responses, StringToBool(config[ gconf.parname(gistconf_verbose_error_responses)]));
     518    if (config[gconf.parname(gistconf_debug_tp)].empty() == false) gconf.setpar(gistconf_debug_tp, StringToBool(config[ gconf.parname(gistconf_debug_tp)]));
    552519
    553520    // give the parameters to NTLP Starter
     521    NTLPStarterParam ntlppar;
    554522    ThreadStarter<NTLPStarter,NTLPStarterParam> ntlpthread(1,ntlppar);
    555523    global_ntlpthread_p= ntlpthread.get_thread_object();
     
    612580  logname<<argv[0]<<"."<<getpid()<<".log";
    613581
    614   // read configuration from config file
    615   if (read_config() == false)
    616   {
    617     // it's not that critical since we will use default values otherwise
    618   }
     582  // init gist configuration parameters
     583  gconf.repository_init();
     584  gconf.setRepository();
    619585
    620586  // process command line options, they should override the config file values, exit on error
     587  // it's not that critical since we will use default values otherwise
    621588  if ( read_cmdline(argc, argv) == false )
    622589        return 1;
     590
     591  // read configuration from config file
     592  configfile read_cfgfile(configpar_repository::instance());
     593
     594  // read in the config file
     595  read_cfgfile.load(gconf.getpar<string>(gistconf_conffilename));
     596
    623597
    624598  tsdb::init(true);
     
    628602  SSL_library_init();
    629603  OpenSSL_add_ssl_algorithms();
     604  // 2nd: load in all digests from OpenSSL
     605  OpenSSL_add_all_digests();
    630606  SSL_load_error_strings();
    631607
  • ntlp/trunk/src/ntlp_proto.cpp

    r3674 r4108  
    215215  if (pdu->get_type()==known_ntlp_pdu::Query)
    216216  {
    217     // Query must be sent via Query Encapsulation
    218     if (peeraddr.get_protocol() != prot_query_encap)
     217    // Query must be sent via Query Encapsulation (check for C-flag set)
     218    if ( pdu->get_C() == false )
    219219    {
    220220      //BINGO! This Query was coming to us accidentally. Tell the sender, he is doing somethin WEIRD
     
    245245    {
    246246      // check for NLI transport match
    247       if (peeraddr.is_ipv4() && pdu->get_mri()->get_ip_version()!=4
     247      if ( (peeraddr.is_ipv4() && pdu->get_mri()->get_ip_version()!=4)
    248248          ||
    249249          (peeraddr.is_ipv6() && !peeraddr.is_mapped_ip() && pdu->get_mri()->get_ip_version()!=6))
     
    269269  else
    270270  { // not a QUERY message
    271     if ((peeraddr.get_protocol() == prot_query_encap) && (pdu->get_type()!=known_ntlp_pdu::Data))
     271    if ( pdu->get_C() && (pdu->get_type()!=known_ntlp_pdu::Data))
    272272    {
    273273      //This is always NOT OUR FAULT, no one should send something other than a QUERY in QE mode
     
    448448
    449449  bool dgram = (peer.get_protocol() == prot_query_encap) || (peer.get_protocol() == tsdb::get_udp_id());
    450   bool qe = (peer.get_protocol() == prot_query_encap);
     450  bool qe = (peer.get_protocol() == prot_query_encap) || pdu->get_C();
    451451
    452452  //DLog(NTLP::modname,"generateErrorPdu() - entered, dgram:" << dgram << "query encap:" << qe); 
  • ntlp/trunk/src/ntlp_proto.h

    r3674 r4108  
    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/trunk/src/ntlp_starter.cpp

    r3674 r4108  
    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 localaddrv4              The list of local IPv4 addresses.
    104  * @param localaddrv6              The list of local IPv6 addresses.
    105  * @param retrylimit               How many retries are performed? Upper limit (T2=64s) Note: exponential backoff!
    106  * @param retryperiod              Initial retry period in milliseconds
    107  * @param retryfactor              This factor is used to calculate the refresh period from peers timers
    108  * @param rs_validity_time         How many milliseconds should routing state be valid by default
    109  * @param refreshtime              Trigger GIST probing (refresh) every x milliseconds
    110  * @param ma_hold_time             Keep an inactive Messaging Association open for x milliseconds
    111  * @param secrets_refreshtime      Local secrets rollover time in seconds
    112  * @param secrets_count            Amount of local secrets
    113  * @param secrets_length           Length of local secrets in bit
    114  * @param latestate                  Use Late State Installation. Will not work in a NATed environment
    115  * @param confirmrequired            Require a full handshake at any time
    116  * @param senddatainquery            Send NSLP data also in query
    117  * @param reqhelloecho               Request a reply to an MA-hello
    118  * @param sctpenable                 Use SCTP in stack configuration if available
    119  * @param intercept_cmd              string that contains the name of the RAO interception script to be called
    120  * @param debug_tp                   debugging transport: if enabled each received or sent message is printed as hexdump
    121  */
    122 NTLPStarterParam::NTLPStarterParam(uint16 udpport,
    123                                    uint16 tcpport,
    124                                    uint16 tlsport,
    125                                    uint16 sctpport,
    126                                    uint32 retrylimit,
    127                                    uint32 retryperiod,
    128                                    float retryfactor,
    129                                    uint32 rs_validity_time,
    130                                    uint32 refreshtime,
    131                                    uint32 ma_hold_time,
    132                                    uint32 secrets_refreshtime,
    133                                    uint32 secrets_count,
    134                                    uint32 secrets_length,
    135                                    bool latestate,
    136                                    bool confirmrequired,
    137                                    bool senddatainquery,
    138                                    bool reqhelloecho,
    139                                    bool sctpenable,
    140                                    list<hostaddress> localaddrv4,
    141                                    list<hostaddress> localaddrv6,
    142                                    const char *intercept_cmd,
    143                                    bool debug_tp)
    144   : ThreadParam(ThreadParam::default_sleep_time, "GIST Starter"),
    145     udpport(udpport),
    146     tcpport(tcpport),
    147     tlsport(tlsport),
    148     sctpport(sctpport),
    149     localaddrv4(localaddrv4),
    150     localaddrv6(localaddrv6),
    151     retrylimit(retrylimit),
    152     retryperiod(retryperiod),
    153     retryfactor(retryfactor),
    154     rs_validity_time(rs_validity_time),
    155     refreshtime(refreshtime),
    156     ma_hold_time(ma_hold_time),
    157     secrets_refreshtime(secrets_refreshtime),
    158     secrets_count(secrets_count),
    159     secrets_length(secrets_length),
    160     latestate(latestate),
    161     confirmrequired(confirmrequired),
    162     senddatainquery(senddatainquery),
    163     reqhelloecho(reqhelloecho),
    164     sctpenable(sctpenable),
    165     intercept_cmd(intercept_cmd),
    166     debug_tp(debug_tp)
    167 {
    168 }
    169 
    170 
    171 string
    172 NTLPStarterParam::to_string() const
    173 {
    174   ostringstream os;
    175 
    176   os << "UDP Port:                     " << udpport << endl;
    177   os << "TCP Port:                     " << tcpport << endl;
    178   os << "SCTP Port:                    " << sctpport << endl;
    179   os << "SCTP advertisment:            " << (sctpenable ? "enabled" : "disabled") << endl;
    180   typedef std::list<hostaddress>::const_iterator addr_iter;
    181  
    182   os << "Specified Local IPv4 addresses: {";
    183   for ( addr_iter i = localaddrv4.begin();
    184         i != localaddrv4.end(); i++ )
    185     os << " " << *i;
    186  
    187   os << " }" << endl;
    188  
    189   os << "Specified Local IPv6 addresses: {";
    190   for ( addr_iter i = localaddrv6.begin();
    191         i != localaddrv6.end(); i++ )
    192     os << " " << *i;
    193  
    194   os << " }" << endl;
    195  
    196   os << "Retry Limit:                    " << retrylimit << " msec" << endl;
    197   os << "Initial Retry Period:           " << retryperiod << " msec" << endl;
    198   os << "Security Timing Factor:         " << retryfactor << endl;
    199   os << "Default Routing State Lifetime: " << rs_validity_time << " ms" << endl;
    200   os << "Maximum Upper Refresh Limit:    " << refreshtime << " ms" << endl;
    201   os << "MA Hold Time:                   " << ma_hold_time << " ms" << endl;
    202   os << "Secrets Rollover Time:          " << secrets_refreshtime <<"sec"<<endl;
    203   os << "Count of local secrets:         " << secrets_count << endl;
    204   os << "Length of local secrets:        " << secrets_length << endl;
    205   os << "Late State Installation:        " << latestate << endl;
    206   os << "Send NSLP Data in Query:        " << senddatainquery << endl;
    207   os << "Require Handshake:              " << confirmrequired << endl;
    208   os << "Debugging on TP level:          " << debug_tp << endl;
    209  
    210   return os.str();
    211 }
    212 
    21393
    21494
     
    233113{
    234114#ifndef _USE_SCTP
    235   param.sctpenable= false;
     115  // sctp cannot be used if not compiled
     116  gconf.setpar(gistconf_advertise_sctp, false);
    236117#endif
    237 
    238118  cout << color[blue] << gist_name << " v" << gist_releasestring
    239119       << " ($Rev$ - development build) (C) 2005-2008 Universitaet Karlsruhe (TH)" << color[off] << endl;
     
    241121  cout << "Parameters:" << endl;
    242122  cout << "-----------------------------------------------------------------" << endl;
    243   cout << param.to_string();
    244   cout << "Digest Function:                " << "SHA1 by OpenSSL" << endl;
     123  cout << gconf.to_string();
    245124  cout << "-----------------------------------------------------------------" << endl;
    246125  cout << endl;
    247  
    248126 
    249127  // Register IEs
     
    299177  TPoverSCTPParam sctppar(ntlp_pdu::common_header_length,
    300178                          ntlp_pdu::decode_common_header_ntlpv1_clen,
    301                           (port_t) param.sctpport);
     179                          gconf.getpar<uint16>(gistconf_sctpport));
    302180 
    303181  ThreadStarter<TPoverSCTP,TPoverSCTPParam> sctptpthread(1,sctppar);
     
    311189  TPoverTCPParam tcppar(ntlp_pdu::common_header_length,
    312190                        ntlp_pdu::decode_common_header_ntlpv1_clen,
    313                         (port_t) param.tcpport,"TPoverTCP", 5000UL,
    314                         param.debug_tp);
     191                        (port_t) gconf.getpar<uint16>(gistconf_tcpport),"TPoverTCP", 5000UL,
     192                        gconf.getpar<bool>(gistconf_debug_tp));
    315193 
    316194 
     
    322200 
    323201 
    324   //start TPoverTLS
    325   TPoverTLS_TCPParam tlspar("client_cert.pem",
    326                             "client_privkey.pem",
    327                             "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(),
    328206                            ntlp_pdu::common_header_length,
    329207                            ntlp_pdu::decode_common_header_ntlpv1_clen,
    330                             param.tlsport,"TPoverTLS_TCP", 5000UL,
    331                             param.debug_tp);
     208                            gconf.getpar<uint16>(gistconf_tlsport),"TPoverTLS_TCP", 5000UL,
     209                            gconf.getpar<bool>(gistconf_debug_tp));
    332210 
    333211 
     
    344222  TPoverUDPParam udppar(ntlp_pdu::common_header_length,
    345223                        ntlp_pdu::decode_common_header_ntlpv1_clen,
    346                         param.udpport,"TPoverUDP",5000UL, param.debug_tp);
     224                        gconf.getpar<uint16>(gistconf_udpport),
     225                        "TPoverUDP",
     226                        5000UL,
     227                        gconf.getpar<bool>(gistconf_debug_tp));
    347228 
    348229  ThreadStarter<TPoverUDP,TPoverUDPParam> udptpthread(1,udppar);
     
    362243  TPqueryEncapParam qepar(ntlp_pdu::common_header_length,
    363244                          ntlp_pdu::decode_common_header_ntlpv1_clen,
    364                           (port_t) param.udpport,
     245                          (port_t) gconf.getpar<uint16>(gistconf_udpport),
    365246                          raovec,
    366247                          udpproto,
     248                          gconf.getparref<bool>(gistconf_strict_rao),
    367249                          GIST_magic_number,
    368                           5000UL, param.debug_tp);
     250                          5000UL,
     251                          gconf.getpar<bool>(gistconf_debug_tp));
    369252 
    370253  ThreadStarter<TPqueryEncap,TPqueryEncapParam> qetpthread(1,qepar);
     
    376259 
    377260  DLog(param.name, "ports used: "
    378        << param.udpport << " (UDP), "
    379        << param.tcpport << " (TCP), "
    380        << param.sctpport << " (SCTP), "
    381        << 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)");
    382265 
    383266 
     
    423306  */
    424307 
    425   secretmanager secrets(param.secrets_count, param.secrets_length);
     308  secretmanager secrets(gconf.getpar<uint32>(gistconf_secrets_count),
     309                        gconf.getpar<uint16>(gistconf_secrets_length));
    426310   
    427311  // BUILD a local NLI!
     
    450334  char* buffer = new char[255];
    451335  gethostname(buffer, 255);
    452  
    453   if ( param.localaddrv4.size() == 0 ) {
     336
     337  hostaddresslist_t& localaddrv4= gconf.getparref< hostaddresslist_t >(gistconf_localaddrv4);
     338  if ( localaddrv4.size() == 0 ) {
    454339   
    455340    DLog(param.name,
     
    471356      DLog(param.name, "Communication via IPv4 not possible, "
    472357           "host has no A record");
    473       addr4=new in_addr;
     358      addr4= new in_addr;
    474359    } else {
    475360      addr4= (struct in_addr *) *host->h_addr_list;
    476361    }
    477     loc_if4=new netaddress();
     362    loc_if4= new netaddress();
    478363    loc_if4->set_ip(*addr4);
    479364   
     365    if (!host)
     366      delete addr4;
     367
    480368  } else {
    481369    DLog(param.name, "This instance was given a specified IP address: "
    482          << param.localaddrv4.front());
    483     loc_if4= new netaddress(param.localaddrv4.front());
     370         << localaddrv4.front());
     371    loc_if4= new netaddress(localaddrv4.front());
    484372  }
    485373 
    486  
    487   if ( param.localaddrv6.size() == 0 ) {
     374  hostaddresslist_t& localaddrv6= gconf.getparref< hostaddresslist_t >(gistconf_localaddrv6);
     375  if ( localaddrv6.size() == 0 ) {
    488376   
    489377    DLog(param.name, "Looking up the main IPv6 Address for host " << buffer);
     
    494382   
    495383    while (!host && (retries < dnslookup_retries_max)) {
    496       //lookup IPv6
     384      // lookup IPv6
    497385      host=gethostbyname2(buffer, AF_INET6);
    498386      if (!host) cout << "retrying reverse DNS lookup" << endl;
     
    511399    if (addr6)
    512400      loc_if6->set_ip(*addr6);
    513    
     401
     402    if (!host)
     403      delete addr6;
     404
    514405  } else {
    515406    DLog(param.name, "This instance was given a specified IP address: "
    516          << param.localaddrv6.front());
    517     loc_if6= new netaddress(param.localaddrv6.front());
     407         << localaddrv6.front());
     408    loc_if6= new netaddress(localaddrv6.front());
    518409  }   
    519410 
     
    523414  DLog(param.name, "Derived Address for IPv4: " << *loc_if4);
    524415  DLog(param.name, "Derived Address for IPv6: " << *loc_if6);
    525  
    526   nli localnliv4(ttl, param.rs_validity_time, mypi, *loc_if4);
    527   nli localnliv6(ttl, param.rs_validity_time, mypi, *loc_if6);
     416
     417  nli localnliv4(ttl, gconf.getpar<uint32>(gistconf_rs_validity_time), mypi, *loc_if4);
     418  nli localnliv6(ttl, gconf.getpar<uint32>(gistconf_rs_validity_time), mypi, *loc_if6);
    528419 
    529420 
     
    538429                         localnliv4,
    539430                         localnliv6,
    540                          param.localaddrv4,
    541                          param.localaddrv6,
    542                          param.retrylimit,
    543                          param.retryperiod,
    544                          param.retryfactor,
    545                          param.rs_validity_time,
    546                          param.refreshtime,
    547                          param.ma_hold_time,
    548431                         secrets,
    549432                         nslptable,
    550433                         raovec,
    551                          param.secrets_refreshtime,
    552                          10, // default sleep time
    553                          param.udpport,
    554                          param.tcpport,
    555                          param.tlsport,
    556                          param.sctpport,
    557                          param.latestate,
    558                          param.confirmrequired,
    559                          param.senddatainquery,
    560                          param.reqhelloecho,
    561                          param.sctpenable);
     434                         10 // default sleep time
     435                        );
    562436
    563437  ThreadStarter<Statemodule,StatemoduleParam> smthread(1,smpar);
     
    605479
    606480       
    607   SignalingNTLPParam sigpar(pm, localnliv4, localnliv6, nslptable, param.udpport);
     481  SignalingNTLPParam sigpar(pm, localnliv4, localnliv6, nslptable, gconf.getpar<uint16>(gistconf_udpport));
    608482  ThreadStarter<SignalingNTLP,SignalingNTLPParam> signaling(1,sigpar); 
    609483       
     
    624498  DLog(param.name, "Startup phase 9: Enabling Packet Interception");
    625499
    626   if ( param.intercept_cmd == NULL )
     500  if ( gconf.getpar<string>(gistconf_intercept_cmd).length() == 0 )
    627501    DLog(param.name, "NOT enabling packet interception, as requested");
    628502  else {
    629     if ( system(param.intercept_cmd) != 0 ) {
     503    if ( system(gconf.getpar<string>(gistconf_intercept_cmd).c_str()) != 0 ) {
    630504      ERRLog(param.name,
    631505             "Packet interception could not be enabled. Aborting");
     
    697571       
    698572  pm.clear();
     573
     574  DLog(param.name, "Shutdown phase 5: Cleaning Up");
     575
     576  delete loc_if4;
     577  delete loc_if6;
    699578}
    700579
  • ntlp/trunk/src/ntlp_statemodule.h

    r3674 r4108  
    6565
    6666/// typedef transfert_t
    67 typedef enum transfer_t {
     67typedef enum transfer_t_enum {
    6868  tx_queryencap,
    6969  tx_dmode,
    7070  tx_cmode,
    7171  tx_cmode_sec
    72 };
     72} transfer_t;
    7373 
    7474/// statemodule parameters
     
    7777                   nli& localnliv4,
    7878                   nli& localnliv6,
    79                    std::list<hostaddress> &localaddrv4,
    80                    std::list<hostaddress> &localaddrv6,
    81                    uint32 retrylimit,
    82                    uint32 retryperiod,
    83                    float retryfactor,
    84                    uint32 rs_validity_time,
    85                    uint32 refreshtime,
    86                    uint32 ma_hold_time,
    8779                   secretmanager& secrets,
    8880                   NSLPtable& nslptable,
    8981                   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
     82                   uint32 sleep = ThreadParam::default_sleep_time
    10283                   );
    10384  const message::qaddr_t qaddr_ext;
     
    10687  nli& localnliv4;
    10788  nli& localnliv6;
    108   std::list<hostaddress> localaddrv4;
    109   std::list<hostaddress> localaddrv6;
    110   uint32 retrylimit;
    111   uint32 retryperiod;
    112   float retryfactor;
    113   uint32 rs_validity_time;
    114   uint32 refreshtime;
    115   uint32 ma_hold_time;
     89
    11690  secretmanager& secrets;
    117   uint32 secrets_refresh;
    118   uint16 wkp;
    119   uint16 tcpport;
    120   uint16 tlsport;
    121   uint16 sctpport;
    122   bool latestate;
    123   bool confirmrequired;
    124   bool senddatainquery;
    125   bool reqhelloecho;
    126   bool sctpenable;
    127   bool verbose_error_responses;
    12891
    12992  NSLPtable& nslptable;
     
    154117
    155118  /// fill a query cookie, use local secrets and OpenSSL hash function
    156   respcookie* create_resp_cookie(const nli* querier_nli, const routingkey* r_key, uint32 gennumber, uint16 if_index);
     119  respcookie* create_resp_cookie(const nli* querier_nli, const routingkey* r_key, uint32 gennumber, uint16 if_index, const NetMsg* transparent_data);
     120
     121  /// check a responder cookie, use local secrets and resp_cookie generation function
     122  bool evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* resp);
    157123
    158124  ///calculation of refresh times. Give maximum time allowed and the factor to apply
     
    176142       
    177143  /// module parameters
    178   const StatemoduleParam param;
     144  const StatemoduleParam& param;
    179145  /// additional queue
    180146  FastQueue* external_fq;
    181147  //@{ message processing
    182148
     149protected:
     150  /// process internal messages
     151  void handleInternalMessage(message* msg);
     152 
     153  /// process timouts
     154  void handleTimeout();
     155
     156private:
    183157  /// get messages from queue
    184158  void process_queue(uint32 nr);
     
    254228  /// check if a stackprofile is applicable
    255229  bool profile_valid(stackprop* proposal, stackprofile* profile);
    256        
    257   /// check a responder cookie, use local secrets and resp_cookie generation function
    258   bool evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* resp);
    259230
    260231  /// check a responder cookie, use local secrets and resp_cookie generation function
  • ntlp/trunk/src/ntlp_statemodule_api.cpp

    r3674 r4108  
    3838#include <sstream>
    3939
     40#include "gist_conf.h"
     41
    4042namespace ntlp {
    4143
     
    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(), r_entry ? r_entry->get_incoming_if() : 0 );
     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()));
     
    507529     
    508530      // set local default RS_Validity Time
    509       r_entry->rs_validity_time=param.rs_validity_time;
     531      r_entry->rs_validity_time= gconf.getpar<uint32>(gistconf_rs_validity_time);
    510532     
    511533      // initiate sending the Query
     
    538560
    539561      // set local Default RS_Validity Time
    540       r_entry->rs_validity_time= param.rs_validity_time;
     562      r_entry->rs_validity_time= gconf.getpar<uint32>(gistconf_rs_validity_time);;
    541563           
    542564      // send a Query requesting handshake, this will NOT transfer data payload!
     
    715737  if (!r_entry)
    716738  {
    717     ERRCLog(param.name, "RecvMessageAnswer while no state. Discarding API call.");
    718     delete apimsg;
     739    ERRCLog(param.name, "Cannot find routing state for RecvMessageAnswer. Ignoring API call.");
     740    // apimsg will be deleted in calling method anyway
    719741    return;
    720742  }
     
    754776           
    755777      // do we enforce late state installation?
    756       if (param.latestate)
     778      if ( gconf.getpar<bool>(gistconf_latestate) )
    757779      {
    758780        DLog(param.name, "Late state installation configured, no state is saved");                 
     
    766788        DLog(param.name, "Immediate state installation configured, set up state");
    767789               
    768         r_entry->rs_validity_time = param.rs_validity_time;
     790        r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    769791       
    770792        // put in state "rn_established"
    771         if (!param.confirmrequired)
     793        if ( gconf.getpar<bool>(gistconf_confirmrequired) == false )
    772794        {
    773795          DLog(param.name, "No full handshake is configured, state set up");
     
    829851        ERRCLog(param.name, "NSLP told us to relay, but we are the end");
    830852        ERRCLog(param.name, "Sending Error Message is redundant, as we would send it to ourself.");
    831        
    832         delete apimsg;
     853        // apimsg will be deleted in calling method anyway
     854       
    833855        return;
    834856      }
  • ntlp/trunk/src/ntlp_statemodule_data.cpp

    r3674 r4108  
    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();
     
    144146  r_entry->msg_id=msghandle;
    145147 
    146   appladdress* peer=new appladdress;
    147   peer->set_port(param.wkp);
     148  appladdress* peer= new appladdress;
     149  peer->set_port( gconf.getpar<uint16>(gistconf_udpport) );
    148150  peer->set_protocol(param.udp);
    149151 
  • ntlp/trunk/src/ntlp_statemodule_main.cpp

    r3674 r4108  
    5151#include <list>
    5252
     53#include "gist_conf.h"
     54
    5355using namespace protlib;
    5456using namespace protlib::log;
     
    7173                                   nli& localnliv4,
    7274                                   nli& localnliv6,
    73                                    std::list<hostaddress> &localaddrv4,
    74                                    std::list<hostaddress> &localaddrv6,
    75                                    uint32 retrylimit,
    76                                    uint32 retryperiod,
    77                                    float retryfactor,
    78                                    uint32 rs_validity_time,
    79                                    uint32 refreshtime,
    80                                    uint32 ma_hold_time,
    8175                                   secretmanager& secrets,
    8276                                   NSLPtable& nslptable,
    8377                                   vector<uint32>& raovec,
    84                                    uint32 secrets_refresh,
    85                                    uint32 sleep,
    86                                    uint16 udpport,
    87                                    uint16 tcpport,
    88                                    uint16 tlsport,
    89                                    uint16 sctpport,
    90                                    bool latestate,
    91                                    bool confirmrequired,
    92                                    bool senddatainquery,
    93                                    bool reqhelloecho,
    94                                    bool sctpenable,
    95                                    bool verbose_error_responses)
     78                                   uint32 sleep)
    9679  : ThreadParam(sleep,"GIST Processing",2),       ///< common thread parameter
    9780    qaddr_ext(message::qaddr_coordination),          ///< queue for messages to coordinator
     
    10083    localnliv4(localnliv4),
    10184    localnliv6(localnliv6),
    102     localaddrv4(localaddrv4),
    103     localaddrv6(localaddrv6),
    104     retrylimit(retrylimit),                ///< Upper limit (time) for Query/Response retransmits?
    105     retryperiod(retryperiod),              ///< The timespan between retransmissions
    106     retryfactor(retryfactor),
    107     rs_validity_time(rs_validity_time),
    108     refreshtime(refreshtime),
    109     ma_hold_time(ma_hold_time),
    11085    secrets(secrets),
    111     secrets_refresh(secrets_refresh),      ///< Secrets Refresh Time in Seconds
    112     wkp(udpport),                          ///< Well-Known Port for Datagram Mode
    113     tcpport(tcpport),
    114     tlsport(tlsport),
    115     sctpport(sctpport),
    116     latestate(latestate),                  ///< Are we running late-state-installation?
    117     confirmrequired(confirmrequired),      ///< Are we requesting full handshakes?
    118     senddatainquery(senddatainquery),      ///< send NSLP data also in a query?
    119     reqhelloecho(reqhelloecho),
    120     sctpenable(sctpenable),
    121     verbose_error_responses(verbose_error_responses), ///< send back error in certain cases (e.g., resp cookie mismatch)
    12286    nslptable(nslptable),
    12387    raovec(raovec),
     
    13195  sctp = tsdb::getprotobyname("sctp");
    13296           
    133   rt.set_own_ma_hold_time(ma_hold_time);
     97  rt.set_own_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time));
    13498
    13599  // show RAOs that will be intercepted
     
    147111Statemodule::Statemodule(const StatemoduleParam& p)
    148112  : Thread(p),
    149     cap(p.wkp, p.tcpport, p.tlsport, p.sctpport),
     113    cap(gconf.getpar<uint16>(gistconf_udpport), gconf.getpar<uint16>(gistconf_tcpport), gconf.getpar<uint16>(gistconf_tlsport), gconf.getpar<uint16>(gistconf_sctpport)),
    150114    param(p),
    151115    external_fq(new FastQueue(message::get_qaddr_name(p.qaddr_ext),true))
     
    176140Statemodule::main_loop(uint32 nr)
    177141{
    178   Log(INFO_LOG,LOG_NORMAL, param.name, "Starting " << param.name << " module thread #" << nr <<", ");
     142  ILog(param.name, "Starting " << param.name << " module thread #" << nr <<", ");
    179143
    180144  // Initially starting timer for secret refresh, only Task #1 will do this!!
     
    186150    *timer_type = refresh_secrets;
    187151
    188     msg->start_relative(param.secrets_refresh, 0, (void*)timer_type, NULL);
     152    msg->start_relative(gconf.getpar<uint32>(gistconf_secrets_refreshtime), 0, (void*)timer_type, NULL);
    189153   
    190154    msg->send_to(message::qaddr_timer);
    191     Log(INFO_LOG,LOG_NORMAL, param.name, "Secrets Refresh Timer activated, refreshing every " << param.secrets_refresh << " seconds");     
     155    Log(INFO_LOG,LOG_NORMAL, param.name, "Secrets Refresh Timer activated, refreshing every " << gconf.getpar<uint32>(gistconf_secrets_refreshtime) << " seconds");     
    192156
    193157  }
     
    196160  process_queue(nr);
    197161
    198   Log(INFO_LOG,LOG_NORMAL, param.name, "Module thread #" << nr << " stopped");
     162  ILog(param.name, "Module thread #" << nr << " stopped");
    199163       
    200164} // end main_loop
    201165
     166
     167/**
     168 *  called to process message
     169 */
     170void Statemodule::handleInternalMessage(message *msg)
     171{
     172  switch (msg->get_type())
     173    {
     174    // internal message from signaling (message from IP network)
     175        case message::type_signaling:
     176         // -----------------------
     177         {
     178          SignalingMsgNTLP* sigmsg= dynamic_cast<SignalingMsgNTLP*>(msg);
     179          if (sigmsg)
     180          {
     181            // =====================================================
     182            process_sig_msg(sigmsg); ///< process signaling messages
     183            // =====================================================
     184          }
     185          else
     186          {
     187            Log(ERROR_LOG,LOG_ALERT, param.name,
     188                "Cannot cast message from "
     189                << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to SignalingMsgNTLP");
     190           
     191            delete msg;
     192          } // end if sigmsg
     193         } break;
     194
     195        // internal message from API
     196        case message::type_API:
     197         // -----------------------
     198         {
     199          APIMsg* apimsg= dynamic_cast<APIMsg*>(msg);
     200          if (apimsg)
     201          {
     202            // =====================================================
     203            process_api_msg(apimsg); ///< process API messages
     204            // =====================================================
     205          }
     206          else
     207          {
     208            Log(ERROR_LOG,LOG_ALERT, param.name,
     209                "Cannot cast message from "
     210                << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to APIMsg");
     211           
     212            delete msg;
     213          } // end if sigmsg
     214         } break;
     215
     216        // internal message from timer module
     217        case message::type_timer:
     218         // -----------------------
     219         {
     220          TimerMsg* timermsg= dynamic_cast<TimerMsg*>(msg);
     221          if (timermsg)
     222          {
     223            // =====================================================
     224            process_timer_msg(timermsg); ///< process timer messages
     225            // =====================================================
     226          }
     227          else
     228          {
     229            Log(ERROR_LOG,LOG_ALERT, param.name,
     230                "Cannot cast message from "
     231                << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to TimerMsg");
     232           
     233            delete msg;
     234          } // end if timermsg
     235         } break;
     236
     237        // everything else is handled by default
     238        default:
     239          ERRLog(param.name, "Received a message from " << msg->get_qaddr_name()
     240                             << " that cannot be processed here: " << msg->get_type_name());
     241                               
     242          delete msg;
     243    } // end switch message type
     244}
     245
     246
     247/**
     248 * called if Timeout happened by dequeue_timedwait()
     249 */
     250void Statemodule::handleTimeout()
     251{
     252        //nothing to do
     253}
    202254
    203255/**
     
    217269  if (!fq)
    218270  {
    219     Log(ERROR_LOG,LOG_ALERT, param.name, "Cannot find input queue");
     271    ERRCLog(param.name, "Cannot find input queue");
    220272   
    221273    return;
     
    223275
    224276  message* msg = NULL;
    225   SignalingMsgNTLP* sigmsg = NULL;
    226   TimerMsg* timermsg = NULL;
    227   APIMsg* apimsg = NULL;
    228277  // maximum wait period (in ms) at queue
    229278  uint32 wait= param.sleep_time;
     
    235284    if (msg)
    236285    {
    237       switch (msg->get_type())
    238       {
    239 
    240         // internal message from signaling (message from IP network)
    241         case message::type_signaling:
    242           // -----------------------
    243           sigmsg= dynamic_cast<SignalingMsgNTLP*>(msg);
    244           if (sigmsg)
    245           {
    246             // =====================================================
    247             process_sig_msg(sigmsg); ///< process signaling messages
    248             // =====================================================
    249           }
    250           else
    251           {
    252             Log(ERROR_LOG,LOG_ALERT, param.name,
    253                 "Cannot cast message from "
    254                 << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to SignalingMsgNTLP");
    255            
    256             delete msg;
    257           } // end if sigmsg
    258           break;
    259 
    260         // internal message from API
    261         case message::type_API:
    262           // -----------------------
    263           apimsg= dynamic_cast<APIMsg*>(msg);
    264           if (apimsg)
    265           {
    266             // =====================================================
    267             process_api_msg(apimsg); ///< process API messages
    268             // =====================================================
    269           }
    270           else
    271           {
    272             Log(ERROR_LOG,LOG_ALERT, param.name,
    273                 "Cannot cast message from "
    274                 << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to APIMsg");
    275            
    276             delete msg;
    277           } // end if sigmsg
    278           break;
    279 
    280         // internal message from timer module
    281         case message::type_timer:
    282           // -----------------------
    283           timermsg= dynamic_cast<TimerMsg*>(msg);
    284           if (timermsg)
    285           {
    286             // =====================================================
    287             process_timer_msg(timermsg); ///< process timer messages
    288             // =====================================================
    289           }
    290           else
    291           {
    292             Log(ERROR_LOG,LOG_ALERT, param.name,
    293                 "Cannot cast message from "
    294                 << msg->get_qaddr_name() << " of " << msg->get_type_name() << " to TimerMsg");
    295            
    296             delete msg;
    297           } // end if timermsg
    298           break;
    299 
    300         // everything else is handled by default
    301         default:
    302           ERRLog(param.name, "Received a message from " << msg->get_qaddr_name()
    303                              << " that cannot be processed here: " << msg->get_type_name());
    304                                
    305           delete msg;
    306       } // end switch message type
     286        handleInternalMessage(msg);
    307287    }  // end if msg
    308 
     288        else handleTimeout();
     289       
    309290    sched_yield();
    310291  } // end while running
    311292} // end process_queue
     293
     294
    312295
    313296
     
    425408  if (ip_version == 6) mynl = param.localnliv6.copy();
    426409
    427   uint32 rs_validity_time= param.rs_validity_time;
     410  uint32 rs_validity_time= gconf.getpar<uint32>(gistconf_rs_validity_time);
    428411
    429412  if (re) rs_validity_time= re->rs_validity_time;
     
    568551  } // endif error PDU
    569552
    570   // check for untranslated mandatory NATed objects
    571   if (incoming_pdu->get_nattraversal())
    572   {
    573     // if the NAT Traversal object does NOT indicate NLI and stack_conf_data to be translated, sppol error.
    574     nattraversal* nattrav = incoming_pdu->get_nattraversal();
    575        
     553  // check for NAT Traversal object (NTO) and any untranslated mandatory NATed objects
     554  // NTOs are only present in Queries or Responses, but we want to use
     555  nattraversal* nattravobj = incoming_pdu->get_nattraversal();
     556  if ( nattravobj )
     557  {
     558    // if the NAT Traversal object does NOT indicate NLI and stack_conf_data to be translated,
     559    // send back an error.
    576560    bool nli_found = false;
    577561    bool stackconf_found = false;
    578562       
    579563    uint16 tmp_trans;
    580     for (unsigned int i = 0; i < nattrav->get_translations().size(); i++)
    581     {
    582       tmp_trans= nattrav->get_translations()[i];
     564    for (unsigned int i = 0; i < nattravobj->get_translations().size(); i++)
     565    {
     566      tmp_trans= nattravobj->get_translations()[i];
    583567
    584568      if (tmp_trans == known_ntlp_object::NLI) nli_found=true;
     
    608592  } // end checking for untranslated NAT Objects
    609593
    610   // if it is a response carrying a NAT Traversal object, we ought to use the MRI from it instead the one from the PDU
    611   if (incoming_pdu->is_response() && incoming_pdu->get_nattraversal())
    612   {
    613     DLog(param.name, "GIST Response carrying a NAT Traversal object, taking MRI from it");
    614     r_key->mr=incoming_pdu->get_nattraversal()->get_embedded_mri()->copy();
     594  // if it is a query/response carrying a NAT Traversal object,
     595  // we ought to use the MRI from it instead the one from the PDU
     596  // because all later messages use untranslated the local querier addresses in MRI/NLI
     597  if (nattravobj)
     598  {
     599    DLog(param.name, "GIST Message carrying a NAT Traversal object, taking MRI from it");
     600    r_key->mr= nattravobj->get_embedded_mri()->copy();
     601    // must invert the direction since original MRI will have
     602    // the D-bit set, but not the Embedded MRI in the NTO
     603    // since code below assumes that D is set, we have to do it explicitly here
     604    if (incoming_pdu->is_response())
     605            r_key->mr->invertDirection();
    615606  }
    616607  else
     
    625616  r_key->nslpid=incoming_pdu->get_nslpid();
    626617
     618  // MRI and SessionID are mandatoy in Query, Response, and Data messages
     619  // Error and Hellos are processed earlier
    627620  if (!r_key->mr)
    628621  {
    629622    ERRCLog(param.name, "No MRI in message, this will not be processed");
    630     // TODO: throw ERROR msg?
     623    senderror(incoming_pdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::MRI);
    631624    return;
    632625  }
     
    635628  {
    636629    ERRCLog(param.name, "No SessionID in message, this will not be processed");
    637     // TODO: Throw ERROR msg?
     630    senderror(incoming_pdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::SessionID);
    638631    return;
    639632  }
     
    704697        {
    705698          // if Data came via Q-Mode we should deliver it to the application and indicate that no routing state exists
    706           if (generic_sigmsg->get_source() == message::qaddr_tp_queryencap)
     699          // since draft -17 we have to check for the C flag
     700          if (incoming_pdu->get_C())
    707701          {
    708702            DLog(param.name, " Data PDU via Q-Mode, simply deliver DATA to NSLP");
     
    12071201    if (pdu->get_nli()) {
    12081202      DLog(param.name, "IP Source is NOT last GIST hop, sending to GIST denoted by NLI");
    1209       target = new appladdress(pdu->get_nli()->get_if_address(), param.udp, param.wkp);
     1203      target = new appladdress(pdu->get_nli()->get_if_address(), param.udp, gconf.getpar<uint16>(gistconf_udpport));
    12101204           
    12111205           
     
    12191213    target = new appladdress(*peer);
    12201214    if (target->get_protocol()== param.qenc) target->set_protocol(param.udp);
    1221     if (target->get_protocol()== param.udp) target->set_port(param.wkp);
     1215    if (target->get_protocol()== param.udp) target->set_port(gconf.getpar<uint16>(gistconf_udpport));
    12221216  }
    12231217   
     
    13761370  *timer_type=refresh_secrets;
    13771371 
    1378   msg->start_relative(param.secrets_refresh, 0, (void*)timer_type, NULL);
     1372  msg->start_relative(gconf.getpar<uint32>(gistconf_secrets_refreshtime), 0, (void*)timer_type, NULL);
    13791373 
    13801374  msg->send_to(message::qaddr_timer);
     
    14401434      EVLog(param.name, "Route Flapping occured, restarting refresh_qnode timer for downstream path");
    14411435           
    1442       starttimer(&tmpkey, tmpentry, refresh_qnode, 0, randomized(tmpentry->nl->get_rs_validity_time(), param.retryfactor));
     1436      starttimer(&tmpkey, tmpentry, refresh_qnode, 0, randomized(tmpentry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    14431437    }
    14441438  }
     
    14591453Statemodule::is_local_address(const hostaddress &addr)
    14601454{
    1461   typedef std::list<hostaddress>::const_iterator addr_iter;
    1462 
    1463   addr_iter begin, end;
     1455  typedef hostaddresslist_t::const_iterator addr_citer;
     1456
     1457  addr_citer begin, end;
    14641458 
    14651459  if ( addr.is_ipv4() ) {
    1466     begin = param.localaddrv4.begin();
    1467     end = param.localaddrv4.end();
     1460    begin = gconf.getparref< hostaddresslist_t >(gistconf_localaddrv4).begin();
     1461    end = gconf.getparref< hostaddresslist_t >(gistconf_localaddrv4).end();
    14681462  } else if ( addr.is_ipv6() ) {
    1469     begin = param.localaddrv6.begin();
    1470     end = param.localaddrv6.end();
    1471   }
    1472  
    1473   for ( addr_iter i = begin; i != end; i++ )
     1463    begin = gconf.getparref< hostaddresslist_t >(gistconf_localaddrv6).begin();
     1464    end = gconf.getparref< hostaddresslist_t >(gistconf_localaddrv6).end();
     1465  }
     1466 
     1467  for ( addr_citer i = begin; i != end; i++ )
    14741468    if ( *i == addr )
    14751469      return true;
  • ntlp/trunk/src/ntlp_statemodule_querier.cpp

    r3674 r4108  
    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    // include local Interface to allow tp_queryencap to bind specifically to it
     
    160165
    161166  // set well-known-port for GIST and dummy prot_query_encap protocol to force the message to tp_queryencap
    162   peer->set_port(param.wkp);
     167  peer->set_port( gconf.getpar<uint16>(gistconf_udpport) );
    163168  peer->set_protocol(refmri->get_mrm() == mri::mri_t_explicitsigtarget ? param.udp : param.qenc);
    164169
     
    180185      if (apimsg->get_data())
    181186      {
    182         if (param.senddatainquery)
     187        if (gconf.getpar<bool>(gistconf_senddatainquery))
    183188        {
    184189          data= new nslpdata(*(apimsg->get_data()));
     
    243248    sp= cap.query_stackprop(secure);
    244249    sc= cap.query_stackconf(secure);
    245     sc->set_ma_hold_time(param.ma_hold_time);
    246  
    247     DLog(param.name, "Constructed Stack Proposal/Stack Configuration data for C-Mode handshake");
     250    sc->set_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time));
     251
     252    if (cap.is_consistent(sp,sc))
     253    {
     254        DLog(param.name, "Successfully constructed Stack Proposal/Stack Configuration data for C-Mode handshake");
     255    }
     256    else
     257    {
     258      ERRCLog(param.name, "Constructed inconsistent Stack Proposal/Stack Configuration data for C-Mode handshake, not sending any query. Programming error, please fix the code.");
     259      delete mysid;
     260      delete mymri;
     261      delete data;
     262      delete mynli;
     263      delete sp;
     264      delete sc;
     265      return;
     266    }
    248267  }
    249268
     
    380399
    381400    r_entry->state=qn_established;             
    382     r_entry->rs_validity_time = param.rs_validity_time;
     401    r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    383402
    384403    // create/reuse and store SII handle for this peer
     
    397416               
    398417    // start Refresh_QNode timer on timer slot #2
    399     starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), param.retryfactor));
     418    starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    400419
    401420    // check whether other side did MA re-use and promoted our D-mode setup to C-mode
     
    589608
    590609  // (re)Start refresh_QNode timer
    591   starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), param.retryfactor));
     610  starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    592611
    593612  // Start inactive_QNode timer if not running
     
    623642           
    624643  // start Refresh_QNode again
    625   starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), param.retryfactor));
     644  starttimer(r_key, r_entry, refresh_qnode, 0, randomized(r_entry->nl->get_rs_validity_time(), gconf.getpar<float>(gistconf_retryfactor)));
    626645
    627646  // Inactive_QNode should be running already (was probably restarted by incoming piggybacked NSLP data earlier)
     
    691710  // construct target address
    692711  appladdress* target= new appladdress;
    693   target->set_port(param.wkp);
     712  target->set_port(gconf.getpar<uint16>(gistconf_udpport));
    694713  if (!r_entry->nl) {
    695714    ERRCLog(param.name, "No NLI saved locally for this peer. Cannot proceed.");
     
    748767  // construct target address for sending back any error messages
    749768  appladdress*  errortarget= new appladdress;
    750   errortarget->set_port(param.wkp);
     769  errortarget->set_port( gconf.getpar<uint16>(gistconf_udpport) );
    751770  if (!r_entry->nl) {
    752771    ERRCLog(param.name, "No NLI saved locally for this peer. Cannot proceed.");
     
    830849  // but this is only required for the very first confirmation message during
    831850  // initial MA setup
    832   stack_conf_data* mysc = (ma_reuse == false)  ? new stack_conf_data(param.ma_hold_time) : NULL;
     851  stack_conf_data* mysc = (ma_reuse == false)  ? new stack_conf_data(gconf.getpar<uint32>(gistconf_ma_hold_time)) : NULL;
    833852   
    834853  // echo responder cookie
  • ntlp/trunk/src/ntlp_statemodule_responder.cpp

    r3674 r4108  
    4444#include "authorized_peer_db.h"
    4545
     46#include "gist_conf.h"
     47
    4648extern "C"
    4749{
     
    6870  // a confirm is received
    6971
    70   //EVLog(param.name, "Delivering Payload to NSLP");
    71   deliver_adjacency_flag(peer, own_addr, query_pdu);
    72 
    7372  DLog(param.name, "Initial GIST Query received");
    7473               
     
    7675  routingentry* r_entry = new routingentry(true);
    7776
    78   // save eventual NAT Traversal payload in routing entry
     77  // save potentially present NAT Traversal payload in routing entry
    7978  if (nattraversal* nattrav = query_pdu->get_nattraversal())
    8079  {
    8180    EVLog(param.name, color[green]<< "This message traversed a NAT, saving NAT information locally" << color[off]);
    8281
    83     r_entry->nattrav=nattrav->copy();
     82    // NTO contains the original (local to the Querier) MRI, NLI and SCD
     83    r_entry->nattrav= nattrav->copy();
    8484  }
    8585       
    8686  // set our RS_Validity time
    87   r_entry->rs_validity_time = param.rs_validity_time;
     87  r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    8888         
    8989  // save Query Cookie for Response retries
    9090  r_entry->qrc=new querycookie(*(query_pdu->get_querycookie()));
    9191
    92   // save NLI and SII handle in the entry
    93   r_entry->nl=new nli(*query_pdu->get_nli());
     92  // if we have a NAT traversal object, use information from it
     93  // for cookie generation etc. otherwise the cookie cannot be validated
     94  // properly
     95  if (r_entry->nattrav)
     96  {
     97          const nli* nto_nli= r_entry->nattrav->get_nli();
     98          // save a copy of the NLI carried in the NAT Traversal object
     99          if ( nto_nli )
     100          {
     101                r_entry->nl= new nli( *nto_nli );
     102                DLog(param.name, "Using NLI from NAT traversal object, i/f address: " << nto_nli->get_if_address());
     103          }
     104  }
     105  else
     106  { // use NLI from the PDU
     107          // save NLI
     108          r_entry->nl= new nli(*query_pdu->get_nli());
     109  }
     110
     111  // check whether this is our own query by comparing the Peer ID
     112  if (r_entry->nl)
     113  {
     114          const peer_identity* pid= r_entry->nl->get_pi();
     115          if (pid && (*pid == *(param.localnliv4.get_pi())) || *pid == *(param.localnliv6.get_pi()))
     116          { // peer id from query nli is the same as ours, this is usually an error
     117                  WLog(param.name,"Detected Query coming from myself, will be ignored and dropped to avoid loopback to myself.");
     118                  delete r_entry;
     119                  return;
     120          }
     121                 
     122  }
     123
     124  // SII handle in the entry
    94125  r_entry->sii_handle= param.rt.generate_sii_handle(r_entry->nl);
    95126  DLog(param.name, "Saved NLI, SII handle = " << r_entry->sii_handle);
     
    160191 
    161192  DLog(param.name, "Prepared for State setup");
     193
     194  EVLog(param.name, "Notifying NSLP of initial Query requesting to peer");
     195  deliver_adjacency_flag(peer, own_addr, query_pdu, r_entry);
     196
    162197}
    163198
     
    214249  }
    215250                   
    216   if (param.confirmrequired)
     251  if (gconf.getpar<bool>(gistconf_confirmrequired))
    217252  {
    218253    DLog(param.name, "Full handshake configured, waiting for GIST Confirm");
     
    287322  if (echoed_resp_cookie && (respcookie_matched= evaluate_resp_cookie(cnfpdu->get_nli(), r_key, echoed_resp_cookie)) == false)
    288323  {
    289     DLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
     324    WLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
    290325    // send back error
    291326    // but only during initial deployment or debugging, because
    292327    // sending the error in general makes a node a source of backscatter
    293     if (param.verbose_error_responses)
     328    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    294329      senderror(cnfpdu, peer, GIST_Error::error_gist_invalid_rcookie);
    295330
     
    398433      // since we already ensured by the responder cookie that this is not a blind attacker
    399434      // chances are high that this is a broken implementation and not an adversary
    400       if (param.verbose_error_responses)
     435      if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    401436        senderror(cnfpdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::NLI);
    402437    }
     
    476511  DLog(param.name, "GIST Confirm while no Routing State - Assuming Late State Installation");
    477512
     513  const respcookie* responder_cookie= cnfpdu->get_respcookie();
    478514  // check whether Responder Cookie is present (we should have sent one, but is it echoed?)
    479   if (cnfpdu->get_respcookie() == NULL)
     515  if (responder_cookie == NULL)
    480516  {
    481517    ERRCLog(param.name,"Confirm in Late State installation: Responder Cookie missing in Confirm, although we sent one for sure.");
    482518    // send back error for missing responder cookie
    483     if (param.verbose_error_responses)
     519    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    484520      senderror(cnfpdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::RespCookie);
    485521
     
    487523  }
    488524
     525  // MUST CHECK with different NLI and r_key if NTO is present...
    489526  // evaluate Responder Cookie in CONFIRM
    490   bool rsp_cookie_matched = evaluate_resp_cookie(cnfpdu->get_nli(), r_key, cnfpdu->get_respcookie());
     527  bool rsp_cookie_matched = evaluate_resp_cookie(cnfpdu->get_nli(), r_key, responder_cookie);
    491528
    492529  // is Responder Cookie valid?
    493530  if (rsp_cookie_matched == false)
    494531  {
    495     DLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
     532    WLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
    496533
    497534    // send back error if enabled
    498     if (param.verbose_error_responses)
     535    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    499536      senderror(cnfpdu, peer, GIST_Error::error_gist_invalid_rcookie);
    500537
     
    511548  // we got a valid confirm, we must set up routing state and begin in "established"
    512549  // as we ignored the Query to the Confirm and did nothing
    513                
     550 
    514551  routingentry* r_entry= new routingentry(true);
    515552
     
    564601    // since we already ensured by the responder cookie that this is not a blind attacker
    565602    // chances are high that this is a broken implementation and not an adversary
    566     if (param.verbose_error_responses)
     603    if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    567604      senderror(cnfpdu, peer, GIST_Error::error_gist_missing_object, known_ntlp_object::NLI);
    568605  }
    569606
    570607  // record incoming interface (is contained in Responder Cookie that we sent back on receiving the query)
    571   r_entry->set_incoming_if(cnfpdu->get_respcookie()->get_if_index());
     608  r_entry->set_incoming_if(responder_cookie->get_if_index());
    572609  DLog(param.name, "saved incoming interface index " << r_entry->get_incoming_if());
    573610
     611  // save any NAT traversal object that comes with the responder_cookie
     612  // since cookie data was protected by our HMAC and found to be correct
     613  // we can be sure, that the NTO is unmodified and correct
     614  if (responder_cookie->get_transparent_data())
     615  {
     616          uint32 bytes_read= 0;
     617          IEErrorList errorlist;
     618          nattraversal* nat_trav_obj= new nattraversal;
     619          NetMsg* tmpbuf= new NetMsg(responder_cookie->get_transparent_data(),
     620                                     responder_cookie->get_transparent_data_len(),
     621                                     false);
     622          nat_trav_obj->deserialize(*tmpbuf, IE::protocol_v1, errorlist, bytes_read, false);
     623          if (errorlist.is_empty() == false)
     624          {
     625                  ERRLog(param.name,"parse error while getting NTO from responder cookie - this is an implementation error");
     626          }
     627          else
     628          {
     629                  // save the nat traversal object
     630                  r_entry->nattrav= nat_trav_obj;
     631          }
     632          delete tmpbuf;
     633  }
     634
    574635  // set our RS_Validity time
    575   r_entry->rs_validity_time = param.rs_validity_time;
     636  r_entry->rs_validity_time = gconf.getpar<uint32>(gistconf_rs_validity_time);
    576637
    577638  // what we want is in the echoed response stack proposal
     
    774835    if (rsp_cookie_matched == false)
    775836    {
    776       DLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
     837      WLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
    777838
    778839      // send back error if enabled
    779       if (param.verbose_error_responses)
     840      if (gconf.getpar<bool>(gistconf_verbose_error_responses))
    780841        senderror(cnfpdu, peer, GIST_Error::error_gist_invalid_rcookie);
    781842
     
    922983  // - include NLI describing OURSELF
    923984  // - store responder locally in routing data table for checking later
    924   // - cookie is only sent when setting up a connection
     985  // - cookie is only sent when setting up routing state
    925986  // - set R-Flag if latestate or C-Mode is requested
    926987 
     
    9441005  // we don't need a confirm only in case of a refresh
    9451006
    946   bool requestconfirm= ( ((r_entry->state == rn_established) && !param.confirmrequired) ) ? false : true;
     1007  bool requestconfirm= ( (r_entry->state == rn_established) && !gconf.getpar<bool>(gistconf_confirmrequired) ) ? false: true;
     1008
    9471009  // if initial handshake and late state installation required, we need a confirm back
    948   if ( (r_entry->state == rn_querynslp) && param.latestate )
     1010  if ( (r_entry->state == rn_querynslp) && gconf.getpar<bool>(gistconf_latestate) )
    9491011    requestconfirm= true;
    9501012
     
    9961058      own_sc = cap.resp_stackconf(NULL, false);
    9971059     
    998       own_sc->set_ma_hold_time(param.ma_hold_time);
     1060      own_sc->set_ma_hold_time(gconf.getpar<uint32>(gistconf_ma_hold_time));
    9991061     
     1062      if (cap.is_consistent(own_sp,own_sc))
     1063      {
     1064              DLog(param.name, "Successfully constructed Stack Proposal/Stack Configuration data for C-Mode handshake");
     1065      }
     1066      else
     1067      {
     1068              ERRCLog(param.name, "Constructed inconsistent Stack Proposal/Stack Configuration data for C-Mode handshake, not sending any query. Programming error, please fix the code.");
     1069      }
     1070
    10001071      // save them for retries
    10011072      delete (r_entry->sp);
     
    10401111  appladdress* response_dest=NULL;
    10411112  // answer goes back to source port or well known port (wkp)
    1042   port_t response_port= peer ? peer->get_port() : param.wkp;
     1113  port_t response_port= peer ? peer->get_port() : gconf.getpar<uint16>(gistconf_udpport);
    10431114
    10441115  // interface index from query
     
    10521123  // this is ususally the case only when we have stored state and no_confirm timer went off
    10531124  nli* qnli= pdu ? pdu->get_nli() : r_entry->nl;
     1125
     1126  // override in case of NAT traversal, use info from NAT traversal object
     1127  if (r_entry->nattrav)
     1128          qnli= r_entry->nl;
    10541129  if (qnli)
    10551130  {
     
    11261201  nli* nl = build_local_nli(mr->get_ip_version(), r_entry);
    11271202
     1203  // test if we have a saved nat traversal object (NTO)
     1204  nattraversal* nto = dynamic_cast<nattraversal*>(r_entry->nattrav);
     1205  NetMsg* ntobuf_p= NULL;
     1206  // put NTO as transparent data into hash if present
     1207  if (nto)
     1208  {
     1209          uint32 ntobuf_size= nto->get_serialized_size(IE::protocol_v1);
     1210          ntobuf_p= new NetMsg(ntobuf_size);
     1211          // should be serialized including the common object header
     1212          uint32 written= 0;
     1213          nto->serialize(*ntobuf_p, IE::protocol_v1, written);
     1214  }
     1215
    11281216  // generate a new responder cookie and include it
    11291217  // but only if MA re-use is not possible or we want late state installation
    1130   respcookie* rc = ( (ma_requested && ma_reuse == false) || requestconfirm ) ? create_resp_cookie(qnli, r_key, 0, if_index) : NULL;
     1218  respcookie* rc = ( (ma_requested && ma_reuse == false) || requestconfirm ) ? create_resp_cookie(qnli, r_key, 0, if_index, ntobuf_p) : NULL;
     1219 
     1220  // ntobuf not required anymore
     1221  delete ntobuf_p;
    11311222 
    11321223  // confirm MUST be requested if responder cookie is present
     
    11431234  if (r_entry->mod_data)
    11441235  {
    1145     if ((param.latestate) || (!param.confirmrequired))
     1236    if (gconf.getpar<bool>(gistconf_latestate) || (!gconf.getpar<bool>(gistconf_confirmrequired)))
    11461237    {
    11471238      DLog(param.name, "There will be no repetitions of this Response, cleaning replacement NSLP data");
     
    11591250  response* rsp = new response(mr, sid, nl, qc, rc, own_sp, own_sc, mydata);
    11601251
    1161   nattraversal* nt = NULL;
    1162    
    1163   // test if we have a saved nat traversal object
    1164   nt = dynamic_cast<nattraversal*>(r_entry->nattrav);
    1165  
    1166   if (nt) {
     1252 
     1253  if (nto) {
    11671254        EVLog(param.name, color[green] << "Included NAT traversal object in GIST Response" << color[off]);
    1168         rsp->add_nat(nt);
     1255        rsp->add_nat(nto);
    11691256  }
    11701257 
     
    11981285 * Our cookie is currently constructed as follows:
    11991286 * Secret generation number(32 bit) +
    1200  * Hash(Q-Node Peer-ID, Q-Node i/f address, MRI, Session-ID, NSLPID, generation number, secret)
     1287 * query receiving interface index +
     1288 * MAC Data Offset +
     1289 * MAC Data= Hash(Q-Node Peer-ID, Q-Node i/f address, MRI, Session-ID, NSLPID, generation number, secret)
    12011290 *
    12021291 * @param querier_nli -- the nli (peer-id, ip address) of the querier
     
    12041293 * @param gennumber -- the generation number to use, if 0 use the current generation number
    12051294 * @param if_index -- interface index
     1295 * @param transparent_data -- e.g., nattraversal object if used, this must be included in the responder cookie if present
    12061296 * @return responder cookie or NULL if secret not available (wrong generation number)
    12071297 */
    12081298respcookie*
    1209 Statemodule::create_resp_cookie(const nli* querier_nli, const routingkey* key, uint32 gennumber, uint16 if_index)
     1299Statemodule::create_resp_cookie(const nli* querier_nli, const routingkey* key, uint32 gennumber, uint16 if_index, const NetMsg* transparent_data)
    12101300{
    12111301
     
    12351325
    12361326
    1237   //============================================
    1238   // Now put our input data into a byte buffer
    1239   //============================================
     1327  //===================================================================
     1328  // Now put our input data into a byte buffer for calculating the hash
     1329  //===================================================================
    12401330 
    12411331         mri* mr= key->mr;
     
    12431333   uint16 nslpid= key->nslpid;
    12441334   uint8  pi_len= querier_nli->get_pi()->get_length();
    1245   // compute size needed for data in NetMsg
     1335   uint16 transparent_data_len= (transparent_data && transparent_data->get_buffer()) ? transparent_data->get_size() : 0;
     1336
     1337  // compute size needed for data in NetMsg (note: just used for computing the hash)
    12461338
    12471339  // generation number (4 byte) in clear text (not hashed)
    12481340   uint32 buffersize = sizeof(generationnumber);
    12491341
    1250   // put the interface index directly after the generation number
    12511342  buffersize+= sizeof(if_index);
    12521343
     
    12631354  // SessionID without header
    12641355  buffersize+= sid->get_serialized_size(IE::protocol_v1)-4;
     1356
    12651357  // NSLPID
    12661358  buffersize+=sizeof(nslpid);
     
    12711363  // secret
    12721364  buffersize+=secretsize;
     1365
     1366  // if any transparent data given
     1367  buffersize+= transparent_data_len;
    12731368   
    12741369  // build NetMsg of sufficient size -> used for calculating the hash
     
    12831378  msg->copy_from(querier_nli->get_pi()->get_buffer(), msg->get_pos(), pi_len);
    12841379  msg->set_pos_r(pi_len);
    1285   written= pi_len;
     1380  written+= pi_len;
    12861381
    12871382  // serialize IP address
     
    13101405  // serialize MRI into NetMsg buffer
    13111406  mr->serializeNoHead(*msg, IE::protocol_v1, written);
    1312    
     1407
    13131408  // serialize SessionID into NetMsg buffer
    13141409  sid->serializeNoHead(*msg, IE::protocol_v1, written);
     
    13211416  msg->copy_from(secret, msg->get_pos(), secretsize);
    13221417  msg->set_pos_r(secretsize);
     1418
     1419  // put transparent_data into hash if present
     1420  if (transparent_data_len > 0)
     1421  {
     1422          memcpy(msg->get_buffer()+msg->get_pos(), transparent_data->get_buffer(), transparent_data_len);
     1423  }
     1424
    13231425   
    13241426  //============================================
     
    13311433  unsigned char md_value[EVP_MAX_MD_SIZE];
    13321434  unsigned int md_len;
    1333  
    1334   // 2nd: load in all digests from OpenSSL
    1335   OpenSSL_add_all_digests();
    1336  
    1337   // 3rd: We want SHA1 (maybe we make this a command line option)
    1338   md = EVP_get_digestbyname("SHA1");
     1435   
     1436  // 2nd: We want SHA1 (maybe we make this a command line option)
     1437  md = EVP_get_digestbyname(gconf.getparref<string>(gistconf_cookie_digest).c_str());
    13391438 
    13401439  if(!md) {
    1341     ERRCLog(param.name, "Hasher SHA-1 not available. Please update your OpenSSL library!");
     1440          ERRCLog(param.name, "Hash algorithm " << gconf.getparref<string>(gistconf_cookie_digest) << " not available. Please update your OpenSSL library!");
    13421441    abort();
    13431442  }
    13441443 
    1345   // 4th: Initialize hasher
     1444  // 3rd: Initialize hasher
    13461445  EVP_MD_CTX_init(&mdctx);
    13471446  EVP_DigestInit_ex(&mdctx, md, NULL);
    1348   // 5th: give input to hasher
     1447  // 4th: give input to hasher
    13491448  EVP_DigestUpdate(&mdctx, msg->get_buffer(), msg->get_size());
    13501449   
    1351   // 6th: Finalize message digest
     1450  // 5th: Finalize message digest
    13521451  EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
    13531452
    1354   // 7th: Cleanup datastructures
     1453  // 6th: Cleanup datastructures
    13551454  EVP_MD_CTX_cleanup(&mdctx);
    13561455
     1456  //==============================================
     1457  // From here on we put the cookie value together
     1458  //==============================================
     1459
     1460  // 7.1: Put together result buffer
     1461  uint16 totallen= sizeof(generationnumber) + 2*sizeof(uint16) + transparent_data_len + md_len;
     1462  uchar* buf = new uchar[totallen];
     1463  uchar* pbuf= buf;
     1464
     1465  // 7.2: Put in Generation Number first
     1466  *((uint32*)pbuf) = htonl(generationnumber);
     1467  pbuf+= sizeof(generationnumber);
     1468
     1469  // 7.3: interface index next (16 bit)
     1470  *((uint16*)pbuf) = htons(if_index);
     1471  pbuf+= sizeof(uint16);
     1472
     1473  // 7.4: byte offset pointing to HMAC data behind optional NTO
     1474  *((uint16*)pbuf) = htons( transparent_data_len );
     1475  pbuf+= sizeof(uint16);
     1476
     1477  // put transparent data into buffer if present, currently it could be the NAT traversal object
     1478  if (transparent_data && transparent_data->get_buffer() && transparent_data_len > 0)
     1479  {
     1480          memcpy(pbuf, transparent_data->get_buffer(), transparent_data_len);
     1481          pbuf+= transparent_data_len;
     1482  }
     1483
     1484  // 7.4th: Copy Resulting Hash/MD into buffer
     1485  memcpy(pbuf, md_value, md_len);
     1486 
     1487  // 8th: Put into Responder Cookie
     1488  respcookie* cookie = new respcookie(buf, totallen);
     1489
     1490  DLog(param.name, "Computed Responder Cookie, length "<< totallen*8 << " Bit: " << cookie->to_str());
     1491
     1492  // delete temporary buffer now
     1493  delete buf;
    13571494  // delete netmsg buffer
    13581495  delete msg;
    1359 
    1360   // 7.1th: Put together result buffer
    1361   uint16 totallen= sizeof(generationnumber) + sizeof(uint32) + md_len;
    1362   uchar* buf = new uchar[totallen];
    1363   uchar* pbuf= buf;
    1364 
    1365   // 7.2th: Put in Generation Number first
    1366   *((uint32*)pbuf) = htonl(generationnumber);
    1367   pbuf+= sizeof(generationnumber);
    1368  
    1369   // 7.3th: Put interface index next (has been hashed)
    1370   // note: fill up to 32bit word due to alignment requirements
    1371   *((uint32*)pbuf) = htonl( (uint32) if_index);
    1372   pbuf+= sizeof(uint32);
    1373 
    1374   // 7.4th: Copy Resulting Hash/MD into buffer
    1375   memcpy(pbuf, md_value, md_len);
    1376    
    1377   // 8th: Put into Responder Cookie
    1378   respcookie* cookie = new respcookie(buf, totallen);
    1379 
    1380   DLog(param.name, "Computed Responder Cookie, length "<< totallen*8 << " Bit: " << cookie->to_str());
    1381 
    1382   // delete temporary buffer now
    1383   delete buf;
    13841496
    13851497  return cookie;
     
    13941506 */
    13951507bool
    1396 Statemodule::evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* responder_cookie) 
     1508Statemodule::evaluate_resp_cookie(const nli* querier_nli, const routingkey* r_key, const respcookie* responder_cookie)
    13971509{
    13981510  // if any argument is missing (probably in incoming pdu, we cannot recalc the responder cookie, so it is invalid)
     
    14031515 
    14041516  uint32 generationnumber= responder_cookie->get_generationnumber();
    1405   // decode interface id (actually 16bit, but sent as 32 bit word)
    1406   uint32 if_index= responder_cookie->get_if_index();
    1407   if (if_index >> 16)
    1408   {
    1409     // in this case the highest bits were set but they shouldn't be
    1410     // someone messed with the cookie
    1411     DLog(param.name, "Validation failed: Interface ID is not 16bit!: 0x" << hex << if_index << dec);
    1412     return false;
    1413   }
     1517
     1518  // decode interface id (16bit)
     1519  uint16 if_index= responder_cookie->get_if_index();
     1520
     1521  uint16 td_len= responder_cookie->get_transparent_data_len();
     1522  // check for any transparent objects carried in the responder cookie
     1523  // and make sure that we don't read behind the end of the buffer
     1524  NetMsg* transparent_data_msgbuf= ( (td_len > 0) && (4+2+2+td_len < responder_cookie->get_size()) ) ?
     1525          new NetMsg(responder_cookie->get_transparent_data(), td_len, false) : NULL;
    14141526
    14151527  // Now generate fitting cookie with decoded generation number of secret
    1416   const respcookie* ourcookie= create_resp_cookie(querier_nli, r_key, generationnumber, if_index);
     1528  const respcookie* ourcookie= create_resp_cookie(querier_nli, r_key, generationnumber, if_index, transparent_data_msgbuf);
     1529  delete transparent_data_msgbuf;
    14171530 
    14181531  if (ourcookie==NULL)
     
    14241537
    14251538  DLog(param.name, "Given Responder Cookie, length "<< responder_cookie->get_size()*8 << " Bit: " << responder_cookie->to_str());
     1539
     1540  // perform actual comparison
    14261541  if (*responder_cookie != *ourcookie) {
    14271542      DLog(param.name, color[red] << "Responder Cookie did not match!" << color[off]);
  • ntlp/trunk/src/pdu/mri_le.cpp

    r3674 r4108  
    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
  • ntlp/trunk/src/pdu/mri_pc.cpp

    r3674 r4108  
    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"
     
    606610}
    607611
     612
     613#ifndef NSIS_OMNETPP_SIM
    608614
    609615/**
     
    847853}
    848854
     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
    849865
    850866// Invert direction flag; responder nodes stores MRI with inverted direction
  • ntlp/trunk/src/pdu/nattraversal.cpp

    r2926 r4108  
    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/trunk/src/pdu/nattraversal.h

    r2548 r4108  
    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/trunk/src/pdu/nli.h

    r3674 r4108  
    160160  void set_ip_ttl(uint8 ttl);
    161161  const netaddress& get_if_address() const { return if_address; }
     162#ifdef NSIS_OMNETPP_SIM
     163  // this is for the OMNeT++ Simulation and is not included otherwise
     164  // need to set this after the constructor is called (in initialize())
     165  void set_if_address(const hostaddress& ha) { if_address=ha; }
     166#endif
    162167}; // end class nli
    163168
  • ntlp/trunk/src/pdu/ntlp_errorobject.h

    r3350 r4108  
    7676    errsub_IncorrectMsgLength= 3,
    7777    errsub_InvalidEFlag      = 4,
     78    errsub_InvalidCFlag      = 5,
    7879    // subtypes for err_ObjectTypeError
    7980    errsub_DuplicateObject              = 0,
  • ntlp/trunk/src/pdu/ntlp_ie.cpp

    r2887 r4108  
    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/trunk/src/pdu/ntlp_object.cpp

    r2928 r4108  
    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/trunk/src/pdu/ntlp_pdu.cpp

    r3871 r4108  
    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.nattrav_ptr),
  • ntlp/trunk/src/pdu/ntlp_pdu.h

    r2873 r4108  
    109109  static bool decode_common_header_ntlpv1_clen(NetMsg& m, uint32& clen_bytes);
    110110  /// decode header
    111   static void decode_common_header_ntlpv1(NetMsg& msg, uint8& ver, uint8& hops, uint16& clen_bytes, uint16& nslpid, uint8& type, uint8& flags, IEErrorList& errorlist);
     111  static void decode_common_header_ntlpv1(NetMsg& msg, uint8& ver, uint8& hops, uint16& clen_bytes, uint16& nslpid, uint8& type, uint8& flags, bool& c_flag, IEErrorList& errorlist);
    112112 
    113113  /// get NTLP message type
     
    358358    return flags & S_Flag;
    359359  }
     360
     361  inline
     362  const bool get_C() const {
     363          return c_flag;
     364  }
     365
     366  inline
     367  void set_C() {
     368          c_flag = true;
     369  }
     370
     371  inline
     372  void unset_C() {
     373          c_flag= false;
     374  }
     375
    360376
    361377protected:
     
    402418  uint8 type;
    403419  uint8 flags;
    404  
     420  bool  c_flag; // this is special, because it's not in the same byte as the other flags
     421
    405422 
    406423  uint32 nattrav_ptr;
  • ntlp/trunk/src/pdu/query.cpp

    r2926 r4108  
    8585        level++;
    8686        os<<setw(level*indent)<<"";
    87         os<<"NSLP ID: " << nslpid;
     87        os<<"NSLP ID: " <<  nslpid;
    8888        if (get_mri()) print_object(mri_ptr,os,level,indent,objects,"Message Routing Information");
    8989        if (get_sessionid()) print_object(sessionid_ptr,os,level,indent,objects,"SessionID");
  • ntlp/trunk/src/pdu/resp_cookie.cpp

    r2981 r4108  
    242242  ostringstream tmpostr;
    243243 
    244   tmpostr << setfill('0') << setw(2) << hex;
    245244  for(unsigned int i = 0; i < buf_length; i++)
    246     tmpostr << (int) buf[i];
     245    tmpostr << setfill('0') << setw(2) << hex << (int) buf[i];
    247246
    248247  return tmpostr.str();
  • ntlp/trunk/src/pdu/resp_cookie.h

    r2981 r4108  
    6262  uint32 get_generationnumber() const { return buf ? ntohl(*(reinterpret_cast<uint32*>(buf))) : 0; }
    6363
    64   // decode interface id (actually 16bit, but sent as 32 bit word), located after the generation number
    65   uint32 get_if_index() const { return buf ? ntohl(*(reinterpret_cast<uint32*>(buf+sizeof(uint32)))) : 0; }
     64  // decode interface id (16bit), located after the generation number field
     65  uint32 get_if_index() const { return buf ? ntohs(*(reinterpret_cast<uint16*>(buf+sizeof(uint32)))) : 0; }
     66
     67  // decode transparent data length field (16bit) expressed as number of bytes, located after the generation num and interface id
     68  uint16 get_transparent_data_len() const { return buf ? ntohs(*(reinterpret_cast<uint16*>(buf+sizeof(uint32)+sizeof(uint16)))) : 0; }
     69
     70  // return start of the transparent data part or 0 if not present
     71  uchar* get_transparent_data() const { return (get_transparent_data_len() > 0) ? buf+sizeof(uint32)+2*sizeof(uint16) : NULL; }
    6672
    6773  string to_str() const;
     
    8389  respcookie () :
    8490    known_ntlp_object(RespCookie, Mandatory),
     91    buf(NULL),
    8592    buf_length(0)
    86   { buf=NULL; };
     93  {
     94  };
    8795
    8896
     
    92100  /// Returns buffer length
    93101  uint32 get_size() const { return buf_length; }
    94 
    95102
    96103  /// This is the one mighty constructor, via which the object SHOULD be built programmatically!
     
    135142  };
    136143
    137   virtual ~respcookie() { if (buf) delete buf; }
     144  virtual ~respcookie() { delete buf; }
     145
    138146
    139147};
  • ntlp/trunk/src/pdu/sessionid.cpp

    r3598 r4108  
    200200      << setw(8) << setfill('0') << hex << b << '-'
    201201      << setw(8) << setfill('0') << hex << c << '-'
    202       << setw(8) << setfill('0') << hex << d;
     202      << setw(8) << setfill('0') << hex << d << setfill(' ') << dec;
    203203
    204204  return os.str();
  • ntlp/trunk/src/pdu/stackconf.cpp

    r2926 r4108  
    332332} // end input
    333333
     334void
     335stack_conf_data::add_protoption(const ma_protocol_option& protopt)
     336{
     337        ma_prot_options.push_back(protopt);
     338        // fix index
     339        ma_prot_options[ma_prot_options.size()-1].set_profile(ma_prot_options.size());
     340}
    334341
    335342//@}
  • ntlp/trunk/src/pdu/stackconf.h

    r2748 r4108  
    3131#include "protlib_types.h"
    3232
     33#include <stdexcept> // for std::out_of_range
    3334
    3435
     
    9495  void set_protocol(protocol_t prot) { protocol=prot; }
    9596
     97  /// returns number of profile
    9698  uint8 get_profile() const { return profile; }
    9799
     100  /// sets number of profile
    98101  void set_profile(uint8 prop) { profile=prop; }
    99102
     
    153156
    154157  /// add protocol option data
    155   void add_protoption(ma_protocol_option protopt) { ma_prot_options.push_back(protopt); }
     158  void add_protoption(const ma_protocol_option& protopt);
    156159
    157160  /// clear prot options
     
    159162
    160163  /// get a protocol option
    161   const ma_protocol_option* get_protoption(uint32 index) const { return &ma_prot_options[index]; }
     164  const ma_protocol_option* get_protoption(uint32 index) const { try { return &ma_prot_options.at(index); } catch (std::out_of_range& e) { return NULL; } }
    162165
    163166  /// get length
  • ntlp/trunk/src/pdu/stackprop.cpp

    r2926 r4108  
    3434#include "logfile.h"
    3535#include <iomanip>
     36#include <stdexcept>
    3637
    3738namespace ntlp {
     
    327328
    328329
     330const stackprofile*
     331stackprop::get_profile(uint32 index) const
     332{
     333        try
     334        {
     335                return &(profiles.at(index));
     336        }
     337        catch(std::out_of_range& orexception)
     338        {
     339                return NULL;
     340        } 
     341}
     342
    329343//@}
    330344
  • ntlp/trunk/src/pdu/stackprop.h

    r2748 r4108  
    110110
    111111  // get a profile
    112   const stackprofile* get_profile(uint32 index) const {return &(profiles[index]); }
     112  const stackprofile* get_profile(uint32 index) const;
    113113
    114114  // return profile count
  • ntlp/trunk/src/routingtable.cpp

    r3674 r4108  
    3535#include "protlib_types.h"
    3636
     37#include "gist_conf.h"
     38
    3739namespace ntlp {
    3840 
     
    4345// put as static method here to avoid circular dependencies in header file
    4446// is, however, also the same for every routingtable object
    45 uint32 routingentry::get_retry_limit() { return global_ntlpstarterthread_p->get_param().retrylimit; }
    46 uint32 routingentry::get_retry_period() { return global_ntlpstarterthread_p->get_param().retryperiod; }
     47uint32 routingentry::get_retry_limit() { return gconf.getpar<uint32>(gistconf_retrylimit); }
     48uint32 routingentry::get_retry_period() { return gconf.getpar<uint32>(gistconf_retryperiod); }
    4749
    4850const char*
     
    236238  *timer_type = ma.timer_type;
    237239 
    238   int timerint= Statemodule::randomized(peer_ma_hold_time, global_ntlpstarterthread_p->get_param().retryfactor);
     240  int timerint= Statemodule::randomized(peer_ma_hold_time, gconf.getpar<float>(gistconf_retryfactor));
    239241  msg->start_relative(0, timerint, (void*) timer_type, (void*)nlikey->copy());
    240242  ma.timer_id = msg->get_id();
     
    720722        {
    721723          // send an MA_HELLO
    722           if (global_ntlpstarterthread_p->get_param().reqhelloecho) {
     724          if (gconf.getpar<bool>(gistconf_reqhelloecho)) {
    723725                sendhello(ma_p->get_peer_address().copy(), true, ma_p->get_new_hello_id());
    724726          } else
     
    734736          *timer_type = ma_p->timer_type;
    735737         
    736           int timerint= Statemodule::randomized(ma_p->get_ma_hold_time(), global_ntlpstarterthread_p->get_param().retryfactor);
     738          int timerint= Statemodule::randomized(ma_p->get_ma_hold_time(), gconf.getpar<float>(gistconf_retryfactor));
    737739          msg->start_relative(0, timerint,(void*) timer_type, (void*)key->copy());
    738740          // change timer_type
  • ntlp/trunk/src/routingtable.h

    r3674 r4108  
    135135
    136136/// States for the running of state machine transitions
    137 typedef enum routingstate_t {
     137typedef enum routingstate_enum {
    138138  initial = 0,
    139139  qn_awaiting_response = 1,
     
    146146  dead = 8,
    147147  rt_state_max= 9
    148 };
     148} routingstate_t;
    149149
    150150const char* const statestring[] = {
     
    160160}; // end statestring
    161161
    162 typedef enum ma_state_t {
     162typedef enum ma_state_enum {
    163163  ma_state_birth= 0,
    164164  ma_state_awaiting_connection = 1,
     
    167167  ma_state_death= 4,
    168168  ma_state_max= 5
    169 };
     169} ma_state_t;
    170170
    171171
     
    179179     
    180180/// Timers
    181 typedef enum timer_type_t {
     181typedef enum time_type_enum {
    182182  invalid        = 0,
    183183  expire_rnode   = 1,
     
    195195  last_timer_type= 13,
    196196  none           = 255
    197 };
     197} timer_type_t;
    198198 
    199199 
     
    345345  vector<queueentry*> dataqueue;
    346346   
    347   /// saved NatTraversal object
     347  /// saved NAT Traversal object
    348348  nattraversal* nattrav;
    349349 
  • ntlp/trunk/src/signalingmodule_ntlp.cpp

    r3674 r4108  
    5252#include "ntlp_proto.h"
    5353
     54#ifndef NSIS_OMNETPP_SIM
     55
    5456#include <net/if.h>
    5557#include <linux/types.h> // in case that this one is not included in netlink.h
     
    5759#include <linux/rtnetlink.h>
    5860
     61#else
     62
     63#include "ip_to_nsis_id.h"
     64
     65#endif // end ifndef NSIS_OMNETPP_SIM
     66
    5967#include <cerrno>
    6068
    6169#include "readnl.h"
    6270#include "ntlp_global_constants.h"
     71#include "gist_conf.h"
    6372
    6473namespace ntlp {
     
    297306SignalingNTLP::get_error_string(error_t e)
    298307{
    299   return errstr[e];
     308        if (e < SignalingNTLP::error_MAX_msg)
     309                return errstr[e];
     310        else
     311                return "invalid error code";
    300312}
    301313
     
    340352
    341353
    342 
    343354/**
    344  * process queue of internal messages for the signaling module
    345  * (usually message::qaddr_signaling)
     355 *  called to process internal message
    346356 */
    347 void
    348 SignalingNTLP::process_queue()
    349 {
    350   uint32 wait = param.sleep_time*1000; // max. waiting time at internal msg queue
    351   message* msg = NULL;
    352   SignalingMsgNTLP* sigmsg = NULL;
    353   TPMsg* tpmsg = NULL;
    354 
    355   // get queue (param.source is usually message::qaddr_signaling)
    356   FastQueue* fq = QueueManager::instance()->get_queue(param.source);
    357   if (!fq)
    358   {
    359     Log(ERROR_LOG,LOG_ALERT, param.name, "Cannot find input msg queue");
    360    
    361     return;
    362   } // end if not fq
    363 
    364  
    365   /// wait for messages if in state running
    366   while (get_state()==STATE_RUN)
    367   {
    368     // dequeue message from internal message queue
    369     msg= fq->dequeue_timedwait(wait);
    370     if (msg)
     357void
     358SignalingNTLP::handleInternalMessage(message *msg)
     359{
     360  Log(DEBUG_LOG,LOG_NORMAL, param.name, "Received incoming message #" << msg->get_id() << " on Queue");
     361  switch( msg->get_type() )
    371362    {
    372       Log(DEBUG_LOG,LOG_NORMAL, param.name, "Received incoming message #" << msg->get_id() << " on Queue");
    373       switch( msg->get_type() )
    374       {
    375363        // message from transport
    376         case message::type_transport:
    377           {
    378            
    379             tpmsg = dynamic_cast<TPMsg*>(msg);
     364        case message::type_transport:
     365          {
     366            TPMsg* tpmsg = dynamic_cast<TPMsg*>(msg);
    380367            if (tpmsg)
    381368            {
     
    384371              Log(DEBUG_LOG,LOG_NORMAL, param.name, "Received incoming message #" << msg->get_id() << " from TP Module");
    385372            }
    386             else 
     373            else
    387374            {
    388375              Log(ERROR_LOG,LOG_ALERT, param.name, "Cannot cast message from source " << msg->get_qaddr_name() << " of type " << msg->get_type_name() << " to TPMsg");
    389              
     376
    390377              delete msg;
    391378            } // end if tpmsg
    392379          } break;
    393          
     380
    394381          // message from coordinator
    395382        case message::type_signaling:
    396383          {
    397             sigmsg = dynamic_cast<SignalingMsgNTLP*>(msg);
    398             if (sigmsg) 
     384            SignalingMsgNTLP* sigmsg = dynamic_cast<SignalingMsgNTLP*>(msg);
     385            if (sigmsg)
    399386            {
    400387              // process message from coordinator to TP
     
    402389              process_sig_msg(sigmsg);
    403390            }
    404             else 
     391            else
    405392            {
    406393              Log(ERROR_LOG,LOG_ALERT, param.name, "Cannot cast message from source " << msg->get_qaddr_name() << " of type " << msg->get_type_name() << " to SignalingMsgNTLP");
     
    408395            } // end if sigmsg
    409396          } break;
    410          
     397
    411398          default:
    412399            {
    413400              Log(ERROR_LOG,LOG_NORMAL, param.name, "Received a message from " << msg->get_qaddr_name() << " of type " << msg->get_type_name() << " that cannot be processed here");
    414              
     401
    415402              delete msg;
    416             }
    417       } // end switch
     403            }
     404    } // end switch
     405}
     406
     407
     408/**
     409 * called if Timeout happened by process_queue()
     410 */
     411void
     412SignalingNTLP::handleTimeout()
     413{
     414        //nothing to do
     415}
     416
     417
     418/**
     419 * process queue of internal messages for the signaling module
     420 * (usually message::qaddr_signaling)
     421 */
     422void
     423SignalingNTLP::process_queue()
     424{
     425  uint32 wait = param.sleep_time*1000; // max. waiting time at internal msg queue
     426  message* msg = NULL;
     427
     428  // get queue (param.source is usually message::qaddr_signaling)
     429  FastQueue* fq = QueueManager::instance()->get_queue(param.source);
     430  if (!fq)
     431  {
     432    Log(ERROR_LOG,LOG_ALERT, param.name, "Cannot find input msg queue");
     433
     434    return;
     435  } // end if not fq
     436
     437
     438  /// wait for messages if in state running
     439  while (get_state()==STATE_RUN)
     440  {
     441    // dequeue message from internal message queue
     442    msg= fq->dequeue_timedwait(wait);
     443    if (msg)
     444    {
     445        handleInternalMessage(msg);
    418446    } // end if msg
     447    else handleTimeout();
    419448
    420449    sched_yield();
    421450  } // end while running
    422451} // end process_queue
     452
     453
    423454
    424455
     
    490521    //#define DEBUG_HARD
    491522    //#ifdef DEBUG_HARD
    492     Log(DEBUG_LOG,LOG_NORMAL,param.name,"process_tp_msg() - received PDU (transport: " << tpmsg->get_qaddr_name() << ") now parsing...") ;
     523    DLog(param.name,"process_tp_msg() - received PDU (transport: " << tpmsg->get_qaddr_name() << ") now parsing...") ;
    493524    //#endif
    494525
     
    659690            appladdress* target = result_pdu->get_mri()->determine_dest_address();
    660691            target->set_port(param.well_known_port);
    661             target->set_protocol(prot_query_encap);
    662             target->set_rao(peer->get_rao());
    663            
     692            // if use RAO option
     693            if ( gconf.getpar<bool>(gistconf_send_rao) )
     694            {
     695                    target->set_protocol(prot_query_encap);
     696                    target->set_rao(peer->get_rao());
     697            }
     698            else // send it via UDP
     699            {
     700                    target->set_protocol(prot_udp);
     701            }
     702
    664703                  //decrement IP TTL
    665704                  if (ip_ttl) {
     
    10601099  errorobject* errobj = NULL;
    10611100
    1062   bool qe = peer->get_protocol() == prot_query_encap;
     1101  bool qe = peer->get_protocol() == prot_query_encap || pdu->get_C();
    10631102  bool dgram = qe || (peer->get_protocol() == tsdb::get_udp_id());
    10641103           
     
    11041143     
    11051144      errobj = new errorobject(mr, sid, errorobject::PermanentFailure, errorobject::err_HopLimitExceeded, 0, pdu->get_version(), pdu->get_hops(), pdu->get_length(), pdu->get_nslpid(), pdu->get_type(), pdu->get_flags(), dgram, qe, NULL, 0, max_mtu_size);
     1145      break;
     1146
     1147    case GIST_Error::error_gist_invalid_r_flag:
     1148      if (pdu->get_mri()) mr = pdu->get_mri()->copy();
     1149      if (pdu->get_sessionid()) sid = pdu->get_sessionid()->copy();
     1150     
     1151      errobj = new errorobject(mr, sid, errorobject::ProtocolError, errorobject::err_CommonHeaderParseError, errorobject::errsub_InvalidRFlag, pdu->get_version(), pdu->get_hops(), pdu->get_length(), pdu->get_nslpid(), pdu->get_type(), pdu->get_flags(), dgram, qe, NULL, 0, max_mtu_size);
     1152      break;
     1153
     1154    case GIST_Error::error_gist_invalid_c_flag:
     1155      if (pdu->get_mri()) mr = pdu->get_mri()->copy();
     1156      if (pdu->get_sessionid()) sid = pdu->get_sessionid()->copy();
     1157