[Asterisk-code-review] pjproject: Upgrade bundled version to pjproject 2.10 (asterisk[master])

Friendly Automation asteriskteam at digium.com
Tue Jun 16 08:07:18 CDT 2020


Friendly Automation has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/14551 )

Change subject: pjproject: Upgrade bundled version to pjproject 2.10
......................................................................

pjproject: Upgrade bundled version to pjproject 2.10

This patch makes the usual necessary changes when upgrading to a new
version pjproject. For instance, version number bump, patches removed
from third-party, new *.md5 file added, etc..

This patch also includes a change to the Asterisk pjproject Makefile to
explicitly create the 'source/pjsip-apps/lib' directory. This directory
is no longer there by default so needs to be added so the Asterisk
malloc debug can be built.

This patch also includes some minor changes to Asterisk that were a result
of the upgrade. Specifically, there was a backward incompatibility change
made in 2.10 that modified the "expires header" variable field from a
signed to an unsigned value. This potentially effects comparison. Namely,
those check for a value less than zero. This patch modified a few locations
in the Asterisk code that may have been affected.

Lastly, this patch adds a new macro PJSIP_MINVERSION that can be used to
check a minimum version of pjproject at compile time.

ASTERISK-28899 #close

Change-Id: Iec8821c6cbbc08c369d0e3cd2f14e691b41d0c81
---
M include/asterisk/res_pjsip.h
M res/res_pjsip_pubsub.c
M res/res_pjsip_registrar.c
M third-party/pjproject/Makefile
D third-party/pjproject/patches/0010-ssl_sock_ossl-sip_transport_tls-Add-peer-to-error-me.patch
A third-party/pjproject/patches/0011-sip_inv_patch.patch
D third-party/pjproject/patches/0020-patch_cnonce_only_digits_option.patch
D third-party/pjproject/patches/0030-ssl-regression-fix.patch
D third-party/pjproject/patches/0031-transport-regression-fix.patch
D third-party/pjproject/patches/0040-ICE-Add-callback-for-finding-valid-pair.patch
D third-party/pjproject/patches/0040-brackets-in-via-received-params.patch
A third-party/pjproject/pjproject-2.10.tar.bz2.md5
D third-party/pjproject/pjproject-2.9.tar.bz2.md5
M third-party/versions.mak
14 files changed, 73 insertions(+), 644 deletions(-)

Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit



diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 363c9a4..2993103 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -50,6 +50,18 @@
 #include "asterisk/stasis_channels.h"
 #include "asterisk/stasis_endpoints.h"
 
+#define PJSIP_MINVERSION(m,n,p) (((m << 24) | (n << 16) | (p << 8)) >= PJ_VERSION_NUM)
+
+#ifndef PJSIP_EXPIRES_NOT_SPECIFIED
+/*
+ * Added in pjproject 2.10.0. However define here if someone compiles against a
+ * version of pjproject < 2.10.0.
+ *
+ * Usually defined in pjsip/include/pjsip/sip_msg.h (included as part of <pjsip.h>)
+ */
+#define PJSIP_EXPIRES_NOT_SPECIFIED	((pj_uint32_t)-1)
+#endif
+
 /* Forward declarations of PJSIP stuff */
 struct pjsip_rx_data;
 struct pjsip_module;
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index bfa3dc9..be1eb39 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -352,7 +352,7 @@
 	/*! \brief The endpoint with which the subscription is communicating */
 	struct ast_sip_endpoint *endpoint;
 	/*! \brief Expiration time of the publication */
-	int expires;
+	unsigned int expires;
 	/*! \brief Scheduled item for expiration of publication */
 	int sched_id;
 	/*! \brief The resource the publication is to */
@@ -676,7 +676,7 @@
 	sub_tree->persistence->cseq = dlg->local.cseq;
 
 	if (rdata) {
-		int expires;
+		unsigned int expires;
 		pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
 		pjsip_contact_hdr *contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
 
@@ -1525,7 +1525,7 @@
 /*! Wrapper structure for initial_notify_task */
 struct initial_notify_data {
 	struct sip_subscription_tree *sub_tree;
-	int expires;
+	unsigned int expires;
 };
 
 static int initial_notify_task(void *obj);
@@ -1560,6 +1560,7 @@
 	int resp;
 	struct resource_tree tree;
 	pjsip_expires_hdr *expires_header;
+	int64_t expires;
 
 	request_uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);
 	resource_size = pj_strlen(&request_uri->user) + 1;
@@ -1616,8 +1617,8 @@
 		pjsip_msg_add_hdr(rdata->msg_info.msg, (pjsip_hdr *) expires_header);
 	}
 
-	expires_header->ivalue = (ast_tvdiff_ms(persistence->expires, ast_tvnow()) / 1000);
-	if (expires_header->ivalue <= 0) {
+	expires = (ast_tvdiff_ms(persistence->expires, ast_tvnow()) / 1000);
+	if (expires <= 0) {
 		/* The subscription expired since we started recreating the subscription. */
 		ast_debug(3, "Expired subscription retrived from persistent store '%s' %s\n",
 			persistence->endpoint, persistence->tag);
@@ -1625,6 +1626,7 @@
 		ao2_ref(endpoint, -1);
 		return 0;
 	}
+	expires_header->ivalue = expires;
 
 	memset(&tree, 0, sizeof(tree));
 	resp = build_resource_tree(endpoint, handler, resource, &tree,
@@ -2937,7 +2939,7 @@
 			ind->sub_tree->root->resource);
 	}
 
