in src/router_core/connections.c [1902:2015]
static void qdr_link_inbound_second_attach_CT(qdr_core_t *core, qdr_action_t *action, bool discard)
{
qdr_link_t *link = safe_deref_qdr_link_t(action->args.connection.link);
qdr_connection_t *conn = safe_deref_qdr_connection_t(action->args.connection.conn);
qdr_terminus_t *source = action->args.connection.source;
qdr_terminus_t *target = action->args.connection.target;
if (discard || !link || !conn) {
qdr_terminus_free(source);
qdr_terminus_free(target);
return;
}
link->oper_status = QDR_LINK_OPER_UP;
link->attach_count++;
//
// Mark the link as an edge link if it's inside an edge connection.
//
link->edge = (conn->role == QDR_ROLE_EDGE_CONNECTION);
if (link->core_endpoint) {
qdrc_endpoint_do_second_attach_CT(core, link->core_endpoint, source, target);
return;
}
//
// Handle attach-routed links
//
if (link->connected_link) {
qdr_terminus_t *remote_terminus = link->link_direction == QD_OUTGOING ? target : source;
if (link->strip_prefix) {
qdr_terminus_strip_address_prefix(remote_terminus, link->strip_prefix);
}
if (link->insert_prefix) {
qdr_terminus_insert_address_prefix(remote_terminus, link->insert_prefix);
}
qdr_link_outbound_second_attach_CT(core, link->connected_link, source, target);
return;
}
if (link->link_direction == QD_INCOMING) {
//
// Handle incoming link cases
//
switch (link->link_type) {
case QD_LINK_ENDPOINT:
if (link->auto_link) {
//
// This second-attach is the completion of an auto-link. If the attach
// has a valid source, transition the auto-link to the "active" state.
//
if (qdr_terminus_get_address(source)) {
link->auto_link->state = QDR_AUTO_LINK_STATE_ACTIVE;
qdr_core_bind_address_link_CT(core, link->auto_link->addr, link);
}
}
//
// Issue credit if this is an anonymous link or if its address has at least one reachable destination.
//
qdr_address_t *addr = link->owning_addr;
if (!addr || (DEQ_SIZE(addr->subscriptions) || DEQ_SIZE(addr->rlinks) || qd_bitmask_cardinality(addr->rnodes)
|| (!!addr->fallback && (DEQ_SIZE(addr->fallback->subscriptions)
|| DEQ_SIZE(addr->fallback->rlinks)
|| qd_bitmask_cardinality(addr->fallback->rnodes)))))
qdr_link_issue_credit_CT(core, link, link->capacity, false);
break;
case QD_LINK_ROUTER:
qdr_attach_link_data_CT(core, conn, link);
// fall-through
case QD_LINK_CONTROL:
qdr_link_issue_credit_CT(core, link, link->capacity, false);
break;
case QD_LINK_EDGE_DOWNLINK:
break;
}
} else {
//
// Handle outgoing link cases
//
switch (link->link_type) {
case QD_LINK_ENDPOINT:
if (link->auto_link) {
//
// This second-attach is the completion of an auto-link. If the attach
// has a valid target, transition the auto-link to the "active" state.
//
if (qdr_terminus_get_address(target)) {
link->auto_link->state = QDR_AUTO_LINK_STATE_ACTIVE;
qdr_core_bind_address_link_CT(core, link->auto_link->addr, link);
}
}
break;
case QD_LINK_CONTROL:
qdr_attach_link_control_CT(core, conn, link);
break;
case QD_LINK_ROUTER:
qdr_attach_link_data_CT(core, conn, link);
break;
case QD_LINK_EDGE_DOWNLINK:
break;
}
}
qdr_terminus_free(source);
qdr_terminus_free(target);
}