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

interfaces.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_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       std::pair<iset_t::iterator, bool> p = _iset.insert(x);
00083       if (p.second) {
00084         _mid_iset.add_key(x.addr());
00085         _mid_iset.insert(p.first);
00086         if (_min_mtu == 0 || x.mtu() < _min_mtu)
00087           _min_mtu = x.mtu();
00088         cproxy.add_interface(x.addr());
00089         gate_set.hna_gset().add_key(x.addr());
00090         scheduler.insert(new sch::PacketReceiver(const_cast<iface_t*>(&*p.first)));
00091       }
00092 //       const_cast<iset_t::value_type&>(x).configure();
00093       return p;
00094     }
00095 
00096     void
00097     InterfaceSet::erase(iterator pos) {
00098       assert(pos != end());
00099 //       const_cast<iset_t::value_type&>(*pos).unconfigure();
00100       const_cast<iface_t&>(*pos).destroy_all_events();
00101       gate_set.hna_gset().remove_key(pos->addr());
00102       cproxy.remove_interface(pos->addr());
00103       if (pos->addr() == main_addr)
00104         main_addr = address_t();
00105       _mid_iset.remove_key(pos->addr());
00106       _mid_iset.erase(pos);
00107       _iset.erase(pos);
00108       _min_mtu = 0;
00109       for (iset_t::iterator i = _iset.begin(); i != _iset.end(); ++i)
00110         if (_min_mtu == 0 || i->mtu() < _min_mtu)
00111           _min_mtu = i->mtu();
00112       if (main_addr == address_t() && !_iset.empty())
00113         main_addr = _iset.begin()->addr();
00114     }
00115 
00116     InterfaceSet::iterator
00117     InterfaceSet::find(const address_t& iaddr) const {
00118       return _iset.find(iface_t::make_key(iaddr));
00119     }
00120 
00121     void
00122     InterfaceSet::send_messages() {
00123 
00124       assert(iface_set.empty() || min_mtu() > 0);
00125 
00126       // FIXME: this should not be that way, we should remove pending
00127       // messages if there are no current interfaces.
00128       if (iface_set.empty()) {
00129         pending_messages.clear();
00130         return;
00131       }
00132 
00133       while (!pending_messages.empty()) {
00134 
00135         typedef std::map<iface_t*,
00136                          pkt::Packet, 
00137                          utl::pless<iface_t> >  packets_t;
00138 
00139         packets_t       packets;
00140 
00141         // Create a packet for each interface.
00142         for (iset_t::iterator i = _iset.begin(); i != _iset.end(); ++i)
00143           packets.insert(packets_t::value_type(const_cast<iface_t*>(&*i),
00144                                                pkt::Packet(_min_mtu,
00145                                                            i->addr())));
00146 
00147         // Add each message in all the packets.
00148         for (pending_t::iterator m = pending_messages.begin();
00149              m != pending_messages.end(); /* ++m elsewhere */) {
00150           // Add the message to the first packet.
00151           bool  resend = packets.begin()->second.add_message(**m);
00152 
00153           // Add the message to the remaining packets and check that
00154           // it fits the same way.
00155 
00156           // FIXME: this should be avoided, since the packets should
00157           // be identical on every interface for we always broadcast
00158           // messages on all interfaces.
00159 # ifndef NDEBUG
00160           for (packets_t::iterator i = ++packets.begin();
00161                i != packets.end(); ++i) {
00162             bool        resend_this = i->second.add_message(**m);
00163             assert(resend_this == resend);
00164           }
00165 # endif
00166 
00167           // Increment the message sequence number.
00168           const_cast<msg::Message*>(*m)->inc_seqnum();
00169 
00170           // Destroy the message if it is not to be resent.
00171           if (!resend) {
00172             pending_t::iterator tmp = m++;
00173             const msg::Message* mptr = *tmp;
00174             pending_messages.erase(tmp);
00175             delete mptr;
00176           }
00177         }
00178 
00179         // Now send the packets.
00180         for (packets_t::iterator i = packets.begin();
00181              i != packets.end(); ++i) {
00182           i->second.close(i->first->addr());
00183           if (i->second.size() > pkt::Packet::min_length)
00184             scheduler.insert(new sch::PacketSender(i->first, i->second));
00185         }
00186       }
00187     }      
00188       
00189 //       for (iset_t::iterator i = iface_set._iset.begin(); 
00190 //         i != iface_set._iset.end(); ++i) {
00191 //      pending_t       local_pm = pending_messages;
00192 
00193 //      while (!local_pm.empty()) {
00194 //        pkt::Packet   p(min_mtu(), i->addr());
00195           
00196 //        p.fill(local_pm);
00197 
00198 //        if (p.size() > pkt::Packet::min_length) {
00199 //          i->send(p);
00200 //        }
00201 //      }
00202 //       }
00203 //       for (pending_t::iterator i = pending_messages.begin();
00204 //         i != pending_messages.end(); ++i)
00205 //      delete *i;
00206 //       pending_messages.clear();
00207 //     }
00208 
00209   } // namespace set
00210 
00211 } // namespace olsr
00212 
00213 #endif // ! QOLYESTER_DAEMON_SET_INTERFACES_HXX

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