Exemplo n.º 1
0
 void AclReader::printConnectionRules(const std::string name, const AclData::bwHostRuleSet& rules) const {
     QPID_LOG(debug, "ACL: " << name << " Connection Rule list : " << rules.size() << " rules found :");
     int cnt = 1;
     for (AclData::bwHostRuleSetItr i=rules.begin(); i<rules.end(); i++,cnt++) {
         QPID_LOG(debug, "ACL:   " << std::setfill(' ') << std::setw(2) << cnt << " " << i->toString());
     }
 }
Exemplo n.º 2
0
void TimerWarnings::log() {
    if (!taskStats.empty() && nextReport < now()) {
        for (TaskStatsMap::iterator i = taskStats.begin(); i != taskStats.end(); ++i) {
            std::string task = i->first;
            TaskStats& stats = i->second;
            if (stats.lateDelay.count)
                QPID_LOG(info, task << " task late "
                         << stats.lateDelay.count << " times by "
                         << stats.lateDelay.average()/TIME_MSEC << "ms on average.");

            if (stats.overranOverrun.count)
                QPID_LOG(info, task << " task overran "
                         << stats.overranOverrun.count << " times by "
                         << stats.overranOverrun.average()/TIME_MSEC << "ms (taking "
                         << stats.overranTime.average() << "ns) on average.");

            if (stats.lateAndOverranOverrun.count)
                QPID_LOG(info, task << " task late and overran "
                         << stats.lateAndOverranOverrun.count << " times: late "
                         << stats.lateAndOverranDelay.average()/TIME_MSEC << "ms, overran "
                         << stats.lateAndOverranOverrun.average()/TIME_MSEC << "ms (taking "
                         << stats.lateAndOverranTime.average() << "ns) on average.");

        }
        nextReport = AbsTime(now(), interval);
        taskStats.clear();
    }
}
Exemplo n.º 3
0
// Handler for deliverEventQueue.
// This thread decodes frames from events.
void Cluster::deliveredEvent(const Event& e) {
    if (e.isCluster()) {
        EventFrame ef(e, e.getFrame());
        // Stop the deliverEventQueue on update offers.
        // This preserves the connection decoder fragments for an update.
        // Only do this for the two brokers that are directly involved in this
        // offer: the one making the offer, or the one receiving it.
        const ClusterUpdateOfferBody* offer = castUpdateOffer(ef.frame.getBody());
        if (offer && ( e.getMemberId() == self || MemberId(offer->getUpdatee()) == self) ) {
            QPID_LOG(info, *this << " stall for update offer from " << e.getMemberId()
                     << " to " << MemberId(offer->getUpdatee()));
            deliverEventQueue.stop();
        }
        deliverFrame(ef);
    }
    else if(!discarding) {
        if (e.isControl())
            deliverFrame(EventFrame(e, e.getFrame()));
        else {
            try { decoder.decode(e, e.getData()); }
            catch (const Exception& ex) {
                // Close a connection that is sending us invalid data.
                QPID_LOG(error, *this << " aborting connection "
                         << e.getConnectionId() << ": " << ex.what());
                framing::AMQFrame abort((ClusterConnectionAbortBody()));
                deliverFrame(EventFrame(EventHeader(CONTROL, e.getConnectionId()), abort));
            }
        }
    }
}
Exemplo n.º 4
0
qpid::sys::ConnectionCodec* ProtocolImpl::create(const qpid::framing::ProtocolVersion& v, qpid::sys::OutputControl& out, const std::string& id, const qpid::sys::SecuritySettings& external)
{
    if (v == qpid::framing::ProtocolVersion(1, 0)) {
        if (v.getProtocol() == qpid::framing::ProtocolVersion::SASL) {
            if (broker.getOptions().auth) {
                QPID_LOG(info, "Using AMQP 1.0 (with SASL layer)");
                return new qpid::broker::amqp::Sasl(out, id, broker, *interconnects,
                                                    qpid::SaslFactory::getInstance().createServer(broker.getOptions().realm,broker.getOptions().requireEncrypted, external),
                                                    domain);
            } else {
                std::auto_ptr<SaslServer> authenticator(new qpid::NullSaslServer(broker.getOptions().realm));
                QPID_LOG(info, "Using AMQP 1.0 (with dummy SASL layer)");
                return new qpid::broker::amqp::Sasl(out, id, broker, *interconnects, authenticator, domain);
            }
        } else {
            if (broker.getOptions().auth) {
                throw qpid::Exception("SASL layer required!");
            } else {
                QPID_LOG(info, "Using AMQP 1.0 (no SASL layer)");
                return new qpid::broker::amqp::Connection(out, id, broker, *interconnects, false, domain);
            }
        }
    }
    return 0;
}
Exemplo n.º 5
0
//delivery-annotations, message-annotations, application-properties, amqp-value
bool MessageReader::onStartMap(uint32_t count, const CharSequence& elements, const CharSequence& raw, const Descriptor* descriptor)
{
    if (delegate) {
        return delegate->onStartMap(count, elements, raw, descriptor);
    } else {
        if (!descriptor) {
            QPID_LOG(warning, "Expected described type but got no descriptor for map.");
            return false;
        } else if (descriptor->match(DELIVERY_ANNOTATIONS_SYMBOL, DELIVERY_ANNOTATIONS_CODE)) {
            onDeliveryAnnotations(elements, raw);
            return false;
        } else if (descriptor->match(MESSAGE_ANNOTATIONS_SYMBOL, MESSAGE_ANNOTATIONS_CODE)) {
            onMessageAnnotations(elements, raw);
            return false;
        } else if (descriptor->match(FOOTER_SYMBOL, FOOTER_CODE)) {
            onFooter(elements, raw);
            return false;
        } else if (descriptor->match(APPLICATION_PROPERTIES_SYMBOL, APPLICATION_PROPERTIES_CODE)) {
            onApplicationProperties(elements, raw);
            return false;
        } else if (descriptor->match(AMQP_VALUE_SYMBOL, AMQP_VALUE_CODE)) {
            onAmqpValue(elements, qpid::amqp::typecodes::MAP_NAME);
            return false;
        } else {
            QPID_LOG(warning, "Unexpected described map: " << *descriptor);
            return false;
        }
    }
}
Exemplo n.º 6
0
//header, properties, amqp-sequence, amqp-value
bool MessageReader::onStartList(uint32_t count, const CharSequence& elements, const CharSequence& raw, const Descriptor* descriptor)
{
    if (delegate) {
        return delegate->onStartList(count, elements, raw, descriptor);
    } else {
        if (!descriptor) {
            QPID_LOG(warning, "Expected described type but got no descriptor for list.");
            return false;
        } else if (descriptor->match(HEADER_SYMBOL, HEADER_CODE)) {
            delegate = &headerReader;
            return true;
        } else if (descriptor->match(PROPERTIES_SYMBOL, PROPERTIES_CODE)) {
            delegate = &propertiesReader;
            return true;
        } else if (descriptor->match(AMQP_SEQUENCE_SYMBOL, AMQP_SEQUENCE_CODE)) {
            onAmqpSequence(raw);
            return false;
        } else if (descriptor->match(AMQP_VALUE_SYMBOL, AMQP_VALUE_CODE)) {
            onAmqpValue(elements, qpid::amqp::typecodes::LIST_NAME);
            return false;
        } else {
            QPID_LOG(warning, "Unexpected described list: " << *descriptor);
            return false;
        }
    }
}
Exemplo n.º 7
0
 // Debug aid
 void AclReader::printRules() const {
     QPID_LOG(debug, "ACL: Rule list: " << rules.size() << " ACL rules found:");
     int cnt = 1;
     for (rlCitr i=rules.begin(); i<rules.end(); i++,cnt++) {
         QPID_LOG(debug, "ACL:   " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString());
     }
 }
