interfaces.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003, 2004, 2005, 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_SET_INTERFACES_HXX
00020 # define QOLYESTER_DAEMON_SET_INTERFACES_HXX 1
00021 
00022 # include <map>
00023 # include <cassert>
00024 
00025 # include "config.hh"
00026 
00027 # include "pkt/packet.hh"
00028 # include "sch/events.hh"
00029 # include "sch/scheduler.hh"
00030 # include "set/gate.hh"
00031 # include "utl/comparator.hh"
00032 
00033 # include "interfaces.hh"
00034 
00035 namespace olsr {
00036 
00037   extern address_t      main_addr;
00038   extern gateset_t      gate_set;
00039   extern cproxy_t       cproxy;
00040   extern sched_t        scheduler;
00041   extern ifaceset_t     iface_set;
00042 
00043   namespace set {
00044 
00045     InterfaceSet::InterfaceSet()
00046       : _iset(),
00047         _mid_iset(_iset),
00048         _min_mtu(0)
00049     {}
00050 
00051     InterfaceSet::iterator
00052     InterfaceSet::begin() const {
00053       return _iset.begin();
00054     }
00055 
00056     InterfaceSet::iterator
00057     InterfaceSet::end() const {
00058       return _iset.end();
00059     }
00060 
00061     bool
00062     InterfaceSet::empty() const {
00063       return _iset.empty();
00064     }
00065 
00066     size_t
00067     InterfaceSet::size() const {
00068       return _iset.size();
00069     }
00070 
00071     const iface_t&
00072     InterfaceSet::operator[](const address_t& iaddr) const {
00073       const_iterator    i = find(iaddr);
00074       assert(i != end());
00075       return *i;
00076     }
00077 
00078     std::pair<InterfaceSet::iterator, bool>
00079     InterfaceSet::insert(const iset_t::value_type& x) {
00080       if (main_addr == address_t())
00081         main_addr = x.addr();
00082       if (_iset.find(x) == _iset.end())
00083         _mid_iset.add_key(x.addr());
00084       std::pair<iset_t::iterator, bool> p = _iset.insert(x);
00085       if (p.second) {
00086         _mid_iset.insert(p.first);
00087         if (_min_mtu == 0 || x.mtu() < _min_mtu)
00088           _min_mtu = x.mtu();
00089         cproxy.add_interface(x.addr());
00090         gate_set.hna_gset().add_key(x.addr());
00091         scheduler.insert(new sch::PacketReceiver(const_cast<iface_t*>(&*p.first)));
00092       }
00093 //       const_cast<iset_t::value_type&>(x).configure();
00094       return p;
00095     }
00096 
00097     void
00098     InterfaceSet::erase(iterator pos) {
00099       assert(pos != end());
00100 //       const_cast<iset_t::value_type&>(*pos).unconfigure();
00101       const_cast<iface_t&>(*pos).destroy_all_events();
00102       gate_set.hna_gset().remove_key(pos->addr());
00103       cproxy.remove_interface(pos->addr());
00104       if (pos->addr() == main_addr)
00105         main_addr = address_t();
00106       _mid_iset.remove_key(pos->addr());
00107       _mid_iset.erase(pos);
00108       _iset.erase(pos);
00109       _min_mtu = 0;
00110       for (iset_t::iterator i = _iset.begin(); i != _iset.end(); ++i)
00111         if (_min_mtu == 0 || i->mtu() < _min_mtu)
00112           _min_mtu = i->mtu();
00113       if (main_addr == address_t() && !_iset.empty())
00114         main_addr = _iset.begin()->addr();
00115     }
00116 
00117     InterfaceSet::iterator
00118     InterfaceSet::find(const address_t& iaddr) const {
00119       return _iset.find(iface_t::make_key(iaddr));
00120     }
00121 
00122     void
00123     InterfaceSet::send_messages() {
00124 
00125       assert(iface_set.empty() || min_mtu() > 0);
00126 
00127       // FIXME: this should not be that way, we should remove pending
00128       // messages if there are no current interfaces.
00129       if (iface_set.empty()) {
00130         pending_messages.clear();
00131         return;
00132       }
00133 
00134       while (!pending_messages.empty()) {
00135 
00136         typedef std::map<iface_t*,
00137                          pkt::Packet,
00138                          utl::pless<iface_t> >  packets_t;
00139 
00140         packets_t       packets;
00141 
00142         // Create a packet for each interface.
00143         for (iset_t::iterator i = _iset.begin(); i != _iset.end(); ++i)
00144           packets.insert(packets_t::value_type(const_cast<iface_t*>(&*i),
00145                                                pkt::Packet(_min_mtu,
00146                                                            i->addr())));
00147 
00148         // Add each message in all the packets.
00149         for (pending_t::iterator m = pending_messages.begin();
00150              m != pending_messages.end(); /* ++m elsewhere */) {
00151           // Add the message to the first packet.
00152           bool  resend = packets.begin()->second.add_message(**m);
00153 
00154           // Add the message to the remaining packets and check that
00155           // it fits the same way.
00156 
00157           // FIXME: this should be avoided, since the packets should
00158           // be identical on every interface for we always broadcast
00159           // messages on all interfaces.
00160           for (packets_t::iterator i = ++packets.begin();
00161                i != packets.end(); ++i) {
00162 # ifndef NDEBUG
00163             bool        resend_this = i->second.add_message(**m);
00164             assert(resend_this == resend);
00165 # else // !NDEBUG
00166             i->second.add_message(**m);
00167 # endif
00168           }
00169 
00170           // Increment the message sequence number.
00171           const_cast<msg::Message*>(*m)->inc_seqnum();
00172 
00173           // Destroy the message if it is not to be resent.
00174           if (!resend) {
00175             pending_t::iterator tmp = m++;
00176             const msg::Message* mptr = *tmp;
00177             pending_messages.erase(tmp);
00178             delete mptr;
00179           }
00180         }
00181 
00182         // Now send the packets.
00183         for (packets_t::iterator i = packets.begin();
00184              i != packets.end(); ++i) {
00185           i->second.close(i->first->addr());
00186           if (i->second.size() > pkt::Packet::min_length)
00187             i->first->shipout(i->second);
00188         }
00189       }
00190     }
00191 
00192 //       for (iset_t::iterator i = iface_set._iset.begin();
00193 //         i != iface_set._iset.end(); ++i) {
00194 //      pending_t       local_pm = pending_messages;
00195 
00196 //      while (!local_pm.empty()) {
00197 //        pkt::Packet   p(min_mtu(), i->addr());
00198 
00199 //        p.fill(local_pm);
00200 
00201 //        if (p.size() > pkt::Packet::min_length) {
00202 //          i->send(p);
00203 //        }
00204 //      }
00205 //       }
00206 //       for (pending_t::iterator i = pending_messages.begin();
00207 //         i != pending_messages.end(); ++i)
00208 //      delete *i;
00209 //       pending_messages.clear();
00210 //     }
00211 
00212   } // namespace set
00213 
00214 } // namespace olsr
00215 
00216 #endif // ! QOLYESTER_DAEMON_SET_INTERFACES_HXX

Generated on Mon Sep 10 17:02:12 2007 for Qolyester daemon by  doxygen 1.5.1