Beispiel #1
0
/**
 * New Outgoing Link Handler
 */
static int router_outgoing_link_handler(void* context, dx_link_t *link)
{
    dx_router_t *router  = (dx_router_t*) context;
    pn_link_t   *pn_link = dx_link_pn(link);
    const char  *r_tgt   = pn_terminus_get_address(pn_link_remote_target(pn_link));

    sys_mutex_lock(router->lock);
    dx_router_link_t *rlink = new_dx_router_link_t();
    rlink->link = link;
    DEQ_INIT(rlink->out_fifo);
    dx_link_set_context(link, rlink);

    dx_field_iterator_t *iter = dx_field_iterator_string(r_tgt, ITER_VIEW_NO_HOST);
    int result = hash_insert(router->out_hash, iter, rlink);
    dx_field_iterator_free(iter);

    if (result == 0) {
        pn_terminus_copy(pn_link_source(pn_link), pn_link_remote_source(pn_link));
        pn_terminus_copy(pn_link_target(pn_link), pn_link_remote_target(pn_link));
        pn_link_open(pn_link);
        sys_mutex_unlock(router->lock);
        dx_log(module, LOG_TRACE, "Registered new local address: %s", r_tgt);
        return 0;
    }

    dx_log(module, LOG_TRACE, "Address '%s' not registered as it already exists", r_tgt);
    pn_link_close(pn_link);
    sys_mutex_unlock(router->lock);
    return 0;
}
receiver session::open_receiver(const std::string &addr, const receiver_options &ro)
{
    std::string name = ro.get_name() ? *ro.get_name() : next_link_name(connection());
    pn_link_t *lnk = pn_receiver(pn_object(), name.c_str());
    pn_terminus_set_address(pn_link_source(lnk), addr.c_str());
    receiver rcv(make_wrapper<receiver>(lnk));
    rcv.open(ro);
    return rcv;
}
Beispiel #3
0
static void pn_handshaker_dispatch(pn_handler_t *handler, pn_event_t *event, pn_event_type_t type) {
  switch (type) {
  case PN_CONNECTION_REMOTE_OPEN:
    {
      pn_connection_t *conn = pn_event_connection(event);
      if (pn_connection_state(conn) & PN_LOCAL_UNINIT) {
        pn_connection_open(conn);
      }
    }
    break;
  case PN_SESSION_REMOTE_OPEN:
    {
      pn_session_t *ssn = pn_event_session(event);
      if (pn_session_state(ssn) & PN_LOCAL_UNINIT) {
        pn_session_open(ssn);
      }
    }
    break;
  case PN_LINK_REMOTE_OPEN:
    {
      pn_link_t *link = pn_event_link(event);
      if (pn_link_state(link) & PN_LOCAL_UNINIT) {
        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);
      }
    }
    break;
  case PN_CONNECTION_REMOTE_CLOSE:
    {
      pn_connection_t *conn = pn_event_connection(event);
      if (!(pn_connection_state(conn) & PN_LOCAL_CLOSED)) {
        pn_connection_close(conn);
      }
    }
    break;
  case PN_SESSION_REMOTE_CLOSE:
    {
      pn_session_t *ssn = pn_event_session(event);
      if (!(pn_session_state(ssn) & PN_LOCAL_CLOSED)) {
        pn_session_close(ssn);
      }
    }
    break;
  case PN_LINK_REMOTE_CLOSE:
    {
      pn_link_t *link = pn_event_link(event);
      if (!(pn_link_state(link) & PN_LOCAL_CLOSED)) {
        pn_link_close(link);
      }
    }
    break;
  default:
    break;
  }
}
Beispiel #4
0
void process_session(ldp_connection_t *conn, pn_event_t *event) {
    fprintf(stderr, "session event %s\n", pn_event_type_name(pn_event_type(event)));

    if (pn_event_type(event) == PN_SESSION_REMOTE_STATE) {
        pn_session_t *session = pn_event_session(event);
        pn_link_t *sender = pn_sender(session, "sender-xxx");
        pn_terminus_set_address(pn_link_source(sender), "hello-world");
        pn_link_open(sender);
    }
}
 void apply(sender& s) {
     if (s.uninitialized()) {
         if (delivery_mode.set) set_delivery_mode(s, delivery_mode.value);
         if (handler.set && handler.value) set_handler(s, *handler.value);
         if (auto_settle.set) get_context(s).auto_settle = auto_settle.value;
         if (source.set) {
             proton::source local_s(make_wrapper<proton::source>(pn_link_source(unwrap(s))));
             source.value.apply(local_s);
         }
         if (target.set) {
             proton::target local_t(make_wrapper<proton::target>(pn_link_target(unwrap(s))));
             target.value.apply(local_t);
         }
     }
 }
