[Asterisk-code-review] res hep: Provide an option to pick the UUID type (asterisk[13])

Anonymous Coward asteriskteam at digium.com
Sat May 14 09:47:34 CDT 2016


Anonymous Coward #1000019 has submitted this change and it was merged.

Change subject: res_hep: Provide an option to pick the UUID type
......................................................................


res_hep: Provide an option to pick the UUID type

At one point in time, it seemed like a good idea to use the Asterisk
channel name as the HEP correlation UUID. In particular, it felt like
this would be a useful identifier to tie PJSIP messages and RTCP
messages together, along with whatever other data we may eventually send
to Homer. This also had the benefit of keeping the correlation UUID
channel technology agnostic.

In practice, it isn't as useful as hoped, for two reasons:
1) The first INVITE request received doesn't have a channel. As a
   result, there is always an 'odd message out', leading it to be
   potentially uncorrelated in Homer.
2) Other systems sending capture packets (Kamailio) use the SIP Call-ID.
   This causes RTCP information to be uncorrelated to the SIP message
   traffic seen by those capture nodes.

In order to support both (in case someone is trying to use res_hep_rtcp
with a non-PJSIP channel), this patch adds a new option, uuid_type, with
two valid values - 'call-id' and 'channel'. The uuid_type option is used
by a module to determine the preferred UUID type. When available, that
source of a correlation UUID is used; when not, the more readily available
source is used.

For res_hep_pjsip:
 - uuid_type = call-id: the module uses the SIP Call-ID header value
 - uuid_type = channel: the module uses the channel name if available,
                        falling back to SIP Call-ID if not
For res_hep_rtcp:
 - uuid_type = call-id: the module uses the SIP Call-ID header if the
                        channel type is PJSIP and we have a channel,
                        falling back to the Stasis event provided
                        channel name if not
 - uuid_type = channel: the module uses the channel name

ASTERISK-25352 #close

Change-Id: Ide67e59a52d9c806e3cc0a797ea1a4b88a00122c
---
M CHANGES
M configs/samples/hep.conf.sample
M include/asterisk/res_hep.h
M res/res_hep.c
M res/res_hep.exports.in
M res/res_hep_pjsip.c
M res/res_hep_rtcp.c
7 files changed, 105 insertions(+), 3 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  Anonymous Coward #1000019: Verified
  Matt Jordan: Looks good to me, approved



diff --git a/CHANGES b/CHANGES
index 965b1b4..5b38649 100644
--- a/CHANGES
+++ b/CHANGES
@@ -26,6 +26,16 @@
    into the "reg_server" field in the ps_contacts table to facilitate
    multi-server setups.
 
+res_hep
+------------------
+ * Added a new option, 'uuid_type', that sets the preferred source of the Homer
+   correlation UUID. The valid options are:
+   - call-id: Use the PJSIP SIP Call-ID header value
+   - channel: Use the Asterisk channel name
+   The default value is 'call-id'. In the event that a HEP module cannot find a
+   valid value using the specified 'uuid_type', the module may fallback to a
+   more readily available source for the correlation UUID.
+
 app_confbridge
 ------------------
  * Added a bridge profile option called regcontext that allows you to
diff --git a/configs/samples/hep.conf.sample b/configs/samples/hep.conf.sample
index 40b17aa..6e409d1 100644
--- a/configs/samples/hep.conf.sample
+++ b/configs/samples/hep.conf.sample
@@ -13,4 +13,8 @@
 capture_id = 1234                  ; A unique integer identifier for this
                                    ; server. This ID will be embedded sent
                                    ; with each packet from this server.
+uuid_type = call-id                ; Specify the preferred source for the Homer
+                                   ; correlation UUID. Valid options are:
+                                   ; - 'call-id' for the PJSIP SIP Call-ID
+                                   ; - 'channel' for the Asterisk channel name
 
diff --git a/include/asterisk/res_hep.h b/include/asterisk/res_hep.h
index 8839fd6..bd0129e 100644
--- a/include/asterisk/res_hep.h
+++ b/include/asterisk/res_hep.h
@@ -49,6 +49,11 @@
 	HEPV3_CAPTURE_TYPE_IAX    = 0x10,
 };
 
