示例#1
0
void proxy::handle_read_payload(const boost_code& ec, size_t,
    const heading& heading)
{
    if (stopped())
        return;

    // Ignore read error here, client may have disconnected.

    if (heading.checksum != bitcoin_checksum(payload_buffer_))
    {
        log_warning(LOG_NETWORK) 
            << "Invalid bitcoin checksum from [" << address() << "]";
        stop(error::bad_stream);
        return;
    }

    // We must copy the payload before restarting the reader.
    const auto payload_copy = payload_buffer_;

    // We must restart the reader before firing subscription events.
    if (!ec)
        read_heading();

    start_inactivity();

    // Parse and publish the payload to message subscribers.
    payload_source source(payload_copy);
    payload_stream istream(source);
    const auto error = message_subscriber_.load(heading.type(), istream);

    // Warn about unconsumed bytes in the stream.
    if (!error && istream.peek() != std::istream::traits_type::eof())
        log_warning(LOG_NETWORK)
            << "Valid message [" << heading.command
            << "] handled, unused bytes remain in payload.";

    // Stop the channel if there was a read error.
    if (ec)
    {
        log_warning(LOG_NETWORK)
            << "Invalid payload of " << heading.command
            << " from [" << address() << "] (deferred)"
            << code(error::boost_to_error_code(ec)).message();
        stop(ec);
        return;
    }

    // Stop the channel if there was an error from parse.
    if (error)
    {
        log_warning(LOG_NETWORK)
            << "Invalid stream load of " << heading.command
            << " from [" << address() << "] " << error.message();
        stop(error);
    }
}
示例#2
0
void proxy::read_payload(const heading& head)
{
    if (stopped())
        return;

    // This does not cause a reallocation.
    payload_buffer_.resize(head.payload_size());

    // The payload buffer is protected by ordering, not the critial section.

    // Critical Section (external)
    ///////////////////////////////////////////////////////////////////////////
    const auto socket = socket_->get_socket();

    using namespace boost::asio;
    async_read(socket->get(), buffer(payload_buffer_, head.payload_size()),
        std::bind(&proxy::handle_read_payload,
            shared_from_this(), _1, _2, head));
    ///////////////////////////////////////////////////////////////////////////
}
示例#3
0
void proxy::handle_read_payload(const boost_code& ec, size_t payload_size,
    const heading& head)
{
    if (stopped())
        return;

    // TODO: verify client quick disconnect.
    if (ec)
    {
        LOG_DEBUG(LOG_NETWORK)
            << "Payload read failure [" << authority() << "] "
            << code(error::boost_to_error_code(ec)).message();
        stop(ec);
        return;
    }

    if (head.checksum() != bitcoin_checksum(payload_buffer_))
    {
        LOG_WARNING(LOG_NETWORK)
            << "Invalid " << head.command() << " payload from [" << authority()
            << "] bad checksum.";
        stop(error::bad_stream);
        return;
    }
    
    ///////////////////////////////////////////////////////////////////////////
    // TODO: we aren't getting a stream benefit if we read the full payload
    // before parsing the message. Should just make this a message parse.
    ///////////////////////////////////////////////////////////////////////////

    // Notify subscribers of the new message.
    payload_source source(payload_buffer_);
    payload_stream istream(source);
    const auto code = message_subscriber_.load(head.type(), version_, istream);
    const auto consumed = istream.peek() == std::istream::traits_type::eof();

    // For finding agents of bad versions.
    ////const auto agent =
    ////    ((!code && consumed) || head.command != version::command) ? "" : " " +
    ////        std::string(payload_buffer_.begin(), payload_buffer_.end());

    if (code)
    {
        LOG_WARNING(LOG_NETWORK)
            << "Invalid " << head.command() << " payload from [" << authority()
            << "] " << code.message();
        stop(code);
        return;
    }

    if (!consumed)
    {
        LOG_WARNING(LOG_NETWORK)
            << "Invalid " << head.command() << " payload from [" << authority()
            << "] trailing bytes.";
        stop(error::bad_stream);
        return;
    }

    LOG_DEBUG(LOG_NETWORK)
        << "Valid " << head.command() << " payload from [" << authority()
        << "] (" << payload_size << " bytes)";

    handle_activity();
    read_heading();
}
示例#4
0
void proxy::handle_read_payload(const boost_code& ec, size_t,
    const heading& head)
{
    if (stopped())
        return;

    ////// Ignore read error here, client may have disconnected.
    ////if (ec)
    ////{
    ////    log::debug(LOG_NETWORK)
    ////        << "Payload read failure [" << authority() << "] "
    ////        << code(error::boost_to_error_code(ec)).message();
    ////    stop(ec);
    ////    return;
    ////}

    ////log::debug(LOG_NETWORK)
    ////    << "Read (" << size << ") payload bytes from [" << authority() << "] ";

    if (head.checksum != bitcoin_checksum(payload_buffer_))
    {
        log::warning(LOG_NETWORK) 
            << "Invalid " << head.command << " checksum from ["
            << authority() << "]";
        stop(error::bad_stream);
        return;
    }

    // Parse and publish the payload to message subscribers.
    payload_source source(payload_buffer_);
    payload_stream istream(source);

    // Notify subscribers of the new message.
    const auto parse_error = message_subscriber_.load(head.type(), istream);
    const auto unconsumed = istream.peek() != std::istream::traits_type::eof();

    if (stopped())
        return;

    if (!parse_error)
    {
        if (unconsumed)
            log::warning(LOG_NETWORK)
            << "Valid " << head.command << " payload from ["
                << authority() << "] unused bytes remain.";
        else
            log::debug(LOG_NETWORK)
            << "Valid " << head.command << " payload from ["
                << authority() << "] (" << payload_buffer_.size() << " bytes)";
    }

    if (ec)
    {
        log::debug(LOG_NETWORK)
            << "Payload read failure [" << authority() << "] "
            << code(error::boost_to_error_code(ec)).message();
        stop(ec);
        return;
    }

    if (parse_error)
    {
        log::warning(LOG_NETWORK)
            << "Invalid " << head.command << " stream from ["
            << authority() << "] " << parse_error.message();
        stop(parse_error);
    }

    handle_activity();
    read_heading();
}