//opts - all options list WITHOUT serverDUID including server id TClntMsgInfRequest::TClntMsgInfRequest(TOptList ReqOpts, int iface) :TClntMsg(iface, 0, INFORMATION_REQUEST_MSG) { IRT = INF_TIMEOUT; MRT = INF_MAX_RT; MRC = 0; MRD = 0; RT=0; Iface=iface; IsDone=false; SPtr<TIfaceIface> ptrIface = ClntIfaceMgr().getIfaceByID(iface); if (!ptrIface) { Log(Error) << "Unable to find interface with ifindex=" << iface << " while trying to generate INF-REQUEST." << LogEnd; IsDone = true; return; } Log(Debug) << "Creating INF-REQUEST on the " << ptrIface->getFullName() << "." << LogEnd; // copy whole list from Verify ... Options = ReqOpts; SPtr<TOpt> opt; firstOption(); while(opt=getOption()) { switch (opt->getOptType()) { //These options possibly receipt from verify transaction //can't appear in request message and have to be deleted case OPTION_UNICAST: case OPTION_STATUS_CODE: case OPTION_PREFERENCE: case OPTION_IA_TA: case OPTION_RELAY_MSG: case OPTION_SERVERID: case OPTION_IA_NA: case OPTION_IAADDR: case OPTION_RAPID_COMMIT: case OPTION_INTERFACE_ID: case OPTION_RECONF_MSG: case OPTION_AUTH: case OPTION_ELAPSED_TIME: //delete the old elapsed option,as we will append a new one delOption(opt->getOptType()); break; } //The other options can be included in Information request option //CLIENTID,ORO,ELAPSED_TIME,USER_CLASS,VENDOR_CLASS, //VENDOR_OPTS,DNS_RESOLVERS,DOMAIN_LIST,NTP_SERVERS,TIME_ZONE, //RECONF_ACCEPT - maybe also SERVERID if information request //is answer to reconfigure message } appendElapsedOption(); appendAuthenticationOption(); this->send(); }
TClntMsgInfRequest::TClntMsgInfRequest(SPtr<TClntCfgIface> iface) :TClntMsg(iface->getID(), 0, INFORMATION_REQUEST_MSG) { IRT = INF_TIMEOUT; MRT = INF_MAX_RT; MRC = 0; MRD = 0; RT= 0 ; Iface=iface->getID(); IsDone=false; if (!ClntCfgMgr().anonInfRequest()) { Options.push_back(new TOptDUID(OPTION_CLIENTID, ClntCfgMgr().getDUID(), this)); } else { Log(Info) << "Sending anonymous INF-REQUEST (ClientID not included)." << LogEnd; } // Append the options we want to configure appendRequestedOptions(); // If there is no ORO (or it is empty), skip the message. SPtr<TClntOptOptionRequest> oro = (Ptr*) getOption(OPTION_ORO); if (!oro || !oro->count()) { IsDone = true; return; } appendAuthenticationOption(); appendElapsedOption(); send(); }
TClntMsgInfRequest::TClntMsgInfRequest(SPtr<TClntCfgIface> iface) :TClntMsg(iface->getID(), 0, INFORMATION_REQUEST_MSG) { IRT = INF_TIMEOUT; MRT = INF_MAX_RT; MRC = 0; MRD = 0; RT= 0 ; Iface=iface->getID(); IsDone=false; if (!ClntCfgMgr().anonInfRequest()) { Options.push_back(new TOptDUID(OPTION_CLIENTID, ClntCfgMgr().getDUID(), this)); } else { Log(Info) << "Sending anonymous INF-REQUEST (ClientID not included)." << LogEnd; } this->appendRequestedOptions(); appendAuthenticationOption(); appendElapsedOption(); send(); }
:TClntMsg(iface, addr, RELEASE_MSG) { SPtr<TDUID> srvDUID; IRT=REL_TIMEOUT; MRT=0; MRC=REL_MAX_RC; MRD=0; RT=0; // obtain IA, TA or PD, so server DUID can be obtained SPtr<TAddrIA> x = 0; if (iaLst.count()) { iaLst.first(); x=iaLst.get(); } if (!x) x = ta; if (!x) { pdLst.first(); x = pdLst.get(); } if (!x) { Log(Error) << "Unable to send RELEASE. No IA, TA or PD provided." << LogEnd; this->IsDone = true; return; } if (!x->getDUID()) { Log(Error) << "Unable to send RELEASE. Unable to find DUID. " << LogEnd; this->IsDone = true; return; } srvDUID = x->getDUID(); Options.push_back(new TOptDUID(OPTION_SERVERID, srvDUID,this)); Options.push_back(new TOptDUID(OPTION_CLIENTID, ClntCfgMgr().getDUID(),this)); #if 0 if (ClntCfgMgr().getNotifyScripts()) { // release workaround (add removed IAs) /// @todo: WTF? Why are those IAs removed? iaLst.first(); SPtr<TAddrIA> ia; while (ia = iaLst.get()) { ClntAddrMgr().addIA(ia); } iaLst.first(); while (ia = iaLst.get()) { ClntAddrMgr().delIA(ia->getIAID()); } } #endif // --- RELEASE IA --- iaLst.first(); while(x=iaLst.get()) { Options.push_back(new TClntOptIA_NA(x,this)); SPtr<TAddrAddr> ptrAddr; SPtr<TClntIfaceIface> ptrIface; ptrIface = (Ptr*)ClntIfaceMgr().getIfaceByID(x->getIface()); x->firstAddr(); while (ptrAddr = x->getAddr()) { ptrIface->delAddr(ptrAddr->get(), ptrAddr->getPrefix()); } // --- DNS Update --- SPtr<TIPv6Addr> dns = x->getFQDNDnsServer(); if (dns) { string fqdn = ptrIface->getFQDN(); ClntIfaceMgr().fqdnDel(ptrIface, x, fqdn); } // --- DNS Update --- } // --- RELEASE TA --- if (ta) Options.push_back(new TClntOptTA(ta, this)); // --- RELEASE PD --- SPtr<TAddrIA> pd = 0; pdLst.first(); while(pd=pdLst.get()) { SPtr<TClntOptIA_PD> pdOpt = new TClntOptIA_PD(pd,this); Options.push_back( (Ptr*)pdOpt ); pdOpt->setContext(srvDUID, addr, this); pdOpt->delPrefixes(); ClntAddrMgr().delPD(pd->getIAID() ); } appendElapsedOption(); appendAuthenticationOption(); IsDone = false; send(); }
:TClntMsg(iface, addr, SOLICIT_MSG) { IRT=SOL_TIMEOUT; MRT=SOL_MAX_RT; MRC=0; //these both below mean there is no ending condition and transactions MRD=0; //lasts till receiving answer RT=0; // ClientIdentifier option appendClientID(); SPtr<TAddrIA> addrIA; // all IAs are provided by ::checkSolicit() SPtr<TClntCfgIA> ia; iaLst.first(); while (ia = iaLst.get()) { SPtr<TClntOptIA_NA> iaOpt; iaOpt = new TClntOptIA_NA(ia, this); Options.push_back( (Ptr*)iaOpt ); if (!remoteAutoconf) ia->setState(STATE_INPROCESS); addrIA = ClntAddrMgr().getIA(ia->getIAID()); if (addrIA) addrIA->setState(STATE_INPROCESS); else Log(Error) << "AddrMgr does not have IA with IAID=" << ia->getIAID() << LogEnd; } // TA is provided by ::checkSolicit() if (ta) { SPtr<TClntOptTA> taOpt = new TClntOptTA(ta->getIAID(), this); Options.push_back( (Ptr*) taOpt); if (!remoteAutoconf) ta->setState(STATE_INPROCESS); addrIA = ClntAddrMgr().getTA(ta->getIAID()); if (addrIA) addrIA->setState(STATE_INPROCESS); else Log(Error) << "AddrMgr does not have TA with IAID=" << ia->getIAID() << LogEnd; } // all PDs are provided by ::checkSolicit() SPtr<TClntCfgPD> pd; pdLst.first(); while ( pd = pdLst.get() ) { SPtr<TClntOptIA_PD> pdOpt = new TClntOptIA_PD(pd, this); Options.push_back( (Ptr*)pdOpt ); if (!remoteAutoconf) pd->setState(STATE_INPROCESS); addrIA = ClntAddrMgr().getPD(pd->getIAID()); if (addrIA) addrIA->setState(STATE_INPROCESS); else Log(Error) << "AddrMgr does not have PD with IAID=" << pd->getIAID() << LogEnd; } if (rapid) Options.push_back(new TOptEmpty(OPTION_RAPID_COMMIT, this)); // RECONF-ACCEPT is added in TClntMsg::appendRequestedOptions() // append and switch to INPROCESS state if (!remoteAutoconf) appendTAOptions(true); // append options specified in the config file if (!remoteAutoconf) appendRequestedOptions(); appendAuthenticationOption(); IsDone = false; send(); }
bool TSrvMsgAdvertise::handleSolicitOptions(SPtr<TSrvMsgSolicit> solicit) { SPtr<TOpt> opt; SPtr<TIPv6Addr> clntAddr = PeerAddr; // is this client supported? // @todo move this to a common place (for every message) if (!SrvCfgMgr().isClntSupported(ClientDUID, clntAddr, Iface)) { //No reply for this client Log(Notice) << "Client (DUID=" << ClientDUID->getPlain() << ",addr=" << *clntAddr << ") was rejected due to accept-only or reject-client." << LogEnd; return false; } // --- process this message --- solicit->firstOption(); while ( opt = solicit->getOption()) { switch (opt->getOptType()) { case OPTION_IA_NA : { SPtr<TSrvOptIA_NA> optIA_NA; optIA_NA = new TSrvOptIA_NA( (Ptr*)opt, ClientDUID, clntAddr, Iface, SOLICIT_MSG, this); Options.push_back((Ptr*)optIA_NA); break; } case OPTION_IA_TA: { SPtr<TSrvOptTA> optTA; optTA = new TSrvOptTA((Ptr*) opt, ClientDUID, clntAddr, Iface, SOLICIT_MSG, this); Options.push_back( (Ptr*) optTA); break; } case OPTION_IA_PD: { SPtr<TSrvOptIA_PD> optPD; optPD = new TSrvOptIA_PD((Ptr*) opt, clntAddr, ClientDUID, Iface, SOLICIT_MSG, this); Options.push_back( (Ptr*) optPD); break; } case OPTION_RAPID_COMMIT: { // RAPID COMMIT present, but we're in ADVERTISE, so obviously // server is configured not to use RAPID COMMIT Log(Notice) << "Generating ADVERTISE message, RAPID COMMIT option ignored." << LogEnd; break; } case OPTION_IAADDR: { Log(Warning) << "Invalid(misplaced) IAADDR option received." << LogEnd; break; } case OPTION_IAPREFIX: { Log(Warning) << "Invalid(misplaced) IAPREFIX option received." << LogEnd; break; } case OPTION_AUTH : { ORO->addOption(OPTION_AUTH); break; } case OPTION_ORO: case OPTION_CLIENTID: case OPTION_ELAPSED_TIME : { break; } case OPTION_STATUS_CODE : { SPtr< TOptStatusCode > ptrStatus = (Ptr*) opt; Log(Error) << "Received STATUS_CODE from client:" << ptrStatus->getCode() << ", (" << ptrStatus->getText() << ")" << LogEnd; break; } //add options requested by client to option Request Option if //client didn't included them case OPTION_FQDN : { SPtr<TSrvOptFQDN> requestFQDN = (Ptr*) opt; SPtr<TOptFQDN> anotherFQDN = (Ptr*) opt; string hint = anotherFQDN->getFQDN(); SPtr<TSrvOptFQDN> optFQDN; SPtr<TIPv6Addr> clntAssignedAddr = SrvAddrMgr().getFirstAddr(ClientDUID); if (clntAssignedAddr) optFQDN = this->prepareFQDN(requestFQDN, ClientDUID, clntAssignedAddr, hint, false); else optFQDN = this->prepareFQDN(requestFQDN, ClientDUID, clntAddr, hint, false); if (optFQDN) { this->Options.push_back((Ptr*) optFQDN); } break; } case OPTION_VENDOR_OPTS: { SPtr<TOptVendorData> v = (Ptr*) opt; appendVendorSpec(ClientDUID, Iface, v->getVendor(), ORO); break; } case OPTION_AAAAUTH: { Log(Debug) << "Auth: Option AAAAuthentication received." << LogEnd; break; } case OPTION_PREFERENCE: case OPTION_UNICAST: case OPTION_SERVERID: case OPTION_RELAY_MSG: case OPTION_INTERFACE_ID: { Log(Warning) << "Invalid option (" << opt->getOptType() << ") received." << LogEnd; break; } case OPTION_DNS_SERVERS: case OPTION_DOMAIN_LIST: case OPTION_SNTP_SERVERS: case OPTION_NEW_TZDB_TIMEZONE: { handleDefaultOption(opt); break; } // options not yet supported case OPTION_USER_CLASS : case OPTION_VENDOR_CLASS: case OPTION_RECONF_MSG : case OPTION_RECONF_ACCEPT: default: { Log(Debug) << "Option " << opt->getOptType() << " is not supported." << LogEnd; break; } } // end of switch } // end of while // append serverID, preference and possibly unicast appendMandatoryOptions(ORO); //if client requested parameters and policy doesn't forbid from answering appendRequestedOptions(ClientDUID, clntAddr, Iface, ORO); appendStatusCode(); // this is ADVERTISE only, so we need to release assigned addresses this->firstOption(); while ( opt = this->getOption()) { switch (opt->getOptType()) { case OPTION_IA_NA: { SPtr<TSrvOptIA_NA> ptrOptIA_NA; ptrOptIA_NA = (Ptr*) opt; ptrOptIA_NA->releaseAllAddrs(false); break; } case OPTION_IA_TA: { SPtr<TSrvOptTA> ta; ta = (Ptr*) opt; ta->releaseAllAddrs(false); break; } default: break; } } appendAuthenticationOption(ClientDUID); pkt = new char[this->getSize()]; MRT = 0; send(); return true; }