Exemplo n.º 8
0
//
// closed - called during Connection's destructor
//
void ConnectionCounter::closed(broker::Connection& connection) {
    QPID_LOG(trace, "ACL ConnectionCounter closed: " << connection.getMgmtId()
        << ", userId:" << connection.getUserId());

    Mutex::ScopedLock locker(dataLock);

    connectCountsMap_t::iterator eRef = connectProgressMap.find(connection.getMgmtId());
    if (eRef != connectProgressMap.end()) {
        if ((*eRef).second == C_OPENED){
            // Normal case: connection was created and opened.
            // Decrement user in-use counts
            releaseLH(connectByNameMap,
                      connection.getUserId());
        } else {
            // Connection was created but not opened.
            // Don't decrement user count.
        }

        // Decrement host in-use count.
        releaseLH(connectByHostMap,
                  getClientHost(connection.getMgmtId()));

        // destroy connection progress indicator
        connectProgressMap.erase(eRef);

    } else {
        // connection not found in progress map
        QPID_LOG(notice, "ACL ConnectionCounter closed info for '" << connection.getMgmtId()
            << "' not found in connection state pool");
    }

    // total connections
    totalCurrentConnections -= 1;
}
Exemplo n.º 9
0
/**
 * Called when a delivery is writable
 */
