Adam Curylo created PROTON-856:
----------------------------------

             Summary: idle timeout doesn't work in openssl mode
                 Key: PROTON-856
                 URL: https://issues.apache.org/jira/browse/PROTON-856
             Project: Qpid Proton
          Issue Type: Bug
          Components: proton-c
    Affects Versions: 0.9
         Environment: Kubuntu 12.04 LTS (64 bit), Intel Core i5, 2 Gb of RAM on 
VMware Player. ActiveMQ broker on localhost machine.
            Reporter: Adam Curylo


"pn_transport_set_idle_timeout" doesn't  work properly for ssl connection. 
There is a proper transport-error message (PN_TRANSPORT_ERROR 
amqp:resource-limit-exceeded: local-idle-timeout expired ) after timeout but 
connections still remains. It is different (wrong) behaviour than unencrypted 
connection. 
I've used for check it following example code (connection with ActiveMQ message 
broker):

#include <proton/reactor.h>
#include <proton/handlers.h>
#include <proton/engine.h>
#include <proton/message.h>
#include <proton/ssl.h>
#include <proton/ssl_io.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>


typedef pn_handler_t client_t;

typedef struct {
    const char *hostname;
    const char *queue;
    const char *container;
    pn_session_t * session;
    pn_ssl_domain_t *sslDomain;
} client_state_t;

client_state_t *client_state(client_t *client) {
    return (client_state_t *) pn_handler_mem(client);
}

void client_cleanup(client_t *client) {
    client_state_t *cs = client_state(client);
    (void)cs;
}

void client_dispatch(pn_handler_t *client, pn_event_t *event, pn_event_type_t 
eventType) {
    client_state_t *state = client_state(client);

    switch (eventType) {
    case PN_TRANSPORT:
    {
        pn_transport_t * transport = pn_event_transport(event);
        assert(transport);
        pn_transport_set_idle_timeout(transport, 20000);
    }
    break;
    case PN_TRANSPORT_ERROR:
    {
        pn_transport_t * transport = pn_event_transport(event);
        pn_error_t * error = pn_transport_error(transport);
        printf("PN_TRANSPORT_ERROR %s \n", pn_error_text(error));
    }
    break;
    case PN_SELECTABLE_INIT:
    {
        //OpenSSL mode
                if (state->sslDomain == NULL) {
                        state->sslDomain = pn_ssl_domain(PN_SSL_MODE_CLIENT);
                }
                if (pn_ssl_domain_set_credentials(state->sslDomain, 
"./device.polyx.crt", "./device.polyx.key", NULL) == 0) {
                        pn_connection_t * conn = 
pn_session_connection(state->session);
                        pn_transport_t * transport = 
pn_connection_transport(conn);
                        assert(transport);
                        pn_ssl_init(pn_ssl(transport), state->sslDomain, NULL);
                }
    }
    break;
    case PN_DELIVERY:
    {

        pn_link_t *link = pn_event_link(event);
        pn_delivery_t *dlv = pn_event_delivery(event);
        if (pn_link_is_receiver(link) && !pn_delivery_partial(dlv)) {
            char buf[1024];
            ssize_t n = pn_link_recv(link, buf, 1024);
            if (n > 0) {
                pn_message_t *msg = pn_message();
                pn_message_decode(msg, buf, n);
                pn_string_t *str = pn_string(NULL);
                pn_inspect(msg, str);
                printf("Got: %s\n", pn_string_get(str));
                pn_message_free(msg);
                pn_free(str);
            }
            pn_delivery_settle(dlv);
        }
    }
    break;
    default:
    break;
    }
}

client_t *client_handler(const char *hostName, const char * queueName, const 
char * containerName) {
    client_t *client = pn_handler_new(client_dispatch, sizeof(client_state_t), 
client_cleanup);
    client_state_t *state = client_state(client);
    state->hostname = hostName;
    state->queue = queueName;
    state->container = containerName;
    state->sslDomain = NULL;
    state->session = NULL;
    return client;
}


int main(int argc, const char **argv) {

    pn_reactor_t *reactor = pn_reactor();

    pn_handler_t *root = pn_reactor_get_handler(reactor);

    client_t *client = client_handler("localhost:5671", "queue://example", 
"example");
    pn_handler_add(root, client);
    pn_handler_add(root, pn_flowcontroller(1024));
    pn_handler_add(root, pn_handshaker());

    client_state_t *state = client_state(client);

    pn_connection_t *conn = pn_reactor_connection(reactor, client);
    pn_connection_set_container(conn, state->container);
    pn_connection_set_hostname(conn, state->hostname);

    pn_connection_open(conn);

    state->session = pn_session(conn);
    pn_session_open(state->session);

    pn_link_t * link = pn_receiver(state->session, state->container);
    pn_terminus_set_address(pn_link_source(link), state->queue);
    pn_terminus_set_address(pn_link_target(link), state->queue);
    pn_link_set_snd_settle_mode(link, PN_SND_UNSETTLED);
    pn_link_set_rcv_settle_mode(link, PN_RCV_SECOND);
    pn_link_open(link);
    pn_link_flow(link, 10000);

    pn_reactor_run(reactor);

    if (state->sslDomain != NULL) {
        pn_ssl_domain_free(state->sslDomain);
    }
    pn_reactor_free(reactor);
    return 0;
}
 




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to