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;
}
Exemple #4
0
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);
}
Exemple #8
0
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];
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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:"");
}
Exemple #21
0
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;
}
Exemple #22
0
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;
}
Exemple #23
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);
}
Exemple #24
0
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;
}
Exemple #25
0
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;
}
Exemple #28
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]);
}
Exemple #30
0
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);
    }
}