static pn_event_type_t message_stream_handler(test_handler_t *th, pn_event_t *e) { struct message_stream_context *ctx = (struct message_stream_context*)th->context; switch (pn_event_type(e)) { case PN_CONNECTION_BOUND: pn_transport_set_max_frame(pn_event_transport(e), FRAME); return PN_EVENT_NONE; case PN_SESSION_INIT: pn_session_set_incoming_capacity(pn_event_session(e), FRAME); /* Single frame incoming */ pn_session_set_outgoing_window(pn_event_session(e), 1); /* Single frame outgoing */ return PN_EVENT_NONE; case PN_LINK_REMOTE_OPEN: common_handler(th, e); if (pn_link_is_receiver(pn_event_link(e))) { pn_link_flow(pn_event_link(e), 1); } else { ctx->sender = pn_event_link(e); } return PN_EVENT_NONE; case PN_LINK_FLOW: /* Start a delivery */ if (pn_link_is_sender(pn_event_link(e)) && !ctx->dlv) { ctx->dlv = pn_delivery(pn_event_link(e), pn_dtag("x", 1)); } return PN_LINK_FLOW; case PN_CONNECTION_WAKE: { /* Send a chunk */ ssize_t remains = ctx->size - ctx->sent; ssize_t n = (CHUNK < remains) ? CHUNK : remains; TEST_CHECK(th->t, n == pn_link_send(ctx->sender, ctx->send_buf.start + ctx->sent, n)); ctx->sent += n; if (ctx->sent == ctx->size) { TEST_CHECK(th->t, pn_link_advance(ctx->sender)); } return PN_CONNECTION_WAKE; } case PN_DELIVERY: { /* Receive a delivery - smaller than a chunk? */ pn_delivery_t *dlv = pn_event_delivery(e); if (pn_delivery_readable(dlv)) { ssize_t n = pn_delivery_pending(dlv); rwbytes_ensure(&ctx->recv_buf, ctx->received + n); TEST_ASSERT(n == pn_link_recv(pn_event_link(e), ctx->recv_buf.start + ctx->received, n)); ctx->received += n; } ctx->complete = !pn_delivery_partial(dlv); return PN_DELIVERY; } default: return common_handler(th, e); } }
void qd_policy_amqp_open(void *context, bool discard) { qd_connection_t *qd_conn = (qd_connection_t *)context; if (!discard) { pn_connection_t *conn = qd_connection_pn(qd_conn); qd_dispatch_t *qd = qd_conn->server->qd; qd_policy_t *policy = qd->policy; bool connection_allowed = true; if (policy->enableAccessRules) { // Open connection or not based on policy. pn_transport_t *pn_trans = pn_connection_transport(conn); const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr); const char *pcrh = pn_connection_remote_hostname(conn); const char *app = (pcrh ? pcrh : ""); const char *conn_name = qdpn_connector_name(qd_conn->pn_cxtr); #define SETTINGS_NAME_SIZE 256 char settings_name[SETTINGS_NAME_SIZE]; uint32_t conn_id = qd_conn->connection_id; qd_conn->policy_settings = NEW(qd_policy_settings_t); // TODO: memory pool for settings memset(qd_conn->policy_settings, 0, sizeof(qd_policy_settings_t)); if (qd_policy_open_lookup_user(policy, qd_conn->user_id, hostip, app, conn_name, settings_name, SETTINGS_NAME_SIZE, conn_id, qd_conn->policy_settings) && settings_name[0]) { // This connection is allowed by policy. // Apply transport policy settings if (qd_conn->policy_settings->maxFrameSize > 0) pn_transport_set_max_frame(pn_trans, qd_conn->policy_settings->maxFrameSize); if (qd_conn->policy_settings->maxSessions > 0) pn_transport_set_channel_max(pn_trans, qd_conn->policy_settings->maxSessions - 1); } else { // This connection is denied by policy. connection_allowed = false; } } else { // No policy implies automatic policy allow // Note that connections not governed by policy have no policy_settings. } if (connection_allowed) { if (pn_connection_state(conn) & PN_LOCAL_UNINIT) pn_connection_open(conn); policy_notify_opened(qd_conn->open_container, qd_conn, qd_conn->context); } else { qd_policy_private_deny_amqp_connection(conn, RESOURCE_LIMIT_EXCEEDED, CONNECTION_DISALLOWED); } } qd_connection_set_event_stall(qd_conn, false); }
void apply(connection& c) { pn_connection_t *pnc = connection_options::pn_connection(c); pn_transport_t *pnt = pn_connection_transport(pnc); connector *outbound = dynamic_cast<connector*>( connection_context::get(c).handler.get()); bool uninit = (c.state() & endpoint::LOCAL_UNINIT); // pnt is NULL between reconnect attempts. // Only apply transport options if uninit or outbound with // transport not yet configured. if (pnt && (uninit || (outbound && !outbound->transport_configured()))) { // SSL if (outbound && outbound->address().scheme() == url::AMQPS) { pn_ssl_t *ssl = pn_ssl(pnt); if (pn_ssl_init(ssl, ssl_client_options.value.pn_domain(), NULL)) throw error(MSG("client SSL/TLS initialization error")); } else if (!outbound) { pn_acceptor_t *pnp = pn_connection_acceptor(pnc); if (pnp) { listener_context &lc(listener_context::get(pnp)); if (lc.ssl) { pn_ssl_t *ssl = pn_ssl(pnt); if (pn_ssl_init(ssl, ssl_server_options.value.pn_domain(), NULL)) throw error(MSG("server SSL/TLS initialization error")); } } } // SASL transport t = c.transport(); if (!sasl_enabled.set || sasl_enabled.value) { if (sasl_enabled.set) // Explicitly set, not just default behaviour. t.sasl(); // Force a sasl instance. Lazily create one otherwise. if (sasl_allow_insecure_mechs.set) t.sasl().allow_insecure_mechs(sasl_allow_insecure_mechs.value); if (sasl_allowed_mechs.set) t.sasl().allowed_mechs(sasl_allowed_mechs.value); if (sasl_config_name.set) t.sasl().config_name(sasl_config_name.value); if (sasl_config_path.set) t.sasl().config_path(sasl_config_path.value); } if (max_frame_size.set) pn_transport_set_max_frame(pnt, max_frame_size.value); if (max_channels.set) pn_transport_set_channel_max(pnt, max_channels.value); if (idle_timeout.set) pn_transport_set_idle_timeout(pnt, idle_timeout.value.ms()); } // Only apply connection options if uninit. if (uninit) { if (reconnect.set && outbound) outbound->reconnect_timer(reconnect.value); if (container_id.set) pn_connection_set_container(pnc, container_id.value.c_str()); if (link_prefix.set) connection_context::get(pnc).link_gen.prefix(link_prefix.value); } }