+enum hep_uuid_type {
+	HEP_UUID_TYPE_CALL_ID = 0,
+	HEP_UUID_TYPE_CHANNEL,
+};
+
 /*! \brief HEPv3 Capture Info */
 struct hepv3_capture_info {
 	/*! The source address of the packet */
@@ -104,6 +109,15 @@
  */
 int hepv3_send_packet(struct hepv3_capture_info *capture_info);
 
+/*!
+ * \brief Get the preferred UUID type
+ *
+ * \since 13.10.0
+ *
+ * \retval The type of UUID the packet should use
+ */
+enum hep_uuid_type hepv3_get_uuid_type(void);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/res/res_hep.c b/res/res_hep.c
index 69a8ab3..723b27d 100644
--- a/res/res_hep.c
+++ b/res/res_hep.c
@@ -60,6 +60,15 @@
 						</enumlist>
 					</description>
 				</configOption>
+				<configOption name="uuid_type" default="call-id">
+					<synopsis>The preferred type of UUID to pass to Homer.</synopsis>
+					<description>
+						<enumlist>
+							<enum name="call-id"><para>Use the PJSIP Call-Id</para></enum>
+							<enum name="channel"><para>Use the Asterisk channel name</para></enum>
+						</enumlist>
+					</description>
+				</configOption>
 				<configOption name="capture_address" default="192.168.1.1:9061">
 					<synopsis>The address and port of the Homer server to send packets to.</synopsis>
 				</configOption>
@@ -231,6 +240,7 @@
 struct hepv3_global_config {
 	unsigned int enabled;                    /*!< Whether or not sending is enabled */
 	unsigned int capture_id;                 /*!< Capture ID for this agent */
+	enum hep_uuid_type uuid_type;            /*!< The preferred type of the UUID */
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(capture_address);   /*!< Address to send to */
 		AST_STRING_FIELD(capture_password);  /*!< Password for Homer server */
@@ -329,6 +339,25 @@
 	return config;
 }
 
+/*! \brief Handler for the uuid_type attribute */
+static int uuid_type_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct hepv3_global_config *global_config = obj;
+
+	if (strcasecmp(var->name, "uuid_type")) {
+		return -1;
+	}
+
+	if (!strcasecmp(var->value, "channel")) {
+		global_config->uuid_type = HEP_UUID_TYPE_CHANNEL;
+	} else if (!strcasecmp(var->value, "call-id")) {
+		global_config->uuid_type = HEP_UUID_TYPE_CALL_ID;
+	} else {
+		return -1;
+	}
+	return 0;
+}
+
 /*! \brief HEPv3 run-time data destructor */
 static void hepv3_data_dtor(void *obj)
 {
@@ -374,6 +403,13 @@
 
 	ast_free(info->uuid);
 	ast_free(info->payload);
+}
+
+enum hep_uuid_type hepv3_get_uuid_type(void)
+{
+	RAII_VAR(struct module_config *, config, ao2_global_obj_ref(global_config), ao2_cleanup);
+
+	return config->general->uuid_type;
 }
 
 struct hepv3_capture_info *hepv3_create_capture_info(const void *payload, size_t len)
@@ -607,6 +643,7 @@
 	aco_option_register(&cfg_info, "capture_address", ACO_EXACT, global_options, DEFAULT_HEP_SERVER, OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_address));
 	aco_option_register(&cfg_info, "capture_password", ACO_EXACT, global_options, "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct hepv3_global_config, capture_password));
 	aco_option_register(&cfg_info, "capture_id", ACO_EXACT, global_options, "0", OPT_UINT_T, 0, STRFLDSET(struct hepv3_global_config, capture_id));
+	aco_option_register_custom(&cfg_info, "uuid_type", ACO_EXACT, global_options, "call-id", uuid_type_handler, 0);
 
 	if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
 		goto error;
diff --git a/res/res_hep.exports.in b/res/res_hep.exports.in
index d09d3f4..df0f2b4 100644
--- a/res/res_hep.exports.in
+++ b/res/res_hep.exports.in
@@ -2,6 +2,7 @@
 	global:
 		LINKER_SYMBOL_PREFIX*hepv3_send_packet;
 		LINKER_SYMBOL_PREFIX*hepv3_create_capture_info;
+		LINKER_SYMBOL_PREFIX*hepv3_get_uuid_type;
 	local:
 		*;
 };
