00001 // Copyright (C) 2003-2006 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