void OutgoingFromRelay::handle(pn_delivery_t* delivery)
{
    void* context = pn_delivery_get_context(delivery);
    BufferedTransfer* transfer = reinterpret_cast<BufferedTransfer*>(context);
    assert(transfer);
    if (pn_delivery_writable(delivery)) {
        if (transfer->write(link)) {
            outgoingMessageSent();
            QPID_LOG(debug, "Sent relayed message " << name << " [" << relay.get() << "]");
        } else {
            QPID_LOG(error, "Failed to send relayed message " << name << " [" << relay.get() << "]");
        }
    }
    if (pn_delivery_updated(delivery)) {
        uint64_t d = transfer->updated();
        switch (d) {
          case PN_ACCEPTED:
            outgoingMessageAccepted();
            break;
          case PN_REJECTED:
          case PN_RELEASED://TODO: not quite true...
          case PN_MODIFIED://TODO: not quite true...
            outgoingMessageRejected();
            break;
          default:
            QPID_LOG(warning, "Unhandled disposition: " << d);
        }
    }
}
Exemplo n.º 10
0
//
// approveConnection
//  check total connections, connections from IP, connections by user and
//  disallow if over any limit
//
bool ConnectionCounter::approveConnection(
        const broker::Connection& connection,
        bool enforcingConnectionQuotas,
        uint16_t connectionUserQuota )
{
    const std::string& hostName(getClientHost(connection.getMgmtId()));
    const std::string& userName(              connection.getUserId());

    Mutex::ScopedLock locker(dataLock);

    // Bump state from CREATED to OPENED
    (void) countConnectionLH(connectProgressMap, connection.getMgmtId(),
                             C_OPENED, false, false);

    // Approve total connections
    bool okTotal  = true;
    if (totalLimit > 0) {
        okTotal = totalCurrentConnections <= totalLimit;
        QPID_LOG(trace, "ACL ConnectionApprover totalLimit=" << totalLimit
                 << " curValue=" << totalCurrentConnections
                 << " result=" << (okTotal ? "allow" : "deny"));
    }

    // Approve by IP host connections
    bool okByIP   = limitApproveLH(connectByHostMap, hostName, hostLimit, true);

    // Count and Approve the connection by the user
    bool okByUser = countConnectionLH(connectByNameMap, userName,
                                      connectionUserQuota, true,
                                      enforcingConnectionQuotas);

    // Emit separate log for each disapproval
    if (!okTotal) {
        QPID_LOG(error, "Client max total connection count limit of " << totalLimit
                 << " exceeded by '"
                 << connection.getMgmtId() << "', user: '******'. Connection refused");
    }
    if (!okByIP) {
        QPID_LOG(error, "Client max per-host connection count limit of "
                 << hostLimit << " exceeded by '"
                 << connection.getMgmtId() << "', user: '******'. Connection refused.");
    }
    if (!okByUser) {
        QPID_LOG(error, "Client max per-user connection count limit of "
                 << connectionUserQuota << " exceeded by '"
                 << connection.getMgmtId() << "', user: '******'. Connection refused.");
    }

    // Count/Event once for each disapproval
    bool result = okTotal && okByIP && okByUser;
    if (!result) {
        acl.reportConnectLimit(userName, hostName);
    }

    return result;
}
Exemplo n.º 11
0
 // Debug aid
 void AclReader::printRules() const {
     QPID_LOG(debug, "ACL: Rule list: " << rules.size() << " ACL rules found:");
     int cnt = 1;
     for (rlCitr i=rules.begin(); i<rules.end(); i++,cnt++) {
         QPID_LOG(debug, "ACL:   " << std::setfill(' ') << std::setw(2) << cnt << " " << (*i)->toString());
         if (!(*i)->actionAll && (*i)->objStatus == aclRule::VALUE) {
             (void)validator.validateAllowedProperties((*i)->action, (*i)->object, (*i)->props, true);
         }
     }
 }
