diff options
6 files changed, 952 insertions, 20 deletions
diff --git a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.c b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.c index 4e4383e4..488e073a 100644 --- a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.c +++ b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.c @@ -64,9 +64,13 @@ char *functional_role = NULL; * * @param fqdn The API's FQDN or IP address. * @param port The API's port. + * @param bakup_fqdn The API's Backup FQDN or IP address. + * @param bakup_port The API's Backup port. * @param path The optional path (may be NULL). * @param topic The optional topic part of the URL (may be NULL). + * @param ring buf size Ring buffer size * @param secure Whether to use HTTPS (0=HTTP, 1=HTTPS) + * @param activmode Whether to use ActivStandby(0) collectors or ActiveStandby(1) * @param cert_file_path Path to client certificate file * @param key_file_path Path to client key file * @param ca_info Path to CA cert file @@ -75,7 +79,10 @@ char *functional_role = NULL; * @param verify_host SSL verification of host 0 or 1 * @param username Username for Basic Authentication of requests. * @param password Password for Basic Authentication of requests. - * @param source_ip The ip of node we represent (NULL for default ip). + * @param bakup_username Username for Basic Authentication of Bakup FQDN. + * @param bakup_password Password for Basic Authentication of Bakup FQDN. + * @param source_ip The ip of node we represent.(NULL for default ip) + * @param bakup_source_ip The ip bakup fqdn interface.(NULL for default ip) * @param source_type The kind of node we represent. * @param role The role this node undertakes. * @param verbosity 0 for normal operation, positive values for chattier @@ -87,10 +94,13 @@ char *functional_role = NULL; *****************************************************************************/ EVEL_ERR_CODES evel_initialize(const char * const fqdn, int port, + const char * const bakup_fqdn, + int bakup_port, const char * const path, const char * const topic, int ring_buf_size, int secure, + int activmode, const char * const cert_file_path, const char * const key_file_path, const char * const ca_info, @@ -99,7 +109,10 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, long verify_host, const char * const username, const char * const password, + const char * const bakup_username, + const char * const bakup_password, const char * const source_ip, + const char * const bakup_source_ip, EVEL_SOURCE_TYPES source_type, const char * const role, int verbosity @@ -108,11 +121,13 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, EVEL_ERR_CODES rc = EVEL_SUCCESS; char base_api_url[EVEL_MAX_URL_LEN + 1] = {0}; char event_api_url[EVEL_MAX_URL_LEN + 1] = {0}; + char bakup_api_url[EVEL_MAX_URL_LEN + 1] = {0}; char throt_api_url[EVEL_MAX_URL_LEN + 1] = {0}; char path_url[EVEL_MAX_URL_LEN + 1] = {0}; char topic_url[EVEL_MAX_URL_LEN + 1] = {0}; char version_string[10] = {0}; int offset; + char * bakup_coll = NULL; /***************************************************************************/ /* Check assumptions. */ @@ -122,10 +137,17 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, assert(source_type < EVEL_MAX_SOURCE_TYPES); assert(role != NULL); + if( bakup_fqdn != NULL ) { + assert(bakup_port > 0 && bakup_port <= 65535); + } + /***************************************************************************/ /* Start logging so we can report on progress. */ /***************************************************************************/ - log_initialize(verbosity == 0 ? EVEL_LOG_INFO : EVEL_LOG_DEBUG, "EVEL"); + if( verbosity >= EVEL_LOG_MIN && verbosity <= EVEL_LOG_MAX) + log_initialize(verbosity, "EVEL"); + else + log_initialize(EVEL_LOG_MIN, "EVEL"); EVEL_INFO("EVEL started"); EVEL_INFO("API server is: %s", fqdn); EVEL_INFO("API port is: %d", port); @@ -238,6 +260,36 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, EVEL_INFO("Vendor Event Listener API is located at: %s", event_api_url); /***************************************************************************/ + /* Build a common base of the Backup API URLs. */ + /***************************************************************************/ + if( bakup_fqdn != NULL ) + { + strcpy(path_url, "/"); + snprintf(base_api_url, + EVEL_MAX_URL_LEN, + "%s://%s:%d%s/eventListener/v%s", + secure ? "https" : "http", + bakup_fqdn, + bakup_port, + (((path != NULL) && (strlen(path) > 0)) ? + strncat(path_url, path, EVEL_MAX_URL_LEN) : ""), + version_string); + + /***************************************************************************/ + /* Build the URL to the event API. */ + /***************************************************************************/ + strcpy(topic_url, "/"); + snprintf(bakup_api_url, + EVEL_MAX_URL_LEN, + "%s%s", + base_api_url, + (((topic != NULL) && (strlen(topic) > 0)) ? + strncat(topic_url, topic, EVEL_MAX_URL_LEN) : "")); + EVEL_INFO("Vendor Backup Event Listener API is located at: %s", bakup_api_url); + bakup_coll = bakup_api_url; + } + + /***************************************************************************/ /* Build the URL to the throttling API. */ /***************************************************************************/ snprintf(throt_api_url, @@ -250,10 +302,13 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, /* Spin-up the event-handler, which gets cURL readied for use. */ /***************************************************************************/ rc = event_handler_initialize(event_api_url, + bakup_coll, throt_api_url, source_ip, + bakup_source_ip, ring_buf_size, secure, + activmode, cert_file_path, key_file_path, ca_info, @@ -262,6 +317,8 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, verify_host, username, password, + bakup_username, + bakup_password, verbosity); if (rc != EVEL_SUCCESS) { diff --git a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.h b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.h index 8f497987..c8587269 100644 --- a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.h +++ b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel.h @@ -1429,10 +1429,13 @@ typedef struct copyright { * * @param fqdn The API's FQDN or IP address. * @param port The API's port. + * @param bakup_fqdn The API's FQDN or IP address. + * @param bakup_port The API's port. * @param path The optional path (may be NULL). * @param topic The optional topic part of the URL (may be NULL). * @param ring_buf_size Ring buffer size (>=100) ~ Avg Messages in 1hr * @param secure Whether to use HTTPS (0=HTTP, 1=HTTPS). + * @param activmode Whether to use ActiveActive or ActiveStandby collector mode * @param cert_file_path Path to client certificate file * @param key_file_path Path to client key file * @param ca_info Path to CA info @@ -1441,7 +1444,10 @@ typedef struct copyright { * @param verify_host SSL verification of host 0 or 1 * @param username Username for Basic Authentication of requests. * @param password Password for Basic Authentication of requests. - * @param source_ip The ip of node we represent.(NULL for default ip) + * @param bakup_username Username for Basic Authentication of Bakup FQDN. + * @param bakup_password Password for Basic Authentication of Bakup FQDN. + * @param source_ip The ip of node we represent.(NULL for default ip) + * @param bakup_source_ip The ip bakup fqdn interface.(NULL for default ip) * @param source_type The kind of node we represent. * @param role The role this node undertakes. * @param verbosity 0 for normal operation, positive values for chattier @@ -1453,10 +1459,13 @@ typedef struct copyright { *****************************************************************************/ EVEL_ERR_CODES evel_initialize(const char * const fqdn, int port, + const char * const bakup_fqdn, + int bakup_port, const char * const path, const char * const topic, int ring_buf_size, int secure, + int activmode, const char * const cert_file_path, const char * const key_file_path, const char * const ca_info, @@ -1465,7 +1474,10 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, long verify_host, const char * const username, const char * const password, + const char * const bakup_username, + const char * const bakup_password, const char * const source_ip, + const char * const bakup_source_ip, EVEL_SOURCE_TYPES source_type, const char * const role, int verbosity diff --git a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_event_mgr.c b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_event_mgr.c index fb94dafb..4fb195c1 100644 --- a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_event_mgr.c +++ b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_event_mgr.c @@ -1,6 +1,6 @@ /*************************************************************************//** * - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. * * Unless otherwise specified, all software contained herein is * Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,7 +41,7 @@ * How long we're prepared to wait for the API service to respond in * seconds. *****************************************************************************/ -static const int EVEL_API_TIMEOUT = 5; +static const int EVEL_API_TIMEOUT = 10; /*****************************************************************************/ /* Prototypes of locally scoped functions. */ @@ -58,21 +58,28 @@ static bool evel_tokens_match_command_list(const MEMORY_CHUNK * const chunk, static bool evel_token_equals_string(const MEMORY_CHUNK * const chunk, const jsmntok_t * const json_token, const char * check_string); +static void * event_multi_handler(void * arg __attribute__ ((unused))); /**************************************************************************//** * Buffers for error strings from libcurl. *****************************************************************************/ static char curl_err_string[CURL_ERROR_SIZE] = "<NULL>"; +static char curl_err_string2[CURL_ERROR_SIZE] = "<NULL>"; /**************************************************************************//** * Handle for the API into libcurl. *****************************************************************************/ static CURL * curl_handle = NULL; +static CURL * curl_handle2 = NULL; +static CURLM * multi_handle = NULL; +int curr_global_handles = 0; +int activmode = -1; /**************************************************************************//** * Special headers that we send. *****************************************************************************/ static struct curl_slist * hdr_chunk = NULL; +static struct curl_slist * hdr_chunk2 = NULL; /**************************************************************************//** * Message queue for sending events to the API. @@ -104,6 +111,11 @@ static char * evel_event_api_url; static char * evel_throt_api_url; static char * evel_batch_api_url; +static char * evel_bevent_api_url; +static char * evel_bthrot_api_url; +static char * evel_bbatch_api_url; + + /**************************************************************************//** * Initialize the event handler. * @@ -129,10 +141,13 @@ static char * evel_batch_api_url; * logs. *****************************************************************************/ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, + const char * const bakup_api_url, const char * const throt_api_url, const char * const source_ip, + const char * const source_ip_bakup, int ring_buf_size, int secure, + int activitymode, const char * const cert_file_path, const char * const key_file_path, const char * const ca_info, @@ -141,6 +156,8 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, long verify_host, const char * const username, const char * const password, + const char * const username2, + const char * const password2, int verbosity) { int rc = EVEL_SUCCESS; @@ -157,6 +174,12 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, assert(throt_api_url != NULL); assert(username != NULL); assert(password != NULL); + if( bakup_api_url != NULL ) + { + assert(username2 != NULL); + assert(password2 != NULL); + } + /***************************************************************************/ /* Store the API URLs. */ @@ -168,6 +191,19 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, assert(evel_batch_api_url != NULL); evel_throt_api_url = strdup(throt_api_url); assert(evel_throt_api_url != NULL); + curr_global_handles = 1; + + if( bakup_api_url != NULL ) + { + evel_bevent_api_url = strdup(bakup_api_url); + assert(evel_bevent_api_url != NULL); + sprintf(batch_api_url,"%s/eventBatch",event_api_url); + evel_bbatch_api_url = strdup(batch_api_url); + assert(evel_bbatch_api_url != NULL); + evel_bthrot_api_url = strdup(throt_api_url); + assert(evel_bthrot_api_url != NULL); + curr_global_handles = 2; + } curl_version_info_data *d = curl_version_info(CURLVERSION_NOW); @@ -203,6 +239,16 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_handle2 = curl_easy_init(); + if (curl_handle2 == NULL) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to get backup libCURL handle"); + goto exit_label; + } + } /***************************************************************************/ /* Prime the library to give friendly error codes. */ /***************************************************************************/ @@ -217,6 +263,21 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_ERRORBUFFER, + curl_err_string2); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL2 to provide friendly errors. " + "Error code=%d", curl_rc); + goto exit_label; + } + } + + /***************************************************************************/ /* If running in verbose mode generate more output. */ /***************************************************************************/ @@ -230,8 +291,22 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d", curl_rc); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, CURLOPT_VERBOSE, 1L); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL to be verbose. " + "Error code=%d", curl_rc); + goto exit_label; + } + } + } + + /***************************************************************************/ /* Set the URL for the API. */ /***************************************************************************/ @@ -245,6 +320,21 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, } EVEL_INFO("Initializing CURL to send events to: %s", event_api_url); + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_URL, + bakup_api_url); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + + /***************************************************************************/ /* send all data to this function. */ /***************************************************************************/ @@ -258,6 +348,21 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_WRITEFUNCTION, + evel_write_callback); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + + /***************************************************************************/ /* configure local ip address if provided */ @@ -280,6 +385,23 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, } } } + if( source_ip_bakup != NULL ) + { + snprintf(local_address,sizeof(local_address),source_ip_bakup); + if( local_address[0] != '\0' ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_INTERFACE, + local_address); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize bakup libCURL with the local address. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + } /***************************************************************************/ /* configure SSL options for HTTPS transfers */ @@ -298,6 +420,19 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_SSLCERT, + cert_file_path); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the client cert. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } } if( key_file_path != NULL ) @@ -312,6 +447,19 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_SSLKEY, + key_file_path); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the client key. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } } if( ca_info != NULL ) @@ -326,6 +474,19 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_CAINFO, + ca_info); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the CA cert file. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } } if( ca_file_path != NULL ) @@ -340,6 +501,19 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_CAPATH, + ca_file_path); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the CA cert path. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } } curl_rc = curl_easy_setopt(curl_handle, @@ -363,6 +537,29 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_SSL_VERIFYPEER, + verify_peer); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with SSL Server verification. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_SSL_VERIFYHOST, + verify_host); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with Client host verification. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } } @@ -381,6 +578,20 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, + CURLOPT_USERAGENT, + "libcurl-agent/1.0"); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + /***************************************************************************/ /* Specify that we are going to POST data. */ @@ -393,6 +604,18 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2,CURLOPT_POST, 1L); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + /***************************************************************************/ /* we want to use our own read function. */ @@ -405,6 +628,18 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "function. Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2,CURLOPT_READFUNCTION, read_callback); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + /***************************************************************************/ /* All of our events are JSON encoded. We also suppress the */ @@ -427,6 +662,21 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + hdr_chunk2 = curl_slist_append(hdr_chunk2, "Content-type: application/json"); + hdr_chunk2 = curl_slist_append(hdr_chunk2, "Expect:"); + curl_rc = curl_easy_setopt(curl_handle2,CURLOPT_HTTPHEADER, hdr_chunk2); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + + /***************************************************************************/ /* Set the timeout for the operation. */ @@ -441,6 +691,18 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2,CURLOPT_TIMEOUT, EVEL_API_TIMEOUT); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + } + /***************************************************************************/ /* Set that we want Basic authentication with username:password Base-64 */ @@ -471,6 +733,45 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, goto exit_label; } + if( bakup_api_url != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle2, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL for Basic Authentication. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + curl_rc = curl_easy_setopt(curl_handle2, CURLOPT_USERNAME, username2); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with username. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + curl_rc = curl_easy_setopt(curl_handle2, CURLOPT_PASSWORD, password2); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with password. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + + multi_handle = curl_multi_init();; + if (multi_handle == NULL) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to get libCURL Multi handle"); + goto exit_label; + } + activmode = activitymode; + + } + + /***************************************************************************/ /* Initialize a message ring-buffer to be used between the foreground and */ /* the thread which sends the messages. This can't fail. */ @@ -515,7 +816,11 @@ EVEL_ERR_CODES event_handler_run() /* Start the event handler thread. */ /***************************************************************************/ evt_handler_state = EVT_HANDLER_INACTIVE; - pthread_rc = pthread_create(&evt_handler_thread, NULL, event_handler, NULL); + if( curr_global_handles <= 1 ) + pthread_rc = pthread_create(&evt_handler_thread, NULL, event_handler, NULL); + else + pthread_rc = pthread_create(&evt_handler_thread, NULL, event_multi_handler, NULL); + if (pthread_rc != 0) { rc = EVEL_PTHREAD_LIBRARY_FAIL; @@ -588,16 +893,31 @@ EVEL_ERR_CODES event_handler_terminate() /***************************************************************************/ /* Clean-up the cURL library. */ /***************************************************************************/ + if (multi_handle != NULL) + { + curl_multi_cleanup(multi_handle); + } if (curl_handle != NULL) { curl_easy_cleanup(curl_handle); curl_handle = NULL; } + if (curl_handle2 != NULL) + { + curl_easy_cleanup(curl_handle2); + curl_handle2 = NULL; + } if (hdr_chunk != NULL) { curl_slist_free_all(hdr_chunk); hdr_chunk = NULL; } + if (hdr_chunk2 != NULL) + { + curl_slist_free_all(hdr_chunk2); + hdr_chunk2 = NULL; + } + /***************************************************************************/ /* Free off the stored API URL strings. */ @@ -881,6 +1201,538 @@ size_t evel_write_callback(void *contents, return realsize; } + +/**************************************************************************//** + * Post an event to the Vendor Event Listener API. + * + * @returns Status code + * @retval EVEL_SUCCESS On success + * @retval "One of ::EVEL_ERR_CODES" On failure. + *****************************************************************************/ +static EVEL_ERR_CODES evel_postmulti_message(char *msg, size_t size, int *still, + CURL *handle, CURL *bhandle, int numhandles ) +{ + int rc = EVEL_SUCCESS; + CURLcode curl_rc = CURLE_OK; + MEMORY_CHUNK rx_chunk[2]; + MEMORY_CHUNK tx_chunk[2]; + int http_response_code = 0, i; + + EVEL_ENTER(); + + EVEL_INFO("Sending :%s: %d\n",msg, numhandles); + + /***************************************************************************/ + /* Create the memory chunk to be used for the response to the post. The */ + /* will be realloced. */ + /***************************************************************************/ +for (i=0;i<numhandles;i++) +{ + rx_chunk[i].memory = malloc(1); + assert(rx_chunk[i].memory != NULL); + rx_chunk[i].size = 0; + + /***************************************************************************/ + /* Create the memory chunk to be sent as the body of the post. */ + /***************************************************************************/ + tx_chunk[i].memory = msg; + tx_chunk[i].size = size; + EVEL_DEBUG("Sending chunk of size %d", tx_chunk[i].size); +} + + /***************************************************************************/ + /* Point to the data to be received. */ + /***************************************************************************/ + curl_rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, &rx_chunk[0]); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL rx to upload. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + + /***************************************************************************/ + /* Pointer to pass to our read function */ + /***************************************************************************/ + curl_rc = curl_easy_setopt(handle, CURLOPT_READDATA, &tx_chunk[0]); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to set upload data for libCURL tx to upload. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + /***************************************************************************/ + /* Size of the data to transmit. */ + /***************************************************************************/ + curl_rc = curl_easy_setopt(handle, + CURLOPT_POSTFIELDSIZE, + tx_chunk[0].size); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to set length of upload data for libCURL to " + "upload. Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + +if(numhandles == 2) +{ + + /***************************************************************************/ + /* Point to the data to be received. */ + /***************************************************************************/ + curl_rc = curl_easy_setopt(bhandle, CURLOPT_WRITEDATA, &rx_chunk[1]); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL2 rx to upload. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + + /***************************************************************************/ + /* Pointer to pass to our read function */ + /***************************************************************************/ + curl_rc = curl_easy_setopt(bhandle, CURLOPT_READDATA, &tx_chunk[1]); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to set upload data for libCURL2 tx to upload. " + "Error code=%d (%s)", curl_rc, curl_err_string2); + goto exit_label; + } + /***************************************************************************/ + /* Size of the data to transmit. */ + /***************************************************************************/ + curl_rc = curl_easy_setopt(bhandle, + CURLOPT_POSTFIELDSIZE, + tx_chunk[1].size); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to set length of upload data for libCURL2 to " + "upload. Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + +} + + /***************************************************************************/ + /* Now run off and do what you've been told! */ + /***************************************************************************/ + curl_rc = curl_multi_perform(multi_handle, still); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to transfer an multi event to Vendor Event Listener! " + "Error code=%d (%s)", curl_rc, curl_multi_strerror(curl_rc +)); + EVEL_ERROR("Dropped event: %s", msg); + goto exit_label; + } + + /***************************************************************************/ + /* See what response we got - any 2XX response is good. */ + /***************************************************************************/ + +exit_label: + for (i=0;i<numhandles;i++) + free(rx_chunk[i].memory); + EVEL_EXIT(); + + return(rc); +} + + +/**************************************************************************//** + * Event Multi Post Handler. + * + * Watch for messages coming on the internal queue and send them to the + * listener. + * + * param[in] jsonmsg json message to be sent. + * param[in] size size of json message + * param[in] currhandle Primary handle + * param[in] url1 pimary url + * param[in] bakkhandle Backup handle + * param[in] url2 secondary url + *****************************************************************************/ +static int evel_post_multiapi(char *jsonmsg, size_t size,CURL *currhandle, char *url1, + CURL *bakkhandle, char *url2) +{ + int rc = EVEL_SUCCESS; + CURLcode curl_rc = 0; + int nhandles = 1; + int still_running,i; + CURLMsg *msg; /* for picking up messages with the transfer status */ + int msgs_left; /* how many messages are left */ + + /***************************************************************************/ + /* Set the URL for the API. */ + /***************************************************************************/ + curl_rc = curl_easy_setopt(currhandle, CURLOPT_URL, url1); + if (curl_rc != CURLE_OK ) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the multi API URL. " + "%s Error code=%d (%s)", url1, curl_rc, curl_err_string); + } + + if( url2 != NULL && activmode == 1 ) + { + curl_rc = curl_easy_setopt(bakkhandle, CURLOPT_URL, url2); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "%s Error code=%d (%s)", url2, curl_rc, curl_err_string2); + } + nhandles = 2; + } + + /* we start some action by calling perform right away */ + curl_multi_add_handle(multi_handle, currhandle); + if(nhandles==2){ + curl_multi_add_handle(multi_handle, bakkhandle); + } + + /* we start some action by calling perform right away */ + curl_multi_perform(multi_handle, &still_running); + + do { + struct timeval timeout; + int rc; /* select() return code */ + CURLMcode mc; /* curl_multi_fdset() return code */ + + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd = -1; + + long curl_timeo = -1; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + /* set a suitable timeout to play around with */ + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + curl_multi_timeout(multi_handle, &curl_timeo); + if(curl_timeo >= 0) { + timeout.tv_sec = curl_timeo / 1000; + if(timeout.tv_sec > 1) + timeout.tv_sec = 1; + else + timeout.tv_usec = (curl_timeo % 1000) * 1000; + } + + /* get file descriptors from the transfers */ + mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); + + if(mc != CURLM_OK) { + EVEL_ERROR("curl_multi_fdset() failed, code %d.\n", mc); + break; + } + + /* On success the value of maxfd is guaranteed to be >= -1. We call + select(maxfd + 1, ...); specially in case of (maxfd == -1) there are + no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- + to sleep 100ms, which is the minimum suggested value in the + curl_multi_fdset() doc. */ + + if(maxfd == -1) { +#ifdef _WIN32 + Sleep(100); + rc = 0; +#else + /* Portable sleep for platforms other than Windows. */ + struct timeval wait = { 0, 300000 }; /* 250ms */ + rc = select(0, NULL, NULL, NULL, &wait); +#endif + } + else { + /* Note that on some platforms 'timeout' may be modified by select(). + If you need access to the original value save a copy beforehand. */ + rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); + } + + switch(rc) { + case -1: + /* select error */ + break; + case 0: /* timeout */ + default: /* action */ + //curl_multi_perform(multi_handle, &still_running); + evel_postmulti_message(jsonmsg, size, &still_running, currhandle, bakkhandle, nhandles); + } + } while(still_running); + + /* See how the transfers went */ + while((msg = curl_multi_info_read(multi_handle, &msgs_left))) { + if(msg->msg == CURLMSG_DONE) { + int idx, found = 0; + EVEL_DEBUG("Transfer status - %s\n", curl_multi_strerror(msg->data.result)); + + /* Find out which handle this message is about */ + for(idx = 0; idx<nhandles; idx++) { + if (msg->easy_handle == currhandle) break; + else if(msg->easy_handle == bakkhandle) break; + } + + switch(idx) { + case 0: + curl_rc = msg->data.result; + break; + case 1: + curl_rc = msg->data.result; + break; + } + } + } + + /* we start some action by calling perform right away */ + curl_multi_remove_handle(multi_handle, currhandle); + if(nhandles==2){ + curl_multi_remove_handle(multi_handle, bakkhandle); + } + + EVEL_DEBUG("Transfer completed with status %s\n", curl_multi_strerror(curl_rc)); + if( curl_rc == 0 || curl_rc == 55 ) + return EVEL_SUCCESS; + else + return EVEL_CURL_LIBRARY_FAIL; + +} +/**************************************************************************//** + * Event Handler. + * + * Watch for messages coming on the internal queue and send them to the + * listener. + * + * param[in] arg Argument - unused. + *****************************************************************************/ +static void * event_multi_handler(void * arg __attribute__ ((unused))) +{ + int old_type = 0; + EVENT_HEADER * msg = NULL; + EVENT_INTERNAL * internal_msg = NULL; + int json_size = 0; + char json_body[EVEL_MAX_JSON_BODY]; + int rc = EVEL_SUCCESS; + CURLcode curl_rc; + CURL *currhandler = NULL; + CURL *bakhandler = NULL; + char *send_url = NULL; + char *send_url2 = NULL; + + EVEL_INFO("Event multi handler thread started"); + + /***************************************************************************/ + /* Set this thread to be cancellable immediately. */ + /***************************************************************************/ + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type); + + /***************************************************************************/ + /* Set the handler as active, defending against weird situations like */ + /* immediately shutting down after initializing the library so the */ + /* handler never gets started up properly. */ + /***************************************************************************/ + if (evt_handler_state == EVT_HANDLER_INACTIVE) + { + evt_handler_state = EVT_HANDLER_ACTIVE; + } + else + { + EVEL_ERROR("Event Handler State was not INACTIVE at start-up - " + "Handler will exit immediately!"); + } + + currhandler = curl_handle; + while (evt_handler_state == EVT_HANDLER_ACTIVE) + { + /*************************************************************************/ + /* Wait for a message to be received. */ + /*************************************************************************/ + msg = ring_buffer_read(&event_buffer); + + /*************************************************************************/ + /* Internal events get special treatment while regular events get posted */ + /* to the far side. */ + /*************************************************************************/ + if (msg->event_domain == EVEL_DOMAIN_BATCH ) + { + EVEL_DEBUG("Batch event received"); + + /***********************************************************************/ + /* Encode the event in JSON. */ + /***********************************************************************/ + json_size = evel_json_encode_batch_event(json_body, EVEL_MAX_JSON_BODY, msg); + + /***************************************************************************/ + /* Set the URL for the API. */ + /***************************************************************************/ + if( currhandler == curl_handle){ + send_url = evel_batch_api_url; + send_url2 = evel_bbatch_api_url; + bakhandler = curl_handle2; + } else if(currhandler == curl_handle2) { + send_url = evel_bbatch_api_url; + send_url2 = evel_batch_api_url; + bakhandler = curl_handle; + } + + /***********************************************************************/ + /* Send the JSON across the API. */ + /***********************************************************************/ + EVEL_DEBUG("Sending Batch JSON of size %d is: %s", json_size, json_body); + rc = evel_post_multiapi(json_body, json_size, currhandler, send_url, bakhandler, send_url2); + if (rc != EVEL_SUCCESS) + { + EVEL_ERROR("Failed to transfer the data to %s. Error code=%d", send_url, rc); + EVEL_INFO("Switched Collector ..."); + if( currhandler == curl_handle){ + currhandler = curl_handle2; + bakhandler = curl_handle; + } else if(currhandler == curl_handle2) { + currhandler = curl_handle; + bakhandler = curl_handle2; + } + rc = evel_post_multiapi(json_body, json_size, currhandler, send_url2, bakhandler,send_url); + if (rc != EVEL_SUCCESS) + EVEL_ERROR("Failed to transfer the data to failover %s. Error code=%d", send_url2, rc); + } + } + else if (msg->event_domain != EVEL_DOMAIN_INTERNAL ) + { + EVEL_DEBUG("External event received"); + + /***********************************************************************/ + /* Encode the event in JSON. */ + /***********************************************************************/ + json_size = evel_json_encode_event(json_body, EVEL_MAX_JSON_BODY, msg); + + /***************************************************************************/ + /* Set the URL for the API. */ + /***************************************************************************/ + if( currhandler == curl_handle){ + send_url = evel_event_api_url; + send_url2 = evel_bevent_api_url; + bakhandler = curl_handle2; + } else if(currhandler == curl_handle2) { + send_url = evel_bevent_api_url; + send_url2 = evel_event_api_url; + bakhandler = curl_handle; + } + + /***********************************************************************/ + /* Send the JSON across the API. */ + /***********************************************************************/ + EVEL_DEBUG("Sending Batch JSON of size %d is: %s", json_size, json_body); + rc = evel_post_multiapi(json_body, json_size, currhandler, send_url, bakhandler, send_url2); + if (rc != EVEL_SUCCESS) + { + EVEL_ERROR("Failed to transfer the data to %s. Error code=%d", send_url, rc); + EVEL_INFO("Switched Collector ..."); + if( currhandler == curl_handle){ + currhandler = curl_handle2; + bakhandler = curl_handle; + } else if(currhandler == curl_handle2) { + currhandler = curl_handle; + bakhandler = curl_handle2; + } + rc = evel_post_multiapi(json_body, json_size, currhandler, send_url2, bakhandler,send_url); + if (rc != EVEL_SUCCESS) + EVEL_ERROR("Failed to transfer the data to failover %s. Error code=%d", send_url2, rc); + } + + } + else + { + EVEL_DEBUG("Internal event received"); + internal_msg = (EVENT_INTERNAL *) msg; + assert(internal_msg->command == EVT_CMD_TERMINATE); + evt_handler_state = EVT_HANDLER_TERMINATING; + } + + /*************************************************************************/ + /* We are responsible for freeing the memory. */ + /*************************************************************************/ + evel_free_event(msg); + msg = NULL; + + /*************************************************************************/ + /* There may be a single priority post to be sent. */ + /*************************************************************************/ + if (priority_post.memory != NULL) + { + EVEL_DEBUG("Priority Post"); + + /***********************************************************************/ + /* Set the URL for the throttling API. */ + /***********************************************************************/ + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_throt_api_url); + if (curl_rc != CURLE_OK) + { + /*********************************************************************/ + /* This is only likely to happen with CURLE_OUT_OF_MEMORY, in which */ + /* case we carry on regardless. */ + /*********************************************************************/ + EVEL_ERROR("Failed to set throttling URL. Error code=%d", rc); + } + else + { + rc = evel_post_api(priority_post.memory, priority_post.size); + if (rc != EVEL_SUCCESS) + { + EVEL_ERROR("Failed to transfer priority post. Error code=%d", rc); + } + } + + /***********************************************************************/ + /* Reinstate the URL for the event API. */ + /***********************************************************************/ + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_event_api_url); + if (curl_rc != CURLE_OK) + { + /*********************************************************************/ + /* This is only likely to happen with CURLE_OUT_OF_MEMORY, in which */ + /* case we carry on regardless. */ + /*********************************************************************/ + EVEL_ERROR("Failed to reinstate events URL. Error code=%d", rc); + } + + /***********************************************************************/ + /* We are responsible for freeing the memory. */ + /***********************************************************************/ + free(priority_post.memory); + priority_post.memory = NULL; + } + } + + /***************************************************************************/ + /* The event handler is now exiting. The ring-buffer could contain events */ + /* which have not been processed, so deplete those. Because we've been */ + /* asked to exit we can be confident that the foreground will have stopped */ + /* sending events in so we know that this process will conclude! */ + /***************************************************************************/ + evt_handler_state = EVT_HANDLER_TERMINATING; + while (!ring_buffer_is_empty(&event_buffer)) + { + EVEL_DEBUG("Reading event from buffer"); + msg = ring_buffer_read(&event_buffer); + evel_free_event(msg); + } + evt_handler_state = EVT_HANDLER_TERMINATED; + EVEL_INFO("Event handler thread stopped"); + + return (NULL); +} + + /**************************************************************************//** * Event Handler. * @@ -960,7 +1812,7 @@ static void * event_handler(void * arg __attribute__ ((unused))) rc = evel_post_api(json_body, json_size); if (rc != EVEL_SUCCESS) { - EVEL_ERROR("Failed to transfer the data. Error code=%d", rc); + EVEL_ERROR("Failed to transfer the data %s. Error code=%d", evel_batch_api_url, rc); } } else if (msg->event_domain != EVEL_DOMAIN_INTERNAL ) @@ -990,7 +1842,7 @@ static void * event_handler(void * arg __attribute__ ((unused))) rc = evel_post_api(json_body, json_size); if (rc != EVEL_SUCCESS) { - EVEL_ERROR("Failed to transfer the data. Error code=%d", rc); + EVEL_ERROR("Failed to transfer the data %s. Error code=%d",evel_event_api_url, rc); } } else @@ -1122,11 +1974,11 @@ void evel_handle_event_response(const MEMORY_CHUNK * const chunk, } else { - EVEL_DEBUG("Decode JSON response tokens"); - if (!evel_handle_response_tokens(chunk, json_tokens, num_tokens, post)) - { - EVEL_ERROR("Failed to handle JSON response."); - } + //EVEL_DEBUG("Decode JSON response tokens"); + //if (!evel_handle_response_tokens(chunk, json_tokens, num_tokens, post)) + //{ + // EVEL_ERROR("Failed to handle JSON response."); + //} } EVEL_EXIT(); diff --git a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_internal.h b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_internal.h index d1a952b6..621f8a53 100644 --- a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_internal.h +++ b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_internal.h @@ -172,27 +172,36 @@ typedef struct evel_throttle_spec { * @param[in] event_api_url * The URL where the Vendor Event Listener API is expected * to be. + * @param[in] bakup_api_url + * The BakupURL where the Vendor Backup Listener is expected + * to be. * @param[in] throt_api_url * The URL where the Throttling API is expected to be. - * @param[in] source_ip Source IP of VES Agent - * @param[in] ring_buf_size Initialization size of Ring Buffer + * @param[in] source_ip Source IP of VES Agent + * @param[in] bakup_source_ip Backup Source IP of VES Agent + * @param[in] ring_buf_size Initialization size of Ring Buffer * @param[in] secure Whether Using http or https * @param[in] cert_file_path Path to Client Certificate file * @param[in] key_file_path Path to Client key file * @param[in] ca_info Path to CA info file - * @param[in] ca_file_path Path to CA file + * @param[in] ca_file_path Path to CA file * @param[in] verify_peer Using peer verification or not * @param[in] verify_host Using host verification or not * @param[in] username The username for the Basic Authentication of requests. * @param[in] password The password for the Basic Authentication of requests. + * @param[in] username2 The username for the Bakup requests. + * @param[in] password2 The password for the Bakup requests. * @param verbosity 0 for normal operation, positive values for chattier * logs. *****************************************************************************/ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, + const char * const bakup_api_url, const char * const throt_api_url, const char * const source_ip, + const char * const bakup_source_ip, int ring_buf_size, int secure, + int activitymode, const char * const cert_file_path, const char * const key_file_path, const char * const ca_info, @@ -201,6 +210,8 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, long verify_host, const char * const username, const char * const password, + const char * const username2, + const char * const password2, int verbosity); /**************************************************************************//** diff --git a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_scaling_measurement.c b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_scaling_measurement.c index 677cb8ea..04bed579 100644 --- a/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_scaling_measurement.c +++ b/vnfs/VES5.0/evel/evel-library/code/evel_library/evel_scaling_measurement.c @@ -3402,7 +3402,7 @@ void evel_json_encode_measurement(EVEL_JSON_BUFFER * jbuf, /* vNIC Usage TBD Performance array */ /***************************************************************************/ evel_json_checkpoint(jbuf); - if (evel_json_open_opt_named_list(jbuf, "vNicUsageArray")) + if (evel_json_open_opt_named_list(jbuf, "vNicPerformanceArray")) { bool item_added = false; diff --git a/vnfs/VES5.0/evel/evel-library/code/evel_library/ring_buffer.c b/vnfs/VES5.0/evel/evel-library/code/evel_library/ring_buffer.c index ad508743..248baf2f 100644 --- a/vnfs/VES5.0/evel/evel-library/code/evel_library/ring_buffer.c +++ b/vnfs/VES5.0/evel/evel-library/code/evel_library/ring_buffer.c @@ -101,9 +101,9 @@ void * ring_buffer_read(ring_buffer * buffer) msg = (buffer->ring)[buffer->next_read]; buffer->ring[buffer->next_read] = NULL; buffer->next_read = (buffer->next_read + 1) % buffer->size; - EVEL_DEBUG("RBR: next read location is %d", buffer->next_read); pthread_mutex_unlock(&buffer->ring_mutex); - break; + EVEL_DEBUG("RBR: next read location is %d data %lp", buffer->next_read,msg); + return msg; } else { @@ -112,7 +112,7 @@ void * ring_buffer_read(ring_buffer * buffer) EVEL_DEBUG("RBR: Condition variable wait completed"); } } - EVEL_DEBUG("RBR: Ring buffer read returning data at %lp", msg); + pthread_mutex_unlock(&buffer->ring_mutex); return msg; } |