void ConnectionHandler::incoming(AMQFrame& frame)
{
    if (getState() == CLOSED) {
        throw Exception("Received frame on closed connection");
    }

    if (rcvTimeoutTask) {
        // Received frame on connection so delay timeout
        rcvTimeoutTask->restart();
    }

    AMQBody* body = frame.getBody();
    try {
        if (frame.getChannel() != 0 || !invoke(static_cast<ConnectionOperations&>(*this), *body)) {
            switch(getState()) {
            case OPEN:
                in(frame);
                break;
            case CLOSING:
                QPID_LOG(warning, "Ignoring frame while closing connection: " << frame);
                break;
            default:
                throw Exception("Cannot receive frames on non-zero channel until connection is established.");
            }
        }
    }catch(std::exception& e){
        QPID_LOG(warning, "Closing connection due to " << e.what());
        setState(CLOSING);
        errorCode = CLOSE_CODE_FRAMING_ERROR;
        errorText = e.what();
        proxy.close(501, e.what());
    }
}
void SslConnector::handle(AMQFrame& frame) {
    bool notifyWrite = false;
    {
    Mutex::ScopedLock l(lock);
    frames.push_back(frame);
    //only ask to write if this is the end of a frameset or if we
    //already have a buffers worth of data
    currentSize += frame.encodedSize();
    if (frame.getEof()) {
        lastEof = frames.size();
        notifyWrite = true;
    } else {
        notifyWrite = (currentSize >= maxFrameSize);
    }
    /*
      NOTE: Moving the following line into this mutex block
            is a workaround for BZ 570168, in which the test
            testConcurrentSenders causes a hang about 1.5%
            of the time.  ( To see the hang much more frequently
            leave this line out of the mutex block, and put a
            small usleep just before it.)

            TODO mgoulish - fix the underlying cause and then
                            move this call back outside the mutex.
    */
    if (notifyWrite && !closed) aio->notifyPendingWrite();
    }
}
Esempio n. 3
0
void MessageTransfer::decodeHeader(framing::Buffer& buffer)
{
    AMQFrame method;
    method.decode(buffer);
    frames.append(method);

    AMQFrame header;
    header.decode(buffer);
    frames.append(header);
}
void SessionHandler::handleIn(AMQFrame& f) {
    // Note on channel states: a channel is attached if session != 0
    AMQMethodBody* m = f.getBody()->getMethod();
    try {
        // Ignore all but detach controls while awaiting detach
        if (awaitingDetached) {
            if (!isSessionControl(m)) return;
            if (m->amqpMethodId() != SESSION_DETACH_METHOD_ID &&
                m->amqpMethodId() != SESSION_DETACHED_METHOD_ID)
                return;
        }
        if (isSessionControl(m)) {
            invoke(*m);
        }
        else {
            // Drop frames if we are detached.
            if (!getState()) return;  
            if (!receiveReady)
                throw IllegalStateException(QPID_MSG(getState()->getId() << ": Not ready to receive data"));
            if (!getState()->receiverRecord(f))
                return; // Ignore duplicates.
            if (getState()->receiverNeedKnownCompleted())
                sendCompletion();
            getInHandler()->handle(f);
        }
    }
    catch(const SessionException& e) {
        executionException(e.code, e.what());
        framing::AMQP_AllProxy::Execution  execution(channel);
        AMQMethodBody* m = f.getMethod();
        SequenceNumber commandId;
        if (getState()) commandId =  getState()->receiverGetCurrent();
        execution.exception(e.code, commandId, m ? m->amqpClassId() : 0, m ? m->amqpMethodId() : 0, 0, e.what(), FieldTable());
        detaching();
        sendDetach();
    }
    catch(const ChannelException& e){
        channelException(e.code, e.what());
        peer.detached(name, e.code);
    }
    catch(const ConnectionException& e) {
        connectionException(e.code, e.getMessage());
    }
    catch(const std::exception& e) {
        connectionException(connection::CLOSE_CODE_FRAMING_ERROR, e.what());
    }
}
size_t SslConnector::decode(const char* buffer, size_t size)
{
    framing::Buffer in(const_cast<char*>(buffer), size);
    try {
        if (checkProtocolHeader(in, version)) {
            AMQFrame frame;
            while(frame.decode(in)){
                QPID_LOG(trace, "RECV [" << identifier << "]: " << frame);
                input->received(frame);
            }
        }
    } catch (const ProtocolVersionError& e) {
        QPID_LOG(info, "Closing connection due to " << e.what());
        close();
    }
    return size - in.available();
}
Esempio n. 6
0
void SessionImpl::handleIn(AMQFrame& frame) // network thread
{
    try {
        if (invoke(static_cast<SessionHandler&>(*this), *frame.getBody())) {
            ;
        } else if (invoke(static_cast<ExecutionHandler&>(*this), *frame.getBody())) {
            //make sure the command id sequence and completion
            //tracking takes account of execution commands
            Lock l(state);
            completedIn.add(nextIn++);
        } else {
            //if not handled by this class, its for the application:
            deliver(frame);
        }
    }
    catch (const SessionException& e) {
        setException(createSessionException(e.code, e.getMessage()));
    }
    catch (const ChannelException& e) {
        setException(createChannelException(e.code, e.getMessage()));
    }
}
Esempio n. 7
0
 void operator()(const AMQFrame& f)
 {
     AMQFrame copy = f;
     if (redelivered || ttl || annotations.size()) {
         copy.cloneBody();
         if (annotations.size()) {
             MessageProperties* props =
                 copy.castBody<AMQHeaderBody>()->get<MessageProperties>(true);
             for (qpid::types::Variant::Map::const_iterator i = annotations.begin();
                  i != annotations.end(); ++i) {
                 props->getApplicationHeaders().set(i->first, qpid::amqp_0_10::translate(i->second));
             }
         }
         if (redelivered || ttl) {
             DeliveryProperties* dp =
                 copy.castBody<AMQHeaderBody>()->get<DeliveryProperties>(true);
             if (ttl) dp->setTtl(ttl);
             if (redelivered) dp->setRedelivered(redelivered);
         }
     }
     handler.handle(copy);
 }
Esempio n. 8
0
string getData(const AMQFrame& frame) {
    const AMQContentBody* content = dynamic_cast<const AMQContentBody*>(frame.getBody());
    BOOST_CHECK(content);
    return content->getData();
}
Esempio n. 9
0
void SessionImpl::sendFrame(AMQFrame& frame, bool canBlock)
{
    connection->expand(frame.encodedSize(), canBlock);
    channel.handle(frame);
}
Esempio n. 10
0
bool isContentFrame(AMQFrame& frame)
{
    AMQBody* body = frame.getBody();
    uint8_t type = body->type();
    return type == HEADER_BODY || type == CONTENT_BODY || isMessageMethod(body); 
}