Beispiel #6
0
/**
 * New Incoming Link Handler
 */
static int router_incoming_link_handler(void* context, dx_link_t *link)
{
    dx_router_t    *router  = (dx_router_t*) context;
    dx_link_item_t *item    = new_dx_link_item_t();
    pn_link_t      *pn_link = dx_link_pn(link);

    if (item) {
        DEQ_ITEM_INIT(item);
        item->link = link;

        sys_mutex_lock(router->lock);
        DEQ_INSERT_TAIL(router->in_links, item);
        sys_mutex_unlock(router->lock);

        pn_terminus_copy(pn_link_source(pn_link), pn_link_remote_source(pn_link));
        pn_terminus_copy(pn_link_target(pn_link), pn_link_remote_target(pn_link));
        pn_link_flow(pn_link, 8);
        pn_link_open(pn_link);
    } else {
        pn_link_close(pn_link);
    }
    return 0;
}
Beispiel #7
0
pn_terminus_t *qd_link_source(qd_link_t *link)
{
    return pn_link_source(link->pn_link);
}
Beispiel #8
0
terminus& link::source() const { return *terminus::cast(pn_link_source(pn_cast(this))); }
Beispiel #9
0
terminus link::local_source() const { return pn_link_source(pn_object()); }
Beispiel #10
0
/* runs the protocol engine, allowing it to handle TCP socket I/O and timer
 * events in the background.
*/
static void *amqp1_thread(void *arg)
{
	DBGPRINTF("omamqp1: Protocol thread started\n");

	pn_handler_t *handler = (pn_handler_t *)arg;
	protocolState_t *ps = PROTOCOL_STATE(handler);
	const configSettings_t *cfg = ps->config;

	// have pn_reactor_process() exit after 5 sec to poll for commands
	pn_reactor_set_timeout(ps->reactor, 5000);
	pn_reactor_start(ps->reactor);

	while (!ps->stopped) {
	    // setup a connection:
	    const char *host = pn_url_get_host(cfg->url);
	    const char *port = pn_url_get_port(cfg->url);
	    if (!port) port = "5672";

#if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 13
	    ps->conn = pn_reactor_connection_to_host(ps->reactor,
	                                             host,
	                                             port,
	                                             handler);
	    pn_connection_set_hostname(ps->conn, host);
#else
	    {
	        char host_addr[300];
	        ps->conn = pn_reactor_connection(ps->reactor, handler);
	        snprintf(host_addr, sizeof(host_addr), "%s:%s", host, port);
	        pn_connection_set_hostname(ps->conn, host_addr);
	    }
#endif
	    pn_connection_set_container(ps->conn, "rsyslogd-omamqp1");

#if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 10
	    // proton version <= 0.9 did not support Cyrus SASL
	    const char *user = cfg->username
	        ? (char *)cfg->username
	        : pn_url_get_username(cfg->url);
	    if (user)
	        pn_connection_set_user(ps->conn, user);

	    const char *pword = cfg->password
	        ? (char *) cfg->password
	        : pn_url_get_password(cfg->url);
	    if (pword)
	        pn_connection_set_password(ps->conn, pword);
#endif
	    pn_connection_open(ps->conn);
	    pn_session_t *ssn = pn_session(ps->conn);
	    pn_session_open(ssn);
	    ps->sender = pn_sender(ssn, (char *)cfg->target);
	    pn_link_set_snd_settle_mode(ps->sender, PN_SND_UNSETTLED);
	    char *addr = (char *)ps->config->target;
	    pn_terminus_set_address(pn_link_target(ps->sender), addr);
	    pn_terminus_set_address(pn_link_source(ps->sender), addr);
	    pn_link_open(ps->sender);

	    // run the protocol engine until the connection closes or thread is shut down
	    sbool engine_running = true;
	    while (engine_running) {
	        engine_running = pn_reactor_process(ps->reactor);
	        _poll_command(ps);
	    }

	    DBGPRINTF("omamqp1: reactor finished\n");

	    _abort_command(ps);   // unblock main thread if necessary

	    // delay reconnectDelay seconds before re-connecting:
	    int delay = ps->config->reconnectDelay;
	    while (delay-- > 0 && !ps->stopped) {
	        srSleep(1, 0);
	        _poll_command(ps);
	    }
	}
	pn_reactor_stop(ps->reactor);

	// stop command is now done:
	threadIPC_t *ipc = ps->ipc;
	pthread_mutex_lock(&ipc->lock);
	ipc->result = RS_RET_OK;
	ipc->command = COMMAND_DONE;
	pthread_cond_signal(&ipc->condition);
	pthread_mutex_unlock(&ipc->lock);

	DBGPRINTF("omamqp1: Protocol thread stopped\n");

	return 0;
}
Beispiel #11
0
void sender_dispatch(pn_handler_t *h, pn_event_t *event, pn_event_type_t type)
{
  sender_context_t *sc = sender_context(h);

  switch (type) {
  case PN_CONNECTION_INIT:
    {
      pn_connection_t *conn = pn_event_connection(event);
      pn_connection_set_container(conn, pn_string_get(sc->container_id));
      pn_connection_set_hostname(conn, pn_string_get(sc->hostname));
      pn_connection_open(conn);
      pn_session_t *ssn = pn_session(conn);
      pn_session_open(ssn);
      pn_link_t *snd = pn_sender(ssn, "sender");
      const char *path = pn_url_get_path(sc->send_url);
      if (path && strlen(path)) {
        pn_terminus_set_address(pn_link_target(snd), path);
        pn_terminus_set_address(pn_link_source(snd), path);
      }
      pn_link_open(snd);
    }
    break;
  case PN_LINK_FLOW:
    {
      pn_link_t *snd = pn_event_link(event);
      while (pn_link_credit(snd) > 0 && sc->sent < sc->opts->msg_count) {
        if (sc->sent == 0)
          statistics_start(sc->stats);

        char tag[8];
        void *ptr = &tag;
        *((uint64_t *) ptr) = sc->sent;
        pn_delivery_t *dlv = pn_delivery(snd, pn_dtag(tag, 8));

        // setup the message to send
        pn_message_t *msg = sc->message;
        pn_message_set_address(msg, sc->opts->targets.addresses[0]);
        sc->id.u.as_ulong = sc->sent;
        pn_message_set_correlation_id(msg, sc->id);
        pn_message_set_creation_time(msg, msgr_now());

        size_t size = sc->encoded_data_size;
        int err = pn_message_encode(msg, sc->encoded_data, &size);
        check(err == 0, "message encoding error");
        pn_link_send(snd, sc->encoded_data, size);
        pn_delivery_settle(dlv);
        sc->sent++;
      }
      if (sc->sent == sc->opts->msg_count && !sc->opts->get_replies) {
        pn_link_close(snd);
        pn_connection_t *conn = pn_event_connection(event);
        pn_connection_close(conn);
      }
    }
    break;
  case PN_LINK_INIT:
    {
      pn_link_t *link = pn_event_link(event);
      if (pn_link_is_receiver(link)) {
        // Response messages link.  Could manage credit and deliveries in this handler but
        // a dedicated handler also works.
        pn_handler_t *replyto = replyto_handler(sc);
        pn_flowcontroller_t *fc = pn_flowcontroller(1024);
        pn_handler_add(replyto, fc);
        pn_decref(fc);
        pn_handshaker_t *handshaker = pn_handshaker();
        pn_handler_add(replyto, handshaker);
        pn_decref(handshaker);
        pn_record_t *record = pn_link_attachments(link);
        pn_record_set_handler(record, replyto);
        pn_decref(replyto);
      }
    }
    break;
  case PN_CONNECTION_LOCAL_CLOSE:
    {
      statistics_report(sc->stats, sc->sent, sc->received);
    }
    break;
  default:
    break;
  }
}
Beispiel #12
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;
}