@@ -108,7 +108,6 @@ static void qd_connector_config_cleanup_conns(void *context)
108108static qd_error_t qd_connector_config_create_connectors (qd_connector_config_t * ctor_config )
109109{
110110 ASSERT_MGMT_THREAD ; // only the mgmt thread can modify the connector list!
111-
112111 qd_error_clear ();
113112
114113 // The connector configuration for inter-router connections may define a data connection count. This is the number
@@ -282,25 +281,6 @@ qd_connector_t *qd_connector_create(qd_connector_config_t *ctor_config, bool is_
282281 snprintf (item -> host_port , hplen , "%s:%s" , item -> host , item -> port );
283282 DEQ_INSERT_TAIL (connector -> conn_info_list , item );
284283
285- //
286- // Set up the vanflow record for this connector (LINK)
287- // Do this only for router-to-router connectors since the record represents an inter-router link
288- //
289- if ((strcmp (ctor_config -> config .role , "inter-router" ) == 0 && !is_data_connector ) ||
290- strcmp (ctor_config -> config .role , "edge" ) == 0 ||
291- strcmp (ctor_config -> config .role , "inter-edge" ) == 0 ) {
292- connector -> vflow_record = vflow_start_record (VFLOW_RECORD_LINK , 0 );
293- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_NAME , ctor_config -> config .name );
294- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_ROLE , ctor_config -> config .role );
295- vflow_set_uint64 (connector -> vflow_record , VFLOW_ATTRIBUTE_LINK_COST , ctor_config -> config .inter_router_cost );
296- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_OPER_STATUS , "down" );
297- vflow_set_uint64 (connector -> vflow_record , VFLOW_ATTRIBUTE_DOWN_COUNT , 0 );
298- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_PROTOCOL , item -> scheme );
299- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_DESTINATION_HOST , item -> host );
300- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_DESTINATION_PORT , item -> port );
301- vflow_set_uint64 (connector -> vflow_record , VFLOW_ATTRIBUTE_OCTETS , 0 );
302- vflow_set_uint64 (connector -> vflow_record , VFLOW_ATTRIBUTE_OCTETS_REVERSE , 0 );
303- }
304284 return connector ;
305285}
306286
@@ -360,8 +340,6 @@ void qd_connector_decref(qd_connector_t* connector)
360340 assert (connector -> qd_conn == 0 );
361341
362342 qd_connector_config_decref (connector -> ctor_config );
363- vflow_end_record (connector -> vflow_record );
364- connector -> vflow_record = 0 ;
365343 qd_timer_free (connector -> reconnect_timer );
366344 sys_mutex_free (& connector -> lock );
367345 sys_atomic_destroy (& connector -> ref_count );
@@ -473,25 +451,34 @@ void qd_connector_remote_opened(qd_connector_t *connector)
473451/**
474452 * Set the child connection of the connector
475453 */
476- void qd_connector_add_connection (qd_connector_t * connector , qd_connection_t * ctx )
454+ void qd_connector_add_connection (qd_connector_t * connector , qd_connection_t * qd_conn )
477455{
478- assert (ctx -> connector == 0 );
479-
456+ assert (qd_conn -> connector == 0 );
480457 sys_atomic_inc (& connector -> ref_count );
481- ctx -> connector = connector ;
482- connector -> qd_conn = ctx ;
458+ qd_conn -> connector = connector ;
459+ connector -> qd_conn = qd_conn ;
460+ if (!connector -> is_data_connector ) {
461+ qd_connector_config_t * ctor_config = connector -> ctor_config ;
462+ sys_atomic_inc (& ctor_config -> active_control_conn_count );
463+ }
483464}
484465
485466
486467void qd_connector_add_link (qd_connector_t * connector )
487468{
488469 if (!connector -> is_data_connector ) {
489- if (connector -> vflow_record && connector -> ctor_config -> tls_config ) {
490- // connector->ctor_config->tls_ordinal is set in the handle_connector_ssl_profile_mgmt_update() callback
491- vflow_set_uint64 (connector -> vflow_record , VFLOW_ATTRIBUTE_ACTIVE_TLS_ORDINAL , connector -> ctor_config -> tls_ordinal );
470+ qd_connector_config_t * ctor_config = connector -> ctor_config ;
471+ if (ctor_config && ctor_config -> vflow_record ) {
472+ if (ctor_config -> tls_config ) {
473+ // connector->ctor_config->tls_ordinal is set in the handle_connector_ssl_profile_mgmt_update() callback
474+ vflow_set_uint64 (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_ACTIVE_TLS_ORDINAL , connector -> ctor_config -> tls_ordinal );
475+ }
476+ if (sys_atomic_get (& ctor_config -> active_control_conn_count ) == 1 ) {
477+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_OPER_STATUS , "up" );
478+ vflow_set_timestamp_now (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_UP_TIMESTAMP );
479+ }
480+
492481 }
493- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_OPER_STATUS , "up" );
494- vflow_set_timestamp_now (connector -> vflow_record , VFLOW_ATTRIBUTE_UP_TIMESTAMP );
495482 connector -> oper_status_down = false;
496483 }
497484}
@@ -505,14 +492,25 @@ void qd_connector_remove_connection(qd_connector_t *connector, bool final, const
505492{
506493 sys_mutex_lock (& connector -> lock );
507494
495+ if (!connector -> is_data_connector ) {
496+ qd_connector_config_t * ctor_config = connector -> ctor_config ;
497+ sys_atomic_dec (& ctor_config -> active_control_conn_count );
498+ }
499+
500+
508501 qd_connection_t * ctx = connector -> qd_conn ;
509502 if (!connector -> is_data_connector && !connector -> oper_status_down && !final ) {
510503 connector -> oper_status_down = true;
511- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_OPER_STATUS , "down" );
512- vflow_inc_counter (connector -> vflow_record , VFLOW_ATTRIBUTE_DOWN_COUNT , 1 );
513- vflow_set_timestamp_now (connector -> vflow_record , VFLOW_ATTRIBUTE_DOWN_TIMESTAMP );
514- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_RESULT , condition_name ? condition_name : "unknown" );
515- vflow_set_string (connector -> vflow_record , VFLOW_ATTRIBUTE_REASON , condition_description ? condition_description : "" );
504+ qd_connector_config_t * ctor_config = connector -> ctor_config ;
505+ // If there are no active control connections, we can safely assume that
506+ // the operation status of the LINK record is "down"
507+ if (ctor_config && ctor_config -> vflow_record && sys_atomic_get (& ctor_config -> active_control_conn_count ) == 0 ) {
508+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_OPER_STATUS , "down" );
509+ vflow_inc_counter (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_DOWN_COUNT , 1 );
510+ vflow_set_timestamp_now (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_DOWN_TIMESTAMP );
511+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_RESULT , condition_name ? condition_name : "unknown" );
512+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_REASON , condition_description ? condition_description : "" );
513+ }
516514 }
517515 connector -> qd_conn = 0 ;
518516 ctx -> connector = 0 ;
@@ -644,6 +642,7 @@ qd_connector_config_t *qd_connector_config_create(qd_dispatch_t *qd, qd_entity_t
644642 ZERO (ctor_config );
645643 DEQ_ITEM_INIT (ctor_config );
646644 sys_atomic_init (& ctor_config -> ref_count , 1 ); // for caller
645+ sys_atomic_init (& ctor_config -> active_control_conn_count , 0 );
647646 ctor_config -> server = qd_dispatch_get_server (qd );
648647 DEQ_INIT (ctor_config -> connectors );
649648 ctor_config -> cleanup_timer = qd_timer (amqp_adaptor .dispatch , qd_connector_config_cleanup_conns , ctor_config );
@@ -663,6 +662,7 @@ qd_connector_config_t *qd_connector_config_create(qd_dispatch_t *qd, qd_entity_t
663662
664663 const bool is_inter_router = strcmp (ctor_config -> config .role , "inter-router" ) == 0 ;
665664 const bool is_edge = strcmp (ctor_config -> config .role , "edge" ) == 0 ;
665+ const bool is_inter_edge = strcmp (ctor_config -> config .role , "inter-edge" ) == 0 ;
666666
667667 //
668668 // If an sslProfile is configured allocate a TLS config to be used by all child connector's connections
@@ -684,9 +684,25 @@ qd_connector_config_t *qd_connector_config_create(qd_dispatch_t *qd, qd_entity_t
684684 handle_connector_ssl_profile_mgmt_update );
685685 }
686686 }
687-
687+ if (is_inter_router || is_edge || is_inter_edge ) {
688+ ctor_config -> vflow_record = vflow_start_record (VFLOW_RECORD_LINK , 0 );
689+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_NAME , ctor_config -> config .name );
690+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_ROLE , ctor_config -> config .role );
691+ vflow_set_uint64 (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_LINK_COST , ctor_config -> config .inter_router_cost );
692+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_OPER_STATUS , "down" );
693+ vflow_set_uint64 (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_DOWN_COUNT , 0 );
694+ if (ctor_config -> config .ssl_required ) {
695+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_PROTOCOL , "amqps" );
696+ } else {
697+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_PROTOCOL , "amqp" );
698+ }
699+ vflow_set_string (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_DESTINATION_PORT , ctor_config -> config .port );
700+ vflow_set_uint64 (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_OCTETS , 0 );
701+ vflow_set_uint64 (ctor_config -> vflow_record , VFLOW_ATTRIBUTE_OCTETS_REVERSE , 0 );
702+ }
703+ //
688704 // For inter-router connectors generate a group correlator and configure the data connection count
689-
705+ //
690706 if (is_inter_router ) {
691707 qd_generate_discriminator (ctor_config -> group_correlator );
692708 ctor_config -> data_connection_count = qd_dispatch_get_data_connection_count (qd );
@@ -742,13 +758,19 @@ void qd_connector_config_decref(qd_connector_config_t *ctor_config)
742758 assert (rc > 0 ); // else underflow
743759
744760 if (rc == 1 ) {
761+ if (ctor_config -> vflow_record ) {
762+ vflow_end_record (ctor_config -> vflow_record );
763+ ctor_config -> vflow_record = 0 ;
764+ }
765+
745766 // Expect: all connectors hold the ref_count so this must be empty
746767 assert (DEQ_IS_EMPTY (ctor_config -> connectors ));
747768
748769 // free the timer first otherwise the callback can run and attempt to access ctor_config while it is being torn
749770 // down:
750771 qd_timer_free (ctor_config -> cleanup_timer );
751772 sys_atomic_destroy (& ctor_config -> ref_count );
773+ sys_atomic_destroy (& ctor_config -> active_control_conn_count );
752774 free (ctor_config -> policy_vhost );
753775 qd_tls_config_decref (ctor_config -> tls_config );
754776 qd_server_config_free (& ctor_config -> config );
0 commit comments