void qd_policy_socket_close(void *context, const qd_connection_t *conn) { qd_policy_t *policy = (qd_policy_t *)context; n_connections -= 1; assert (n_connections >= 0); if (policy->enableVhostPolicy) { // HACK ALERT: TODO: This should be deferred to a Python thread qd_python_lock_state_t lock_state = qd_python_lock(); PyObject *module = PyImport_ImportModule("qpid_dispatch_internal.policy.policy_manager"); if (module) { PyObject *close_connection = PyObject_GetAttrString(module, "policy_close_connection"); if (close_connection) { PyObject *result = PyObject_CallFunction(close_connection, "(OK)", (PyObject *)policy->py_policy_manager, conn->connection_id); if (result) { Py_XDECREF(result); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: Connection close failed: result"); } Py_XDECREF(close_connection); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: Connection close failed: close_connection"); } Py_XDECREF(module); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: Connection close failed: module"); } qd_python_unlock(lock_state); } const char *hostname = qdpn_connector_name(conn->pn_cxtr); qd_log(policy->log_source, QD_LOG_DEBUG, "Connection '%s' closed with resources n_sessions=%d, n_senders=%d, n_receivers=%d. nConnections= %d.", hostname, conn->n_sessions, conn->n_senders, conn->n_receivers, n_connections); }
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); }