realinterface.hxx

Go to the documentation of this file.
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 
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019 // Boston, MA  02110-1301, USA.
00020 
00021 #include "config.hh"
00022 
00023 #ifndef QOLYESTER_ENABLE_VIRTUAL
00024 
00025 # ifndef QOLYESTER_DAEMON_NET_REALINTERFACE_HXX
00026 #  define QOLYESTER_DAEMON_NET_REALINTERFACE_HXX 1
00027 
00028 #  include "cst/constants.hh"
00029 #  include "sys/realinterfaceinfo.hh"
00030 #  include "sys/socket.hh"
00031 #  include "sch/events.hh"
00032 
00033 #  include "realinterface.hh"
00034 
00035 namespace olsr {
00036 
00037   extern sch::Scheduler scheduler;
00038 
00039   namespace net {
00040 
00041     void
00042     RealInterface::configure() {
00043       assert(config_ != 0);
00044       config_->setup();
00045     }
00046 
00047     void
00048     RealInterface::unconfigure() {
00049       assert(config_ != 0);
00050       config_->revert();
00051     }
00052 
00053     RealInterface::RealInterface()
00054       : info_(),
00055         addr_(),
00056         prefix_(0),
00057 #  ifdef QOLYESTER_TWO_SOCKETS
00058         insock_(sys::Socket::dummy()),
00059         outsock_(sys::Socket::dummy()),
00060 #  else // !QOLYESTER_TWO_SOCKETS
00061         sock_(sys::Socket::dummy()),
00062 #  endif
00063         events_(),
00064         sender_(0),
00065         usecount_(new unsigned(1)),
00066         config_(0),
00067         queue_size_(cst::queue_size)
00068     {}
00069 
00070     RealInterface::RealInterface(const sys::RealInterfaceInfo& info)
00071       : info_(info),
00072         addr_(info_.get_addr()),
00073         prefix_(info_.get_prefix(addr_)),
00074 #  ifdef QOLYESTER_TWO_SOCKETS
00075         insock_(),
00076         outsock_(),
00077         events_(),
00078         sender_(0),
00079         usecount_(new unsigned(1)),
00080         config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00081         queue_size_(cst::queue_size) {
00082       insock_.set_mtu(info_.mtu() - address_t::header_length);
00083       outsock_.set_mtu(info_.mtu() - address_t::header_length);
00084 
00085       address_t bcast = info_.get_bcast(addr_);
00086 
00087 #   if QOLYESTER_FAMILY_INET == 6
00088       insock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00089       outsock_.set_multicast(info_);
00090       if (addr_.is_linklocal())
00091         outsock_.bind(addr_, OLSR_PORT_NUMBER, info_.index());
00092       else
00093         outsock_.bind(addr_, OLSR_PORT_NUMBER);
00094 #   else // QOLYESTER_FAMILY_INET != 6
00095       //      outsock_.bind(addr_, OLSR_PORT_NUMBER);
00096       insock_.bind(bcast, OLSR_PORT_NUMBER);
00097       outsock_.bind_multicast(info_, addr_, OLSR_PORT_NUMBER);
00098 #   endif
00099 
00100       outsock_.set_baddr(bcast);
00101 
00102       outsock_.set_priority();
00103 #  else // !QOLYESTER_TWO_SOCKETS
00104         sock_(),
00105         events_(),
00106         sender_(0),
00107         usecount_(new unsigned(1)),
00108         config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00109         queue_size_(cst::queue_size) {
00110       address_t bcast = info_.get_bcast(addr_);
00111       sock_.set_mtu(info_.mtu() - address_t::header_length);
00112       sock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00113       sock_.set_baddr(bcast);
00114 #  endif
00115     }
00116 
00117     RealInterface::RealInterface(const sys::RealInterfaceInfo& info,
00118                                  const address_t& addr)
00119       : info_(info),
00120         addr_(info_.get_addr(addr)),
00121         prefix_(info_.get_prefix(addr)),
00122 #  ifdef QOLYESTER_TWO_SOCKETS
00123         insock_(),
00124         outsock_(),
00125         events_(),
00126         sender_(0),
00127         usecount_(new unsigned(1)),
00128         config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00129         queue_size_(cst::queue_size) {
00130       insock_.set_mtu(info_.mtu() - address_t::header_length);
00131       outsock_.set_mtu(info_.mtu() - address_t::header_length);
00132 
00133       address_t bcast = info_.get_bcast(addr_);
00134 
00135 #   if QOLYESTER_FAMILY_INET == 6
00136       insock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00137       outsock_.set_multicast(info_);
00138       if (addr_.is_linklocal())
00139         outsock_.bind(addr_, OLSR_PORT_NUMBER, info_.index());
00140       else
00141         outsock_.bind(addr_, OLSR_PORT_NUMBER);
00142 #   else // QOLYESTER_FAMILY_INET != 6
00143       insock_.bind(bcast, OLSR_PORT_NUMBER);
00144       outsock_.bind_multicast(info_, addr_, OLSR_PORT_NUMBER);
00145 #   endif
00146 
00147       outsock_.set_baddr(bcast);
00148       outsock_.set_priority();
00149 #  else // !QOLYSTER_TWO_SOCKETS
00150         sock_(),
00151         events_(),
00152         sender_(0),
00153         usecount_(new unsigned(1)),
00154         config_(new sys::RealInterfaceInfo::config_t(info_.name())),
00155         queue_size_(cst::queue_size) {
00156       address_t bcast = info_.get_bcast(addr_);
00157       sock_.set_mtu(info_.mtu() - address_t::header_length);
00158       sock_.bind_multicast(info_, bcast, OLSR_PORT_NUMBER);
00159       sock_.set_baddr(bcast);
00160 #  endif
00161     }
00162 
00163     RealInterface::RealInterface(const This& other)
00164       : Super(other),
00165         info_(other.info_),
00166         addr_(other.addr_),
00167         prefix_(other.prefix_),
00168 #  ifdef QOLYESTER_TWO_SOCKETS
00169         insock_(other.insock_),
00170         outsock_(other.outsock_),
00171 #  else // !QOLYESTER_TWO_SOCKETS
00172         sock_(other.sock_),
00173 #  endif
00174         events_(),
00175         sender_(0),
00176         usecount_(other.usecount_),
00177         config_(other.config_),
00178         queue_size_(other.queue_size_) {
00179       ++(*usecount_);
00180     }
00181 
00182     RealInterface::~RealInterface() {
00183       debug << "Destroying interface instance {\n";
00184       for (events_t::iterator i = events_.begin(); i != events_.end();
00185            /* ++i elsewhere */) {
00186         debug << "  Destroying " << (*i)->name() << '\n';
00187         events_t::iterator tmp = i++;
00188         scheduler.destroy(*tmp);
00189       }
00190       debug << '}' << std::endl;
00191       --(*usecount_);
00192       if (*usecount_ == 0) {
00193         delete usecount_;
00194 #  ifdef QOLYESTER_TWO_SOCKETS
00195         insock_.close();
00196         outsock_.close();
00197 #  else // !QOLYESTER_TWO_SOCKETS
00198         sock_.close();
00199 #  endif
00200         if (config_ != 0) {
00201           unconfigure();
00202           delete config_;
00203         }
00204       }
00205     }
00206 
00207     unsigned
00208     RealInterface::mtu() const {
00209       return info_.mtu() - address_t::header_length;
00210     }
00211 
00212     sch::IOEvent::p_t
00213     RealInterface::recv_p() const {
00214 #  ifdef QOLYESTER_TWO_SOCKETS
00215       return insock_.read_p();
00216 #  else
00217       return sock_.read_p();
00218 #  endif
00219     }
00220 
00221     sch::IOEvent::p_t
00222     RealInterface::send_p() const {
00223 #  ifdef QOLYESTER_TWO_SOCKETS
00224       return outsock_.write_p();
00225 #  else
00226       return sock_.write_p();
00227 #  endif
00228     }
00229 
00230     void
00231     RealInterface::insert_event(sch::IOEvent* e) {
00232       debug << "Inserting " << e->name() << " into interface" << std::endl;
00233       events_.insert(e);
00234     }
00235 
00236     void
00237     RealInterface::erase_event(sch::IOEvent* e) {
00238       debug << "Erasing " << e->name() << " from interface" << std::endl;
00239       if (e == sender_)
00240         sender_ = 0;
00241       events_.erase(e);
00242     }
00243 
00244     void
00245     RealInterface::destroy_all_events() {
00246       while (!events_.empty()) {
00247         sch::IOEvent*   e = *events_.begin();
00248         events_.erase(events_.begin());
00249         if (sender_ == e)
00250           sender_ = 0;
00251         scheduler.destroy(e);
00252       }
00253     }
00254 
00255 //     const sys::Socket&
00256 //     RealInterface::socket() const {
00257 //       return sock_;
00258 //     }
00259 
00260     pkt::Packet
00261     RealInterface::receive() const {
00262       address_t         from;
00263 #  ifdef QOLYESTER_TWO_SOCKETS
00264       utl::Data data = insock_.receive(from);
00265 #  else // !QOLYESTER_TWO_SOCKETS
00266       utl::Data data = sock_.receive(from);
00267 #  endif
00268       return pkt::Packet(from, data);
00269     }
00270 
00271     void
00272     RealInterface::send(const pkt::Packet& p) const {
00273 #  ifdef QOLYESTER_TWO_SOCKETS
00274       outsock_.sendto_bcast(p.data());
00275 #  else // !QOLYESTER_TWO_SOCKETS
00276       sock_.sendto_bcast(p.data());
00277 #  endif
00278     }
00279 
00280     void
00281     RealInterface::shipout(const pkt::Packet& p) {
00282       debug << up << "Shipping out packet of " << p.size()
00283             << " bytes through " << info_.name() << std::endl << down;
00284       if (sender_ == 0) {
00285         sender_ = new sch::PacketSender(this, p);
00286         scheduler.insert(sender_);
00287       } else {
00288         sender_->push_packet(p);
00289       }
00290     }
00291 
00292     bool
00293     RealInterface::operator<(const This& rhs) const {
00294       return addr_ < rhs.addr_;
00295     }
00296 
00297     RealInterface&
00298     RealInterface::make_key(const address_t& a) {
00299       const_cast<address_t&>(dummy_for_find_.addr_) = a;
00300       return dummy_for_find_;
00301     }
00302 
00303   } // namespace net
00304 
00305 } // namespace olsr
00306 
00307 # endif // ! QOLYESTER_DAEMON_NET_REALINTERFACE_HXX
00308 
00309 #endif // ! QOLYESTER_ENABLE_VIRTUAL

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