/** * Note: requestOptions list MUST NOT contain server DUID. */ void TClntTransMgr::sendRequest(TOptList requestOptions, int iface) { sortAdvertiseLst(); for (TOptList::iterator opt= requestOptions.begin(); opt!=requestOptions.end(); ++opt) { if (!allowOptInMsg(REQUEST_MSG, (*opt)->getOptType())) opt = requestOptions.erase(opt); } SPtr<TClntMsg> ptr = new TClntMsgRequest(requestOptions, iface); Transactions.append( (Ptr*)ptr ); }
bool TSrvTransMgr::unicastCheck(SPtr<TSrvMsg> msg) { // If it's relayed message, then it's ok if (!msg->RelayInfo_.empty()) return true; // Ok, we don't know what address it was received on. // This must be one weird OS we're running on. Anyway, let's // pretend it was not unicast. if (!msg->getLocalAddr()) return true; // All good, received on multicast if (msg->getLocalAddr()->multicast()) return true; // Received on unicast and it's not relayed. Do we have // unicast support enabled on this interface? SPtr<TSrvCfgIface> cfgIface = SrvCfgMgr().getIfaceByID(msg->getIface()); // That's weird! We don't have a configuration for this interface? if (!cfgIface) return true; // Do we have unicast enabled on this interface? Yes => all is good. if (cfgIface->getUnicast()) return true; // Ok, so we've got a problem here. Unicast is forbidden and we // received unicast traffic. if (!SrvCfgMgr().dropUnicast()) { Log(Warning) << "Received message on address " << msg->getLocalAddr()->getPlain() << " on interface " << cfgIface->getFullName() << ", but unicast is not allowed on this interface." << LogEnd; return true; } TOptList options; SPtr<TOpt> status(new TOptStatusCode(STATUSCODE_USEMULTICAST, string("Please send your message to multicast, not to ") + msg->getLocalAddr()->getPlain(), NULL)); options.push_back(status); // Message will be sent in the constructor TSrvMsgReply(msg, options); return false; }
/// @brief Copies a list of forced options. /// /// This method add a list of forced options. Forced options are the ones that /// are sent to a client, regardless if client requested them or not. /// /// @param forced list of forced options to be copied void TSrvCfgOptions::addForcedOptions(const TOptList& forced) { for (TOptList::const_iterator opt = forced.begin(); opt != forced.end(); ++opt) ForcedOpts_.push_back(*opt); }
/// @brief Copies a list of extra options. /// /// Extra options are options that may be requested by a client. This list also /// contains forced options (i.e. options that are sent regardless if client /// asks for them or not). /// /// @param extra list of options to be copied void TSrvCfgOptions::addExtraOptions(const TOptList& extra) { for (TOptList::const_iterator opt = extra.begin(); opt != extra.end(); ++opt) ExtraOpts_.push_back(*opt); }
bool TSrvMsgReply::handleConfirmOptions(TOptList & options) { SPtr<TSrvCfgIface> cfgIface = SrvCfgMgr().getIfaceByID(Iface); if (!cfgIface) { Log(Crit) << "Msg received through not configured interface. " "Somebody call an exorcist!" << LogEnd; IsDone = true; return false; } EAddrStatus onLink = ADDRSTATUS_YES; int checkCnt = 0; TOptList::iterator opt = options.begin(); while ( (opt!=options.end()) && (onLink==ADDRSTATUS_YES) ) { switch ( (*opt)->getOptType()) { case OPTION_IA_NA: { SPtr<TSrvOptIA_NA> ia = (Ptr*) (*opt); // now we check whether this IA exists in Server Address database or not. SPtr<TOpt> opt; ia->firstOption(); while ((opt = ia->getOption()) && (onLink == ADDRSTATUS_YES) ) { if (opt->getOptType() != OPTION_IAADDR){ continue; } SPtr<TSrvOptIAAddress> optAddr = (Ptr*) opt; onLink = cfgIface->confirmAddress(IATYPE_IA, optAddr->getAddr()); checkCnt++; } break; } case OPTION_IA_TA: { SPtr<TSrvOptTA> ta = (Ptr*) (*opt); SPtr<TOpt> opt; ta->firstOption(); while (opt = ta->getOption() && (onLink == ADDRSTATUS_YES)) { if (opt->getOptType() != OPTION_IAADDR) continue; SPtr<TSrvOptIAAddress> optAddr = (Ptr*) opt; onLink = cfgIface->confirmAddress(IATYPE_TA, optAddr->getAddr()); checkCnt++; } break; } case OPTION_IA_PD: { SPtr<TSrvOptIA_PD> ta = (Ptr*) (*opt); SPtr<TOpt> opt; ta->firstOption(); while (opt = ta->getOption() && (onLink == ADDRSTATUS_YES)) { if (opt->getOptType() != OPTION_IAPREFIX) continue; SPtr<TSrvOptIAPrefix> optPrefix = (Ptr*) opt; onLink = cfgIface->confirmAddress(IATYPE_PD, optPrefix->getPrefix()); checkCnt++; } break; } default: handleDefaultOption(*opt); break; } ++opt; } if (!checkCnt) { Log(Info) << "No addresses or prefixes in CONFIRM. Not sending reply." << LogEnd; return false; } switch (onLink) { case ADDRSTATUS_YES: { SPtr <TOptStatusCode> ptrCode = new TOptStatusCode(STATUSCODE_SUCCESS, "Your addresses are correct for this link! Yay!", this); Options.push_back( (Ptr*) ptrCode); return true; } case ADDRSTATUS_NO: { SPtr <TOptStatusCode> ptrCode = new TOptStatusCode(STATUSCODE_NOTONLINK, "Sorry, those addresses are not valid for this link.", this); Options.push_back( (Ptr*) ptrCode ); return true; } default: case ADDRSTATUS_UNKNOWN: { Log(Info) << "Address/prefix being confirmed is outside of defined class," << " but there is no subnet defined, so can't answer authoratively." << " Will not send answer." << LogEnd; return false; } } // should never get here return false; }
bool TSrvMsgReply::handleConfirmOptions(TOptList & options) { SPtr<TSrvCfgIface> ptrIface = SrvCfgMgr().getIfaceByID( Iface ); if (!ptrIface) { Log(Crit) << "Msg received through not configured interface. " "Somebody call an exorcist!" << LogEnd; this->IsDone = true; return false; } bool OnLink = true; int checkCnt = 0; List(TSrvOptIA_NA) validIAs; TOptList::iterator opt = options.begin(); while ( (opt!=options.end()) && OnLink ) { switch ( (*opt)->getOptType()) { case OPTION_IA_NA: { SPtr<TSrvOptIA_NA> ia = (Ptr*) (*opt); // now we check whether this IA exists in Server Address database or not. SPtr<TOpt> subOpt; unsigned long addrCnt = 0; ia->firstOption(); while ( (subOpt = ia->getOption()) && (OnLink) ) { if (subOpt->getOptType() != OPTION_IAADDR){ continue; } SPtr<TSrvOptIAAddress> optAddr = (Ptr*) subOpt; Log(Debug) << "CONFIRM message: checking if " << optAddr->getAddr()->getPlain() << " is supported:"; if (!SrvCfgMgr().isIAAddrSupported(this->Iface, optAddr->getAddr())) { Log(Cont) << "no." << LogEnd; OnLink = false; } else { Log(Cont) << "yes." << LogEnd; addrCnt++; } checkCnt++; } if (addrCnt) { SPtr<TSrvOptIA_NA> tempIA = new TSrvOptIA_NA(ia, PeerAddr, ClientDUID, Iface, addrCnt,CONFIRM_MSG, this); validIAs.append(tempIA); } break; } case OPTION_IA_TA: { SPtr<TSrvOptTA> ta = (Ptr*) (*opt); // now we check whether this IA exists in Server Address database or not. SPtr<TOpt> subOpt; ta->firstOption(); while (subOpt = ta->getOption() && (OnLink)) { if (subOpt->getOptType() != OPTION_IAADDR) continue; SPtr<TSrvOptIAAddress> optAddr = (Ptr*) subOpt; if (!SrvCfgMgr().isTAAddrSupported(this->Iface, optAddr->getAddr())) { OnLink = false; } checkCnt++; } break; } default: handleDefaultOption( *opt); break; } ++opt; } if (!checkCnt) { // no check SPtr <TSrvOptStatusCode> ptrCode = new TSrvOptStatusCode(STATUSCODE_NOTONLINK, "No addresses checked. Did you send any?", this); Options.push_back( (Ptr*) ptrCode ); } else if (!OnLink) { // not-on-link SPtr <TSrvOptStatusCode> ptrCode = new TSrvOptStatusCode(STATUSCODE_NOTONLINK, "Sorry, those addresses are not valid for this link.", this); Options.push_back( (Ptr*) ptrCode ); } else { // success SPtr <TSrvOptStatusCode> ptrCode = new TSrvOptStatusCode(STATUSCODE_SUCCESS, "Your addresses are correct for this link! Yay!", this); Options.push_back( (Ptr*) ptrCode); if(validIAs.count()){ SPtr<TSrvOptIA_NA> ia; validIAs.first(); while(ia=validIAs.get() ){ Options.push_back((Ptr*)ia ); } } } return true; }