/** * 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; }
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; } }
void ConnectionContext::attach(boost::shared_ptr<SessionContext> ssn, boost::shared_ptr<SenderContext> lnk) { lnk->configure(); attach(ssn->session, (pn_link_t*) lnk->sender); if (!pn_link_remote_target((pn_link_t*) lnk->sender)) { std::string msg("No such target : "); msg += lnk->getTarget(); throw qpid::messaging::NotFound(msg); } }
static void setup_incoming_link(qd_container_t *container, pn_link_t *pn_link) { sys_mutex_lock(container->lock); qd_node_t *node = 0; const char *target = pn_terminus_get_address(pn_link_remote_target(pn_link)); qd_field_iterator_t *iter; if (target) { iter = qd_address_iterator_string(target, ITER_VIEW_NODE_ID); qd_hash_retrieve(container->node_map, iter, (void*) &node); qd_field_iterator_free(iter); } sys_mutex_unlock(container->lock); if (node == 0) { if (container->default_node) node = container->default_node; else { pn_condition_t *cond = pn_link_condition(pn_link); pn_condition_set_name(cond, "amqp:not-found"); pn_condition_set_description(cond, "Target node does not exist"); pn_link_close(pn_link); return; } } qd_link_t *link = new_qd_link_t(); if (!link) { pn_condition_t *cond = pn_link_condition(pn_link); pn_condition_set_name(cond, "amqp:internal-error"); pn_condition_set_description(cond, "Insufficient memory"); pn_link_close(pn_link); return; } link->pn_sess = pn_link_session(pn_link); link->pn_link = pn_link; link->direction = QD_INCOMING; link->context = 0; link->node = node; link->drain_mode = pn_link_get_drain(pn_link); link->remote_snd_settle_mode = pn_link_remote_snd_settle_mode(pn_link); link->close_sess_with_link = false; // // Keep the borrowed references // pn_incref(pn_link); pn_incref(link->pn_sess); pn_link_set_context(pn_link, link); node->ntype->incoming_handler(node->context, link); }
bool qd_policy_approve_amqp_sender_link(pn_link_t *pn_link, qd_connection_t *qd_conn) { const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr); const char *app = pn_connection_remote_hostname(qd_connection_pn(qd_conn)); if (qd_conn->policy_settings->maxSenders) { if (qd_conn->n_senders == qd_conn->policy_settings->maxSenders) { // Max sender limit specified and violated. qd_log(qd_conn->server->qd->policy->log_source, QD_LOG_INFO, "DENY AMQP Attach sender for user '%s', host '%s', app '%s' based on maxSenders limit", qd_conn->user_id, hostip, app); _qd_policy_deny_amqp_sender_link(pn_link, qd_conn); return false; } else { // max sender limit not violated } } else { // max sender limit not specified } // Approve sender link based on target const char * target = pn_terminus_get_address(pn_link_remote_target(pn_link)); bool lookup; if (target && *target) { // a target is specified lookup = _qd_policy_approve_link_name(qd_conn->user_id, qd_conn->policy_settings->targets, target); qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach sender link '%s' for user '%s', host '%s', app '%s' based on link target name", (lookup ? "ALLOW" : "DENY"), target, qd_conn->user_id, hostip, app); if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } } else { // A sender with no remote target. // This happens all the time with anonymous relay lookup = qd_conn->policy_settings->allowAnonymousSender; qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach anonymous sender for user '%s', host '%s', app '%s'", (lookup ? "ALLOW" : "DENY"), qd_conn->user_id, hostip, app); if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } } // Approved return true; }
/** * Link Detached Handler */ static int router_link_detach_handler(void* context, dx_link_t *link, int closed) { 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)); dx_link_item_t *item; sys_mutex_lock(router->lock); if (pn_link_is_sender(pn_link)) { item = DEQ_HEAD(router->out_links); dx_field_iterator_t *iter = dx_field_iterator_string(r_tgt, ITER_VIEW_NO_HOST); dx_router_link_t *rlink; if (iter) { int result = hash_retrieve(router->out_hash, iter, (void*) &rlink); if (result == 0) { dx_field_iterator_reset(iter, ITER_VIEW_NO_HOST); hash_remove(router->out_hash, iter); free_dx_router_link_t(rlink); dx_log(module, LOG_TRACE, "Removed local address: %s", r_tgt); } dx_field_iterator_free(iter); } } else item = DEQ_HEAD(router->in_links); while (item) { if (item->link == link) { if (pn_link_is_sender(pn_link)) DEQ_REMOVE(router->out_links, item); else DEQ_REMOVE(router->in_links, item); free_dx_link_item_t(item); break; } item = item->next; } sys_mutex_unlock(router->lock); return 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; }
pn_terminus_t *qd_link_remote_target(qd_link_t *link) { return pn_link_remote_target(link->pn_link); }
terminus& link::remote_target() const { return *terminus::cast(pn_link_remote_target(pn_cast(this))); }
terminus link::remote_target() const { return pn_link_remote_target(pn_object()); }
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; }