Пример #1
0
/* Tests for error handling */
static void test_errors(test_t *t) {
  test_proactor_t tps[] =  { test_proactor(t, open_wake_handler), test_proactor(t, listen_handler) };
  pn_proactor_t *client = tps[0].proactor, *server = tps[1].proactor;

  /* Invalid connect/listen service name */
  pn_connection_t *c = pn_connection();
  pn_proactor_connect2(client, c, NULL, "127.0.0.1:xxx");
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));
  TEST_COND_DESC(t, "xxx", last_condition);
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  pn_proactor_listen(server, pn_listener(), "127.0.0.1:xxx", 1);
  TEST_PROACTORS_RUN(tps);
  TEST_HANDLER_EXPECT(&tps[1].handler, PN_LISTENER_CLOSE, 0); /* CLOSE only, no OPEN */
  TEST_COND_DESC(t, "xxx", last_condition);
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  /* Invalid connect/listen host name */
  c = pn_connection();
  pn_proactor_connect2(client, c, NULL, "nosuch.example.com:");
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));
  TEST_COND_DESC(t, "nosuch", last_condition);
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  test_handler_clear(&tps[1].handler, 0);
  pn_proactor_listen(server, pn_listener(), "nosuch.example.com:", 1);
  TEST_PROACTORS_RUN(tps);
  TEST_HANDLER_EXPECT(&tps[1].handler, PN_LISTENER_CLOSE, 0); /* CLOSE only, no OPEN */
  TEST_COND_DESC(t, "nosuch", last_condition);
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  /* Listen on a port already in use */
  pn_listener_t *l = pn_listener();
  pn_proactor_listen(server, l, ":0", 1);
  TEST_ETYPE_EQUAL(t, PN_LISTENER_OPEN, TEST_PROACTORS_RUN(tps));
  test_handler_clear(&tps[1].handler, 0);
  struct addrinfo laddr = listener_info(l);
  pn_proactor_listen(server, pn_listener(), laddr.connect, 1); /* Busy */
  TEST_PROACTORS_RUN(tps);
  TEST_HANDLER_EXPECT(&tps[1].handler, PN_LISTENER_CLOSE, 0); /* CLOSE only, no OPEN */
  TEST_COND_NAME(t, "proton:io", last_condition);
  pn_listener_close(l);
  TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
  TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));

  /* Connect with no listener */
  c = pn_connection();
  pn_proactor_connect2(client, c, NULL, laddr.connect);
  if (TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps))) {
    TEST_COND_DESC(t, "refused", last_condition);
    TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));
  }

  TEST_PROACTORS_DESTROY(tps);
}
Пример #2
0
/* Make sure we clean up released connections and open sockets correctly */
static void test_release_free(test_t *t) {
  test_proactor_t tps[] = { test_proactor(t, open_wake_handler), test_proactor(t, listen_handler) };
  pn_proactor_t *client = tps[0].proactor;
  pn_listener_t *l = test_listen(&tps[1], "");

  /* leave one connection to the proactor  */
  pn_proactor_connect2(client, NULL, NULL, listener_info(l).connect);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps));

  /* release c1 and free immediately */
  pn_connection_t *c1 = pn_connection();
  pn_proactor_connect2(client, c1, NULL, listener_info(l).connect);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps));
  pn_proactor_release_connection(c1); /* We free but socket should still be cleaned up */
  pn_connection_free(c1);
  TEST_CHECK(t, pn_proactor_get(client) == NULL); /* Should be idle */
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps)); /* Server closed */

  /* release c2 and but don't free till after proactor free */
  pn_connection_t *c2 = pn_connection();
  pn_proactor_connect2(client, c2, NULL, listener_info(l).connect);
  TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, TEST_PROACTORS_RUN(tps));
  pn_proactor_release_connection(c2);
  TEST_CHECK(t, pn_proactor_get(client) == NULL); /* Should be idle */
  TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps)); /* Server closed */

  TEST_PROACTORS_DESTROY(tps);
  pn_connection_free(c2);

  /* Check freeing a listener or connection that was never given to a proactor */
  pn_listener_free(pn_listener());
  pn_connection_free(pn_connection());
}
Пример #3
0
/* Return a pn_listener_t*, raise errors if not successful */
pn_listener_t *test_listen(test_proactor_t *tp, const char *host) {
  char addr[1024];
  pn_listener_t *l = pn_listener();
  (void)pn_proactor_addr(addr, sizeof(addr), host, "0");
  pn_proactor_listen(tp->proactor, l, addr, 4);
  TEST_ETYPE_EQUAL(tp->handler.t, PN_LISTENER_OPEN, test_proactors_run(tp, 1));
  TEST_COND_EMPTY(tp->handler.t, last_condition);
  return l;
}
Пример #4
0
/* Test that we can control listen/select on ipv6/v4 and listen on both by default */
static void test_ipv4_ipv6(test_t *t) {
  test_proactor_t tps[] ={ test_proactor(t, open_close_handler), test_proactor(t, listen_handler) };
  pn_proactor_t *client = tps[0].proactor, *server = tps[1].proactor;

  /* Listen on all interfaces for IPv4 only. */
  pn_listener_t *l4 = test_listen(&tps[1], "0.0.0.0");
  TEST_PROACTORS_DRAIN(tps);

  /* Empty address listens on both IPv4 and IPv6 on all interfaces */
  pn_listener_t *l = test_listen(&tps[1], "");
  TEST_PROACTORS_DRAIN(tps);

#define EXPECT_CONNECT(LISTENER, HOST) do {                             \
    char addr[1024];                                                    \
    pn_proactor_addr(addr, sizeof(addr), HOST, listener_info(LISTENER).port); \
    pn_proactor_connect2(client, NULL, NULL, addr);                     \
    TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, TEST_PROACTORS_RUN(tps));  \
    TEST_COND_EMPTY(t, last_condition);                                 \
    TEST_PROACTORS_DRAIN(tps);                                          \
  } while(0)

  EXPECT_CONNECT(l4, "127.0.0.1"); /* v4->v4 */
  EXPECT_CONNECT(l4, "");          /* local->v4*/

  EXPECT_CONNECT(l, "127.0.0.1"); /* v4->all */
  EXPECT_CONNECT(l, "");          /* local->all */

  /* Listen on ipv6 loopback, if it fails skip ipv6 tests.

     NOTE: Don't use the unspecified address "::" here - ipv6-disabled platforms
     may allow listening on "::" without complaining. However they won't have a
     local ipv6 loopback configured, so "::1" will force an error.
  */
  TEST_PROACTORS_DRAIN(tps);
  pn_listener_t *l6 = pn_listener();
  pn_proactor_listen(server, l6, "::1:0", 4);
  pn_event_type_t e = TEST_PROACTORS_RUN(tps);
  if (e == PN_LISTENER_OPEN && !pn_condition_is_set(last_condition)) {
    TEST_PROACTORS_DRAIN(tps);

    EXPECT_CONNECT(l6, "::1"); /* v6->v6 */
    EXPECT_CONNECT(l6, "");    /* local->v6 */
    EXPECT_CONNECT(l, "::1");  /* v6->all */

    pn_listener_close(l6);
  } else  {
    const char *d = pn_condition_get_description(last_condition);
    TEST_LOGF(t, "skip IPv6 tests: %s %s", pn_event_type_name(e), d ? d : "no condition");
  }

  pn_listener_close(l);
  pn_listener_close(l4);
  TEST_PROACTORS_DESTROY(tps);
}
Пример #5
0
pn_listener_t *pn_messenger_isource(pn_messenger_t *messenger, const char *source)
{
  char buf[strlen(source) + 1];
  strcpy(buf, source);
  char *domain, *name;
  parse_address(buf, &domain, &name);
  char *user = NULL;
  char *pass = NULL;
  char *host = "0.0.0.0";
  char *port = "5672";
  parse_url(domain + 1, &user, &pass, &host, &port);

  pn_listener_t *listener = pn_listener(messenger->driver, host, port, NULL);
  if (listener) {
    messenger->listeners++;
  }
  return listener;
}
Пример #6
0
int main(int argc, char **argv)
{
  char *url = NULL;
  char *address = "queue";
  char *mechanism = "ANONYMOUS";
  int count = 1;
  bool quiet = false;
  int high = 100;
  int low = 50;
  int size = 32;

  int opt;
  while ((opt = getopt(argc, argv, "c:a:m:n:s:u:l:qhVXY")) != -1)
  {
    switch (opt) {
    case 'c':
      if (url) pn_fatal("multiple connect urls not allowed\n");
      url = optarg;
      break;
    case 'a':
      address = optarg;
      break;
    case 'm':
      mechanism = optarg;
      break;
    case 'n':
      count = atoi(optarg);
      break;
    case 's':
      size = atoi(optarg);
      break;
    case 'u':
      high = atoi(optarg);
      break;
    case 'l':
      low = atoi(optarg);
      break;
    case 'q':
      quiet = true;
      break;
    case 'V':
      printf("proton version %i.%i\n", PN_VERSION_MAJOR, PN_VERSION_MINOR);
      exit(EXIT_SUCCESS);
    case 'X':
      value(argc, argv);
      exit(EXIT_SUCCESS);
    case 'Y':
      buffer(argc, argv);
      exit(EXIT_SUCCESS);
    case 'h':
      printf("Usage: %s [-h] [-c [user[:password]@]host[:port]] [-a <address>] [-m <sasl-mech>]\n", argv[0]);
      printf("\n");
      printf("    -c    The connect url.\n");
      printf("    -a    The AMQP address.\n");
      printf("    -m    The SASL mechanism.\n");
      printf("    -n    The number of messages.\n");
      printf("    -s    Message size.\n");
      printf("    -u    Upper flow threshold.\n");
      printf("    -l    Lower flow threshold.\n");
      printf("    -q    Supress printouts.\n");
      printf("    -h    Print this help.\n");
      exit(EXIT_SUCCESS);
    default: /* '?' */
      pn_fatal("Usage: %s -h\n", argv[0]);
    }
  }

  char *user = NULL;
  char *pass = NULL;
  char *host = "0.0.0.0";
  char *port = "5672";

  parse_url(url, &user, &pass, &host, &port);

  pn_driver_t *drv = pn_driver();
  if (url) {
    struct client_context ctx = {false, false, count, count, drv, quiet, size, high, low};
    ctx.username = user;
    ctx.password = pass;
    ctx.mechanism = mechanism;
    ctx.hostname = host;
    ctx.address = address;
    pn_connector_t *ctor = pn_connector(drv, host, port, &ctx);
    if (!ctor) pn_fatal("connector failed\n");
    pn_connector_set_connection(ctor, pn_connection());
    while (!ctx.done) {
      pn_driver_wait(drv, -1);
      pn_connector_t *c;
      while ((c = pn_driver_connector(drv))) {
        pn_connector_process(c);
        client_callback(c);
        if (pn_connector_closed(c)) {
	  pn_connection_free(pn_connector_connection(c));
          pn_connector_free(c);
        } else {
          pn_connector_process(c);
        }
      }
    }
  } else {
    struct server_context ctx = {0, quiet, size};
    if (!pn_listener(drv, host, port, &ctx)) pn_fatal("listener failed\n");
    while (true) {
      pn_driver_wait(drv, -1);
      pn_listener_t *l;
      pn_connector_t *c;

      while ((l = pn_driver_listener(drv))) {
        c = pn_listener_accept(l);
        pn_connector_set_context(c, &ctx);
      }

      while ((c = pn_driver_connector(drv))) {
        pn_connector_process(c);
        server_callback(c);
        if (pn_connector_closed(c)) {
	  pn_connection_free(pn_connector_connection(c));
          pn_connector_free(c);
        } else {
          pn_connector_process(c);
        }
      }
    }
  }

  pn_driver_free(drv);

  return 0;
}
Пример #7
0
int 
main ( int argc, char ** argv )
{
  char info[1000];
  int  expected = (argc > 1) ? atoi(argv[1]) : 100000;
  int  received = 0;
  int  size     = 32;
  int  msg_size = 50;
  bool done     = false;
  int  initial_credit   = 500,
       new_credit       = 250,
       low_credit_limit = 250;

  char const * host = "0.0.0.0";
  char const * port = "5672";

  bool sasl_done = false;

  pn_driver_t     * driver;
  pn_listener_t   * listener;
  pn_connector_t  * connector;
  pn_connection_t * connection;
  pn_session_t    * session;
  pn_link_t       * link;
  pn_delivery_t   * delivery;


  char * message_data          = (char *) malloc ( MY_BUF_SIZE );
  int    message_data_capacity = MY_BUF_SIZE;


  fprintf ( stderr, "drecv expecting %d messages.\n", expected );
  driver = pn_driver ( );

  if ( ! pn_listener(driver, host, port, 0) ) 
  {
    fprintf ( stderr, "listener creation failed.\n" );
    exit ( 1 );
  }

  while ( ! done)
  {
    pn_driver_wait ( driver, -1 );

    if ( (listener = pn_driver_listener(driver)) ) 
      pn_listener_accept( listener );

    if ( (connector = pn_driver_connector(driver)) ) 
    {
      pn_connector_process ( connector );

      if ( ! sasl_done )
        if( ! (sasl_done = get_sasl_over_with(connector) ))
          continue;

      connection = pn_connector_connection ( connector );


      /*=========================================================
        Open everything that is ready on the 
        other side but not here.
      =========================================================*/
      pn_state_t hes_ready_im_not = PN_LOCAL_UNINIT | PN_REMOTE_ACTIVE;

      if (pn_connection_state(connection) == hes_ready_im_not)
        pn_connection_open( connection);


      for ( session = pn_session_head(connection, hes_ready_im_not);
            session;
            session = pn_session_next(session, hes_ready_im_not)
          )
        pn_session_open(session);


      for ( link = pn_link_head(connection, hes_ready_im_not);
            link;
            link = pn_link_next(link, hes_ready_im_not)
          )
       {
         pn_terminus_copy(pn_link_source(link), pn_link_remote_source(link));
         pn_terminus_copy(pn_link_target(link), pn_link_remote_target(link));
         pn_link_open ( link );
         if ( pn_link_is_receiver(link) ) 
           pn_link_flow ( link, initial_credit );
       }


      /*==========================================================
        Get all available deliveries.
      ==========================================================*/
      for ( delivery = pn_work_head ( connection );
            delivery;
            delivery = pn_work_next ( delivery )
          )
      {
        if ( pn_delivery_readable(delivery) ) 
        {
          link = pn_delivery_link ( delivery );
          while ( PN_EOS != pn_link_recv(link, message_data, MY_BUF_SIZE) )
            ;
          pn_link_advance ( link );
          pn_delivery_update ( delivery, PN_ACCEPTED );
          pn_delivery_settle ( delivery );


          if ( ++ received >= expected )
          {
            sprintf ( info, "received %d messages", received );
            print_timestamp ( stderr, info );
            done = true;
          }

          // a progress report for long tests.
          if ( ! (received % 5000000) )
            fprintf ( stderr, "received: %d\n", received );


          if ( pn_link_credit(link) <= low_credit_limit ) 
            pn_link_flow ( link, new_credit );
        } 
        else
        {
          // TODO
          // Why am I getting writables?
          // And what to do with them?
        }
      } 


      /*===============================================================
        Shut down everything that the other side has closed.
      ===============================================================*/
      pn_state_t active_here_closed_there = PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED;

      if ( pn_connection_state(connection) == active_here_closed_there )
        pn_connection_close ( connection );

      for ( session = pn_session_head(connection, active_here_closed_there);
            session;
            session = pn_session_next(session, active_here_closed_there)
          )
        pn_session_close ( session );

      for ( link = pn_link_head(connection, active_here_closed_there);
            link;
            link = pn_link_next(link, active_here_closed_there)
          )
        pn_link_close ( link );

      if ( pn_connector_closed(connector) ) 
      {
        pn_connection_free ( pn_connector_connection(connector) );
        pn_connector_free ( connector );
        done = true;
      } 
      else 
        pn_connector_process(connector);
    }
  }

  pn_driver_free(driver);

  return 0;
}