-	if (ind->expires > -1) {
+	if (ind->expires != PJSIP_EXPIRES_NOT_SPECIFIED) {
 		char *name = ast_alloca(strlen("->/ ") +
 			strlen(ind->sub_tree->persistence->endpoint) +
 			strlen(ind->sub_tree->root->resource) +
@@ -3063,7 +3065,7 @@
 
 		ind->sub_tree = ao2_bump(sub_tree);
 		/* Since this is a normal subscribe, pjproject takes care of the timer */
-		ind->expires = -1;
+		ind->expires = PJSIP_EXPIRES_NOT_SPECIFIED;
 
 		sub_tree->persistence = subscription_persistence_create(sub_tree);
 		subscription_persistence_update(sub_tree, rdata, SUBSCRIPTION_PERSISTENCE_CREATED);
@@ -3098,7 +3100,7 @@
 }
 
 static enum sip_publish_type determine_sip_publish_type(pjsip_rx_data *rdata,
-	pjsip_generic_string_hdr *etag_hdr, int *expires, int *entity_id)
+	pjsip_generic_string_hdr *etag_hdr, unsigned int *expires, int *entity_id)
 {
 	pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
 
@@ -3331,7 +3333,8 @@
 	pjsip_generic_string_hdr *etag_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_sip_if_match, NULL);
 	enum sip_publish_type publish_type;
 	RAII_VAR(struct ast_sip_publication *, publication, NULL, ao2_cleanup);
-	int expires = 0, entity_id, response = 0;
+	unsigned int expires = 0;
+	int entity_id, response = 0;
 
 	endpoint = ast_pjsip_rdata_get_endpoint(rdata);
 	ast_assert(endpoint != NULL);
@@ -4215,7 +4218,7 @@
 	return cli.callid;
 }
 
