Exemplo n.º 1
0
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();
}
Exemplo n.º 2
0
/**
 * 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();
}
Exemplo n.º 3
0
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();
}
Exemplo n.º 4
0
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();
}