00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00093 return p;
00094 }
00095
00096 void
00097 InterfaceSet::erase(iterator pos) {
00098 assert(pos != end());
00099
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
00127
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
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
00148 for (pending_t::iterator m = pending_messages.begin();
00149 m != pending_messages.end(); ) {
00150
00151 bool resend = packets.begin()->second.add_message(**m);
00152
00153
00154
00155
00156
00157
00158
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
00168 const_cast<msg::Message*>(*m)->inc_seqnum();
00169
00170
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
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
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 }
00210
00211 }
00212
00213 #endif // ! QOLYESTER_DAEMON_SET_INTERFACES_HXX