qd_config_listener_t *qd_dispatch_configure_listener(qd_dispatch_t *qd, qd_entity_t *entity) { qd_error_clear(); qd_connection_manager_t *cm = qd->connection_manager; qd_config_listener_t *cl = NEW(qd_config_listener_t); cl->is_connector = false; cl->state = QD_BIND_NONE; cl->listener = 0; qd_config_ssl_profile_t *ssl_profile = 0; if (load_server_config(qd, &cl->configuration, entity, &ssl_profile) != QD_ERROR_NONE) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create config listener: %s", qd_error_message()); qd_config_listener_free(qd->connection_manager, cl); return 0; } cl->ssl_profile = ssl_profile; DEQ_ITEM_INIT(cl); DEQ_INSERT_TAIL(cm->config_listeners, cl); qd_log(cm->log_source, QD_LOG_INFO, "Configured Listener: %s:%s proto=%s, role=%s%s%s", cl->configuration.host, cl->configuration.port, cl->configuration.protocol_family ? cl->configuration.protocol_family : "any", cl->configuration.role, cl->ssl_profile ? ", sslProfile=":"", cl->ssl_profile ? cl->ssl_profile->name:""); return cl; }
qd_config_ssl_profile_t *qd_dispatch_configure_ssl_profile(qd_dispatch_t *qd, qd_entity_t *entity) { qd_error_clear(); qd_connection_manager_t *cm = qd->connection_manager; qd_config_ssl_profile_t *ssl_profile = NEW(qd_config_ssl_profile_t); DEQ_ITEM_INIT(ssl_profile); DEQ_INSERT_TAIL(cm->config_ssl_profiles, ssl_profile); ssl_profile->name = qd_entity_opt_string(entity, "name", 0); CHECK(); ssl_profile->ssl_certificate_file = qd_entity_opt_string(entity, "certFile", 0); CHECK(); ssl_profile->ssl_private_key_file = qd_entity_opt_string(entity, "keyFile", 0); CHECK(); ssl_profile->ssl_password = qd_entity_opt_string(entity, "password", 0); CHECK(); ssl_profile->ssl_trusted_certificate_db = qd_entity_opt_string(entity, "certDb", 0); CHECK(); ssl_profile->ssl_trusted_certificates = qd_entity_opt_string(entity, "trustedCerts", 0); CHECK(); ssl_profile->ssl_uid_format = qd_entity_opt_string(entity, "uidFormat", 0); CHECK(); ssl_profile->ssl_display_name_file = qd_entity_opt_string(entity, "displayNameFile", 0); CHECK(); sys_atomic_init(&ssl_profile->ref_count, 0); qd_log(cm->log_source, QD_LOG_INFO, "Created SSL Profile with name %s ", ssl_profile->name); return ssl_profile; error: qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create ssl profile: %s", qd_error_message()); qd_config_ssl_profile_free(cm, ssl_profile); return 0; }
qd_config_connector_t *qd_dispatch_configure_connector(qd_dispatch_t *qd, qd_entity_t *entity) { qd_error_clear(); qd_connection_manager_t *cm = qd->connection_manager; qd_config_connector_t *cc = NEW(qd_config_connector_t); ZERO(cc); cc->is_connector = true; qd_config_ssl_profile_t *ssl_profile = 0; if (load_server_config(qd, &cc->configuration, entity, &ssl_profile) != QD_ERROR_NONE) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create config connector: %s", qd_error_message()); qd_config_connector_free(qd->connection_manager, cc); return 0; } cc->ssl_profile = ssl_profile; DEQ_ITEM_INIT(cc); DEQ_INSERT_TAIL(cm->config_connectors, cc); qd_log(cm->log_source, QD_LOG_INFO, "Configured Connector: %s:%s proto=%s, role=%s %s%s", cc->configuration.host, cc->configuration.port, cc->configuration.protocol_family ? cc->configuration.protocol_family : "any", cc->configuration.role, cc->ssl_profile ? ", sslProfile=":"", cc->ssl_profile ? cc->ssl_profile->name:""); return cc; }
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); }
qd_listener_t *qd_dispatch_configure_listener(qd_dispatch_t *qd, qd_entity_t *entity) { qd_connection_manager_t *cm = qd->connection_manager; qd_listener_t *li = qd_server_listener(qd->server); if (!li || load_server_config(qd, &li->config, entity, true) != QD_ERROR_NONE) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create listener: %s", qd_error_message()); qd_listener_decref(li); return 0; } char *fol = qd_entity_opt_string(entity, "failoverList", 0); if (fol) { li->config.failover_list = qd_failover_list(fol); free(fol); if (li->config.failover_list == 0) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create listener, bad failover list: %s", qd_error_message()); qd_listener_decref(li); return 0; } } else { li->config.failover_list = 0; } DEQ_ITEM_INIT(li); DEQ_INSERT_TAIL(cm->listeners, li); log_config(cm->log_source, &li->config, "Listener"); return li; }
static void qdr_set_next_hop_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; int nh_router_maskbit = action->args.route_table.nh_router_maskbit; if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_next_hop: Router maskbit out of range: %d", router_maskbit); return; } if (nh_router_maskbit >= qd_bitmask_width() || nh_router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_next_hop: Next hop router maskbit out of range: %d", router_maskbit); return; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_next_hop: Router not found"); return; } if (core->routers_by_mask_bit[nh_router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_next_hop: Next hop router not found"); return; } if (router_maskbit != nh_router_maskbit) { qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; rnode->next_hop = core->routers_by_mask_bit[nh_router_maskbit]; } }
static void qdr_set_valid_origins_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; qd_bitmask_t *valid_origins = action->args.route_table.router_set; if (discard) { qd_bitmask_free(valid_origins); return; } do { if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_valid_origins: Router maskbit out of range: %d", router_maskbit); break; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_valid_origins: Router not found"); break; } qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; if (rnode->valid_origins) qd_bitmask_free(rnode->valid_origins); rnode->valid_origins = valid_origins; valid_origins = 0; } while (false); if (valid_origins) qd_bitmask_free(valid_origins); }
bool qd_policy_approve_amqp_session(pn_session_t *ssn, qd_connection_t *qd_conn) { bool result = true; if (qd_conn->policy_settings) { if (qd_conn->policy_settings->maxSessions) { if (qd_conn->n_sessions == qd_conn->policy_settings->maxSessions) { qd_policy_deny_amqp_session(ssn, qd_conn); result = false; } } } pn_connection_t *conn = qd_connection_pn(qd_conn); qd_dispatch_t *qd = qd_conn->server->qd; qd_policy_t *policy = qd->policy; const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr); const char *app = pn_connection_remote_hostname(conn); if (result) { qd_log(policy->log_source, QD_LOG_TRACE, "ALLOW AMQP Begin Session. user: %s, hostip: %s, app: %s", qd_conn->user_id, hostip, app); } else { qd_log(policy->log_source, QD_LOG_INFO, "DENY AMQP Begin Session due to session limit. user: %s, hostip: %s, app: %s", qd_conn->user_id, hostip, app); } return result; }
static void qdr_set_link_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; int link_maskbit = action->args.route_table.link_maskbit; if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_link: Router maskbit out of range: %d", router_maskbit); return; } if (link_maskbit >= qd_bitmask_width() || link_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_link: Link maskbit out of range: %d", link_maskbit); return; } if (core->control_links_by_mask_bit[link_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_link: Invalid link reference: %d", link_maskbit); return; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "set_link: Router not found"); return; } // // Add the peer_link reference to the router record. // qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; rnode->peer_control_link = core->control_links_by_mask_bit[link_maskbit]; rnode->peer_data_link = core->data_links_by_mask_bit[link_maskbit]; }
bool qd_policy_approve_amqp_receiver_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->maxReceivers) { if (qd_conn->n_receivers == qd_conn->policy_settings->maxReceivers) { // Max sender limit specified and violated. qd_log(qd_conn->server->qd->policy->log_source, QD_LOG_INFO, "DENY AMQP Attach receiver for user '%s', host '%s', app '%s' based on maxReceivers limit", qd_conn->user_id, hostip, app); _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } else { // max receiver limit not violated } } else { // max receiver limit not specified } // Approve receiver link based on source bool dynamic_src = pn_terminus_is_dynamic(pn_link_remote_source(pn_link)); if (dynamic_src) { bool lookup = qd_conn->policy_settings->allowDynamicSrc; qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach receiver dynamic source for user '%s', host '%s', app '%s',", (lookup ? "ALLOW" : "DENY"), qd_conn->user_id, hostip, app); // Dynamic source policy rendered the decision if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); } return lookup; } const char * source = pn_terminus_get_address(pn_link_remote_source(pn_link)); if (source && *source) { // a source is specified bool lookup = _qd_policy_approve_link_name(qd_conn->user_id, qd_conn->policy_settings->sources, source); qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach receiver link '%s' for user '%s', host '%s', app '%s' based on link source name", (lookup ? "ALLOW" : "DENY"), source, qd_conn->user_id, hostip, app); if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } } else { // A receiver with no remote source. qd_log(qd_conn->server->qd->policy->log_source, QD_LOG_TRACE, "DENY AMQP Attach receiver link '' for user '%s', host '%s', app '%s'", qd_conn->user_id, hostip, app); _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } // Approved return true; }
static void qdr_del_router_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "del_router: Router maskbit out of range: %d", router_maskbit); return; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "del_router: Deleting nonexistent router: %d", router_maskbit); return; } qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; qdr_address_t *oaddr = rnode->owning_addr; assert(oaddr); // // Unlink the router node from the address record // qd_bitmask_clear_bit(oaddr->rnodes, router_maskbit); qd_bitmask_clear_bit(core->router_addr_T->rnodes, router_maskbit); qd_bitmask_clear_bit(core->routerma_addr_T->rnodes, router_maskbit); rnode->ref_count -= 3; // // While the router node has a non-zero reference count, look for addresses // to unlink the node from. // qdr_address_t *addr = DEQ_HEAD(core->addrs); while (addr && rnode->ref_count > 0) { if (qd_bitmask_clear_bit(addr->rnodes, router_maskbit)) // // If the cleared bit was originally set, decrement the ref count // rnode->ref_count--; addr = DEQ_NEXT(addr); } assert(rnode->ref_count == 0); // // Free the router node and the owning address records. // qd_bitmask_free(rnode->valid_origins); DEQ_REMOVE(core->routers, rnode); free_qdr_node_t(rnode); qd_hash_remove_by_handle(core->addr_hash, oaddr->hash_handle); DEQ_REMOVE(core->addrs, oaddr); qd_hash_handle_free(oaddr->hash_handle); core->routers_by_mask_bit[router_maskbit] = 0; free_qdr_address_t(oaddr); }
qd_router_t *qd_router(qd_dispatch_t *qd, qd_router_mode_t mode, const char *area, const char *id) { if (!type_registered) { type_registered = 1; qd_container_register_node_type(qd, &router_node); } size_t dplen = 9 + strlen(area) + strlen(id); node_id = (char*) malloc(dplen); strcpy(node_id, area); strcat(node_id, "/"); strcat(node_id, id); qd_router_t *router = NEW(qd_router_t); ZERO(router); router_node.type_context = router; qd->router = router; router->qd = qd; router->router_core = 0; router->log_source = qd_log_source("ROUTER"); router->router_mode = mode; router->router_area = area; router->router_id = id; router->node = qd_container_set_default_node_type(qd, &router_node, (void*) router, QD_DIST_BOTH); router->lock = sys_mutex(); router->timer = qd_timer(qd, qd_router_timer_handler, (void*) router); // // Inform the field iterator module of this router's id and area. The field iterator // uses this to offload some of the address-processing load from the router. // qd_iterator_set_address(area, id); // // Seed the random number generator // unsigned int seed = (unsigned int) time(0); srandom(seed); switch (router->router_mode) { case QD_ROUTER_MODE_STANDALONE: qd_log(router->log_source, QD_LOG_INFO, "Router started in Standalone mode"); break; case QD_ROUTER_MODE_INTERIOR: qd_log(router->log_source, QD_LOG_INFO, "Router started in Interior mode, area=%s id=%s", area, id); break; case QD_ROUTER_MODE_EDGE: qd_log(router->log_source, QD_LOG_INFO, "Router started in Edge mode"); break; case QD_ROUTER_MODE_ENDPOINT: qd_log(router->log_source, QD_LOG_INFO, "Router started in Endpoint mode"); break; } return router; }
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; }
static void qdr_map_destination_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { // // TODO - handle the class-prefix and phase explicitly // int router_maskbit = action->args.route_table.router_maskbit; qdr_field_t *address = action->args.route_table.address; if (discard) { qdr_field_free(address); return; } do { if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "map_destination: Router maskbit out of range: %d", router_maskbit); break; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "map_destination: Router not found"); break; } qd_field_iterator_t *iter = address->iterator; qdr_address_t *addr = 0; qd_hash_retrieve(core->addr_hash, iter, (void**) &addr); if (!addr) { addr = qdr_address_CT(core, qdr_treatment_for_address_hash_CT(core, iter)); qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle); DEQ_ITEM_INIT(addr); DEQ_INSERT_TAIL(core->addrs, addr); } qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; qd_bitmask_set_bit(addr->rnodes, router_maskbit); rnode->ref_count++; qdr_addr_start_inlinks_CT(core, addr); // // TODO - If this affects a waypoint, create the proper side effects // } while (false); qdr_field_free(address); }
void qd_connection_manager_start(qd_dispatch_t *qd) { static bool first_start = true; qd_listener_t *li = DEQ_HEAD(qd->connection_manager->listeners); qd_connector_t *ct = DEQ_HEAD(qd->connection_manager->connectors); while (li) { if (!li->pn_listener) { if (!qd_listener_listen(li) && first_start) { qd_log(qd->connection_manager->log_source, QD_LOG_CRITICAL, "Listen on %s failed during initial config", li->config.host_port); exit(1); } else { li->exit_on_error = first_start; } } li = DEQ_NEXT(li); } while (ct) { qd_connector_connect(ct); ct = DEQ_NEXT(ct); } first_start = false; }
qd_connector_t *qd_dispatch_configure_connector(qd_dispatch_t *qd, qd_entity_t *entity) { qd_connection_manager_t *cm = qd->connection_manager; qd_connector_t *ct = qd_server_connector(qd->server); if (ct && load_server_config(qd, &ct->config, entity, false) == QD_ERROR_NONE) { DEQ_ITEM_INIT(ct); DEQ_INSERT_TAIL(cm->connectors, ct); log_config(cm->log_source, &ct->config, "Connector"); // // Add the first item to the ct->conn_info_list // The initial connection information and any backup connection information is stored in the conn_info_list // qd_failover_item_t *item = NEW(qd_failover_item_t); ZERO(item); item->scheme = 0; item->host = strdup(ct->config.host); item->port = strdup(ct->config.port); item->hostname = 0; int hplen = strlen(item->host) + strlen(item->port) + 2; item->host_port = malloc(hplen); snprintf(item->host_port, hplen, "%s:%s", item->host , item->port); DEQ_INSERT_TAIL(ct->conn_info_list, item); return ct; } qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create connector: %s", qd_error_message()); qd_connector_decref(ct); return 0; }
void qdra_config_auto_link_delete_CT(qdr_core_t *core, qdr_query_t *query, qd_field_iterator_t *name, qd_field_iterator_t *identity) { qdr_auto_link_t *al = 0; if (!name && !identity) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = "No name or identity provided"; qd_log(core->agent_log, QD_LOG_ERROR, "Error performing DELETE of %s: %s", CONFIG_AUTOLINK_TYPE, query->status.description); } else { if (identity) al = qdr_auto_link_config_find_by_identity_CT(core, identity); else if (name) al = qdr_auto_link_config_find_by_name_CT(core, name); if (al) { qdr_route_del_auto_link_CT(core, al); query->status = QD_AMQP_NO_CONTENT; } else query->status = QD_AMQP_NOT_FOUND; } // // Enqueue the response. // qdr_agent_enqueue_response_CT(core, query); }
void *router_core_thread(void *arg) { qdr_core_t *core = (qdr_core_t*) arg; qdr_action_list_t action_list; qdr_action_t *action; qdr_forwarder_setup_CT(core); qdr_route_table_setup_CT(core); qdr_agent_setup_CT(core); qd_log(core->log, QD_LOG_INFO, "Router Core thread running. %s/%s", core->router_area, core->router_id); while (core->running) { // // Use the lock only to protect the condition variable and the action list // sys_mutex_lock(core->action_lock); // // Block on the condition variable when there is no action to do // while (core->running && DEQ_IS_EMPTY(core->action_list)) sys_cond_wait(core->action_cond, core->action_lock); // // Move the entire action list to a private list so we can process it without // holding the lock // DEQ_MOVE(core->action_list, action_list); sys_mutex_unlock(core->action_lock); // // Process and free all of the action items in the list // action = DEQ_HEAD(action_list); while (action) { DEQ_REMOVE_HEAD(action_list); if (action->label) qd_log(core->log, QD_LOG_TRACE, "Core action '%s'%s", action->label, core->running ? "" : " (discard)"); action->action_handler(core, action, !core->running); free_qdr_action_t(action); action = DEQ_HEAD(action_list); } } qd_log(core->log, QD_LOG_INFO, "Router Core thread exited"); return 0; }
void qd_connection_manager_start_on_demand(qd_dispatch_t *qd, qd_config_connector_t *cc) { if (cc && cc->connector == 0) { qd_log(qd->connection_manager->log_source, QD_LOG_INFO, "Starting on-demand connector: %s", cc->configuration.name); cc->connector = qd_server_connect(qd, &cc->configuration, cc); } }
static void log_config(qd_log_source_t *log, qd_server_config_t *c, const char *what) { qd_log(log, QD_LOG_INFO, "Configured %s: %s proto=%s, role=%s%s%s%s", what, c->host_port, c->protocol_family ? c->protocol_family : "any", c->role, c->http ? ", http" : "", c->ssl_profile ? ", sslProfile=":"", c->ssl_profile ? c->ssl_profile:""); }
bool qd_policy_socket_accept(void *context, const char *hostname) { qd_policy_t *policy = (qd_policy_t *)context; bool result = true; if (n_connections < policy->max_connection_limit) { // connection counted and allowed n_connections += 1; qd_log(policy->log_source, QD_LOG_TRACE, "ALLOW Connection '%s' based on global connection count. nConnections= %d", hostname, n_connections); } else { // connection denied result = false; n_denied += 1; qd_log(policy->log_source, QD_LOG_INFO, "DENY Connection '%s' based on global connection count. nConnections= %d", hostname, n_connections); } n_processed += 1; return result; }
static void qdr_remove_link_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "remove_link: Router maskbit out of range: %d", router_maskbit); return; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "remove_link: Router not found"); return; } qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; rnode->peer_control_link = 0; rnode->peer_data_link = 0; }
static void qdr_unmap_destination_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; qdr_field_t *address = action->args.route_table.address; if (discard) { qdr_field_free(address); return; } do { if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "unmap_destination: Router maskbit out of range: %d", router_maskbit); break; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "unmap_destination: Router not found"); break; } qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; qd_field_iterator_t *iter = address->iterator; qdr_address_t *addr = 0; qd_hash_retrieve(core->addr_hash, iter, (void**) &addr); if (!addr) { qd_log(core->log, QD_LOG_CRITICAL, "unmap_destination: Address not found"); break; } qd_bitmask_clear_bit(addr->rnodes, router_maskbit); rnode->ref_count--; // // TODO - If this affects a waypoint, create the proper side effects // qdr_check_addr_CT(core, addr, false); } while (false); qdr_field_free(address); }
qdr_core_t *qdr_core(qd_dispatch_t *qd, qd_router_mode_t mode, const char *area, const char *id) { qdr_core_t *core = NEW(qdr_core_t); ZERO(core); core->qd = qd; core->router_mode = mode; core->router_area = area; core->router_id = id; // // Set up the logging sources for the router core // core->log = qd_log_source("ROUTER_CORE"); core->agent_log = qd_log_source("AGENT"); // // Report on the configuration for unsettled multicasts // qd_log(core->log, QD_LOG_INFO, "Allow Unsettled Multicast: %s", qd->allow_unsettled_multicast ? "yes" : "no"); // // Set up the threading support // core->action_cond = sys_cond(); core->action_lock = sys_mutex(); core->running = true; DEQ_INIT(core->action_list); core->work_lock = sys_mutex(); DEQ_INIT(core->work_list); core->work_timer = qd_timer(core->qd, qdr_general_handler, core); // // Set up the unique identifier generator // core->next_identifier = 1; core->id_lock = sys_mutex(); // // Launch the core thread // core->thread = sys_thread(router_core_thread, core); // // Perform outside-of-thread setup for the management agent // core->agent_subscription_mobile = qdr_core_subscribe(core, "$management", 'M', '0', QD_TREATMENT_ANYCAST_CLOSEST, qdr_management_agent_on_message, core); core->agent_subscription_local = qdr_core_subscribe(core, "$management", 'L', '0', QD_TREATMENT_ANYCAST_CLOSEST, qdr_management_agent_on_message, core); return core; }
qd_node_t *qd_container_set_default_node_type(qd_dispatch_t *qd, const qd_node_type_t *nt, void *context, qd_dist_mode_t supported_dist) { qd_container_t *container = qd->container; if (container->default_node) qd_container_destroy_node(container->default_node); if (nt) { container->default_node = qd_container_create_node(qd, nt, 0, context, supported_dist, QD_LIFE_PERMANENT); qd_log(container->log_source, QD_LOG_TRACE, "Node of type '%s' installed as default node", nt->type_name); } else { container->default_node = 0; qd_log(container->log_source, QD_LOG_TRACE, "Default node removed"); } return container->default_node; }
static void on_conn_event(void *context, qdrc_event_t event, qdr_connection_t *conn) { qcm_edge_conn_mgr_t *cm = (qcm_edge_conn_mgr_t*) context; switch (event) { case QDRC_EVENT_CONN_OPENED : if (cm->active_edge_connection == 0 && conn->role == QDR_ROLE_EDGE_CONNECTION) { qd_log(cm->core->log, QD_LOG_INFO, "Edge connection (id=%"PRIu64") to interior established", conn->identity); cm->active_edge_connection = conn; cm->core->active_edge_connection = conn; qdrc_event_conn_raise(cm->core, QDRC_EVENT_CONN_EDGE_ESTABLISHED, conn); } break; case QDRC_EVENT_CONN_CLOSED : if (cm->active_edge_connection == conn) { qdrc_event_conn_raise(cm->core, QDRC_EVENT_CONN_EDGE_LOST, conn); qdr_connection_t *alternate = DEQ_HEAD(cm->core->open_connections); while (alternate && (alternate == conn || alternate->role != QDR_ROLE_EDGE_CONNECTION)) alternate = DEQ_NEXT(alternate); if (alternate) { qd_log(cm->core->log, QD_LOG_INFO, "Edge connection (id=%"PRIu64") to interior lost, activating alternate id=%"PRIu64"", conn->identity, alternate->identity); cm->active_edge_connection = alternate; cm->core->active_edge_connection = alternate; qdrc_event_conn_raise(cm->core, QDRC_EVENT_CONN_EDGE_ESTABLISHED, alternate); } else { qd_log(cm->core->log, QD_LOG_INFO, "Edge connection (id=%"PRIu64") to interior lost, no alternate connection available", conn->identity); cm->active_edge_connection = 0; } } break; default: assert(false); break; } }
qd_config_sasl_plugin_t *qd_dispatch_configure_sasl_plugin(qd_dispatch_t *qd, qd_entity_t *entity) { qd_error_clear(); qd_connection_manager_t *cm = qd->connection_manager; qd_config_sasl_plugin_t *sasl_plugin = NEW(qd_config_sasl_plugin_t); DEQ_ITEM_INIT(sasl_plugin); DEQ_INSERT_TAIL(cm->config_sasl_plugins, sasl_plugin); sasl_plugin->name = qd_entity_opt_string(entity, "name", 0); CHECK(); sasl_plugin->auth_service = qd_entity_opt_string(entity, "authService", 0); CHECK(); sasl_plugin->sasl_init_hostname = qd_entity_opt_string(entity, "saslInitHostname", 0); CHECK(); sasl_plugin->auth_ssl_profile = qd_entity_opt_string(entity, "authSslProfile", 0); CHECK(); qd_log(cm->log_source, QD_LOG_INFO, "Created SASL plugin config with name %s", sasl_plugin->name); return sasl_plugin; error: qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create SASL plugin config: %s", qd_error_message()); config_sasl_plugin_free(cm, sasl_plugin); return 0; }
static void qdr_remove_next_hop_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "remove_next_hop: Router maskbit out of range: %d", router_maskbit); return; } qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; rnode->next_hop = 0; }
static void qdr_route_log_CT(qdr_core_t *core, const char *text, const char *name, uint64_t id, qdr_connection_t *conn) { const char *key = (const char*) qd_hash_key_by_handle(conn->conn_id->hash_handle); char id_string[64]; const char *log_name = name ? name : id_string; if (!name) snprintf(id_string, 64, "%"PRId64, id); qd_log(core->log, QD_LOG_INFO, "%s '%s' on %s %s", text, log_name, key[0] == 'L' ? "connection" : "container", &key[1]); }
static void check(int fd) { if (qd_error_code()) { qd_log(log_source, QD_LOG_CRITICAL, "Router start-up failed: %s", qd_error_message()); #ifdef __sun FILE *file = fdopen(fd, "a+"); fprintf(file, "%s: %s\n", argv0, qd_error_message()); #else dprintf(fd, "%s: %s\n", argv0, qd_error_message()); #endif close(fd); exit(1); } }