diff --git a/res/res_hep_pjsip.c b/res/res_hep_pjsip.c
index b5cf0b8..caffd25 100644
--- a/res/res_hep_pjsip.c
+++ b/res/res_hep_pjsip.c
@@ -51,13 +51,18 @@
 	RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
 	pjsip_dialog *dlg;
 	char *uuid = NULL;
+	enum hep_uuid_type uuid_type = hepv3_get_uuid_type();
 
-	if ((dlg = pjsip_ua_find_dialog(call_id, local_tag, remote_tag, PJ_FALSE))
+	if ((uuid_type == HEP_UUID_TYPE_CHANNEL)
+		&& (dlg = pjsip_ua_find_dialog(call_id, local_tag, remote_tag, PJ_FALSE))
 	    && (session = ast_sip_dialog_get_session(dlg))
 	    && (session->channel)) {
 
 		uuid = ast_strdup(ast_channel_name(session->channel));
-	} else {
+	}
+
+	/* If we couldn't get the channel or we never wanted it, default to the call-id */
+	if (!uuid) {
 
 		uuid = ast_malloc(pj_strlen(call_id) + 1);
 		if (uuid) {
diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c
index 787512b..49a9253 100644
--- a/res/res_hep_rtcp.c
+++ b/res/res_hep_rtcp.c
@@ -36,12 +36,43 @@
 #include "asterisk/res_hep.h"
 #include "asterisk/module.h"
 #include "asterisk/netsock2.h"
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
 #include "asterisk/stasis.h"
 #include "asterisk/rtp_engine.h"
 #include "asterisk/json.h"
 #include "asterisk/config.h"
 
 static struct stasis_subscription *stasis_rtp_subscription;
+
+static char *assign_uuid(struct ast_json *json_channel)
+{
+	const char *channel_name = ast_json_string_get(ast_json_object_get(json_channel, "name"));
+	enum hep_uuid_type uuid_type = hepv3_get_uuid_type();
+	char *uuid = NULL;
+
+	if (!channel_name) {
+		return NULL;
+	}
+
+	if (uuid_type == HEP_UUID_TYPE_CALL_ID && ast_begins_with(channel_name, "PJSIP")) {
+		struct ast_channel *chan = ast_channel_get_by_name(channel_name);
+		char buf[128];
+
+		if (chan && !ast_func_read(chan, "CHANNEL(pjsip,call-id)", buf, sizeof(buf))) {
+			uuid = ast_strdup(buf);
+		}
+
+		ast_channel_cleanup(chan);
+	}
+
+	/* If we couldn't get the call-id or didn't want it, just use the channel name */
+	if (!uuid) {
+		uuid = ast_strdup(channel_name);
+	}
+
+	return uuid;
+}
 
 static void rtcp_message_handler(struct stasis_message *message)
 {
@@ -94,7 +125,7 @@
 	ast_sockaddr_parse(&capture_info->src_addr, ast_json_string_get(from), PARSE_PORT_REQUIRE);
 	ast_sockaddr_parse(&capture_info->dst_addr, ast_json_string_get(to), PARSE_PORT_REQUIRE);
 
-	capture_info->uuid = ast_strdup(ast_json_string_get(ast_json_object_get(json_channel, "name")));
+	capture_info->uuid = assign_uuid(json_channel);
 	if (!capture_info->uuid) {
 		ao2_ref(capture_info, -1);
 		return;

-- 
To view, visit https://gerrit.asterisk.org/2814
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ide67e59a52d9c806e3cc0a797ea1a4b88a00122c
Gerrit-PatchSet: 3
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Matt Jordan <mjordan at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Matt Jordan <mjordan at digium.com>



More information about the asterisk-code-review mailing list