-static int cli_subscription_expiry(struct sip_subscription_tree *sub_tree)
+static unsigned int cli_subscription_expiry(struct sip_subscription_tree *sub_tree)
 {
 	int expiry;
 
@@ -4263,7 +4266,7 @@
 
 	ast_str_append(&buf, 0, "Resource: %s\n", sub_tree->root->resource);
 	ast_str_append(&buf, 0, "Event: %s\n", sub_tree->root->handler->event_name);
-	ast_str_append(&buf, 0, "Expiry: %d\n", cli_subscription_expiry(sub_tree));
+	ast_str_append(&buf, 0, "Expiry: %u\n", cli_subscription_expiry(sub_tree));
 
 	sip_subscription_to_ami(sub_tree, &buf);
 
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index 523eb0a..be40a20 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -81,12 +81,12 @@
 static int pjsip_max_url_size = PJSIP_MAX_URL_SIZE;
 
 /*! \brief Internal function which returns the expiration time for a contact */
-static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
+static unsigned int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
 {
 	pjsip_expires_hdr *expires;
-	int expiration = aor->default_expiration;
+	unsigned int expiration = aor->default_expiration;
 
-	if (contact && contact->expires != -1) {
+	if (contact && contact->expires != PJSIP_EXPIRES_NOT_SPECIFIED) {
 		/* Expiration was provided with the contact itself */
 		expiration = contact->expires;
 	} else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
@@ -148,7 +148,7 @@
 	};
 
 	for (; (contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next)); pj_pool_reset(pool)) {
-		int expiration = registrar_get_expiration(aor, contact, rdata);
+		unsigned int expiration = registrar_get_expiration(aor, contact, rdata);
 		struct ast_sip_contact *existing;
 		char contact_uri[pjsip_max_url_size];
 
diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile
index d52ad4a..fce2768 100644
--- a/third-party/pjproject/Makefile
+++ b/third-party/pjproject/Makefile
@@ -170,6 +170,7 @@
 source/pjsip-apps/src/asterisk_malloc_debug.c: patches/asterisk_malloc_debug.c
 	$(ECHO_PREFIX) Copying $< to $@
 	$(CMD_PREFIX) cp -f $< $@
+	$(CMD_PREFIX) mkdir source/pjsip-apps/lib/
 
 source/pjsip-apps/lib/asterisk_malloc_debug.o: source/pjsip-apps/src/asterisk_malloc_debug.c .rebuild_needed
 	$(ECHO_PREFIX) Compiling asterisk debug malloc stubs
diff --git a/third-party/pjproject/patches/0010-ssl_sock_ossl-sip_transport_tls-Add-peer-to-error-me.patch b/third-party/pjproject/patches/0010-ssl_sock_ossl-sip_transport_tls-Add-peer-to-error-me.patch
deleted file mode 100644
index 53bde48..0000000
--- a/third-party/pjproject/patches/0010-ssl_sock_ossl-sip_transport_tls-Add-peer-to-error-me.patch
+++ /dev/null
@@ -1,157 +0,0 @@
->From 85b28c475b5dfd3b01dafffd1d0b3dbb6f087829 Mon Sep 17 00:00:00 2001
-From: George Joseph <gjoseph at digium.com>
-Date: Thu, 27 Jun 2019 11:19:47 -0600
-Subject: [PATCH] ssl_sock_ossl/sip_transport_tls:  Add peer to error messages
-
-Added peer address:port to error messages in ssl_sock_ossl.
-Added peer hostname to error messages in sip_transport_tls.
----
- pjlib/src/pj/ssl_sock_ossl.c        | 22 +++++++++++++---------
- pjsip/src/pjsip/sip_transport_tls.c | 17 +++++++++--------
- 2 files changed, 22 insertions(+), 17 deletions(-)
-
-diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
-index b4ac5c15f..42db8fdbe 100644
---- a/pjlib/src/pj/ssl_sock_ossl.c
-+++ b/pjlib/src/pj/ssl_sock_ossl.c
-@@ -210,15 +210,19 @@ static char *SSLErrorString (int err)
-     }
- }
- 
--#define ERROR_LOG(msg, err) \
--    PJ_LOG(2,("SSL", "%s (%s): Level: %d err: <%lu> <%s-%s-%s> len: %d", \
-+#define ERROR_LOG(msg, err, ssock) \
-+{ \
-+    char buf[PJ_INET6_ADDRSTRLEN+10]; \
-+    PJ_LOG(2,("SSL", "%s (%s): Level: %d err: <%lu> <%s-%s-%s> len: %d peer: %s", \
- 	      msg, action, level, err, \
- 	      (ERR_lib_error_string(err)? ERR_lib_error_string(err): "???"), \
- 	      (ERR_func_error_string(err)? ERR_func_error_string(err):"???"),\
- 	      (ERR_reason_error_string(err)? \
--	       ERR_reason_error_string(err): "???"), len));
-+	       ERR_reason_error_string(err): "???"), len, \
-+	       pj_sockaddr_print(&ssock->rem_addr, buf, sizeof(buf), 3))); \
-+}
- 
--static void SSLLogErrors(char * action, int ret, int ssl_err, int len)
-+static void SSLLogErrors(char * action, int ret, int ssl_err, int len, pj_ssl_sock_t *ssock)
- {
-     char *ssl_err_str = SSLErrorString(ssl_err);
- 
-@@ -233,7 +237,7 @@ static void SSLLogErrors(char * action, int ret, int ssl_err, int len)
- 	if (err2) {
- 	    int level = 0;
- 	    while (err2) {
--	        ERROR_LOG("SSL_ERROR_SYSCALL", err2);
-+	        ERROR_LOG("SSL_ERROR_SYSCALL", err2, ssock);
- 		level++;
- 		err2 = ERR_get_error();
- 	    }
-@@ -264,7 +268,7 @@ static void SSLLogErrors(char * action, int ret, int ssl_err, int len)
- 	int level = 0;
- 
- 	while (err2) {
--	    ERROR_LOG("SSL_ERROR_SSL", err2);
-+	    ERROR_LOG("SSL_ERROR_SSL", err2, ssock);
- 	    level++;
- 	    err2 = ERR_get_error();
- 	}
-@@ -302,13 +306,13 @@ static pj_status_t STATUS_FROM_SSL_ERR(char *action, pj_ssl_sock_t *ssock,
-     int level = 0;
-     int len = 0; //dummy
- 
--    ERROR_LOG("STATUS_FROM_SSL_ERR", err);
-+    ERROR_LOG("STATUS_FROM_SSL_ERR", err, ssock);
-     level++;
- 
-     /* General SSL error, dig more from OpenSSL error queue */
-     if (err == SSL_ERROR_SSL) {
- 	err = ERR_get_error();
--	ERROR_LOG("STATUS_FROM_SSL_ERR", err);
-+	ERROR_LOG("STATUS_FROM_SSL_ERR", err, ssock);
-     }
- 
-     ssock->last_err = err;
-@@ -326,7 +330,7 @@ static pj_status_t STATUS_FROM_SSL_ERR2(char *action, pj_ssl_sock_t *ssock,
-     }
- 
-     /* Dig for more from OpenSSL error queue */
--    SSLLogErrors(action, ret, err, len);
-+    SSLLogErrors(action, ret, err, len, ssock);
- 
-     ssock->last_err = ssl_err;
-     return GET_STATUS_FROM_SSL_ERR(ssl_err);
-diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
-index 38349aa7a..d40bc7ea3 100644
---- a/pjsip/src/pjsip/sip_transport_tls.c
-+++ b/pjsip/src/pjsip/sip_transport_tls.c
-@@ -173,9 +173,10 @@ static void wipe_buf(pj_str_t *buf);
- 
- 
- static void tls_perror(const char *sender, const char *title,
--		       pj_status_t status)
-+		       pj_status_t status, pj_str_t *remote_name)
- {
--    PJ_PERROR(3,(sender, status, "%s: [code=%d]", title, status));
-+    PJ_PERROR(3,(sender, status, "%s: [code=%d]%s%.*s", title, status,
-+        remote_name ? " peer: " : "", remote_name ? remote_name->slen : 0, remote_name ? remote_name->ptr : ""));
- }
- 
- 
-@@ -730,7 +731,7 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_restart(pjsip_tpfactory *factory,
-     status = pjsip_tls_transport_lis_start(factory, local, a_name);
-     if (status != PJ_SUCCESS) {	
- 	tls_perror(listener->factory.obj_name, 
--		   "Unable to start listener after closing it", status);
-+		   "Unable to start listener after closing it", status, NULL);
- 
- 	return status;
-     }
-@@ -739,7 +740,7 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_restart(pjsip_tpfactory *factory,
- 					    &listener->factory);
-     if (status != PJ_SUCCESS) {
- 	tls_perror(listener->factory.obj_name,
--		    "Unable to register the transport listener", status);
-+		    "Unable to register the transport listener", status, NULL);
- 
- 	listener->is_registered = PJ_FALSE;	
-     } else {
-@@ -1085,7 +1086,7 @@ static pj_status_t tls_start_read(struct tls_transport *tls)
- 				   PJSIP_POOL_RDATA_LEN,
- 				   PJSIP_POOL_RDATA_INC);
-     if (!pool) {
--	tls_perror(tls->base.obj_name, "Unable to create pool", PJ_ENOMEM);
-+	tls_perror(tls->base.obj_name, "Unable to create pool", PJ_ENOMEM, NULL);
- 	return PJ_ENOMEM;
-     }
- 
-@@ -1772,7 +1773,7 @@ static pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock,
-     /* Check connect() status */
-     if (status != PJ_SUCCESS) {
- 
--	tls_perror(tls->base.obj_name, "TLS connect() error", status);
-+	tls_perror(tls->base.obj_name, "TLS connect() error", status, &tls->remote_name);
- 
- 	/* Cancel all delayed transmits */
- 	while (!pj_list_empty(&tls->delayed_list)) {
-@@ -1916,7 +1917,7 @@ static pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock,
-     pjsip_transport_dec_ref(&tls->base);
-     if (is_shutdown) {
- 	status = tls->close_reason;
--	tls_perror(tls->base.obj_name, "TLS connect() error", status);
-+	tls_perror(tls->base.obj_name, "TLS connect() error", status, &tls->remote_name);
- 
- 	/* Cancel all delayed transmits */
- 	while (!pj_list_empty(&tls->delayed_list)) {
-@@ -2015,7 +2016,7 @@ static void tls_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e)
- 
-     if (status != PJ_SUCCESS && status != PJ_EPENDING) {
- 	tls_perror(tls->base.obj_name, 
--		   "Error sending keep-alive packet", status);
-+		   "Error sending keep-alive packet", status, &tls->remote_name);
- 
- 	tls_init_shutdown(tls, status);
- 	return;
--- 
-2.21.0
-
diff --git a/third-party/pjproject/patches/0011-sip_inv_patch.patch b/third-party/pjproject/patches/0011-sip_inv_patch.patch
new file mode 100644
index 0000000..7f77c74
--- /dev/null
+++ b/third-party/pjproject/patches/0011-sip_inv_patch.patch
@@ -0,0 +1,39 @@
+commit c3c1bf45cae2a35003aa16c267d59f97027f9c5e
+Author: Kevin Harwell <kharwell at digium.com>
+Date:   Thu Jun 11 11:11:13 2020 -0500
+
+    sip_inv - fix invite session ref count crash
+    
+    Ensure the session's ref count is only decremented under proper conditons.
+    
+    For more details see the following issue report:
+    https://github.com/pjsip/pjproject/issues/2443
+    
+    Patch supplied by sauwming
+
+diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
+index ca225015b..7c11b1c8e 100644
+--- a/pjsip/src/pjsip-ua/sip_inv.c
++++ b/pjsip/src/pjsip-ua/sip_inv.c
+@@ -323,9 +323,19 @@ static void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,
+ 	(*mod_inv.cb.on_state_changed)(inv, e);
+     pjsip_inv_dec_ref(inv);
+ 
+-    /* Only decrement when previous state is not already DISCONNECTED */
++    /* The above callback may change the state, so we need to be careful here
++     * and only decrement inv under the following conditions:
++     * 1. If the state parameter is DISCONNECTED, and previous state is not
++     *    already DISCONNECTED.
++     *    This is to make sure that dec_ref() is not called more than once.
++     * 2. If current state is PJSIP_INV_STATE_DISCONNECTED.
++     *    This is to make sure that dec_ref() is not called if user restarts
++     *    inv within the callback. Note that this check must be last since
++     *    inv may have already been destroyed.
++     */
+     if (state == PJSIP_INV_STATE_DISCONNECTED &&
+-	prev_state != PJSIP_INV_STATE_DISCONNECTED) 
++	prev_state != PJSIP_INV_STATE_DISCONNECTED &&
++	inv->state == PJSIP_INV_STATE_DISCONNECTED) 
+     {
+ 	pjsip_inv_dec_ref(inv);
+     }
diff --git a/third-party/pjproject/patches/0020-patch_cnonce_only_digits_option.patch b/third-party/pjproject/patches/0020-patch_cnonce_only_digits_option.patch
deleted file mode 100644
index ecf6c94..0000000
--- a/third-party/pjproject/patches/0020-patch_cnonce_only_digits_option.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-Index: pjsip/include/pjsip/sip_config.h
-===================================================================
---- a/pjsip/include/pjsip/sip_config.h	(revision 6050)
-+++ b/pjsip/include/pjsip/sip_config.h	(working copy)
-@@ -1190,6 +1190,20 @@
- #   define PJSIP_AUTH_CACHED_POOL_MAX_SIZE	(20 * 1024)
- #endif
- 
-+
-+/**
-+ * Specify whether the cnonce used for SIP authentication contain digits only.
-+ * The "cnonce" value is setup using GUID generator, i.e:
-+ * pj_create_unique_string(), and the GUID string may contain hyphen character
-+ * ("-"). Some SIP servers do not like this GUID format, so this option will
-+ * strip any hyphens from the GUID string.
-+ *
-+ * Default is 1 (cnonce will only contain digit characters).
-+ */
-+#ifndef PJSIP_AUTH_CNONCE_USE_DIGITS_ONLY
-+#   define PJSIP_AUTH_CNONCE_USE_DIGITS_ONLY	1
-+#endif
-+
- /*****************************************************************************
-  *  SIP Event framework and presence settings.
-  */
-Index: pjsip/src/pjsip/sip_auth_client.c
-===================================================================
---- a/pjsip/src/pjsip/sip_auth_client.c	(revision 6050)
-+++ b/pjsip/src/pjsip/sip_auth_client.c	(working copy)
-@@ -396,7 +396,23 @@
- 
- 	/* Create cnonce */
- 	pj_create_unique_string( cached_auth->pool, &cached_auth->cnonce );
-+#if defined(PJSIP_AUTH_CNONCE_USE_DIGITS_ONLY) && \
-+    PJSIP_AUTH_CNONCE_USE_DIGITS_ONLY!=0
-+	if (pj_strchr(&cached_auth->cnonce, '-')) {
-+	    /* remove hyphen character. */
-+	    int w, r, len = pj_strlen(&cached_auth->cnonce);
-+	    char *s = cached_auth->cnonce.ptr;
- 
-+	    w = r = 0;
-+	    for (; r < len; r++) {
-+		if (s[r] != '-')
-+		    s[w++] = s[r];
-+	    }
-+	    s[w] = '\0';
-+	    cached_auth->cnonce.slen = w;
-+	}
-+#endif
-+
- 	/* Initialize nonce-count */
- 	cached_auth->nc = 1;
- 
diff --git a/third-party/pjproject/patches/0030-ssl-regression-fix.patch b/third-party/pjproject/patches/0030-ssl-regression-fix.patch
deleted file mode 100644
index 8ddcaf7..0000000
--- a/third-party/pjproject/patches/0030-ssl-regression-fix.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 489281f29fc7b97143cf79154f22e5007adaba39 Mon Sep 17 00:00:00 2001
-From: George Joseph <gjoseph at digium.com>
-Date: Wed, 9 Oct 2019 07:49:44 -0600
-Subject: [PATCH 30/31] ssl regression fix
-
----
- pjlib/src/pj/ssl_sock_gtls.c       | 6 ++++--
- pjlib/src/pj/ssl_sock_imp_common.c | 4 ++++
- pjlib/src/pj/ssl_sock_imp_common.h | 3 +++
- pjlib/src/pj/ssl_sock_ossl.c       | 9 +++++----
- 4 files changed, 16 insertions(+), 6 deletions(-)
-
-diff --git a/pjlib/src/pj/ssl_sock_gtls.c b/pjlib/src/pj/ssl_sock_gtls.c
-index 311b7b757..484770ae4 100644
---- a/pjlib/src/pj/ssl_sock_gtls.c
-+++ b/pjlib/src/pj/ssl_sock_gtls.c
-@@ -1050,7 +1050,8 @@ static void ssl_update_certs_info(pj_ssl_sock_t *ssock)
-         goto us_out;
- 
-     tls_cert_get_info(ssock->pool, &ssock->local_cert_info, cert);
--    tls_cert_get_chain_raw(ssock->pool, &ssock->local_cert_info, us, 1);
-+    pj_pool_reset(ssock->info_pool);
-+    tls_cert_get_chain_raw(ssock->info_pool, &ssock->local_cert_info, us, 1);
- 
- us_out:
-     tls_last_error = ret;
-@@ -1077,7 +1078,8 @@ us_out:
-         goto peer_out;
- 
-     tls_cert_get_info(ssock->pool, &ssock->remote_cert_info, cert);
--    tls_cert_get_chain_raw(ssock->pool, &ssock->remote_cert_info, certs,
-+    pj_pool_reset(ssock->info_pool);
-+    tls_cert_get_chain_raw(ssock->info_pool, &ssock->remote_cert_info, certs,
-     			   certslen);
- 
- peer_out:
-diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
-index e6273d832..51a62a2fb 100644
---- a/pjlib/src/pj/ssl_sock_imp_common.c
-+++ b/pjlib/src/pj/ssl_sock_imp_common.c
-@@ -616,6 +616,7 @@ static void ssl_on_destroy(void *arg)
-     }
- 
-     /* Secure release pool, i.e: all memory blocks will be zeroed first */
-+    pj_pool_secure_release(&ssock->info_pool);
-     pj_pool_secure_release(&ssock->pool);
- }
- 
-@@ -1262,15 +1263,18 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
- {
-     pj_ssl_sock_t *ssock;
-     pj_status_t status;
-+    pj_pool_t *info_pool;
- 
-     PJ_ASSERT_RETURN(pool && param && p_ssock, PJ_EINVAL);
-     PJ_ASSERT_RETURN(param->sock_type == pj_SOCK_STREAM(), PJ_ENOTSUP);
- 
-+    info_pool = pj_pool_create(pool->factory, "ssl_chain%p", 512, 512, NULL);
-     pool = pj_pool_create(pool->factory, "ssl%p", 512, 512, NULL);
- 
-     /* Create secure socket */
-     ssock = ssl_alloc(pool);
-     ssock->pool = pool;
-+    ssock->info_pool = info_pool;
-     ssock->sock = PJ_INVALID_SOCKET;
-     ssock->ssl_state = SSL_STATE_NULL;
-     ssock->circ_buf_input.owner = ssock;
-diff --git a/pjlib/src/pj/ssl_sock_imp_common.h b/pjlib/src/pj/ssl_sock_imp_common.h
-index 09f259ef7..eb45f14e0 100644
---- a/pjlib/src/pj/ssl_sock_imp_common.h
-+++ b/pjlib/src/pj/ssl_sock_imp_common.h
-@@ -96,6 +96,9 @@ typedef struct circ_buf_t {
- struct pj_ssl_sock_t
- {
-     pj_pool_t		 *pool;
-+    pj_pool_t		 *info_pool; /* this is for certificate chain 
-+				      * information allocation. Don't use for 
-+				      * other purposes. */
-     pj_ssl_sock_t	 *parent;
-     pj_ssl_sock_param	  param;
-     pj_ssl_sock_param	  newsock_param;
-diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
-index b4ac5c15f..2545b7c37 100644
---- a/pjlib/src/pj/ssl_sock_ossl.c
-+++ b/pjlib/src/pj/ssl_sock_ossl.c
-@@ -1637,11 +1637,12 @@ static void ssl_update_certs_info(pj_ssl_sock_t *ssock)
- 
-     chain = SSL_get_peer_cert_chain(ossock->ossl_ssl);
-     if (chain) {
--       ssl_update_remote_cert_chain_info(ssock->pool,
--       					 &ssock->remote_cert_info,
--       					 chain, PJ_TRUE);
-+	pj_pool_reset(ssock->info_pool);
-+	ssl_update_remote_cert_chain_info(ssock->info_pool,
-+       					  &ssock->remote_cert_info,
-+       					  chain, PJ_TRUE);
-     } else {
--       ssock->remote_cert_info.raw_chain.cnt = 0;
-+	ssock->remote_cert_info.raw_chain.cnt = 0;
-     }
- }
- 
--- 
-2.21.0
-
diff --git a/third-party/pjproject/patches/0031-transport-regression-fix.patch b/third-party/pjproject/patches/0031-transport-regression-fix.patch
deleted file mode 100644
index fdd8836..0000000
--- a/third-party/pjproject/patches/0031-transport-regression-fix.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From 9c6108ca392d5e0392e7fb5d2ffde85e3c44ce55 Mon Sep 17 00:00:00 2001
-From: George Joseph <gjoseph at digium.com>
-Date: Wed, 9 Oct 2019 07:50:32 -0600
-Subject: [PATCH 31/31] transport regression fix
-
----
- pjsip/src/pjsip/sip_transport.c | 73 +++++++++++++++++++++++++++------
- 1 file changed, 61 insertions(+), 12 deletions(-)
-
-diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
-index 65ac823d4..da6b70e50 100644
---- a/pjsip/src/pjsip/sip_transport.c
-+++ b/pjsip/src/pjsip/sip_transport.c
-@@ -50,6 +50,24 @@ static const char *addr_string(const pj_sockaddr_t *addr)
- 		 str, sizeof(str));
-     return str;
- }
-+static const char* print_tpsel_info(const pjsip_tpselector *sel)
-+{
-+    static char tpsel_info_buf[80];
-+    if (!sel) return "(null)";
-+    if (sel->type==PJSIP_TPSELECTOR_LISTENER)
-+	pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
-+			 "listener[%s], reuse=%d", sel->u.listener->obj_name,
-+			 !sel->disable_connection_reuse);
-+    else if (sel->type==PJSIP_TPSELECTOR_TRANSPORT)
-+	pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
-+			 "transport[%s], reuse=%d", sel->u.transport->info,
-+			 !sel->disable_connection_reuse);
-+    else
-+	pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
-+			 "unknown[%p], reuse=%d", sel->u.ptr,
-+			 !sel->disable_connection_reuse);
-+    return tpsel_info_buf;
-+}
- #else
- #   define TRACE_(x)
- #endif
-@@ -1210,10 +1228,14 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
- 	 * new transport to the list.
- 	 */
- 	pj_list_push_back(tp_ref, tp_add);
-+	TRACE_((THIS_FILE, "Remote address already registered, "
-+			   "appended the transport to the list"));
-     } else {
- 	/* Transport list not found, add it to the hash table. */
- 	pj_hash_set_np(mgr->table, &tp->key, key_len, hval, tp_add->tp_buf,
- 		       tp_add);
-+	TRACE_((THIS_FILE, "Remote address not registered, "
-+			   "added the transport to the hash"));
-     }
- 
-     /* Add ref transport group lock, if any */
-@@ -1283,6 +1305,13 @@ static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
- 			/* The transport list has multiple entry. */
- 			pj_hash_set_np(mgr->table, &tp_next->tp->key, key_len,
- 				       hval, tp_next->tp_buf, tp_next);
-+			TRACE_((THIS_FILE, "Hash entry updated after "
-+					   "transport %d being destroyed",
-+					   tp->obj_name));
-+		    } else {
-+			TRACE_((THIS_FILE, "Hash entry deleted after "
-+					   "transport %d being destroyed",
-+					   tp->obj_name));
- 		    }
- 		}
- 
-@@ -1294,6 +1323,14 @@ static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
- 	    }
- 	    tp_iter = tp_iter->next;
- 	} while (tp_iter != tp_ref);
-+
-+	if (tp_iter->tp != tp) {
-+	    PJ_LOG(3, (THIS_FILE, "Warning: transport %s being destroyed is "
-+				  "not registered", tp->obj_name));
-+	}
-+    } else {
-+	PJ_LOG(3, (THIS_FILE, "Warning: transport %s being destroyed is "
-+			      "not found in the hash table", tp->obj_name));
-     }
- 
-     pj_lock_release(mgr->lock);
-@@ -2159,6 +2196,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
- 					  NULL, tp);
- }
- 
-+
- /*
-  * pjsip_tpmgr_acquire_transport2()
-  *
-@@ -2176,8 +2214,9 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
-     pjsip_tpfactory *factory;
-     pj_status_t status;
- 
--    TRACE_((THIS_FILE,"Acquiring transport type=%s, remote=%s:%d",
-+    TRACE_((THIS_FILE,"Acquiring transport type=%s, sel=%s remote=%s:%d",
- 		       pjsip_transport_get_type_name(type),
-+		       print_tpsel_info(sel),
- 		       addr_string(remote),
- 		       pj_sockaddr_get_port(remote)));
- 
-@@ -2194,6 +2233,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- 	/* See if the transport is (not) suitable */
- 	if (seltp->key.type != type) {
- 	    pj_lock_release(mgr->lock);
-+	    TRACE_((THIS_FILE, "Transport type in tpsel not matched"));
- 	    return PJSIP_ETPNOTSUITABLE;
- 	}
- 
-@@ -2234,6 +2274,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- 	{
- 	    if (sel->u.listener->type != type) {
- 		pj_lock_release(mgr->lock);
-+		TRACE_((THIS_FILE, "Listener type in tpsel not matched"));
- 		return PJSIP_ETPNOTSUITABLE;
- 	    }
- 	}
-@@ -2249,21 +2290,25 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- 	    tp_entry = (transport *)pj_hash_get(mgr->table, &key, key_len,
- 						NULL);
- 	    if (tp_entry) {
--		if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER) {
--		    transport *tp_iter = tp_entry;
--		    do {
-+		transport *tp_iter = tp_entry;
-+		do {
-+		    /* Don't use transport being shutdown */
-+		    if (!tp_iter->tp->is_shutdown) {
- 			if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
--			    sel->u.listener &&
--			    tp_iter->tp->factory == sel->u.listener)
-+			    sel->u.listener)
- 			{
-+			    /* Match listener if selector is set */
-+			    if (tp_iter->tp->factory == sel->u.listener) {
-+				tp_ref = tp_iter->tp;
-+				break;
-+			    }
-+			} else {
- 			    tp_ref = tp_iter->tp;
- 			    break;
- 			}
--			tp_iter = tp_iter->next;
--		    } while (tp_iter != tp_entry);
--		} else {
--		    tp_ref = tp_entry->tp;
--		}
-+		    }
-+		    tp_iter = tp_iter->next;
-+		} while (tp_iter != tp_entry);
- 	    }
- 	}
- 
-@@ -2276,7 +2321,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- 
- 	    /* Ignore address for loop transports. */
- 	    if (type == PJSIP_TRANSPORT_LOOP ||
--		     type == PJSIP_TRANSPORT_LOOP_DGRAM)
-+		type == PJSIP_TRANSPORT_LOOP_DGRAM)
- 	    {
- 		pj_sockaddr *addr = &key.rem_addr;
- 
-@@ -2315,6 +2360,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- 	     * 'duplicate' of the existing transport (same type & remote addr,
- 	     * but different factory).
- 	     */
-+	    TRACE_((THIS_FILE, "Transport found but from different listener"));
- 	}
- 
- 	if (tp_ref!=NULL && !tp_ref->is_shutdown) {
-@@ -2347,10 +2393,13 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- 	     */
- 
- 	    /* Verify that the listener type matches the destination type */
-+	    /* Already checked above. */
-+	    /*
- 	    if (sel->u.listener->type != type) {
- 		pj_lock_release(mgr->lock);
- 		return PJSIP_ETPNOTSUITABLE;
- 	    }
-+	    */
- 
- 	    /* We'll use this listener to create transport */
- 	    factory = sel->u.listener;
--- 
-2.21.0
-
diff --git a/third-party/pjproject/patches/0040-ICE-Add-callback-for-finding-valid-pair.patch b/third-party/pjproject/patches/0040-ICE-Add-callback-for-finding-valid-pair.patch
deleted file mode 100644
index 062e75e..0000000
--- a/third-party/pjproject/patches/0040-ICE-Add-callback-for-finding-valid-pair.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 8b8199180766e3eab6014feaa64ccaedcdc12816 Mon Sep 17 00:00:00 2001
-From: Ben Ford <bford at digium.com>
-Date: Mon, 23 Dec 2019 11:11:13 -0600
-Subject: [PATCH] ICE: Add callback for finding valid pair.
-
-It's possible to start sending as soon as one valid pair is found during
-ICE negotiation. The reason we would want to do this is because it is
-possible for a delay to occur at the start of a call for up to 3 seconds
-until ICE negotiation has actually completed. More information can be
-found here:
-https://bugs.chromium.org/p/chromium/issues/detail?id=1024096
-
-This patch adds a callback once a valid pair is found that applications
-can use to start sending to avoid this scenario. Since only one valid
-pair is needed to start media, we only trigger the callback once.
----
- pjnath/include/pjnath/ice_session.h |  9 +++++++++
- pjnath/src/pjnath/ice_session.c     | 16 ++++++++++++++++
- 2 files changed, 25 insertions(+)
-
-diff --git a/pjnath/include/pjnath/ice_session.h b/pjnath/include/pjnath/ice_session.h
-index 15f0d04..8971220 100644
---- a/pjnath/include/pjnath/ice_session.h
-+++ b/pjnath/include/pjnath/ice_session.h
-@@ -468,6 +468,14 @@ typedef struct pj_ice_sess_cb
- {
-     /**
-      * An optional callback that will be called by the ICE session when
-+     * a valid pair has been found during ICE negotiation.
-+     *
-+     * @param ice           The ICE session.
-+     */
-+    void	(*on_valid_pair)(pj_ice_sess *ice);
-+
-+    /**
-+     * An optional callback that will be called by the ICE session when
-      * ICE negotiation has completed, successfully or with failure.
-      *
-      * @param ice	    The ICE session.
-@@ -625,6 +633,7 @@ struct pj_ice_sess
-     pj_bool_t		 is_nominating;		    /**< Nominating stage   */
-     pj_bool_t		 is_complete;		    /**< Complete?	    */
-     pj_bool_t		 is_destroying;		    /**< Destroy is called  */
-+    pj_bool_t            valid_pair_found;          /**< First pair found   */
-     pj_status_t		 ice_status;		    /**< Error status.	    */
-     pj_timer_entry	 timer;			    /**< ICE timer.	    */
-     pj_ice_sess_cb	 cb;			    /**< Callback.	    */
-diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c
-index c51dba7..ed4138a 100644
---- a/pjnath/src/pjnath/ice_session.c
-+++ b/pjnath/src/pjnath/ice_session.c
-@@ -418,6 +418,8 @@ PJ_DEF(pj_status_t) pj_ice_sess_create(pj_stun_config *stun_cfg,
- 
-     pj_list_init(&ice->early_check);
- 
-+    ice->valid_pair_found = PJ_FALSE;
-+
-     /* Done */
-     *p_ice = ice;
- 
-@@ -1348,6 +1350,20 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice,
- 	     GET_CHECK_ID(&ice->clist, check),
- 	     (check->nominated ? "  and nominated" : "")));
- 
-+	{
-+	    /* On the first valid pair, we call the callback, if present */
-+	    if (ice->valid_pair_found == PJ_FALSE) {
-+	        void (*on_valid_pair)(pj_ice_sess *ice);
-+
-+		ice->valid_pair_found = PJ_TRUE;
-+	        on_valid_pair = ice->cb.on_valid_pair;
-+
-+	        if (on_valid_pair) {
-+		    (*on_valid_pair)(ice);
-+	        }
-+	    }
-+	}
-+
-     }
- 
-     /* 8.2.  Updating States
--- 
-2.7.4
-
diff --git a/third-party/pjproject/patches/0040-brackets-in-via-received-params.patch b/third-party/pjproject/patches/0040-brackets-in-via-received-params.patch
deleted file mode 100644
index bf96d3d..0000000
--- a/third-party/pjproject/patches/0040-brackets-in-via-received-params.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 6324760c2fb0ffeb2e29c6c0a96a33906caa8d5f Mon Sep 17 00:00:00 2001
-From: Sean Bright <sean.bright at gmail.com>
-Date: Thu, 16 Jan 2020 10:46:11 -0500
-Subject: [PATCH] sip_parser.c: Allow brackets in via parameters
-
-From RFC 5118 section 4.5:
-
-  While it would be beneficial if the same non-terminal
-  ("IPv6reference") was used for both the "sent-by" and "via-received"
-  production rules, there has not been a consensus in the working group
-  to that effect.  Thus, the best that can be suggested is that
-  implementations must follow the Robustness Principle [RFC1122] and be
-  liberal in accepting a "received" parameter with or without the
-  delimiting "[" and "]" tokens.  When sending a request,
-  implementations must not put the delimiting "[" and "]" tokens.
----
- pjsip/src/pjsip/sip_parser.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
-index e01e672fb..4f9c7fca4 100644
---- a/pjsip/src/pjsip/sip_parser.c
-+++ b/pjsip/src/pjsip/sip_parser.c
-@@ -384,11 +384,11 @@ static pj_status_t init_parser()
- 
-     status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC, &pconst.pjsip_TOKEN_SPEC);
-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
--    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":");
-+    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, "[:]");
- 
-     status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC);
-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
--    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC_ESC, ":");
-+    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC_ESC, "[:]");
- 
-     status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC);
-     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
--- 
-2.20.1
-
diff --git a/third-party/pjproject/pjproject-2.10.tar.bz2.md5 b/third-party/pjproject/pjproject-2.10.tar.bz2.md5
new file mode 100644
index 0000000..57261b4
--- /dev/null
+++ b/third-party/pjproject/pjproject-2.10.tar.bz2.md5
@@ -0,0 +1,2 @@
+5d0202f79a7aeb14873c45b0e4c14a70 *pjproject-2.10.zip
+4fffc49b461133f0a4143b05a22fb30e  pjproject-2.10.tar.bz2
diff --git a/third-party/pjproject/pjproject-2.9.tar.bz2.md5 b/third-party/pjproject/pjproject-2.9.tar.bz2.md5
deleted file mode 100644
index 5e11195..0000000
--- a/third-party/pjproject/pjproject-2.9.tar.bz2.md5
+++ /dev/null
@@ -1,2 +0,0 @@
-e4ec23a6bfa06fb53c313aa7fed81236 *pjproject-2.9.zip
-66757078e7bd7cf316acb0425c2fdd6f  pjproject-2.9.tar.bz2
\ No newline at end of file
diff --git a/third-party/versions.mak b/third-party/versions.mak
index 103ac58..fae41c6 100644
--- a/third-party/versions.mak
+++ b/third-party/versions.mak
@@ -1,2 +1,2 @@
 JANSSON_VERSION = 2.12
-PJPROJECT_VERSION = 2.9
+PJPROJECT_VERSION = 2.10

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/14551
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Iec8821c6cbbc08c369d0e3cd2f14e691b41d0c81
Gerrit-Change-Number: 14551
Gerrit-PatchSet: 2
Gerrit-Owner: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at sangoma.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20200616/217b8ccc/attachment-0001.html>


More information about the asterisk-code-review mailing list