[ https://issues.apache.org/jira/browse/PROTON-856?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Adam Curylo updated PROTON-856: ------------------------------- Description: "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): {code} #include <proton/reactor.h> #include <proton/handlers.h> #include <proton/engine.h> #include <proton/message.h> #include <proton/ssl.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; } {code} was: "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): {code} #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; } {code} > 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): > {code} > #include <proton/reactor.h> > #include <proton/handlers.h> > #include <proton/engine.h> > #include <proton/message.h> > #include <proton/ssl.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; > } > > {code} -- This message was sent by Atlassian JIRA (v6.3.4#6332)