Exemplo n.º 12
0
 void received(Message& message)
 {
     QPID_LOG(debug, "received: " << message.getData() << " for " << message.getDestination());
     if (message.getDestination() == source) {
         receivedFromSource(message);
     } else if (message.getDestination() == control) {
         receivedFromControl(message);
     } else {
         QPID_LOG(error, "Unexpected message: " << message.getData() << " to " << message.getDestination());
     }
 }
Exemplo n.º 13
0
void Quorum::start(boost::shared_ptr<sys::Poller> p) {
    poller = p;
    QPID_LOG(debug, "Connecting to quorum service.");
    cman = cman_init(0);
    if (cman == 0) throw ErrnoException("Can't connect to cman service");
    if (!cman_is_quorate(cman)) {
        QPID_LOG(notice, "Waiting for cluster quorum.");
        while(!cman_is_quorate(cman)) sys::sleep(5);
    }
    int err = cman_start_notification(cman, cmanCallbackFn);
    if (err != 0) throw ErrnoException("Can't register for cman notifications");
    watch(getFd());
}
Exemplo n.º 14
0
void ConnectionContext::attach(pn_session_t* /*session*/, pn_link_t* link, int credit)
{
    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
    QPID_LOG(debug, "Attaching link " << link << ", state=" << pn_link_state(link));
    pn_link_open(link);
    QPID_LOG(debug, "Link attached " << link << ", state=" << pn_link_state(link));
    if (credit) pn_link_flow(link, credit);
    wakeupDriver();
    while (pn_link_state(link) & PN_REMOTE_UNINIT) {
        QPID_LOG(debug, "waiting for confirmation of link attach for " << link << ", state=" << pn_link_state(link));
        wait();
    }
}
Exemplo n.º 15
0
    void enqueue(TransactionContext* ,
                 const boost::intrusive_ptr<PersistableMessage>& pmsg,
                 const PersistableQueue& )
    {
        qpid::broker::amqp_0_10::MessageTransfer* msg = dynamic_cast<qpid::broker::amqp_0_10::MessageTransfer*>(pmsg.get());
        assert(msg);

        // Dump the message if there is a dump file.
        if (dump.get()) {
            msg->getFrames().getMethod()->print(*dump);
            *dump  << endl << "  ";
            msg->getFrames().getHeaders()->print(*dump);
            *dump << endl << "  ";
            *dump << msg->getFrames().getContentSize() << endl;
        }

        // Check the message for special instructions.
        string data = msg->getFrames().getContent();
        size_t i = string::npos;
        size_t j = string::npos;
        if (strncmp(data.c_str(), TEST_STORE_DO.c_str(), strlen(TEST_STORE_DO.c_str())) == 0
            && (i = data.find(name+"[")) != string::npos
            && (j = data.find("]", i)) != string::npos)
        {
            size_t start = i+name.size()+1;
            string action = data.substr(start, j-start);

            if (action == EXCEPTION) {
                throw Exception(QPID_MSG("TestStore " << name << " throwing exception for: " << data));
            }
            else if (action == EXIT_PROCESS) {
                // FIXME aconway 2009-04-10: this is a dubious way to
                // close the process at best, it can cause assertions or seg faults
                // rather than clean exit.
                QPID_LOG(critical, "TestStore " << name << " forcing process exit for: " << data);
                exit(0);
            }
            else if (strncmp(action.c_str(), ASYNC.c_str(), strlen(ASYNC.c_str())) == 0) {
                std::string delayStr(action.substr(ASYNC.size()));
                int delay = boost::lexical_cast<int>(delayStr);
                threads.push_back(Thread(*new Completer(msg, delay)));
            }
            else {
                QPID_LOG(error, "TestStore " << name << " unknown action " << action);
                msg->enqueueComplete();
            }
        }
        else
            msg->enqueueComplete();
    }
