![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5