void pni_handle_bound(pn_reactor_t *reactor, pn_event_t *event) { assert(reactor); assert(event); pn_connection_t *conn = pn_event_connection(event); pn_transport_t *transport = pn_event_transport(event); pn_record_t *record = pn_connection_attachments(conn); pn_url_t *url = (pn_url_t *)pn_record_get(record, PNI_CONN_PEER_ADDRESS); const char *host = NULL; const char *port = "5672"; pn_string_t *str = NULL; // link the new transport to its reactor: pni_record_init_reactor(pn_transport_attachments(transport), reactor); if (pn_connection_acceptor(conn) != NULL) { // this connection was created by the acceptor. There is already a // socket assigned to this connection. Nothing needs to be done. return; } if (url) { host = pn_url_get_host(url); const char *uport = pn_url_get_port(url); if (uport) { port = uport; } else { const char *scheme = pn_url_get_scheme(url); if (scheme && strcmp(scheme, "amqps") == 0) { port = "5671"; } } if (!pn_connection_get_user(conn)) { // user did not manually set auth info const char *user = pn_url_get_username(url); if (user) pn_connection_set_user(conn, user); const char *passwd = pn_url_get_password(url); if (passwd) pn_connection_set_password(conn, passwd); } } else { // for backward compatibility, see if the connection's hostname can be // used for the remote address. See JIRA PROTON-1133 const char *hostname = pn_connection_get_hostname(conn); if (hostname) { str = pn_string(hostname); char *h = pn_string_buffer(str); // see if a port has been included in the hostname. This is not // allowed by the spec, but the old reactor interface allowed it. char *colon = strrchr(h, ':'); if (colon) { *colon = '\0'; port = colon + 1; } host = h; } } if (!host) { // error: no address configured pn_condition_t *cond = pn_transport_condition(transport); pn_condition_set_name(cond, "proton:io"); pn_condition_set_description(cond, "Connection failed: no address configured"); pn_transport_close_tail(transport); pn_transport_close_head(transport); } else { pn_socket_t sock = pn_connect(pni_reactor_io(reactor), host, port); // invalid sockets are ignored by poll, so we need to do this manually if (sock == PN_INVALID_SOCKET) { pn_condition_t *cond = pn_transport_condition(transport); pn_condition_set_name(cond, "proton:io"); pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor))); pn_transport_close_tail(transport); pn_transport_close_head(transport); } else { pn_reactor_selectable_transport(reactor, sock, transport); } } pn_free(str); }
/* 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; }
void connection::user(const std::string &name) { pn_connection_set_user(pn_object(), name.c_str()); }