Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

msg/mid.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003, 2004, 2005 Laboratoire de Recherche en Informatique
00002 
00003 // This file is part of Qolyester.
00004 
00005 // Qolyester is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 // Qolyester is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 
00019 #ifndef QOLYESTER_DAEMON_MSG_MID_HXX
00020 # define QOLYESTER_DAEMON_MSG_MID_HXX 1
00021 
00022 # include "set/interfaces.hh"
00023 # include "set/mid.hh"
00024 # include "set/neighbors.hh"
00025 # include "utl/args.hh"
00026 
00027 # include "mid.hh"
00028 
00029 namespace olsr {
00030 
00031   extern ifaceset_t     iface_set;
00032   extern midset_t       mid_set;
00033   extern cproxy_t       cproxy;
00034   extern std::ostream   dump_mid;
00035 
00036   namespace msg {
00037 
00038     MIDMessage::MIDMessage() : _data() {}
00039 
00040     MIDMessage::MIDMessage(const utl::Data& d, const address_t&) : _data(d) {}
00041 
00042     bool
00043     MIDMessage::dump(utl::Data& d, const address_t& interface) const {
00044       bool      ret = false;
00045 
00046       if (_data.empty()) { // generate a MID message
00047 
00048 //      assert(!iface_set.empty());
00049 
00050         if (d.size() < Message::min_length + min_length)
00051           return true; // try again immediately
00052 
00053         if (do_dump_mid)
00054           dump_mid << "MID preparation (" << interface << ") "
00055                    << Message::seqnum << " {\n";
00056 
00057         Message::raw*   mraw = reinterpret_cast<Message::raw*>(d.raw());
00058 
00059         d += sizeof *mraw;
00060 
00061         mraw->type     = MID_MESSAGE;
00062         mraw->vtime    = utl::Vtime(cst::mid_hold_time);
00063         mraw->size     = 0; // set later
00064         main_addr.dump(mraw->addr);
00065         mraw->ttl      = 255;
00066         mraw->hopcount = 0;
00067         mraw->seqnum   = htons(Message::seqnum);
00068 
00069         typedef std::list<ifaceset_t::mid_iset_t::iterator>     ipset_t;
00070         ipset_t                 ip_set;
00071 
00072         for (ifaceset_t::mid_iset_t::iterator i =
00073                iface_set.mid_iset().begin(interface);
00074              i != iface_set.mid_iset().end(interface); ++i) {
00075 
00076           if (iface_set.mid_iset().stamp(i) == timeval_t::now())
00077             break;
00078 
00079           if (i->addr() == main_addr)
00080             continue;
00081 
00082           if (d.size() < ADDRESS_SIZE) {
00083             if (iface_set.mid_iset().expired(i,
00084                                              cst::mid_interval,
00085                                              timeval_t::in(cst::mid_interval)))
00086               ret = true;
00087             break;
00088           }
00089 
00090           if (do_dump_mid)
00091             dump_mid << "  " << i->addr() << "\n";
00092 
00093           i->addr().dump(d.raw());
00094           ip_set.push_back(i);
00095           d += ADDRESS_SIZE;
00096         }
00097 
00098         mraw->size = htons(d.raw() - reinterpret_cast<u_int8_t*>(mraw));
00099 
00100         if (do_dump_mid)
00101           dump_mid << "}" << std::endl;
00102 
00103         for (ipset_t::const_iterator i = ip_set.begin();
00104              i != ip_set.end(); ++i)
00105           iface_set.mid_iset().set_stamp(*i);
00106 
00107       } else {
00108         if (d.size() < _data.size())
00109           return true;
00110 
00111         _data.dump(d);
00112         d += _data.size();
00113       }
00114 
00115       return ret;
00116     }
00117 
00118     void
00119     MIDMessage::parse(const utl::ConstData& d, const Message::header& mh) {
00120       if (do_dump_mid)
00121         dump_mid << "MID from " << mh.originator
00122                  << " (" << mh.sender << " -> " << mh.receiver << ") M("
00123                  << mh.mseqnum << ") P(" << mh.pseqnum << ") {\n";
00124 
00125       // The following is the check that the message comes from a
00126       // symmetric neighbor.  We check against links and neighbors,
00127       // since we don't know the iface addr <-> main addr association
00128       // yet.
00129       cproxy_t::linkset_t::iterator     l =
00130         cproxy.linkset().find(set::Link::make_key(mh.receiver, mh.sender));
00131 
00132       if (l == cproxy.linkset().end() || !l->is_sym()) {
00133 
00134         if (do_dump_mid)
00135           dump_mid << "  (ignored since not from symmetric neighbor)\n}"
00136                    << std::endl;
00137         return;
00138       }
00139 
00140       const u_int8_t    (*addrs)[ADDRESS_SIZE] =
00141         reinterpret_cast<const u_int8_t (*)[ADDRESS_SIZE]>(d.raw());
00142       unsigned  len = d.size() / ADDRESS_SIZE;
00143 
00144       for (unsigned i = 0; i < len; ++i) {
00145         address_t       addr(addrs[i], ADDRESS_SIZE);
00146 
00147         if (do_dump_mid)
00148           dump_mid << "  " << addr << "\n";
00149 
00150         mid_set.insert(set::MIDEntry(addr, mh.originator, mh.validity));
00151       }
00152 
00153       if (do_dump_mid)
00154         dump_mid << "}" << std::endl;
00155     }
00156 
00157   } // namespace msg
00158 
00159 } // namespace olsr
00160 
00161 #endif // ! QOLYESTER_DAEMON_MSG_MID_HXX

Generated on Thu Jul 28 21:21:47 2005 for Qolyester daemon by  doxygen 1.4.1