Exemplo n.º 16
0
    // Return true if the line is successfully processed without errors
    // If cont is true, then groupName must be set to the continuation group name
    bool AclReader::processGroupLine(tokList& toks, const bool cont) {
        const unsigned toksSize = toks.size();

        if (contFlag) {
            gmCitr citr = groups.find(groupName);
            for (unsigned i = 0; i < toksSize; i++) {
                if (isValidGroupName(toks[i])) {
                    if (toks[i] == groupName) {
                        QPID_LOG(debug, "ACL: Line: " << lineNumber
                            << ", Ignoring recursive sub-group \"" << toks[i] << "\".");
                        continue;
                    } else if (groups.find(toks[i]) == groups.end()) {
                        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
                            << ", Sub-group \"" << toks[i] << "\" not defined yet.";
                        return false;
                    }
                } else if (!isValidUserName(toks[i])) return false;
                addName(toks[i], citr->second);
            }
        } else {
            const unsigned minimumSize = (cont ? 2 : 3);
            if (toksSize < minimumSize) {
                errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
                    << ", Insufficient tokens for group definition.";
                return false;
            }
            if (!isValidGroupName(toks[1])) {
                errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
                    << ", Group name \"" << toks[1] << "\" contains illegal characters.";
                return false;
            }
            gmCitr citr = addGroup(toks[1]);
            if (citr == groups.end()) return false;
            for (unsigned i = 2; i < toksSize; i++) {
                if (isValidGroupName(toks[i])) {
                    if (toks[i] == groupName) {
                        QPID_LOG(debug, "ACL: Line: " << lineNumber
                            << ", Ignoring recursive sub-group \"" << toks[i] << "\".");
                        continue;
                    } else if (groups.find(toks[i]) == groups.end()) {
                        errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
                            << ", Sub-group \"" << toks[i] << "\" not defined yet.";
                        return false;
                    }
                } else if (!isValidUserName(toks[i])) return false;
                addName(toks[i], citr->second);
            }
        }
        return true;
    }
Exemplo n.º 17
0
/**
 * Expects lock to be held by caller
 */
