|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2005 Andras Varga 00003 // Copyright (C) 2005 Wei Yang, Ng 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // This program 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 Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with this program; if not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 #include <sstream> 00020 #include <algorithm> 00021 #include "IPv6InterfaceData.h" 00022 00023 //FIXME invoked changed() from state-changing methods, to trigger notification... 00024 00025 00026 IPv6InterfaceData::IPv6InterfaceData() 00027 { 00028 /*******************Setting host/node/router Protocol Constants************/ 00029 routerConstants.maxInitialRtrAdvertInterval = IPv6_MAX_INITIAL_RTR_ADVERT_INTERVAL; 00030 routerConstants.maxInitialRtrAdvertisements = IPv6_MAX_INITIAL_RTR_ADVERTISEMENTS; 00031 routerConstants.maxFinalRtrAdvertisements = IPv6_MAX_FINAL_RTR_ADVERTISEMENTS; 00032 routerConstants.minDelayBetweenRAs = IPv6_MIN_DELAY_BETWEEN_RAS; 00033 routerConstants.maxRADelayTime = IPv6_MAX_RA_DELAY_TIME; 00034 00035 hostConstants.maxRtrSolicitationDelay = IPv6_MAX_RTR_SOLICITATION_DELAY; 00036 hostConstants.rtrSolicitationInterval = IPv6_RTR_SOLICITATION_INTERVAL; 00037 hostConstants.maxRtrSolicitations = IPv6_MAX_RTR_SOLICITATIONS; 00038 00039 nodeConstants.maxMulticastSolicit = IPv6_MAX_MULTICAST_SOLICIT; 00040 nodeConstants.maxUnicastSolicit = IPv6_MAX_UNICAST_SOLICIT; 00041 nodeConstants.maxAnycastDelayTime = IPv6_MAX_ANYCAST_DELAY_TIME; 00042 nodeConstants.maxNeighbourAdvertisement = IPv6_MAX_NEIGHBOUR_ADVERTISEMENT; 00043 nodeConstants.reachableTime = IPv6_REACHABLE_TIME; 00044 nodeConstants.retransTimer = IPv6_RETRANS_TIMER; 00045 nodeConstants.delayFirstProbeTime = IPv6_DELAY_FIRST_PROBE_TIME; 00046 nodeConstants.minRandomFactor = IPv6_MIN_RANDOM_FACTOR; 00047 nodeConstants.maxRandomFactor = IPv6_MAX_RANDOM_FACTOR; 00048 00049 /*******************Setting host/node/router variables*********************/ 00050 nodeVars.dupAddrDetectTransmits = IPv6_DEFAULT_DUPADDRDETECTTRANSMITS; 00051 00052 hostVars.linkMTU = IPv6_MIN_MTU; 00053 hostVars.curHopLimit = IPv6_DEFAULT_ADVCURHOPLIMIT;//value specified in RFC 1700-can't find it 00054 hostVars.baseReachableTime = IPv6_REACHABLE_TIME; 00055 hostVars.reachableTime = generateReachableTime(_getMinRandomFactor(), 00056 _getMaxRandomFactor(), getBaseReachableTime()); 00057 hostVars.retransTimer = IPv6_RETRANS_TIMER; 00058 00059 //rtrVars.advSendAdvertisements is set in RoutingTable6.cc:line 143 00060 rtrVars.maxRtrAdvInterval = IPv6_DEFAULT_MAX_RTR_ADV_INT; 00061 rtrVars.minRtrAdvInterval = 0.33*rtrVars.maxRtrAdvInterval; 00062 rtrVars.advManagedFlag = false; 00063 rtrVars.advOtherConfigFlag = false; 00064 rtrVars.advLinkMTU = IPv6_MIN_MTU; 00065 rtrVars.advReachableTime = IPv6_DEFAULT_ADV_REACHABLE_TIME; 00066 rtrVars.advRetransTimer = IPv6_DEFAULT_ADV_RETRANS_TIMER; 00067 rtrVars.advCurHopLimit = IPv6_DEFAULT_ADVCURHOPLIMIT; 00068 rtrVars.advDefaultLifetime = 3*rtrVars.maxRtrAdvInterval; 00069 #if USE_MOBILITY 00070 if (rtrVars.advDefaultLifetime<1) 00071 rtrVars.advDefaultLifetime = 1; 00072 #endif 00073 } 00074 00075 std::string IPv6InterfaceData::info() const 00076 { 00077 // FIXME FIXME FIXME FIXME info() should never print a newline 00078 std::ostringstream os; 00079 os << "IPv6:{" << endl; 00080 for (int i=0; i<getNumAddresses(); i++) 00081 { 00082 os << (i?"\t , ":"\tAddrs:") << getAddress(i) 00083 << "(" << IPv6Address::scopeName(getAddress(i).getScope()) 00084 << (isTentativeAddress(i)?" tent":"") << ") " 00085 << " expiryTime: " << (addresses[i].expiryTime==0 ? "inf" : SIMTIME_STR(addresses[i].expiryTime)) 00086 << " prefExpiryTime: " << (addresses[i].prefExpiryTime==0 ? "inf" : SIMTIME_STR(addresses[i].prefExpiryTime)) 00087 << endl; 00088 } 00089 00090 for (int i=0; i<getNumAdvPrefixes(); i++) 00091 { 00092 const AdvPrefix& a = getAdvPrefix(i); 00093 os << (i?", ":"\tAdvPrefixes: ") << a.prefix << "/" << a.prefixLength << "(" 00094 << (a.advOnLinkFlag?"":"off-link ") 00095 << (a.advAutonomousFlag?"":"non-auto "); 00096 if (a.advValidLifetime==0) 00097 os << "lifetime:inf"; 00098 else if (a.advValidLifetime>0) 00099 os << "expires:" << a.advValidLifetime; 00100 else 00101 os << "lifetime:+" << (-1 * a.advValidLifetime); 00102 os << ")" << endl; 00103 } 00104 os << " "; 00105 00106 // uncomment the following as needed! 00107 os << "\tNode:"; 00108 os << " dupAddrDetectTrans=" << nodeVars.dupAddrDetectTransmits; 00109 //os << " curHopLimit=" << hostVars.curHopLimit; 00110 //os << " retransTimer=" << hostVars.retransTimer; 00111 //os << " baseReachableTime=" << hostVars.baseReachableTime; 00112 os << " reachableTime=" << hostVars.reachableTime << endl; 00113 00114 if (rtrVars.advSendAdvertisements) 00115 { 00116 os << "\tRouter:"; 00117 os << " maxRtrAdvInt=" << rtrVars.maxRtrAdvInterval; 00118 os << " minRtrAdvInt=" << rtrVars.minRtrAdvInterval << endl; 00119 //os << " advManagedFlag=" << rtrVars.advManagedFlag; 00120 //os << " advOtherFlag=" << rtrVars.advOtherFlag; 00121 //os << " advLinkMTU=" << rtrVars.advLinkMTU; 00122 //os << " advReachableTime=" << rtrVars.advReachableTime; 00123 //os << " advRetransTimer=" << rtrVars.advRetransTimer; 00124 //os << " advCurHopLimit=" << rtrVars.advCurHopLimit; 00125 //os << " advDefaultLifetime=" << rtrVars.advDefaultLifetime; 00126 } 00127 00128 os << " }" << endl; 00129 return os.str(); 00130 } 00131 00132 std::string IPv6InterfaceData::detailedInfo() const 00133 { 00134 return info(); // TBD this could be improved: multi-line text, etc 00135 } 00136 00137 void IPv6InterfaceData::assignAddress(const IPv6Address& addr, bool tentative, 00138 simtime_t expiryTime, simtime_t prefExpiryTime) 00139 { 00140 addresses.push_back(AddressData()); 00141 AddressData& a = addresses.back(); 00142 a.address = addr; 00143 a.tentative = tentative; 00144 a.expiryTime = expiryTime; 00145 a.prefExpiryTime = prefExpiryTime; 00146 choosePreferredAddress(); 00147 } 00148 00149 void IPv6InterfaceData::updateMatchingAddressExpiryTimes(const IPv6Address& prefix, int length, 00150 simtime_t expiryTime, simtime_t prefExpiryTime) 00151 { 00152 for (AddressDataVector::iterator it=addresses.begin(); it!=addresses.end(); it++) 00153 { 00154 if (it->address.matches(prefix,length)) 00155 { 00156 it->expiryTime = expiryTime; 00157 it->prefExpiryTime = prefExpiryTime; 00158 } 00159 } 00160 choosePreferredAddress(); 00161 } 00162 00163 int IPv6InterfaceData::findAddress(const IPv6Address& addr) const 00164 { 00165 for (AddressDataVector::const_iterator it=addresses.begin(); it!=addresses.end(); it++) 00166 if (it->address==addr) 00167 return it-addresses.begin(); 00168 return -1; 00169 } 00170 00171 const IPv6Address& IPv6InterfaceData::getAddress(int i) const 00172 { 00173 ASSERT(i>=0 && i<(int)addresses.size()); 00174 return addresses[i].address; 00175 } 00176 00177 bool IPv6InterfaceData::isTentativeAddress(int i) const 00178 { 00179 ASSERT(i>=0 && i<(int)addresses.size()); 00180 return addresses[i].tentative; 00181 } 00182 00183 bool IPv6InterfaceData::hasAddress(const IPv6Address& addr) const 00184 { 00185 return findAddress(addr)!=-1; 00186 } 00187 00188 bool IPv6InterfaceData::matchesSolicitedNodeMulticastAddress(const IPv6Address& solNodeAddr) const 00189 { 00190 for (AddressDataVector::const_iterator it=addresses.begin(); it!=addresses.end(); it++) 00191 if (it->address.formSolicitedNodeMulticastAddress()==solNodeAddr) 00192 return true; 00193 return false; 00194 } 00195 00196 bool IPv6InterfaceData::isTentativeAddress(const IPv6Address& addr) const 00197 { 00198 int k = findAddress(addr); 00199 return k!=-1 && addresses[k].tentative; 00200 } 00201 00202 void IPv6InterfaceData::permanentlyAssign(const IPv6Address& addr) 00203 { 00204 int k = findAddress(addr); 00205 ASSERT(k!=-1); 00206 addresses[k].tentative = false; 00207 choosePreferredAddress(); 00208 } 00209 00210 const IPv6Address& IPv6InterfaceData::getLinkLocalAddress() const 00211 { 00212 for (AddressDataVector::const_iterator it=addresses.begin(); it!=addresses.end(); it++) 00213 if (it->address.isLinkLocal()) // FIXME and valid 00214 return it->address; 00215 return IPv6Address::UNSPECIFIED_ADDRESS; 00216 } 00217 00218 void IPv6InterfaceData::removeAddress(const IPv6Address& address) 00219 { 00220 int k = findAddress(address); 00221 ASSERT(k!=-1); 00222 addresses.erase(addresses.begin()+k); 00223 choosePreferredAddress(); 00224 } 00225 00226 bool IPv6InterfaceData::addrLess(const AddressData& a, const AddressData& b) 00227 { 00228 // This method is used in choosePreferredAddress(). 00229 // sort() produces increasing order, so "better" addresses should 00230 // compare as "less", to make them appear first in the array 00231 if (a.tentative!=b.tentative) 00232 return !a.tentative; // tentative=false is better 00233 if (a.address.getScope()!=b.address.getScope()) 00234 return a.address.getScope()>b.address.getScope(); // bigger scope is better 00235 return (a.expiryTime==0 && b.expiryTime!=0) || a.expiryTime>b.expiryTime; // longer expiry time is better 00236 } 00237 00238 void IPv6InterfaceData::choosePreferredAddress() 00239 { 00240 // do we have addresses? 00241 if (addresses.size()==0) 00242 { 00243 preferredAddr = IPv6Address(); 00244 return; 00245 } 00246 00247 // FIXME shouldn't we stick to the current preferredAddress if its prefLifetime 00248 // hasn't expired yet? 00249 00250 // FIXME TBD throw out expired addresses! 0 should be treated as infinity 00251 00252 // sort addresses by scope and expiry time, then pick the first one 00253 std::sort(addresses.begin(), addresses.end(), addrLess); 00254 preferredAddr = addresses[0].address; 00255 preferredAddrExpiryTime = addresses[0].expiryTime; 00256 } 00257 00258 void IPv6InterfaceData::addAdvPrefix(const AdvPrefix& advPrefix) 00259 { 00260 rtrVars.advPrefixList.push_back(advPrefix); 00261 } 00262 00263 const IPv6InterfaceData::AdvPrefix& IPv6InterfaceData::getAdvPrefix(int i) const 00264 { 00265 ASSERT(i>=0 && i<(int)rtrVars.advPrefixList.size()); 00266 return rtrVars.advPrefixList[i]; 00267 } 00268 00269 void IPv6InterfaceData::setAdvPrefix(int i, const AdvPrefix& advPrefix) 00270 { 00271 ASSERT(i>=0 && i<(int)rtrVars.advPrefixList.size()); 00272 ASSERT(rtrVars.advPrefixList[i].prefix == advPrefix.prefix); 00273 ASSERT(rtrVars.advPrefixList[i].prefixLength == advPrefix.prefixLength); 00274 rtrVars.advPrefixList[i] = advPrefix; 00275 } 00276 00277 void IPv6InterfaceData::removeAdvPrefix(int i) 00278 { 00279 ASSERT(i>=0 && i<(int)rtrVars.advPrefixList.size()); 00280 rtrVars.advPrefixList.erase(rtrVars.advPrefixList.begin()+i); 00281 } 00282 00283 simtime_t IPv6InterfaceData::generateReachableTime(double MIN_RANDOM_FACTOR, 00284 double MAX_RANDOM_FACTOR, uint baseReachableTime) 00285 { 00286 return uniform(MIN_RANDOM_FACTOR, MAX_RANDOM_FACTOR) * baseReachableTime; 00287 } 00288 00289 simtime_t IPv6InterfaceData::generateReachableTime() 00290 { 00291 return uniform(_getMinRandomFactor(), _getMaxRandomFactor()) * getBaseReachableTime(); 00292 } 00293 00294