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

Changeset 4204


Ignore:
Timestamp:
Aug 4, 2009, 5:38:59 PM (8 years ago)
Author:
bless
Message:
  • implemented new NAT traversal logic
  • changed responder cookie to include NLI now if GIST-aware NAT traversal happened
  • changed natinfo class in nat traversal object implementation back to carry transparent data objects
  • code beautifying in ntlp_object.cpp and additional information for parse errors
  • added translated_nli info in routingentry
Location:
ntlp/branches/20081127-merge-mobility-mk3
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • ntlp/branches/20081127-merge-mobility-mk3/src/ntlp_statemodule_responder.cpp

    r4192 r4204  
    9999  r_entry->qrc=new querycookie(*(query_pdu->get_querycookie()));
    100100
    101   // if we have a NAT traversal object, use information from it
    102   // for cookie generation etc. otherwise the cookie cannot be validated
    103   // properly
    104   if (r_entry->nattrav)
    105   {
    106           const nli* nto_nli= r_entry->nattrav->get_nli();
    107           // save a copy of the NLI carried in the NAT Traversal object
    108           if ( nto_nli )
    109           {
    110                 r_entry->nl= new nli( *nto_nli );
    111                 DLog(param.name, "Using NLI from NAT traversal object, i/f address: " << nto_nli->get_if_address());
    112           }
    113   }
    114   else
     101  nli* query_nli= query_pdu->get_nli();
     102  if (query_nli)
    115103  { // use NLI from the PDU
    116           // save NLI
    117           r_entry->nl= new nli(*query_pdu->get_nli());
     104    // save NLI
     105    r_entry->nl= new nli(*query_nli);
     106    // if this Query traversed a GIST-aware NAT we have a translated NLI to save
     107    if (r_entry->nattrav)
     108            r_entry->translated_nli= new nli(*query_nli);
    118109  }
    119110
     
    291282                   
    292283  // save Query Cookie
    293   r_entry->qrc=new querycookie(*(query_pdu->get_querycookie()));
     284  r_entry->qrc= new querycookie(*(query_pdu->get_querycookie()));
    294285                   
    295286  // save newer Stackprop
     
    327318  const respcookie* echoed_resp_cookie= cnfpdu->get_respcookie();
    328319
     320  // we must use the original NLI from the query since the one in Confirm is untranslated
     321 
     322  nli* translated_nli= echoed_resp_cookie ? echoed_resp_cookie->get_nli() : NULL;
     323  // peer_nli is the NLI for responder cookie verification
     324  const nli* peer_nli= translated_nli ? translated_nli : cnfpdu->get_nli();
     325
    329326  bool respcookie_matched= false;
    330327  // evaluate Responder Cookie in CONFIRM
    331   if (echoed_resp_cookie && (respcookie_matched= evaluate_resp_cookie(cnfpdu->get_nli(), r_key, echoed_resp_cookie)) == false)
     328  if (echoed_resp_cookie && (respcookie_matched= evaluate_resp_cookie(peer_nli, r_key, echoed_resp_cookie)) == false)
    332329  {
    333330    WLog(param.name, "Responder Cookie did not match, discarding GIST Confirm");
     
    342339  else
    343340  {
    344     if (echoed_resp_cookie)
    345     {
    346       DLog(param.name, "Responder Cookie matched, processing GIST Confirm");
    347 
    348       if (echoed_resp_cookie->get_if_index() != r_entry->get_incoming_if())
    349       {
    350         ILog(param.name, "Responder Cookie indicated that Query used a different interface: old idx="
    351              << r_entry->get_incoming_if() << " new idx=" << echoed_resp_cookie->get_if_index());
    352       }
    353     }
    354 
    355     // For C-Mode first we must check what is required by us, i.e.
    356     // if we require security we have only secure protocols in the proposal
    357     // we must check with the peers policy though
     341          if (echoed_resp_cookie)
     342          {
     343                  DLog(param.name, "Responder Cookie matched, processing GIST Confirm");
     344                 
     345                  if (echoed_resp_cookie->get_if_index() != r_entry->get_incoming_if())
     346                  {
     347                          ILog(param.name, "Responder Cookie indicated that Query used a different interface: old idx="
     348                               << r_entry->get_incoming_if() << " new idx=" << echoed_resp_cookie->get_if_index());
     349                  }
     350          }
     351 
     352
     353          if (translated_nli && r_entry->translated_nli && (*translated_nli != *(r_entry->translated_nli)))
     354          {
     355                  WLog(param.name,"Translated NLI differs between initial query and routing state entry");
     356          }
     357          delete translated_nli;
     358         
     359          // For C-Mode first we must check what is required by us, i.e.
     360          // if we require security we have only secure protocols in the proposal
     361          // we must check with the peers policy though
    358362    if (echoed_resp_proposal)
    359363    {
     
    537541
    538542  // MUST CHECK with different NLI and r_key if NTO is present...
     543  nli* translated_nli= responder_cookie->get_nli();
     544  nli* peer_nli= translated_nli ? translated_nli : cnfpdu->get_nli();
     545
    539546  // evaluate Responder Cookie in CONFIRM
    540   bool rsp_cookie_matched = evaluate_resp_cookie(cnfpdu->get_nli(), r_key, responder_cookie);
     547  bool rsp_cookie_matched = evaluate_resp_cookie(peer_nli, r_key, responder_cookie);
    541548
    542549  // is Responder Cookie valid?
     
    570577  }
    571578  r_entry->set_local_src(*src->copy());
     579
     580  if (translated_nli)
     581  {       // please note that translated_nli will be freed by rentry destructor
     582          r_entry->translated_nli= peer_nli;
     583  }
    572584
    573585  bool ma_reuse= false;
     
    634646  if (responder_cookie->get_transparent_data())
    635647  {
    636           uint32 bytes_read= 0;
    637           IEErrorList errorlist;
    638           nattraversal* nat_trav_obj= new nattraversal;
    639           NetMsg* tmpbuf= new NetMsg(responder_cookie->get_transparent_data(),
    640                                      responder_cookie->get_transparent_data_len(),
    641                                      false);
    642           nat_trav_obj->deserialize(*tmpbuf, IE::protocol_v1, errorlist, bytes_read, false);
    643           if (errorlist.is_empty() == false)
    644           {
    645                   ERRLog(param.name,"parse error while getting NTO from responder cookie - this is an implementation error");
    646           }
    647           else
    648           {
    649                   // save the nat traversal object
    650                   r_entry->nattrav= nat_trav_obj;
    651           }
    652           delete tmpbuf;
     648          r_entry->nattrav= responder_cookie->get_nto(peer_nli->get_serialized_size(IE::protocol_v1));
    653649  }
    654650
     
    11531149  // use the saved nli (in latestate case, we would not repeat but have a PDU)
    11541150  // this is ususally the case only when we have stored state and no_confirm timer went off
     1151  // note that in case of gist aware-NAT traversal an initial query carries the translated NLI (external addr)
     1152  // and further refreshing queries carry untranslated addresses (local/internal addr)
    11551153  nli* qnli= pdu ? pdu->get_nli() : r_entry->nl;
    11561154
    1157   // override in case of NAT traversal, use info from NAT traversal object
    1158   if (r_entry->nattrav)
    1159           qnli= r_entry->nl;
    11601155  if (qnli)
    11611156  {
     
    12361231  nattraversal* nto = dynamic_cast<nattraversal*>(r_entry->nattrav);
    12371232  NetMsg* ntobuf_p= NULL;
    1238   // put NTO as transparent data into hash if present
     1233  // put NLI and NTO as transparent data into hash if present
    12391234  if (nto)
    12401235  {
    1241           uint32 ntobuf_size= nto->get_serialized_size(IE::protocol_v1);
     1236          if (!qnli)
     1237                  ERRLog(param.name,"Querier NLI not present when trying to insert it into NAT traversal object");
     1238
     1239          // put NLI first, because we need it for validation
     1240          uint32 ntobuf_size= qnli->get_serialized_size(IE::protocol_v1) + nto->get_serialized_size(IE::protocol_v1);
    12421241          ntobuf_p= new NetMsg(ntobuf_size);
    12431242          // should be serialized including the common object header
    12441243          uint32 written= 0;
     1244          // write NLI first
     1245          qnli->serialize(*ntobuf_p, IE::protocol_v1, written);
     1246          // write NTO as second object
    12451247          nto->serialize(*ntobuf_p, IE::protocol_v1, written);
    12461248  }
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/nattraversal.cpp

    r4147 r4204  
    4747 */
    4848
    49 void
    50 natinfo::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 
    59 natinfo::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 
    69 natinfo&
    70 natinfo::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 
    82 bool
    83 natinfo::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 
    99 uint16
    100 natinfo::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 
    113 const nli*
    114 natinfo::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 }
    12649
    12750
     
    244167        tmp= msg.decode16();
    245168
    246 
    247     // read NLI infos
    248    
    249     natinfo nat_info_temp;
    250 
    251     // iterate over profile_count to read whole NAT information
     169    // read opaque NAT infos
     170    // iterate over NAT count to read all NAT information objects
    252171    for (i=0; i<nat_count; i++) {
    253         nat_info_temp.clear();
    254 
    255172        // read length of total opaque information fields of NAT i:
    256173        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
     174
     175        // allocate new NetMsg buffer and don't copy contents!
     176        NetMsg* netmsgbuf= new NetMsg(msg.get_buffer()+msg.get_pos(), len, false);
     177        // move forward within the message
     178        msg.set_pos_r(len);
     179
     180        natinfo nat_info_temp;
     181        nat_info_temp.set(netmsgbuf);
     182
     183        // this will actually create a copy of the natinfo netmsg buffer
     184        push_natinfo(nat_info_temp);
    305185
    306186        // handle padding, initial length field of NAT info is 16-bit
     
    311191                padbytes--;
    312192        }
    313        
    314         push_natinfo(nat_info_temp);
    315193    } // end for iterating over NAT info objects
    316194
     
    331209// special serialization function with the ability to omit the TLV header
    332210void nattraversal::serializeEXT(NetMsg& msg, coding_t cod, uint32& wbytes, bool header) const {
    333         const char *const methodname= "nattraversal::serialize()";
    334 
    335         uint32 nto_length = get_serialized_size(cod) - (header ? 0 : header_length); // includes object header
     211    const char *const methodname= "nattraversal::serialize()";
     212
     213    // get_serialized_size includes object header
     214    uint32 nto_length = get_serialized_size(cod) - (header ? 0 : header_length);
     215
    336216    DLog(methodname,"should be of length " << nto_length);
    337217    // check arguments and IE state
     
    341221    if (header)
    342222    {
    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");
     223            encode_header_ntlpv1(msg, nto_length - header_length); // length should exclude the header
     224            DLog(methodname, "Common Object header encoded (objlen=" << nto_length - header_length << " bytes), 4 bytes, bytes left in NetMsg: " << msg.get_bytes_left());
     225    }
     226    DLog(methodname, "Begin of object content serialization");
    347227       
    348228    // encode mri length (get_serialized_size currently returns byte size INCLUDING TLV header, we must subtract 1 word = 4 byte)
     
    398278            msg.encode16(info_len);
    399279           
    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 
     280            if (nat_information[i].get())
     281            {
     282                    msg.copy_from(nat_information[i].get()->get_buffer(), msg.get_pos(), info_len);
     283                    msg.set_pos_r(info_len);
     284            }
    423285            // must pad two length bytes + NAT info part to a 32-bit boundary
    424286            uint8 padbytes= (2 + info_len) % 4;
     
    469331            // length info for all translated info of NAT #i
    470332            size+= 16;
    471             uint16 natinfosize= 0;
    472333            // 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             }
     334            // the length of opaque information and the padding to a 32bit alignment
     335            uint16 natinfosize= nat_information[i].length();
     336            size+= natinfosize * 8;
     337            //DLog("nattraversal::get_serialized_size()","nat info objects size " << natinfosize << " bytes");
     338
    479339            // add padding if necessary
    480340            // starting from length field, padding up to the next 32-bit boundary
     
    520380                //DLog("nattraversal::operator==","No of NAT info ok.");
    521381
    522                 const known_ntlp_object* ni1;
    523                 const known_ntlp_object* ni2;
    524 
    525382                for (uint32 i=0; i<nat_information.size(); i++) {
    526383                        // translated objects of NAT#i
    527                         if (nat_information[i].size() != nto->nat_information[i].size())
     384                        if (nat_information[i].length() != nto->nat_information[i].length())
    528385                                return false;
    529386
    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
     387                        // size of both buffers is equal due to precondition
     388                        if (memcmp(nat_information[i].get()->get_buffer(), nto->nat_information[i].get()->get_buffer(),nat_information[i].length()))
     389                                return false;
    538390                } // end for NAT info #i
    539391
     
    551403    if (name && (*name!=0)) os<<name<< endl;
    552404
    553     uint j=0;
    554405    uint i=0;
    555406       
     
    574425    }
    575426    os << endl;
    576    
     427
    577428    // 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);
    582             }
    583             os << endl;
     429    for (i=0; i<nat_information.size(); i++) {     
     430            os << *(nat_information[i].get()) << endl;
    584431    }
    585432   
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/nattraversal.h

    r4147 r4204  
    4646
    4747/**
    48  * list of translated NTLP objects / information per NAT
     48 * list of translated NTLP objects / information per NAT,
     49 * this information is opaque and specific per NAT
    4950 **/
    5051class natinfo {
    5152 public:
    5253        /// constructor
    53         natinfo() {};
     54        natinfo() : netmsgbuf(NULL) {};
     55
    5456        /// copy constructor
    55         natinfo(const natinfo& nat_info);
     57        natinfo(const natinfo& nat_info) {
     58                netmsgbuf= nat_info.get() ? new NetMsg(*nat_info.get()) : NULL;
     59        }
     60
    5661        /// destructor
    5762        ~natinfo() { clear(); }
    5863
    5964        // 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;
     65        natinfo& operator=(const natinfo& nat_info) {
     66                if (netmsgbuf) { delete netmsgbuf; }
     67                netmsgbuf= nat_info.get() ? new NetMsg(*nat_info.get()) : NULL;
     68                return *this;
     69        }
     70
     71        bool operator==(const natinfo& ni) const {
     72                if (netmsgbuf==NULL && ni.get()==NULL)
     73                        return true;
     74                else
     75                if (netmsgbuf!=NULL && ni.get()!=NULL)
     76                        return *netmsgbuf == *(ni.get());
     77                else
     78                        return false;
     79        }
     80
     81        /// add a copy of the translated NAT information
     82        void set(const NetMsg& givennetmsgbuf) {
     83                if (netmsgbuf) { delete netmsgbuf; }
     84                netmsgbuf= new NetMsg(givennetmsgbuf);
     85        }
     86
     87        /// add the netmsg as translated NAT information (object will be taken over!)
     88        void set(NetMsg* givennetmsgbuf) {
     89                if (netmsgbuf) { delete netmsgbuf; }
     90                netmsgbuf= givennetmsgbuf;
     91        }
     92       
     93        /// get opaque NAT info back (as NetMsg buffer)
     94        const NetMsg* get() const { return netmsgbuf; }
     95
     96        /// remove all contents
     97        void clear() { delete netmsgbuf; }
     98
     99        uint16 length() const { return netmsgbuf ? netmsgbuf->get_size() : 0; }
    82100
    83101private:
    84         typedef std::vector<known_ntlp_object *> translated_object_list_t;
    85 
    86         translated_object_list_t translated_object_list;
    87 
     102        NetMsg* netmsgbuf;
    88103};
    89104
     
    155170
    156171        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         }
    163 
    164172
    165173 private:
    166174        typedef std::vector<natinfo> nat_information_t;
    167175
    168         // the vector holding NLI information (one information object per traversed NAT)
     176        // the vector holding NAT specific opaque information
     177        // (one information object per traversed NAT)
    169178        nat_information_t nat_information;
    170179       
     
    210219        // This is the one mighty constructor, via which the object SHOULD be built programmatically!
    211220        inline
    212         nattraversal (const mri* mr, std::vector <natinfo> nat_information, std::vector <uint16> translated_object_types):
     221        nattraversal (const mri* mr, nat_information_t nat_information, std::vector <uint16> translated_object_types):
    213222                known_ntlp_object(NatTraversal, Mandatory),
    214223                nat_information(nat_information),
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/ntlp_object.cpp

    r4147 r4204  
    154154        if (bytes_left<header_length) {
    155155                catch_bad_alloc(iee = new IEMsgTooShort(protocol_v1,category,saved_pos));
    156                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << " , category " << category << ", position " << saved_pos);
     156                ERRLog("NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << " , category " << category << ", position " << saved_pos << ", bytes left=" << bytes_left << " required:" << header_length);
    157157                errorlist.put(iee);
    158158                msg.set_pos(saved_pos);
     
    164164        } catch(IEError& ignored) {
    165165                catch_bad_alloc(iee = new IETooBigForImpl(protocol_v1,category,saved_pos));
    166                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << " , category " << category << ", position " << saved_pos);
     166                ERRLog("NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << " , category " << category << ", position " << saved_pos);
    167167                errorlist.put(iee);
    168168                msg.set_pos(saved_pos);
     
    172172        if (bytes_left<ielen) {
    173173                catch_bad_alloc(iee = new IEMsgTooShort(protocol_v1,category,saved_pos));
    174                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << " , category " << category << ", position " << saved_pos);
     174                ERRLog("NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << " , category " << category << ", position " << saved_pos << ", required: " << ielen << " bytes, available: " << bytes_left << " bytes");
    175175                errorlist.put(iee);
    176176                msg.set_pos(saved_pos);
     
    184184        if (t!=type) {
    185185                catch_bad_alloc(iee = new IEWrongType(protocol_v1,category,saved_pos));
    186                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << ", " << t << (skip ?  ", skipping IE." : "."));
     186                ERRLog("NTLP_object", "known_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << protocol_v1 << ", " << t << (skip ?  ", skipping IE." : "."));
    187187                if (skip) {
    188188                  bread = ielen;
     
    225225  {
    226226    IEWrongLength err(protocol_v1,category,type,255,msg.get_pos());
    227     Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::encode_header_ntlpv1(): IE " << get_ie_name()
     227    ERRLog("NTLP_object", "known_ntlp_object::encode_header_ntlpv1(): IE " << get_ie_name()
    228228        << ", error " << err.getstr() << ", length " << len << ", object is not aligned to 32-bit word boundary");
    229229    throw err;
     
    234234  {
    235235    IEMsgTooShort err(protocol_v1,category,msg.get_pos());
    236     Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "known_ntlp_object::encode_header_ntlpv1(): IE " << get_ie_name()
     236    ERRLog("NTLP_object", "known_ntlp_object::encode_header_ntlpv1(): IE " << get_ie_name()
    237237        << ", error " << err.getstr() << ", required: " << objlen << " bytes, available: " << msg.get_bytes_left() << " bytes");
    238238    throw err;
     
    280280        IEError* iee = NULL;
    281281        catch_bad_alloc(iee = new IEWrongLength(cod,category,type,255,msgpos));
    282         Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", get_ie_name() << "::deserialize(): error, " << iee->getstr() << ", coding " << cod << ", type " << (int)type << ", wrong_length " << len << ", position " << msgpos << (skip ? ", skipping IE." : "." ));
     282        ERRLog("NTLP_object", get_ie_name() << "::deserialize(): error, " << iee->getstr() << ", coding " << cod << ", type " << (int)type << ", wrong_length " << len << ", position " << msgpos << (skip ? ", skipping IE." : "." ));
    283283        elist.put(iee);
    284284        msg.set_pos(resume);
     
    337337        if (bytes_left<header_length) {
    338338                catch_bad_alloc(iee = new IEMsgTooShort(cod,category,saved_pos));
    339                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "raw_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << cod << ", category " << category << ", position " << saved_pos);
     339                ERRLog("NTLP_object", "raw_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << cod << ", category " << category << ", position " << saved_pos);
    340340                errorlist.put(iee);
    341341                return NULL;
     
    346346        } catch(IEError& ignored) {
    347347                catch_bad_alloc(iee = new IETooBigForImpl(cod,category,saved_pos));
    348                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "raw_ntlp_object::deserialize: error " << iee->getstr() << ", coding " << cod << ", category " << category << ", position " << saved_pos);
     348                ERRLog("NTLP_object", "raw_ntlp_object::deserialize: error " << iee->getstr() << ", coding " << cod << ", category " << category << ", position " << saved_pos);
    349349                errorlist.put(iee);
    350350                msg.set_pos(saved_pos);
     
    356356        if (bytes_left<ielen) {
    357357                catch_bad_alloc(iee = new IEMsgTooShort(cod,category,saved_pos));
    358                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "raw_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << cod << ", category " << category << ", position " << saved_pos);
     358                ERRLog("NTLP_object", "raw_ntlp_object::decode_header_ntlpv1: IE " << get_ie_name() << ", error " << iee->getstr() << ", coding " << cod << ", category " << category << ", position " << saved_pos);
    359359                errorlist.put(iee);
    360360                return NULL;
     
    369369                return this;
    370370        } else {
    371           Log(ERROR_LOG,LOG_CRIT, "NTLP_object", "raw_ntlp_object::deserialize: Unable to allocate content buffer");
     371          ERRCLog("NTLP_object", "raw_ntlp_object::deserialize: Unable to allocate content buffer");
    372372          throw IEError(IEError::ERROR_NO_MEM);
    373373          return NULL;
     
    395395        if (coding!=cod) {
    396396                IEError err(IEError::ERROR_CODING);
    397                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "raw_ntlp_object::serialize(), error " << err.getstr() << ", coding " << cod);
     397                ERRLog("NTLP_object", "raw_ntlp_object::serialize(), error " << err.getstr() << ", coding " << cod);
    398398                throw err;
    399399        } // end if coding
     
    401401        if (msg.get_bytes_left()<buflen) {
    402402                IEMsgTooShort err(cod,category,msg.get_pos());
    403                 Log(ERROR_LOG,LOG_NORMAL, "NTLP_object", "raw_ntlp_object::serialize(), error " << err.getstr() << " Required additional " << buflen);
     403                ERRLog("NTLP_object", "raw_ntlp_object::serialize(), error " << err.getstr() << " Required additional " << buflen);
    404404                throw err;
    405405        } // end if not enough memory
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/resp_cookie.cpp

    r4147 r4204  
    249249
    250250
     251nli*
     252respcookie::get_nli() const
     253{
     254  uint16 transparent_data_len= get_transparent_data_len();
     255  uchar* transparent_data= get_transparent_data();
     256
     257  // first extract the NLI from transparent data if present 
     258  if (transparent_data)
     259  {
     260          // perform a sanity check first (transparent data len must be smaller than resp cookie length)
     261          // if someone messed with the length value in transparent data
     262          if (transparent_data_len < buf_length)
     263          {
     264                  uint32 bytes_read= 0;
     265                  IEErrorList errorlist;
     266                  // data is not copied into NetMsg buffer
     267                  NetMsg tmpbuf(transparent_data, transparent_data_len, false);
     268                  nli* nli_obj= new nli;
     269                  nli_obj->deserialize(tmpbuf, IE::protocol_v1, errorlist, bytes_read, false);
     270                  if (errorlist.is_empty() == false)
     271                  { // parse error
     272                          ERRLog("respcookie::get_nli()","parse error while getting NLI from responder cookie - this is an implementation error or some attacker messed with it");
     273                          return NULL;
     274                  }
     275                  else // parsing successful
     276                          return nli_obj;
     277          }
     278  }
     279
     280  return NULL;
     281}
     282
     283
     284nattraversal*
     285respcookie::get_nto(uint16 byteoffset) const
     286{
     287  uint16 transparent_data_len= get_transparent_data_len();
     288  uchar* transparent_data= get_transparent_data();
     289
     290  if (transparent_data && byteoffset < transparent_data_len)
     291  {
     292          uint32 bytes_read= 0;
     293          IEErrorList errorlist;
     294          nattraversal* nat_trav_obj= new nattraversal;
     295          NetMsg tmpbuf(transparent_data+byteoffset, transparent_data_len-byteoffset, false);
     296          nat_trav_obj->deserialize(tmpbuf, IE::protocol_v1, errorlist, bytes_read, false);
     297          if (errorlist.is_empty() == false)
     298          {
     299                  ERRLog("respcookie::get_nto()","parse error while getting NTO from responder cookie - this is an implementation error");
     300                  return NULL;
     301          }
     302          else
     303          {
     304                  return nat_trav_obj;
     305          }
     306  }
     307  return NULL;
     308}
     309
    251310//@}
    252311
  • ntlp/branches/20081127-merge-mobility-mk3/src/pdu/resp_cookie.h

    r4147 r4204  
    2727//
    2828// ===========================================================
     29#ifndef _NTLP__RESPCOOKIE_H_
     30#define _NTLP__RESPCOOKIE_H_
     31
    2932#include "ntlp_object.h"
    3033#include "address.h"
    3134#include "protlib_types.h"
    3235
     36#include "nli.h"
     37#include "nattraversal.h"
    3338
    34 #ifndef _NTLP__RESPCOOKIE_H_
    35 #define _NTLP__RESPCOOKIE_H_
    3639
    3740
     
    6669
    6770  // 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; }
     71  uint16 get_transparent_data_len() const { return (buf && buf_length>=8) ? ntohs(*(reinterpret_cast<uint16*>(buf+sizeof(uint32)+sizeof(uint16)))) : 0; }
    6972
    7073  // return start of the transparent data part or 0 if not present
     
    144147  virtual ~respcookie() { delete buf; }
    145148
     149  nli*  get_nli() const;
     150  nattraversal* get_nto(uint16 byteoffset) const;
    146151
    147152};
  • ntlp/branches/20081127-merge-mobility-mk3/src/routingtable.h

    r4147 r4204  
    266266  {
    267267    if (nattrav) delete nattrav;
     268    if (translated_nli) delete translated_nli;
    268269    if (nl) delete nl;
    269270    if (qrc) delete qrc;
     
    280281    dataqueue.clear();
    281282    if (n.nattrav) nattrav=n.nattrav->copy(); else nattrav = NULL;
     283    if (n.translated_nli) translated_nli=n.translated_nli->copy(); else translated_nli= NULL;
    282284    dmode=n.dmode;
    283285    secure=n.secure;
     
    354356  /// saved NAT Traversal object
    355357  nattraversal* nattrav;
     358  ///
     359  nli* translated_nli;
    356360 
    357361  /// role of the node
     
    682686routingentry::routingentry(bool is_responder) :
    683687    nattrav(NULL),
     688    translated_nli(NULL),
    684689    is_responder(is_responder),
    685690    dmode(true),
  • ntlp/branches/20081127-merge-mobility-mk3/test/responder_cookie.cpp

    r4182 r4204  
    164164        void test_resp_cookie() {
    165165                // test if we have a saved nat traversal object (NTO)
     166                NetMsg opaque_natinfobuf(localnliv4.get_serialized_size(IE::protocol_v1));
     167                uint32 written= 0;
     168                localnliv4.serialize(opaque_natinfobuf, IE::protocol_v1, written);
    166169                natinfo nat_info;
    167                 nat_info.add(localnliv4);
     170                nat_info.set(opaque_natinfobuf);
    168171
    169172                std::vector<natinfo> txlated_information;
     
    184187                ntobuf_p= new NetMsg(ntobuf_size);
    185188                // should be serialized including the common object header
    186                 uint32 written= 0;
     189                written= 0;
    187190                nto.serialize(*ntobuf_p, IE::protocol_v1, written);
    188191                // object should be completely written into buffer
  • ntlp/branches/20081127-merge-mobility-mk3/test/test_nattraversal.cpp

    r4147 r4204  
    7474
    7575          natinfo info;
    76           info.add(localnliv4);
     76          string opaque_natinfo="Hello World!"; // 12 bytes
     77          // only ref
     78          NetMsg opaque_natinfo_buf(opaque_natinfo.length());
     79          opaque_natinfo_buf.copy_from(reinterpret_cast<const uchar*>(opaque_natinfo.c_str()), opaque_natinfo.length());
     80
     81          info.set(opaque_natinfo_buf);
     82
     83          // this push will actually copy the NetMsg buffer
    7784          nto->push_natinfo(info);
    7885
     
    137144               
    138145          natinfo info;
    139           info.add(localnliv4);
     146          string opaque_natinfo="Hello World!"; // 12 bytes will require padding of 2 bytes
     147          // only ref
     148          NetMsg opaque_natinfo_buf(opaque_natinfo.length());
     149          opaque_natinfo_buf.copy_from(reinterpret_cast<const uchar*>(opaque_natinfo.c_str()), opaque_natinfo.length());
     150          info.set(opaque_natinfo_buf);
     151          // append a copy of the natinfo object to the list
     152          nto->push_natinfo(info);
     153
     154          string opaque_natinfo2="Second Hello World!!"; // 21 bytes, will require padding of 1 byte
     155          NetMsg opaque_natinfo_buf2(opaque_natinfo2.length());
     156          opaque_natinfo_buf2.copy_from(reinterpret_cast<const uchar*>(opaque_natinfo2.c_str()), opaque_natinfo2.length());
     157          info.set(opaque_natinfo_buf2);
     158          // append a copy of the natinfo object to the list
    140159          nto->push_natinfo(info);
    141160
Note: See TracChangeset for help on using the changeset viewer.