User Manual, Developers Guide and API Documentation

Forwarding.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <IP/Component.hpp>
00029 #include <IP/Forwarding.hpp>
00030 
00031 #include <WNS/module/Base.hpp>
00032 
00033 using namespace ip;
00034 
00035 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00036     Forwarding,
00037     wns::ldk::FunctionalUnit,
00038     "ip.forwarding",
00039     wns::ldk::FUNConfigCreator);
00040 
00041 Forwarding::Forwarding(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& _pyco) :
00042     wns::ldk::CommandTypeSpecifier<ForwardingCommand>(fun),
00043     wns::ldk::HasReceptor<>(),
00044     wns::ldk::HasConnector<>(),
00045     wns::ldk::HasDeliverer<>(),
00046     wns::Cloneable<Forwarding>(),
00047     ipHeaderReader(NULL),
00048     pyco(_pyco),
00049     log(_pyco.get("logger")),
00050     isForwarding(_pyco.get<bool>("isForwarding")),
00051     ttl(_pyco.get<int>("ttl"))
00052 {
00053 
00054 }
00055 
00056 void
00057 Forwarding::addListeningAddress(wns::service::nl::Address _la)
00058 {
00059     MESSAGE_SINGLE(NORMAL, log, "Adding " << _la << " to listening addresses");
00060 
00061     assure(find(this->listeningAddresses.begin(), this->listeningAddresses.end(), _la)
00062            == this->listeningAddresses.end(), "Address already registered!");
00063 
00064     this->listeningAddresses.insert(this->listeningAddresses.end(), _la);
00065 }
00066 
00067 void
00068 Forwarding::removeListeningAddress(wns::service::nl::Address _la)
00069 {
00070     MESSAGE_SINGLE(NORMAL, log, "Adding " << _la << " to listening addresses");
00071 
00072     assure(find(this->listeningAddresses.begin(), this->listeningAddresses.end(), _la)
00073            != this->listeningAddresses.end(), "Address not registered!");
00074 
00075     this->listeningAddresses.erase(find(this->listeningAddresses.begin(), this->listeningAddresses.end(), _la));
00076 }
00077 
00078 
00079 void
00080 Forwarding::onFUNCreated()
00081 {
00082     ipHeaderReader = getFUN()->getCommandReader("ip.ipHeader");
00083     assure(ipHeaderReader, "No reader for the IP Header available!");
00084 }
00085 
00086 void
00087 Forwarding::processOutgoing(const wns::ldk::CompoundPtr& compound)
00088 {
00089     activateCommand(compound->getCommandPool());
00090 
00091     assure(ipHeaderReader, "No reader for the IP Header available!");
00092     IPCommand* ipHeader = ipHeaderReader->readCommand<IPCommand>(compound->getCommandPool());
00093 
00094     // Set initial TimeToLive
00095     ipHeader->peer.TTL = this->ttl;
00096 
00097     // This packet originates here, we do not mark it as a forwarded packet
00098     ipHeader->local.isForwarded = false;
00099 
00100     MESSAGE_BEGIN(NORMAL, log, m, "Initial TTL value");
00101     m << " (TTL:" << ipHeader->peer.TTL << ")";
00102     MESSAGE_END();
00103 
00104     // Forward to lower FU.
00105     assure(hasCapacity(), "received PDU although not accepting");
00106 
00107     this->buffer = compound;
00108 
00109 //  getConnector()->getAcceptor(compound)->sendData(compound);
00110 }
00111 
00112 void
00113 Forwarding::processIncoming(const wns::ldk::CompoundPtr& compound)
00114 {
00115     assure(ipHeaderReader, "No reader for the IP Header available!");
00116     IPCommand* ipHeader = ipHeaderReader->readCommand<IPCommand>(compound->getCommandPool());
00117 
00118     // Test wether compound is for us
00119     if (reachedDestination(compound))
00120     {
00121       MESSAGE_BEGIN(NORMAL, log, m, "Delivering compound from : " << ipHeader->peer.source);
00122       m << " (TTL:" << ipHeader->peer.TTL << ")";
00123       MESSAGE_END();
00124 
00125       MESSAGE_BEGIN(VERBOSE, log, m, getFUN()->getName());
00126       m << ": Compound backtrace"
00127         << compound->dumpJourney(); // JOURNEY
00128       MESSAGE_END();
00129 
00130       // Hand compound to upper FU
00131       if(getDeliverer()->size())
00132         getDeliverer()->getAcceptor(compound)->onData(compound);
00133     }
00134     else
00135     {
00136         if(putOnNextHop(compound))
00137         {
00138             MESSAGE_BEGIN(NORMAL, log, m, "Forwarding compound from : " << ipHeader->peer.source);
00139             m << " (TTL:" << ipHeader->peer.TTL << ")";
00140             MESSAGE_END();
00141 
00142             MESSAGE_BEGIN(VERBOSE, log, m, getFUN()->getName());
00143             m << ": Compound backtrace"
00144               << compound->dumpJourney(); // JOURNEY
00145             MESSAGE_END();
00146 
00147             // We now create a partial copy of the CommandPool we received which we can
00148             // then pass down the stack again. All commands from FUs above this FU stay
00149             // activated (cmp. 2.8. Relaying in fds diploma thesis).
00150             wns::ldk::CommandPool* newCP = getFUN()->getProxy()->createCommandPool();
00151             getFUN()->getProxy()->partialCopy(this, newCP, compound->getCommandPool());
00152 
00153             assure(ipHeaderReader, "No reader for the IP Header available!");
00154             IPCommand* newIPHeader = ipHeaderReader->readCommand<IPCommand>(newCP);
00155 
00156             // Decrease the TTL
00157             newIPHeader->peer.TTL = ipHeader->peer.TTL - 1;
00158 
00159             // We put this packet on the next hop, thus we mark it as a forwarded packet
00160             newIPHeader->local.isForwarded = true;
00161 
00162             // New compound....
00163             wns::ldk::CompoundPtr newcompound(new wns::ldk::Compound(newCP, compound->getData()));
00164 
00165             activateCommand(newcompound->getCommandPool());
00166 
00167             // and off we go.
00168 
00169             // Forward to lower FU.
00170             assure(hasCapacity(), "received PDU although not accepting");
00171 
00172             this->buffer = newcompound;
00173         }
00174         else
00175         {
00176             MESSAGE_BEGIN(NORMAL, log, m, "Dropping compound from : " << ipHeader->peer.source);
00177             m << " (TTL:" << ipHeader->peer.TTL << ")";
00178             MESSAGE_END();
00179 
00180             MESSAGE_BEGIN(VERBOSE, log, m, getFUN()->getName());
00181             m << ": Compound backtrace"
00182               << compound->dumpJourney(); // JOURNEY
00183             MESSAGE_END();
00184         }
00185     }
00186 }
00187 
00188 //bool
00189 //Forwarding::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
00190 //{
00191 //  return getConnector()->hasAcceptor(compound);
00192 //}
00193 
00194 bool
00195 Forwarding::hasCapacity() const
00196 {
00197     return this->buffer == wns::ldk::CompoundPtr();
00198 }
00199 
00200 //void
00201 //Forwarding::doWakeup()
00202 //{
00203 //  getReceptor()->wakeup();
00204 //}
00205 
00206 const wns::ldk::CompoundPtr
00207 Forwarding::hasSomethingToSend() const
00208 {
00209     return this->buffer;
00210 }
00211 
00212 wns::ldk::CompoundPtr
00213 Forwarding::getSomethingToSend()
00214 {
00215     wns::ldk::CompoundPtr it;
00216     it = this->buffer;
00217     this->buffer = wns::ldk::CompoundPtr();
00218     return it;
00219 }
00220 
00221 bool
00222 Forwarding::reachedDestination(const wns::ldk::CompoundPtr& compound)
00223 {
00224     assure(ipHeaderReader, "No reader for the IP Header available!");
00225     IPCommand* ipHeader = ipHeaderReader->readCommand<IPCommand>(compound->getCommandPool());
00226 
00227     // Is this compound for us?
00228     if ( (find(this->listeningAddresses.begin(), this->listeningAddresses.end(), ipHeader->peer.destination) 
00229           != this->listeningAddresses.end()))
00230     {
00231         if (ipHeader->peer.TTL >= 0)
00232         {
00233             // TTL ok
00234             return true;
00235         }
00236         else
00237         {
00238             // TTL exceeded
00239             return false;
00240         }
00241     }
00242     else
00243     {
00244         return false;
00245     }
00246 }
00247 
00248 bool
00249 Forwarding::putOnNextHop(const wns::ldk::CompoundPtr& compound)
00250 {
00251     assure(ipHeaderReader, "No reader for the IP Header available!");
00252     IPCommand* ipHeader = ipHeaderReader->readCommand<IPCommand>(compound->getCommandPool());
00253 
00254     if (ipHeader->peer.TTL > 0)
00255     { // TTL available
00256         if(isForwarding)
00257         {
00258             // Routing
00259             return true;
00260         }
00261         else
00262         {
00263             // No Routing
00264             return false;
00265         }
00266     }
00267     else
00268     {
00269         // TTL exceeded for another hop
00270         return false;
00271     }
00272 }

Generated on Thu May 24 03:32:15 2012 for openWNS by  doxygen 1.5.5