void ConnectionContext::wakeupDriver()
{
    switch (state) {
      case CONNECTED:
        haveOutput = true;
        transport->activateOutput();
        QPID_LOG(debug, "wakeupDriver()");
        break;
      case DISCONNECTED:
      case CONNECTING:
        QPID_LOG(error, "wakeupDriver() called while not connected");
        break;
    }
}
Exemplo n.º 18
0
bool SaslClient::onStartList(uint32_t count, const CharSequence& arguments, const CharSequence& /*full raw data*/, const Descriptor* descriptor)
{
    if (!descriptor) {
        QPID_LOG(error, "Expected described type in SASL negotiation but got no descriptor");
    } else if (descriptor->match(SASL_MECHANISMS_SYMBOL, SASL_MECHANISMS_CODE)) {
        QPID_LOG(trace, "Reading SASL-MECHANISMS");
        Decoder decoder(arguments.data, arguments.size);
        if (count != 1) QPID_LOG(error, "Invalid SASL-MECHANISMS frame; exactly one field expected, got " << count);
        SaslMechanismsReader reader(*this);
        decoder.read(reader);
    } else if (descriptor->match(SASL_CHALLENGE_SYMBOL, SASL_CHALLENGE_CODE)) {
        QPID_LOG(trace, "Reading SASL-CHALLENGE");
        Decoder decoder(arguments.data, arguments.size);
        if (count != 1) QPID_LOG(error, "Invalid SASL-CHALLENGE frame; exactly one field expected, got " << count);
        SaslChallengeReader reader(*this);
        decoder.read(reader);
    } else if (descriptor->match(SASL_OUTCOME_SYMBOL, SASL_OUTCOME_CODE)) {
        QPID_LOG(trace, "Reading SASL-OUTCOME");
        Decoder decoder(arguments.data, arguments.size);
        if (count == 1) {
            SaslOutcomeReader reader(*this, false);
            decoder.read(reader);
        } else if (count == 2) {
            SaslOutcomeReader reader(*this, true);
            decoder.read(reader);
        } else {
            QPID_LOG(error, "Invalid SASL-OUTCOME frame; got " << count << " fields");
        }
    } else {
        QPID_LOG(error, "Unexpected descriptor in SASL negotiation: " << *descriptor);
    }
    return false;
}
Exemplo n.º 19
0
void Cluster::memberUpdate(Lock& l) {
    // Ignore config changes while we are joining.
    if (state < CATCHUP) return;
    QPID_LOG(info, *this << " member update: " << map);
    size_t aliveCount = map.aliveCount();
    assert(map.isAlive(self));
    failoverExchange->updateUrls(getUrls(l));

    // Mark store clean if I am the only broker, dirty otherwise.
    if (store.hasStore()) {
        if (aliveCount == 1) {
            if (store.getState() != STORE_STATE_CLEAN_STORE) {
                QPID_LOG(notice, *this << "Sole member of cluster, marking store clean.");
                store.clean(Uuid(true));
            }
        }
        else {
            if (store.getState() != STORE_STATE_DIRTY_STORE) {
                QPID_LOG(notice, "Running in a cluster, marking store dirty.");
                store.dirty();
            }
        }
    }

    // If I am the last member standing, set queue policies.
    if (aliveCount == 1 && lastAliveCount > 1 && state >= CATCHUP) {
        QPID_LOG(notice, *this << " last broker standing, update queue policies");
        lastBroker = true;
        broker.getQueues().updateQueueClusterState(true);
    }
    else if (aliveCount > 1 && lastBroker) {
        QPID_LOG(notice, *this << " last broker standing joined by " << aliveCount-1
                 << " replicas, updating queue policies.");
        lastBroker = false;
        broker.getQueues().updateQueueClusterState(false);
    }
    lastAliveCount = aliveCount;

    // Close connections belonging to members that have left the cluster.
    ConnectionMap::iterator i = connections.begin();
    while (i != connections.end()) {
        ConnectionMap::iterator j = i++;
        MemberId m = j->second->getId().getMember();
        if (m != self && !map.isMember(m)) {
            j->second->close();
            erase(j->second->getId(), l);
        }
    }
}
Exemplo n.º 20
0
// Called in update thread or deliver thread.
void Cluster::checkUpdateIn(Lock& l) {
    if (state != UPDATEE) return; // Wait till we reach the stall point.
    if (!updateClosed) return;  // Wait till update connection closes.
    if (updatedMap) { // We're up to date
        map = *updatedMap;
        mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self);
        state = CATCHUP;
        /* In CATCHUP mode the update has finished, and we are consuming
        ** whatever backlog of messages has built up during the update.
        ** We should enable queue events here, or messages that are received
        ** during this phase will not be replicated properly. ( If there are
        ** relevant replication queues. ) */
        broker.getQueueEvents().enable();
        memberUpdate(l);
        // Must be called *after* memberUpdate() to avoid sending an extra update.
        failoverExchange->setReady();
        // NB: don't updateMgmtMembership() here as we are not in the deliver
        // thread. It will be updated on delivery of the "ready" we just mcast.
        broker.setClusterUpdatee(false);
        broker.setAcl(acl);     // Restore ACL
        discarding = false;     // OK to set, we're stalled for update.
        QPID_LOG(notice, *this << " update complete, starting catch-up.");
        QPID_LOG(debug, debugSnapshot()); // OK to call because we're stalled.
        if (mAgent) {
            // Update management agent now, after all update activity is complete.
            updateDataExchange->updateManagementAgent(mAgent);
            mAgent->suppress(false); // Enable management output.
            mAgent->clusterUpdate();
        }
        // Restore alternate exchange settings on exchanges.
        broker.getExchanges().eachExchange(
            boost::bind(&broker::Exchange::recoveryComplete, _1,
                        boost::ref(broker.getExchanges())));
        enableClusterSafe();    // Enable cluster-safe assertions
        deliverEventQueue.start();
        // FIXME aconway 2012-04-04: unregister/delete Update[Data]Exchange
        updateDataExchange.reset();
        broker.getExchanges().destroy(UpdateDataExchange::EXCHANGE_NAME);
        broker.getExchanges().destroy(UpdateClient::UPDATE);
    }
    else if (updateRetracted) { // Update was retracted, request another update
        updateRetracted = false;
        updateClosed = false;
        state = JOINER;
        QPID_LOG(notice, *this << " update retracted, sending new update request.");
        mcast.mcastControl(ClusterUpdateRequestBody(ProtocolVersion(), myUrl.str()), self);
        deliverEventQueue.start();
    }
}
Exemplo n.º 21
0
void Cluster::ready(const MemberId& id, const std::string& url, Lock& l) {
    try {
        if (map.ready(id, Url(url)))
            memberUpdate(l);
        if (state == CATCHUP && id == self) {
            setReady(l);
            QPID_LOG(notice, *this << " caught up.");
        }
    } catch (const Url::Invalid& e) {
        QPID_LOG(error, "Invalid URL in cluster ready command: " << url);
    }
     // Update management on every ready event to be consistent across cluster.
    setMgmtStatus(l);
    updateMgmtMembership(l);
}
Exemplo n.º 22
0
boost::shared_ptr<RecoverableMessage> ProtocolImpl::recover(qpid::framing::Buffer& buffer)
{
    QPID_LOG(debug, "Recovering, checking for 1.0 message format indicator...");
    uint32_t format = buffer.getLong();
    if (format == 0) {
        QPID_LOG(debug, "Recovered message IS in 1.0 format");
        //this is a 1.0 format message
        boost::intrusive_ptr<qpid::broker::amqp::Message> m(new qpid::broker::amqp::Message(buffer.available()));
        m->decodeHeader(buffer);
        return RecoverableMessage::shared_ptr(new RecoverableMessageImpl(qpid::broker::Message(m, m)));
    } else {
        QPID_LOG(debug, "Recovered message is NOT in 1.0 format");
        return RecoverableMessage::shared_ptr();
    }
}
Exemplo n.º 23
0
 void receivedFromSource(Message& message)
 {
     QPID_LOG(debug, "transfering  " << (transfered+1) << " of " << expected);
     message.getDeliveryProperties().setRoutingKey(destination);
     async(sourceSubscription.getSession()).messageTransfer(arg::content=message);
     if (++transfered == expected) {
         QPID_LOG(info, "completed job: " << transfered << " messages shifted from " <<
                  source << " to " << destination);
         sourceSubscription.accept(sourceSubscription.getUnaccepted());
         sourceSubscription.getSession().txCommit();
         sourceSubscription.cancel();
         //grant credit to allow broker to send us another control message
         controlSubscription.grantMessageCredit(1);
     }
 }
