Uploaded image for project: 'Qpid Proton'
  1. Qpid Proton
  2. PROTON-856

idle timeout doesn't work in openssl mode

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Pending Closed
    • proton-0.9
    • None
    • proton-c
    • Kubuntu 12.04 LTS (64 bit), Intel Core i5, 2 Gb of RAM on VMware Player. ActiveMQ broker on localhost machine.

    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):

      #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;
      }
       
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            fredlak Adam Curylo
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: