void TClntTransMgr::relayMsg(SPtr<TClntMsg> msgAnswer) { SPtr<TIfaceIface> ifaceQuestion; SPtr<TIfaceIface> ifaceAnswer; // is message valid? if (!msgAnswer->check()) return ; if (msgAnswer->getType() == RECONFIGURE_MSG) { handleReconfigure(msgAnswer); return; } #ifdef MOD_REMOTE_AUTOCONF if (neighborInfoGet(msgAnswer->getTransID())) { processRemoteReply(msgAnswer); return; } #endif // find which message this is answer for bool found = false; SPtr<TClntMsg> msgQuestion; Transactions.first(); while( msgQuestion = SPtr_cast<TClntMsg>(Transactions.get())) { if (msgQuestion->getTransID()==msgAnswer->getTransID()) { found =true; if (msgQuestion->getIface()!=msgAnswer->getIface()) { ifaceQuestion = ClntIfaceMgr().getIfaceByID(msgQuestion->getIface()); ifaceAnswer = ClntIfaceMgr().getIfaceByID(msgAnswer->getIface()); Log(Warning) << "Reply for transaction 0x" << hex << msgQuestion->getTransID() << dec << " sent on " << ifaceQuestion->getFullName() << " was received on interface " << ifaceAnswer->getFullName() << "." << LogEnd; // return; // don't return, just fix interface ID // useful, when sending thru eth0, but receiving via loopback msgAnswer->setIface(msgQuestion->getIface()); } handleResponse(msgQuestion, msgAnswer); break; } } if (!found) { if (!Shutdown) Log(Warning) << "Message with wrong transID (0x" << hex << msgAnswer->getTransID() << dec << ") received. Ignoring." << LogEnd; else Log(Debug) << "Message with transID=0x" << hex << msgAnswer->getTransID() << dec << " received, but ignored during shutdown." << LogEnd; } ClntCfgMgr().dump(); ClntAddrMgr().dump(); }
/** * relays normal (i.e. not server replies) messages to defined servers */ void TRelTransMgr::relayMsg(SPtr<TRelMsg> msg) { static char buf[MAX_PACKET_LEN]; int offset = 0; int bufLen; int hopCount = 0; if (!msg->check()) { Log(Warning) << "Invalid message received." << LogEnd; return; } if (msg->getDestAddr()) { this->relayMsgRepl(msg); return; } if (msg->getType() == RELAY_FORW_MSG) { hopCount = msg->getHopCount()+1; } // prepare message SPtr<TIfaceIface> iface = RelIfaceMgr().getIfaceByID(msg->getIface()); SPtr<TIPv6Addr> addr; // store header buf[offset++] = RELAY_FORW_MSG; buf[offset++] = hopCount; // store link-addr iface->firstGlobalAddr(); addr = iface->getGlobalAddr(); if (!addr) { Log(Warning) << "Interface " << iface->getFullName() << " does not have global address." << LogEnd; addr = new TIPv6Addr("::", true); } addr->storeSelf(buf+offset); offset += 16; // store peer-addr addr = msg->getRemoteAddr(); addr->storeSelf(buf+offset); offset += 16; SPtr<TRelCfgIface> cfgIface; cfgIface = RelCfgMgr().getIfaceByID(msg->getIface()); TRelOptInterfaceID ifaceID(cfgIface->getInterfaceID(), 0); if (RelCfgMgr().getInterfaceIDOrder()==REL_IFACE_ID_ORDER_BEFORE) { // store InterfaceID option ifaceID.storeSelf(buf + offset); offset += ifaceID.getSize(); Log(Debug) << "Interface-id option added before relayed message." << LogEnd; } // store relay msg option writeUint16((buf+offset), OPTION_RELAY_MSG); offset += sizeof(uint16_t); writeUint16((buf+offset), msg->getSize()); offset += sizeof(uint16_t); bufLen = msg->storeSelf(buf+offset); offset += bufLen; if (RelCfgMgr().getInterfaceIDOrder()==REL_IFACE_ID_ORDER_AFTER) { // store InterfaceID option ifaceID.storeSelf(buf + offset); offset += ifaceID.getSize(); Log(Debug) << "Interface-id option added after relayed message." << LogEnd; } if (RelCfgMgr().getInterfaceIDOrder()==REL_IFACE_ID_ORDER_NONE) { Log(Warning) << "Interface-id option not added (interface-id-order omit used in relay.conf). " << "That is a debugging feature and violates RFC3315. Use with caution." << LogEnd; } SPtr<TOptVendorData> remoteID = RelCfgMgr().getRemoteID(); if (remoteID) { remoteID->storeSelf(buf+offset); offset += remoteID->getSize(); Log(Debug) << "Appended RemoteID with " << remoteID->getVendorDataLen() << "-byte long data (option length=" << remoteID->getSize() << ")." << LogEnd; } SPtr<TOpt> relayID = RelCfgMgr().getRelayID(); if (relayID) { relayID->storeSelf(buf + offset); offset += relayID->getSize(); Log(Debug) << "Appended Relay-ID with " << relayID->getSize() << " bytes." << LogEnd; } if (RelCfgMgr().getClientLinkLayerAddress()) { SPtr<TOpt> lladdr = getClientLinkLayerAddr(msg); if (lladdr) { Log(Debug) << "Appended client link-layer address option with " << lladdr->getSize() << " bytes." << LogEnd; lladdr->storeSelf(buf + offset); offset += lladdr->getSize(); } } SPtr<TRelOptEcho> echo = RelCfgMgr().getEcho(); if (echo) { echo->storeSelf(buf+offset); offset += echo->getSize(); Log(Debug) << "Appended EchoRequest option with "; int i=0; char tmpBuf[256]; for (i=0;i<255;i++) tmpBuf[i] = 255-i; for (int i=0; i<echo->count(); i++) { int code = echo->getReqOpt(i); SPtr<TRelOptGeneric> gen = new TRelOptGeneric(code, tmpBuf, 4, 0); gen->storeSelf(buf+offset); offset += gen->getSize(); Log(Cont) << code << " "; } Log(Cont) << " opt(s)." << LogEnd; } RelCfgMgr().firstIface(); while (cfgIface = RelCfgMgr().getIface()) { if (cfgIface->getServerUnicast()) { Log(Notice) << "Relaying encapsulated " << msg->getName() << " message on the " << cfgIface->getFullName() << " interface to unicast (" << cfgIface->getServerUnicast()->getPlain() << ") address, port " << DHCPSERVER_PORT << "." << LogEnd; if (!RelIfaceMgr().send(cfgIface->getID(), buf, offset, cfgIface->getServerUnicast(), DHCPSERVER_PORT)) { Log(Error) << "Failed to send data to server unicast address." << LogEnd; } } if (cfgIface->getServerMulticast()) { addr = new TIPv6Addr(ALL_DHCP_SERVERS, true); Log(Notice) << "Relaying encapsulated " << msg->getName() << " message on the " << cfgIface->getFullName() << " interface to multicast (" << addr->getPlain() << ") address, port " << DHCPSERVER_PORT << "." << LogEnd; if (!RelIfaceMgr().send(cfgIface->getID(), buf, offset, addr, DHCPSERVER_PORT)) { Log(Error) << "Failed to send data to server multicast address." << LogEnd; } } } // save DB state regardless of action taken RelCfgMgr().dump(); }
void TSrvTransMgr::relayMsg(SPtr<TSrvMsg> msg) { if (!msg->check()) { // proper warnings will be printed in the check() method, if necessary. // Log(Warning) << "Invalid message received." << LogEnd; return; } // If unicast is disabled and the client sent it to unicast, // send back status code with UseMulticast and be done with it. if (!unicastCheck(msg)) { Log(Warning) << "Message was dropped, because it was sent to unicast and " << "unicast traffic is not allowed." << LogEnd; return; } SPtr<TSrvCfgIface> cfgIface = SrvCfgMgr().getIfaceByID(msg->getIface()); if (!cfgIface) { Log(Error) << "Received message on unknown interface (ifindex=" << msg->getIface() << LogEnd; return; } // LEASE ASSIGN STEP 1: Evaluate defined expressions (client classification) // Ask NodeClietSpecific to analyse the message NodeClientSpecific::analyseMessage(msg); // LEASE ASSIGN STEP 2: Is this client supported? // is this client supported? (white-list, black-list) if (!SrvCfgMgr().isClntSupported(msg)) { return; } SPtr<TMsg> q, a; // question and answer q = (Ptr*) msg; switch(msg->getType()) { case SOLICIT_MSG: { if (msg->getOption(OPTION_RAPID_COMMIT)) { if (!cfgIface->getRapidCommit()) { Log(Info) << "SOLICIT with RAPID-COMMIT received, but RAPID-COMMIT is disabled on " << cfgIface->getName() << " interface." << LogEnd; a = new TSrvMsgAdvertise((Ptr*)msg); } else { SPtr<TSrvMsgSolicit> nmsg = (Ptr*)msg; a = new TSrvMsgReply(nmsg); } } else { a = new TSrvMsgAdvertise( (Ptr*) msg); } break; } case REQUEST_MSG: { SPtr<TSrvMsgRequest> nmsg = (Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case CONFIRM_MSG: { SPtr<TSrvMsgConfirm> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case RENEW_MSG: { SPtr<TSrvMsgRenew> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case REBIND_MSG: { SPtr<TSrvMsgRebind> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case DECLINE_MSG: { SPtr<TSrvMsgDecline> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case RELEASE_MSG: { SPtr<TSrvMsgRelease> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case INFORMATION_REQUEST_MSG : { SPtr<TSrvMsgInfRequest> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case LEASEQUERY_MSG: { int iface = msg->getIface(); if (!SrvCfgMgr().getIfaceByID(iface) || !SrvCfgMgr().getIfaceByID(iface)->leaseQuerySupport()) { Log(Error) << "LQ: LeaseQuery message received on " << iface << " interface, but it is not supported there." << LogEnd; return; } Log(Debug) << "LQ: LeaseQuery received, preparing RQ_REPLY" << LogEnd; SPtr<TSrvMsgLeaseQuery> lq = (Ptr*)msg; a = new TSrvMsgLeaseQueryReply(lq); break; } case RECONFIGURE_MSG: case ADVERTISE_MSG: case REPLY_MSG: { Log(Warning) << "Invalid message type received: " << msg->getType() << LogEnd; break; } case RELAY_FORW_MSG: // They should be decapsulated earlier case RELAY_REPL_MSG: default: { Log(Warning)<< "Message type " << msg->getType() << " not supported." << LogEnd; break; } } if (a && !a->isDone()) { SPtr<TSrvMsg> answ = (Ptr*)a; // Send the packet sendPacket(answ); // Call notify script SrvIfaceMgr().notifyScripts(SrvCfgMgr().getScriptName(), q, a); } // save DB state regardless of action taken SrvAddrMgr().dump(); SrvCfgMgr().dump(); }
void TSrvTransMgr::relayMsg(SPtr<TSrvMsg> msg) { if (!msg->check()) { // proper warnings will be printed in the check() method, if necessary. // Log(Warning) << "Invalid message received." << LogEnd; return; } // LEASE ASSIGN STEP 1: Evaluate defined expressions (client classification) // Ask NodeClietSpecific to analyse the message NodeClientSpecific::analyseMessage(msg); // LEASE ASSIGN STEP 2: Is this client supported? // is this client supported? (white-list, black-list) if (!SrvCfgMgr().isClntSupported(msg)) { return; } /// @todo remove (or at least disable by default) answer buffering mechanism SPtr<TSrvMsg> answ; Log(Debug) << MsgLst.count() << " answers buffered."; MsgLst.first(); while(answ=(Ptr*)MsgLst.get()) { if (answ->getTransID()==msg->getTransID() && msg->getType() != RELEASE_MSG ) { Log(Cont) << " Old reply with transID=" << hex << msg->getTransID() << dec << " found. Sending old reply." << LogEnd; answ->send(); return; } } Log(Cont) << " Old reply for transID=" << hex << msg->getTransID() << " not found. Generating new answer." << dec << LogEnd; SPtr<TMsg> q, a; // question and answer q = (Ptr*) msg; switch(msg->getType()) { case SOLICIT_MSG: { SPtr<TSrvCfgIface> ptrCfgIface = SrvCfgMgr().getIfaceByID(msg->getIface()); if (msg->getOption(OPTION_RAPID_COMMIT)) { if (!ptrCfgIface->getRapidCommit()) { Log(Info) << "SOLICIT with RAPID-COMMIT received, but RAPID-COMMIT is disabled on " << ptrCfgIface->getName() << " interface." << LogEnd; a = new TSrvMsgAdvertise((Ptr*)msg); } else { SPtr<TSrvMsgSolicit> nmsg = (Ptr*)msg; a = new TSrvMsgReply(nmsg); } } else { a = new TSrvMsgAdvertise( (Ptr*) msg); } break; } case REQUEST_MSG: { SPtr<TSrvMsgRequest> nmsg = (Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case CONFIRM_MSG: { SPtr<TSrvMsgConfirm> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case RENEW_MSG: { SPtr<TSrvMsgRenew> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case REBIND_MSG: { SPtr<TSrvMsgRebind> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case DECLINE_MSG: { SPtr<TSrvMsgDecline> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case RELEASE_MSG: { SPtr<TSrvMsgRelease> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case INFORMATION_REQUEST_MSG : { SPtr<TSrvMsgInfRequest> nmsg=(Ptr*)msg; a = new TSrvMsgReply(nmsg); break; } case LEASEQUERY_MSG: { if(!msg->Bulk) { int iface = msg->getIface(); if (!SrvCfgMgr().getIfaceByID(iface) || !SrvCfgMgr().getIfaceByID(iface)->leaseQuerySupport() ) { Log(Error) << "LQ: LeaseQuery message received on " << iface << " interface, but it is not supported there." << LogEnd; return; } Log(Debug) << "LQ: LeaseQuery received, preparing RQ_REPLY" << LogEnd; SPtr<TSrvMsgLeaseQuery> lq = (Ptr*) msg; a = new TSrvMsgLeaseQueryReply(lq); //TSrvMsgLeaseQuery(int iface, SPtr<TIPv6Addr> addr, char* buf, // int bufSize,int MsgType, bool tcp = false); break; } else { int iface = msg->getIface(); if (!SrvCfgMgr().getIfaceByID(iface) || (!SrvCfgMgr().getIfaceByID(iface)->bulkLeaseQuerySupport()) ) { Log(Error) << "BLQ: LeaseQuery message received on " << iface << " interface, but it is not supported there." << LogEnd; return; } Log(Debug) << "BLQ: Bulk LeaseQuery received, preparing RQ_REPLY" << LogEnd; SPtr<TSrvMsgLeaseQuery> lq = (Ptr*) msg; a = new TSrvMsgLeaseQueryReply(lq); //TSrvMsgLeaseQuery(int iface, SPtr<TIPv6Addr> addr, char* buf, // int bufSize,int MsgType, bool tcp = false); break; } } case RECONFIGURE_MSG: case ADVERTISE_MSG: case REPLY_MSG: { Log(Warning) << "Invalid message type received: " << msg->getType() << LogEnd; break; } case RELAY_FORW_MSG: // They should be decapsulated earlier case RELAY_REPL_MSG: default: { Log(Warning)<< "Message type " << msg->getType() << " not supported." << LogEnd; break; } } if (a) { /// @todo: messages should not call send() in their ctors, send should be done here MsgLst.append((Ptr*)a); SrvIfaceMgr().notifyScripts(SrvCfgMgr().getScriptName(), q, a); } // save DB state regardless of action taken SrvAddrMgr().dump(); SrvCfgMgr().dump(); }