Exemplo n.º 24
0
boost::shared_ptr<FieldValue> convertString(const std::string& value, const std::string& encoding)
{
    bool large = value.size() > std::numeric_limits<uint16_t>::max();
    if (encoding.empty() || encoding == amqp0_10_binary || encoding == binary) {
        if (large) {
            return boost::shared_ptr<FieldValue>(new Var32Value(value, 0xa0));
        } else {
            return boost::shared_ptr<FieldValue>(new Var16Value(value, 0x90));
        }
    } else if (encoding == utf8) {
        if (!large)
            return boost::shared_ptr<FieldValue>(new Str16Value(value));
        throw Exception(QPID_MSG("Could not encode utf8 character string - too long (" << value.size() << " bytes)"));
    } else if (encoding == utf16) {
        if (!large)
            return boost::shared_ptr<FieldValue>(new Var16Value(value, 0x96));
        throw Exception(QPID_MSG("Could not encode utf16 character string - too long (" << value.size() << " bytes)"));
    } else if (encoding == iso885915) {
        if (!large)
            return boost::shared_ptr<FieldValue>(new Var16Value(value, 0x94));
        throw Exception(QPID_MSG("Could not encode iso-8859-15 character string - too long (" << value.size() << " bytes)"));
    } else {
        // the encoding was not recognised
        QPID_LOG(warning, "Unknown byte encoding: [" << encoding << "], encoding as vbin32.");
        return boost::shared_ptr<FieldValue>(new Var32Value(value, 0xa0));
    }
}
Exemplo n.º 25
0
std::size_t ConnectionContext::encode(char* buffer, std::size_t size)
{
    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
    QPID_LOG(trace, id << " encode(" << size << ")");
    if (writeHeader) {
        size_t encoded = writeProtocolHeader(buffer, size);
        if (encoded < size) {
            encoded += encode(buffer + encoded, size - encoded);
        }
        return encoded;
    }

    ssize_t n = pn_transport_output(engine, buffer, size);
    if (n > 0) {
        QPID_LOG_CAT(debug, network, id << " encoded " << n << " bytes from " << size)
        haveOutput = true;
        return n;
    } else if (n == PN_ERR) {
        throw qpid::Exception(QPID_MSG("Error on output: " << getError()));
    } else if (n == PN_EOS) {
        haveOutput = false;
        return 0;//Is this right?
    } else {
        haveOutput = false;
        return 0;
    }
}
Exemplo n.º 26
0
std::size_t ConnectionContext::decode(const char* buffer, std::size_t size)
{
    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
    QPID_LOG(trace, id << " decode(" << size << ")");
    if (readHeader) {
        size_t decoded = readProtocolHeader(buffer, size);
        if (decoded < size) {
            decoded += decode(buffer + decoded, size - decoded);
        }
        return decoded;
    }

    //TODO: Fix pn_engine_input() to take const buffer
    ssize_t n = pn_transport_input(engine, const_cast<char*>(buffer), size);
    if (n > 0 || n == PN_EOS) {
        //If engine returns EOS, have no way of knowing how many bytes
        //it processed, but can assume none need to be reprocessed so
        //consider them all read:
        if (n == PN_EOS) n = size;
        QPID_LOG_CAT(debug, network, id << " decoded " << n << " bytes from " << size)
        pn_transport_tick(engine, 0);
        lock.notifyAll();
        return n;
    } else if (n == PN_ERR) {
        throw qpid::Exception(QPID_MSG("Error on input: " << getError()));
    } else {
        return 0;
    }

}
Exemplo n.º 27
0
void ConnectionContext::send(boost::shared_ptr<SenderContext> snd, const qpid::messaging::Message& message, bool sync)
{
    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
    SenderContext::Delivery* delivery(0);
    while (!(delivery = snd->send(message))) {
        QPID_LOG(debug, "Waiting for capacity...");
        wait();//wait for capacity
    }
    wakeupDriver();
    if (sync) {
        while (!delivery->accepted()) {
            QPID_LOG(debug, "Waiting for confirmation...");
            wait();//wait until message has been confirmed
        }
    }
}
Exemplo n.º 28
0
void ConnectionContext::close()
{
    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
    if (state != CONNECTED) return;
    if (!(pn_connection_state(connection) & PN_LOCAL_CLOSED)) {
        for (SessionMap::iterator i = sessions.begin(); i != sessions.end(); ++i) {
            //wait for outstanding sends to settle
            while (!i->second->settled()) {
                QPID_LOG(debug, "Waiting for sends to settle before closing");
                wait();//wait until message has been confirmed
            }


            if (!(pn_session_state(i->second->session) & PN_LOCAL_CLOSED)) {
                pn_session_close(i->second->session);
            }
        }
        pn_connection_close(connection);
        wakeupDriver();
        //wait for close to be confirmed by peer?
        while (!(pn_connection_state(connection) & PN_REMOTE_CLOSED)) {
            wait();
        }
        sessions.clear();
    }
    transport->close();
    while (state != DISCONNECTED) {
        lock.wait();
    }
}
Exemplo n.º 29
0
size_t Sasl::encode(char* buffer, size_t size)
{
    if (state == AUTHENTICATED) {
        if (securityLayer.get()) return securityLayer->encode(buffer, size);
        else return connection.encode(buffer, size);
    } else {
        size_t encoded = 0;
        if (writeHeader) {
            encoded += writeProtocolHeader(buffer, size);
            if (!encoded) return 0;
            writeHeader = false;
        }
        if (encoded < size) {
            encoded += write(buffer + encoded, size - encoded);
        }
        if (state == SUCCESS_PENDING) {
            state = AUTHENTICATED;
        } else if (state == FAILURE_PENDING) {
            state = FAILED;
        } else {
            haveOutput = (encoded == size);
        }
        QPID_LOG(trace, id << " Sasl::encode(" << size << "): " << encoded);
        return encoded;
    }
}
Exemplo n.º 30
0
 void AclReader::printUserConnectRules() const {
     QPID_LOG(debug, "ACL: User Connection Rule lists : " << userHostRules->size() << " user lists found :");
     int cnt = 1;
     for (AclData::bwHostUserRuleMapItr i=userHostRules->begin(); i!=userHostRules->end(); i++,cnt++) {
         printConnectionRules(std::string((*i).first), (*i).second);
     }
 }