/** * Sets the error status on a new composed field. */ static void qd_set_response_status(const qd_amqp_error_t *error, qd_composed_field_t **field) { // // Insert appropriate success or error // *field = qd_compose(QD_PERFORMATIVE_APPLICATION_PROPERTIES, *field); qd_compose_start_map(*field); qd_compose_insert_string(*field, status_description); qd_compose_insert_string(*field, error->description); qd_compose_insert_string(*field, status_code); qd_compose_insert_uint(*field, error->status); qd_compose_end_map(*field); }
static void qd_core_agent_query_handler(qdr_core_t *core, qd_router_entity_type_t entity_type, qd_router_operation_type_t operation_type, qd_message_t *msg, int *count, int *offset) { // // Add the Body. // qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_BODY_AMQP_VALUE, 0); // Start a map in the body. Look for the end map in the callback function, qd_manage_response_handler. qd_compose_start_map(field); //add a "attributeNames" key qd_compose_insert_string(field, ATTRIBUTE_NAMES); // Call local function that creates and returns a local qd_management_context_t object containing the values passed in. qd_management_context_t *ctx = qd_management_context(qd_message(), msg, field, 0, core, operation_type, (*count)); // Grab the attribute names from the incoming message body. The attribute names will be used later on in the response. qd_parsed_field_t *attribute_names_parsed_field = 0; qd_field_iterator_t *body_iter = qd_message_field_iterator(msg, QD_FIELD_BODY); qd_parsed_field_t *body = qd_parse(body_iter); if (body != 0 && qd_parse_is_map(body)) { attribute_names_parsed_field = qd_parse_value_by_key(body, ATTRIBUTE_NAMES); } // Set the callback function. qdr_manage_handler(core, qd_manage_response_handler); ctx->query = qdr_manage_query(core, ctx, entity_type, attribute_names_parsed_field, field); //Add the attribute names qdr_query_add_attribute_names(ctx->query); //this adds a list of attribute names like ["attribute1", "attribute2", "attribute3", "attribute4",] qd_compose_insert_string(field, results); //add a "results" key qd_compose_start_list(field); //start the list for results qdr_query_get_first(ctx->query, (*offset)); qd_field_iterator_free(body_iter); qd_parse_free(body); }
static void qdr_agent_emit_columns(qdr_query_t *query, const char *qdr_columns[], int column_count) { qd_compose_start_list(query->body); int i = 0; while (query->columns[i] >= 0) { assert(query->columns[i] < column_count); qd_compose_insert_string(query->body, qdr_columns[query->columns[i]]); i++; } qd_compose_end_list(query->body); }
static void qdr_manage_write_response_map_CT(qd_composed_field_t *body, qdr_link_t *link) { qd_compose_start_map(body); for(int i = 0; i < QDR_LINK_COLUMN_COUNT; i++) { qd_compose_insert_string(body, qdr_link_columns[i]); qdr_agent_write_column_CT(body, i, link); } qd_compose_end_map(body); }
static PyObject *qd_python_send(PyObject *self, PyObject *args) { qd_error_clear(); IoAdapter *ioa = (IoAdapter*) self; qd_composed_field_t *field = 0; PyObject *message = 0; int no_echo = 1; int control = 0; if (!PyArg_ParseTuple(args, "O|ii", &message, &no_echo, &control)) return 0; if (compose_python_message(&field, message, ioa->qd) == QD_ERROR_NONE) { qd_message_t *msg = qd_message(); qd_message_compose_2(msg, field); qd_composed_field_t *ingress = qd_compose_subfield(0); qd_compose_insert_string(ingress, qd_router_id(ioa->qd)); qd_composed_field_t *trace = qd_compose_subfield(0); qd_compose_start_list(trace); qd_compose_insert_string(trace, qd_router_id(ioa->qd)); qd_compose_end_list(trace); qd_message_set_ingress_annotation(msg, ingress); qd_message_set_trace_annotation(msg, trace); PyObject *address = PyObject_GetAttrString(message, "address"); if (address) { qdr_send_to2(ioa->core, msg, PyString_AsString(address), (bool) no_echo, (bool) control); Py_DECREF(address); } qd_compose_free(field); qd_message_free(msg); Py_RETURN_NONE; } if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, qd_error_message()); return 0; }
static void qdr_manage_write_config_auto_link_map_CT(qdr_core_t *core, qdr_auto_link_t *al, qd_composed_field_t *body, const char *qdr_config_auto_link_columns[]) { qd_compose_start_map(body); for(int i = 0; i < QDR_CONFIG_AUTO_LINK_COLUMN_COUNT; i++) { qd_compose_insert_string(body, qdr_config_auto_link_columns[i]); qdr_config_auto_link_insert_column_CT(al, i, body, false); } qd_compose_end_map(body); }
static void qdr_manage_write_address_map_CT(qdr_core_t *core, qdr_address_t *addr, qd_composed_field_t *body, const char *qdr_address_columns[]) { qd_compose_start_map(body); for(int i = 0; i < QDR_ADDRESS_COLUMN_COUNT; i++) { qd_compose_insert_string(body, qdr_address_columns[i]); qdr_insert_address_columns_CT(core, addr, body, i); } qd_compose_end_map(body); }
void qd_message_compose_1(qd_message_t *msg, const char *to, qd_buffer_list_t *buffers) { qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_HEADER, 0); qd_message_content_t *content = MSG_CONTENT(msg); qd_compose_start_list(field); qd_compose_insert_bool(field, 0); // durable //qd_compose_insert_null(field); // priority //qd_compose_insert_null(field); // ttl //qd_compose_insert_boolean(field, 0); // first-acquirer //qd_compose_insert_uint(field, 0); // delivery-count qd_compose_end_list(field); qd_buffer_list_t out_ma; if (compose_message_annotations((qd_message_pvt_t*)msg, &out_ma)) { qd_compose_insert_buffers(field, &out_ma); } field = qd_compose(QD_PERFORMATIVE_PROPERTIES, field); qd_compose_start_list(field); qd_compose_insert_null(field); // message-id qd_compose_insert_null(field); // user-id qd_compose_insert_string(field, to); // to //qd_compose_insert_null(field); // subject //qd_compose_insert_null(field); // reply-to //qd_compose_insert_null(field); // correlation-id //qd_compose_insert_null(field); // content-type //qd_compose_insert_null(field); // content-encoding //qd_compose_insert_timestamp(field, 0); // absolute-expiry-time //qd_compose_insert_timestamp(field, 0); // creation-time //qd_compose_insert_null(field); // group-id //qd_compose_insert_uint(field, 0); // group-sequence //qd_compose_insert_null(field); // reply-to-group-id qd_compose_end_list(field); if (buffers) { field = qd_compose(QD_PERFORMATIVE_BODY_DATA, field); qd_compose_insert_binary_buffers(field, buffers); } qd_compose_take_buffers(field, &content->buffers); qd_compose_free(field); }
static void _insert_column_CT(qdr_link_route_t *lr, int col, qd_composed_field_t *body, bool as_map) { if (as_map) qd_compose_insert_string(body, qdr_conn_link_route_columns[col]); switch(col) { case QDR_CONN_LINK_ROUTE_NAME: if (lr->name) qd_compose_insert_string(body, lr->name); else qd_compose_insert_null(body); break; case QDR_CONN_LINK_ROUTE_IDENTITY: { char id_str[100]; snprintf(id_str, 100, "%"PRId64, lr->identity); qd_compose_insert_string(body, id_str); break; } case QDR_CONN_LINK_ROUTE_TYPE: qd_compose_insert_string(body, CONN_LINK_ROUTE_TYPE); break; case QDR_CONN_LINK_ROUTE_PATTERN: qd_compose_insert_string(body, lr->pattern); break; case QDR_CONN_LINK_ROUTE_DIRECTION: qd_compose_insert_string(body, lr->dir == QD_INCOMING ? "in" : "out"); break; case QDR_CONN_LINK_ROUTE_CONTAINER_ID: if (lr->parent_conn && lr->parent_conn->connection_info) { if (lr->parent_conn->connection_info->container) { qd_compose_insert_string(body, lr->parent_conn->connection_info->container); break; } } qd_compose_insert_null(body); break; } }
static void qdr_config_auto_link_insert_column_CT(qdr_auto_link_t *al, int col, qd_composed_field_t *body, bool as_map) { const char *text = 0; const char *key; char id_str[100]; if (as_map) qd_compose_insert_string(body, qdr_config_auto_link_columns[col]); switch(col) { case QDR_CONFIG_AUTO_LINK_NAME: if (al->name) qd_compose_insert_string(body, al->name); else qd_compose_insert_null(body); break; case QDR_CONFIG_AUTO_LINK_IDENTITY: snprintf(id_str, 100, "%"PRId64, al->identity); qd_compose_insert_string(body, id_str); break; case QDR_CONFIG_AUTO_LINK_TYPE: qd_compose_insert_string(body, CONFIG_AUTOLINK_TYPE); break; case QDR_CONFIG_AUTO_LINK_ADDR: key = (const char*) qd_hash_key_by_handle(al->addr->hash_handle); if (key && key[0] == 'M') qd_compose_insert_string(body, &key[2]); else qd_compose_insert_null(body); break; case QDR_CONFIG_AUTO_LINK_DIR: text = al->dir == QD_INCOMING ? "in" : "out"; qd_compose_insert_string(body, text); break; case QDR_CONFIG_AUTO_LINK_PHASE: qd_compose_insert_int(body, al->phase); break; case QDR_CONFIG_AUTO_LINK_CONNECTION: case QDR_CONFIG_AUTO_LINK_CONTAINER_ID: if (al->conn_id) { key = (const char*) qd_hash_key_by_handle(al->conn_id->hash_handle); if (key && key[0] == 'L' && col == QDR_CONFIG_AUTO_LINK_CONNECTION) { qd_compose_insert_string(body, &key[1]); break; } if (key && key[0] == 'C' && col == QDR_CONFIG_AUTO_LINK_CONTAINER_ID) { qd_compose_insert_string(body, &key[1]); break; } } qd_compose_insert_null(body); break; case QDR_CONFIG_AUTO_LINK_LINK_REF: if (al->link) { snprintf(id_str, 100, "%"PRId64, al->link->identity); qd_compose_insert_string(body, id_str); } else qd_compose_insert_null(body); break; case QDR_CONFIG_AUTO_LINK_OPER_STATUS: switch (al->state) { case QDR_AUTO_LINK_STATE_INACTIVE: text = "inactive"; break; case QDR_AUTO_LINK_STATE_ATTACHING: text = "attaching"; break; case QDR_AUTO_LINK_STATE_FAILED: text = "failed"; break; case QDR_AUTO_LINK_STATE_ACTIVE: text = "active"; break; case QDR_AUTO_LINK_STATE_QUIESCING: text = "quiescing"; break; case QDR_AUTO_LINK_STATE_IDLE: text = "idle"; break; } if (text) qd_compose_insert_string(body, text); else qd_compose_insert_null(body); break; case QDR_CONFIG_AUTO_LINK_LAST_ERROR: if (al->last_error) qd_compose_insert_string(body, al->last_error); else qd_compose_insert_null(body); break; } }
static void qdr_agent_write_column_CT(qd_composed_field_t *body, int col, qdr_core_t *core) { switch(col) { case QDR_ROUTER_IDENTITY: // There is only one instance of router. Just give it an identity of 1 qd_compose_insert_string(body, "1"); break; case QDR_ROUTER_TYPE: qd_compose_insert_string(body, "org.apache.qpid.dispatch.router"); break; case QDR_ROUTER_MODE: qd_compose_insert_string(body, router_mode(core->router_mode)); break; case QDR_ROUTER_AREA: if (core->router_area) qd_compose_insert_string(body, core->router_area); else qd_compose_insert_null(body); break; case QDR_ROUTER_VERSION: qd_compose_insert_string(body, QPID_DISPATCH_VERSION); break; case QDR_ROUTER_HELLO_INTERVAL: qd_compose_insert_null(body); break; case QDR_ROUTER_ADDR_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(core->addrs)); break; case QDR_ROUTER_LINK_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(core->open_links)); break; case QDR_ROUTER_NODE_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(core->routers)); break; case QDR_ROUTER_CONNECTION_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(core->open_connections)); break; case QDR_ROUTER_LINK_ROUTE_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(core->link_routes)); break; case QDR_ROUTER_AUTO_LINK_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(core->auto_links)); break; case QDR_ROUTER_ROUTER_ID: case QDR_ROUTER_ID: case QDR_ROUTER_NAME: if (core->router_id) qd_compose_insert_string(body, core->router_id); else qd_compose_insert_null(body); break; default: qd_compose_insert_null(body); break; } }
static char *test_tracemask(void *context) { qd_bitmask_t *bm = NULL; qd_tracemask_t *tm = qd_tracemask(); qd_buffer_list_t list; static char error[1024]; error[0] = 0; qd_iterator_set_address(false, "0", "ROUTER"); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.A", 0); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.B", 1); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.C", 2); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.D", 3); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.E", 4); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.F", 5); qd_tracemask_set_link(tm, 0, 4); qd_tracemask_set_link(tm, 3, 10); qd_tracemask_set_link(tm, 4, 3); qd_tracemask_set_link(tm, 5, 2); qd_composed_field_t *comp = qd_compose_subfield(0); qd_compose_start_list(comp); qd_compose_insert_string(comp, "0/Router.A"); qd_compose_insert_string(comp, "0/Router.D"); qd_compose_insert_string(comp, "0/Router.E"); qd_compose_end_list(comp); DEQ_INIT(list); qd_compose_take_buffers(comp, &list); qd_compose_free(comp); int length = 0; qd_buffer_t *buf = DEQ_HEAD(list); while (buf) { length += qd_buffer_size(buf); buf = DEQ_NEXT(buf); } qd_iterator_t *iter = qd_iterator_buffer(DEQ_HEAD(list), 0, length, ITER_VIEW_ALL); qd_parsed_field_t *pf = qd_parse(iter); qd_iterator_free(iter); int ingress = -1; bm = qd_tracemask_create(tm, pf, &ingress); if (qd_bitmask_cardinality(bm) != 3) { sprintf(error, "Expected cardinality of 3, got %d", qd_bitmask_cardinality(bm)); goto cleanup; } if (ingress != 0) { sprintf(error, "(A) Expected ingress index of 0, got %d", ingress); goto cleanup; } int total = 0; int bit, c; for (QD_BITMASK_EACH(bm, bit, c)) { total += bit; } if (total != 17) { sprintf(error, "Expected total bit value of 17, got %d", total); goto cleanup; } qd_bitmask_free(bm); bm = 0; qd_tracemask_del_router(tm, 3); qd_tracemask_remove_link(tm, 0); ingress = -1; bm = qd_tracemask_create(tm, pf, &ingress); qd_parse_free(pf); pf = 0; if (qd_bitmask_cardinality(bm) != 1) { sprintf(error, "Expected cardinality of 1, got %d", qd_bitmask_cardinality(bm)); goto cleanup; } if (ingress != 0) { sprintf(error, "(B) Expected ingress index of 0, got %d", ingress); goto cleanup; } total = 0; for (QD_BITMASK_EACH(bm, bit, c)) { total += bit; } if (total != 3) { sprintf(error, "Expected total bit value of 3, got %d", total); // fallthrough } cleanup: qd_parse_free(pf); qd_tracemask_free(tm); qd_bitmask_free(bm); for (qd_buffer_t *buf = DEQ_HEAD(list); buf; buf = DEQ_HEAD(list)) { DEQ_REMOVE_HEAD(list); qd_buffer_free(buf); } return *error ? error : 0; }
static void qdr_config_link_route_insert_column_CT(qdr_link_route_t *lr, int col, qd_composed_field_t *body, bool as_map) { const char *text = 0; const char *key; if (as_map) qd_compose_insert_string(body, qdr_config_link_route_columns[col]); switch(col) { case QDR_CONFIG_LINK_ROUTE_NAME: if (lr->name) qd_compose_insert_string(body, lr->name); else qd_compose_insert_null(body); break; case QDR_CONFIG_LINK_ROUTE_IDENTITY: { char id_str[100]; snprintf(id_str, 100, "%"PRId64, lr->identity); qd_compose_insert_string(body, id_str); break; } case QDR_CONFIG_LINK_ROUTE_TYPE: qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.config.linkRoute"); break; case QDR_CONFIG_LINK_ROUTE_PREFIX: key = (const char*) qd_hash_key_by_handle(lr->addr->hash_handle); if (key && (key[0] == 'C' || key[0] == 'D')) qd_compose_insert_string(body, &key[1]); else qd_compose_insert_null(body); break; case QDR_CONFIG_LINK_ROUTE_DISTRIBUTION: switch (lr->treatment) { case QD_TREATMENT_LINK_BALANCED: text = "linkBalanced"; break; default: text = 0; } if (text) qd_compose_insert_string(body, text); else qd_compose_insert_null(body); break; case QDR_CONFIG_LINK_ROUTE_CONNECTION: case QDR_CONFIG_LINK_ROUTE_CONTAINER_ID: if (lr->conn_id) { key = (const char*) qd_hash_key_by_handle(lr->conn_id->hash_handle); if (key && key[0] == 'L' && col == QDR_CONFIG_LINK_ROUTE_CONNECTION) { qd_compose_insert_string(body, &key[1]); break; } if (key && key[0] == 'C' && col == QDR_CONFIG_LINK_ROUTE_CONTAINER_ID) { qd_compose_insert_string(body, &key[1]); break; } } qd_compose_insert_null(body); break; case QDR_CONFIG_LINK_ROUTE_DIR: text = lr->dir == QD_INCOMING ? "in" : "out"; qd_compose_insert_string(body, text); break; case QDR_CONFIG_LINK_ROUTE_OPER_STATUS: text = lr->active ? "active" : "inactive"; qd_compose_insert_string(body, text); break; } }
static qd_iterator_t *router_annotate_message(qd_router_t *router, qd_parsed_field_t *in_ma, qd_message_t *msg, qd_bitmask_t **link_exclusions, bool strip_inbound_annotations) { qd_iterator_t *ingress_iter = 0; qd_parsed_field_t *trace = 0; qd_parsed_field_t *ingress = 0; qd_parsed_field_t *to = 0; qd_parsed_field_t *phase = 0; *link_exclusions = 0; if (in_ma && !strip_inbound_annotations) { uint32_t count = qd_parse_sub_count(in_ma); bool done = false; for (uint32_t idx = 0; idx < count && !done; idx++) { qd_parsed_field_t *sub = qd_parse_sub_key(in_ma, idx); if (!sub) continue; qd_iterator_t *iter = qd_parse_raw(sub); if (!iter) continue; if (qd_iterator_equal(iter, (unsigned char*) QD_MA_TRACE)) { trace = qd_parse_sub_value(in_ma, idx); } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_INGRESS)) { ingress = qd_parse_sub_value(in_ma, idx); } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_TO)) { to = qd_parse_sub_value(in_ma, idx); } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_PHASE)) { phase = qd_parse_sub_value(in_ma, idx); } done = trace && ingress && to && phase; } } // // QD_MA_TRACE: // If there is a trace field, append this router's ID to the trace. // If the router ID is already in the trace the msg has looped. // qd_composed_field_t *trace_field = qd_compose_subfield(0); qd_compose_start_list(trace_field); if (trace) { if (qd_parse_is_list(trace)) { // // Create a link-exclusion map for the items in the trace. This map will // contain a one-bit for each link that leads to a neighbor router that // the message has already passed through. // *link_exclusions = qd_tracemask_create(router->tracemask, trace); // // Append this router's ID to the trace. // uint32_t idx = 0; qd_parsed_field_t *trace_item = qd_parse_sub_value(trace, idx); while (trace_item) { qd_iterator_t *iter = qd_parse_raw(trace_item); qd_iterator_reset_view(iter, ITER_VIEW_ALL); qd_compose_insert_string_iterator(trace_field, iter); idx++; trace_item = qd_parse_sub_value(trace, idx); } } } qd_compose_insert_string(trace_field, node_id); qd_compose_end_list(trace_field); qd_message_set_trace_annotation(msg, trace_field); // // QD_MA_TO: // Preserve the existing value. // if (to) { qd_composed_field_t *to_field = qd_compose_subfield(0); qd_compose_insert_string_iterator(to_field, qd_parse_raw(to)); qd_message_set_to_override_annotation(msg, to_field); } // // QD_MA_PHASE: // Preserve the existing value. // if (phase) { int phase_val = qd_parse_as_int(phase); qd_message_set_phase_annotation(msg, phase_val); } // // QD_MA_INGRESS: // If there is no ingress field, annotate the ingress as // this router else keep the original field. // qd_composed_field_t *ingress_field = qd_compose_subfield(0); if (ingress && qd_parse_is_scalar(ingress)) { ingress_iter = qd_parse_raw(ingress); qd_compose_insert_string_iterator(ingress_field, ingress_iter); } else qd_compose_insert_string(ingress_field, node_id); qd_message_set_ingress_annotation(msg, ingress_field); // // Return the iterator to the ingress field _if_ it was present. // If we added the ingress, return NULL. // return ingress_iter; }
/** * Inbound Delivery Handler */ static void AMQP_rx_handler(void* context, qd_link_t *link, pn_delivery_t *pnd) { qd_router_t *router = (qd_router_t*) context; pn_link_t *pn_link = qd_link_pn(link); qdr_link_t *rlink = (qdr_link_t*) qd_link_get_context(link); qdr_delivery_t *delivery = 0; qd_message_t *msg; // // Receive the message into a local representation. If the returned message // pointer is NULL, we have not yet received a complete message. // // Note: In the link-routing case, consider cutting the message through. There's // no reason to wait for the whole message to be received before starting to // send it. // msg = qd_message_receive(pnd); if (!msg) return; // // Consume the delivery. // pn_link_advance(pn_link); // // If there's no router link, free the message and finish. It's likely that the link // is closing. // if (!rlink) { qd_message_free(msg); return; } // // Handle the link-routed case // if (qdr_link_is_routed(rlink)) { pn_delivery_tag_t dtag = pn_delivery_tag(pnd); delivery = qdr_link_deliver_to_routed_link(rlink, msg, pn_delivery_settled(pnd), (uint8_t*) dtag.start, dtag.size); if (delivery) { if (pn_delivery_settled(pnd)) pn_delivery_settle(pnd); else { pn_delivery_set_context(pnd, delivery); qdr_delivery_set_context(delivery, pnd); qdr_delivery_incref(delivery); } } return; } // // Determine if the incoming link is anonymous. If the link is addressed, // there are some optimizations we can take advantage of. // bool anonymous_link = qdr_link_is_anonymous(rlink); // // Determine if the user of this connection is allowed to proxy the // user_id of messages. A message user_id is proxied when the // property value differs from the authenticated user name of the connection. // If the user is not allowed to proxy the user_id then the message user_id // must be blank or it must be equal to the connection user name. // bool check_user = false; qd_connection_t *conn = qd_link_connection(link); if (conn->policy_settings) check_user = !conn->policy_settings->allowUserIdProxy; // // Validate the content of the delivery as an AMQP message. This is done partially, only // to validate that we can find the fields we need to route the message. // // If the link is anonymous, we must validate through the message properties to find the // 'to' field. If the link is not anonymous, we don't need the 'to' field as we will be // using the address from the link target. // qd_message_depth_t validation_depth = (anonymous_link || check_user) ? QD_DEPTH_PROPERTIES : QD_DEPTH_MESSAGE_ANNOTATIONS; bool valid_message = qd_message_check(msg, validation_depth); if (valid_message) { if (check_user) { // This connection must not allow proxied user_id qd_iterator_t *userid_iter = qd_message_field_iterator(msg, QD_FIELD_USER_ID); if (userid_iter) { // The user_id property has been specified if (qd_iterator_remaining(userid_iter) > 0) { // user_id property in message is not blank if (!qd_iterator_equal(userid_iter, (const unsigned char *)conn->user_id)) { // This message is rejected: attempted user proxy is disallowed qd_log(router->log_source, QD_LOG_DEBUG, "Message rejected due to user_id proxy violation. User:%s", conn->user_id); pn_link_flow(pn_link, 1); pn_delivery_update(pnd, PN_REJECTED); pn_delivery_settle(pnd); qd_message_free(msg); qd_iterator_free(userid_iter); return; } } qd_iterator_free(userid_iter); } } qd_parsed_field_t *in_ma = qd_message_message_annotations(msg); qd_bitmask_t *link_exclusions; bool strip = qdr_link_strip_annotations_in(rlink); qd_iterator_t *ingress_iter = router_annotate_message(router, in_ma, msg, &link_exclusions, strip); if (anonymous_link) { qd_iterator_t *addr_iter = 0; int phase = 0; // // If the message has delivery annotations, get the to-override field from the annotations. // if (in_ma) { qd_parsed_field_t *ma_to = qd_parse_value_by_key(in_ma, QD_MA_TO); if (ma_to) { addr_iter = qd_iterator_dup(qd_parse_raw(ma_to)); phase = qd_message_get_phase_annotation(msg); } } // // Still no destination address? Use the TO field from the message properties. // if (!addr_iter) addr_iter = qd_message_field_iterator(msg, QD_FIELD_TO); if (addr_iter) { qd_iterator_reset_view(addr_iter, ITER_VIEW_ADDRESS_HASH); if (phase > 0) qd_iterator_annotate_phase(addr_iter, '0' + (char) phase); delivery = qdr_link_deliver_to(rlink, msg, ingress_iter, addr_iter, pn_delivery_settled(pnd), link_exclusions); } } else { const char *term_addr = pn_terminus_get_address(qd_link_remote_target(link)); if (!term_addr) term_addr = pn_terminus_get_address(qd_link_source(link)); if (term_addr) { qd_composed_field_t *to_override = qd_compose_subfield(0); qd_compose_insert_string(to_override, term_addr); qd_message_set_to_override_annotation(msg, to_override); int phase = qdr_link_phase(rlink); if (phase != 0) qd_message_set_phase_annotation(msg, phase); } delivery = qdr_link_deliver(rlink, msg, ingress_iter, pn_delivery_settled(pnd), link_exclusions); } if (delivery) { if (pn_delivery_settled(pnd)) pn_delivery_settle(pnd); else { pn_delivery_set_context(pnd, delivery); qdr_delivery_set_context(delivery, pnd); qdr_delivery_incref(delivery); } } else { // // The message is now and will always be unroutable because there is no address. // pn_link_flow(pn_link, 1); pn_delivery_update(pnd, PN_REJECTED); pn_delivery_settle(pnd); qd_message_free(msg); } // // Rules for delivering messages: // // For addressed (non-anonymous) links: // to-override must be set (done in the core?) // uses qdr_link_deliver to hand over to the core // // For anonymous links: // If there's a to-override in the annotations, use that address // Or, use the 'to' field in the message properties // } else { // // Message is invalid. Reject the message and don't involve the router core. // pn_link_flow(pn_link, 1); pn_delivery_update(pnd, PN_REJECTED); pn_delivery_settle(pnd); qd_message_free(msg); } }
static void qdr_insert_address_columns_CT(qdr_core_t *core, qdr_address_t *addr, qd_composed_field_t *body, int column_index) { switch(column_index) { case QDR_ADDRESS_NAME: case QDR_ADDRESS_IDENTITY: case QDR_ADDRESS_KEY: if (addr->hash_handle) qd_compose_insert_string(body, (const char*) qd_hash_key_by_handle(addr->hash_handle)); else qd_compose_insert_null(body); break; case QDR_ADDRESS_TYPE: qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.address"); break; case QDR_ADDRESS_DISTRIBUTION: { switch (addr->treatment) { case QD_TREATMENT_MULTICAST_FLOOD: qd_compose_insert_string(body, "flood"); break; case QD_TREATMENT_MULTICAST_ONCE: qd_compose_insert_string(body, "multicast"); break; case QD_TREATMENT_ANYCAST_CLOSEST: qd_compose_insert_string(body, "closest"); break; case QD_TREATMENT_ANYCAST_BALANCED: qd_compose_insert_string(body, "balanced"); break; case QD_TREATMENT_LINK_BALANCED: qd_compose_insert_string(body, "linkBalanced"); break; } break; } case QDR_ADDRESS_IN_PROCESS: qd_compose_insert_uint(body, DEQ_SIZE(addr->subscriptions)); break; case QDR_ADDRESS_SUBSCRIBER_COUNT: qd_compose_insert_uint(body, DEQ_SIZE(addr->rlinks)); break; case QDR_ADDRESS_REMOTE_COUNT: qd_compose_insert_uint(body, qd_bitmask_cardinality(addr->rnodes)); break; case QDR_ADDRESS_CONTAINER_COUNT: qd_compose_insert_uint(body, DEQ_SIZE(addr->conns)); break; case QDR_ADDRESS_REMOTE_HOST_ROUTERS: { qd_compose_start_list(body); int c; int bit; for (QD_BITMASK_EACH(addr->rnodes, bit, c)) { qdr_node_t *rnode = core->routers_by_mask_bit[bit]; if (rnode && rnode->owning_addr) { const char *ar = (char*) qd_hash_key_by_handle(rnode->owning_addr->hash_handle); qd_compose_insert_string(body, ar + 1); // Remove the 'R' prefix from the router address } } qd_compose_end_list(body); break; } case QDR_ADDRESS_DELIVERIES_INGRESS: qd_compose_insert_ulong(body, addr->deliveries_ingress); break; case QDR_ADDRESS_DELIVERIES_EGRESS: qd_compose_insert_ulong(body, addr->deliveries_egress); break; case QDR_ADDRESS_DELIVERIES_TRANSIT: qd_compose_insert_ulong(body, addr->deliveries_transit); break; case QDR_ADDRESS_DELIVERIES_TO_CONTAINER: qd_compose_insert_ulong(body, addr->deliveries_to_container); break; case QDR_ADDRESS_DELIVERIES_FROM_CONTAINER: qd_compose_insert_ulong(body, addr->deliveries_from_container); break; case QDR_ADDRESS_TRANSIT_OUTSTANDING: if (addr->outstanding_deliveries) { qd_compose_start_list(body); for (int i = 0; i < qd_bitmask_width(); i++) qd_compose_insert_long(body, addr->outstanding_deliveries[i]); qd_compose_end_list(body); } else qd_compose_insert_null(body); break; case QDR_ADDRESS_TRACKED_DELIVERIES: qd_compose_insert_long(body, addr->tracked_deliveries); break; default: qd_compose_insert_null(body); break; } }
static void qdr_agent_write_column_CT(qd_composed_field_t *body, int col, qdr_link_t *link) { char *text = 0; switch(col) { case QDR_LINK_NAME: { if (link->name) qd_compose_insert_string(body, link->name); else qd_compose_insert_null(body); break; } case QDR_LINK_IDENTITY: { char id[100]; snprintf(id, 100, "%"PRId64, link->identity); qd_compose_insert_string(body, id); break; } case QDR_LINK_TYPE: qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.link"); break; case QDR_LINK_LINK_NAME: qd_compose_insert_string(body, link->name); break; case QDR_LINK_LINK_TYPE: qd_compose_insert_string(body, qd_link_type_name(link->link_type)); break; case QDR_LINK_LINK_DIR: qd_compose_insert_string(body, link->link_direction == QD_INCOMING ? "in" : "out"); break; case QDR_LINK_OWNING_ADDR: if (link->owning_addr) qd_compose_insert_string(body, address_key(link->owning_addr)); else qd_compose_insert_null(body); break; case QDR_LINK_CAPACITY: qd_compose_insert_uint(body, link->capacity); break; case QDR_LINK_PEER: if (link->connected_link) { char id[100]; snprintf(id, 100, "%"PRId64, link->connected_link->identity); qd_compose_insert_string(body, id); } else qd_compose_insert_null(body); break; case QDR_LINK_UNDELIVERED_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(link->undelivered)); break; case QDR_LINK_UNSETTLED_COUNT: qd_compose_insert_ulong(body, DEQ_SIZE(link->unsettled)); break; case QDR_LINK_DELIVERY_COUNT: qd_compose_insert_ulong(body, link->total_deliveries); break; case QDR_LINK_CONNECTION_ID: qd_compose_insert_ulong(body, link->conn->management_id); break; case QDR_LINK_ADMIN_STATE: text = link->admin_enabled ? "enabled" : "disabled"; qd_compose_insert_string(body, text); break; case QDR_LINK_OPER_STATE: switch (link->oper_status) { case QDR_LINK_OPER_UP: text = "up"; break; case QDR_LINK_OPER_DOWN: text = "down"; break; case QDR_LINK_OPER_QUIESCING: text = "quiescing"; break; case QDR_LINK_OPER_IDLE: text = "idle"; break; default: text = 0; } if (!!text) qd_compose_insert_string(body, text); else qd_compose_insert_null(body); break; case QDR_LINK_PRESETTLED_COUNT: qd_compose_insert_ulong(body, link->presettled_deliveries); break; case QDR_LINK_ACCEPTED_COUNT: qd_compose_insert_ulong(body, link->accepted_deliveries); break; case QDR_LINK_REJECTED_COUNT: qd_compose_insert_ulong(body, link->rejected_deliveries); break; case QDR_LINK_RELEASED_COUNT: qd_compose_insert_ulong(body, link->released_deliveries); break; case QDR_LINK_MODIFIED_COUNT: qd_compose_insert_ulong(body, link->modified_deliveries); break; default: qd_compose_insert_null(body); break; } }
qd_error_t qd_py_to_composed(PyObject *value, qd_composed_field_t *field) { qd_python_check_lock(); qd_error_clear(); if (value == Py_None) { qd_compose_insert_null(field); } else if (PyBool_Check(value)) { qd_compose_insert_bool(field, PyInt_AS_LONG(value) ? 1 : 0); } else if (PyInt_Check(value)) { qd_compose_insert_long(field, (int64_t) PyInt_AS_LONG(value)); } else if (PyLong_Check(value)) { qd_compose_insert_long(field, (int64_t) PyLong_AsLongLong(value)); } else if (PyString_Check(value) || PyUnicode_Check(value)) { qd_compose_insert_string(field, PyString_AsString(value)); } else if (PyDict_Check(value)) { Py_ssize_t iter = 0; PyObject *key; PyObject *val; qd_compose_start_map(field); while (PyDict_Next(value, &iter, &key, &val)) { qd_py_to_composed(key, field); QD_ERROR_RET(); qd_py_to_composed(val, field); QD_ERROR_RET(); } QD_ERROR_PY_RET(); qd_compose_end_map(field); } else if (PyList_Check(value)) { Py_ssize_t count = PyList_Size(value); if (count == 0) qd_compose_empty_list(field); else { qd_compose_start_list(field); for (Py_ssize_t idx = 0; idx < count; idx++) { PyObject *item = PyList_GetItem(value, idx); QD_ERROR_PY_RET(); qd_py_to_composed(item, field); QD_ERROR_RET(); } qd_compose_end_list(field); } } else if (PyTuple_Check(value)) { Py_ssize_t count = PyTuple_Size(value); if (count == 0) qd_compose_empty_list(field); else { qd_compose_start_list(field); for (Py_ssize_t idx = 0; idx < count; idx++) { PyObject *item = PyTuple_GetItem(value, idx); QD_ERROR_PY_RET(); qd_py_to_composed(item, field); QD_ERROR_RET(); } qd_compose_end_list(field); } } else { PyObject *type=0, *typestr=0, *repr=0; if ((type = PyObject_Type(value)) && (typestr = PyObject_Str(type)) && (repr = PyObject_Repr(value))) qd_error(QD_ERROR_TYPE, "Can't compose object of type %s: %s", PyString_AsString(typestr), PyString_AsString(repr)); else qd_error(QD_ERROR_TYPE, "Can't compose python object of unknown type"); Py_XDECREF(type); Py_XDECREF(typestr); Py_XDECREF(repr); } return qd_error_code(); }