summaryrefslogtreecommitdiff
path: root/third-party/pjproject
diff options
context:
space:
mode:
Diffstat (limited to 'third-party/pjproject')
-rw-r--r--third-party/pjproject/.gitignore4
-rw-r--r--third-party/pjproject/Makefile110
-rw-r--r--third-party/pjproject/Makefile.rules7
-rwxr-xr-xthird-party/pjproject/apply_patches39
-rw-r--r--third-party/pjproject/configure.m446
-rw-r--r--third-party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch224
-rw-r--r--third-party/pjproject/patches/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch70
-rw-r--r--third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch80
-rw-r--r--third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch114
-rw-r--r--third-party/pjproject/patches/config_site.h34
-rw-r--r--third-party/pjproject/patches/user.mak2
11 files changed, 730 insertions, 0 deletions
diff --git a/third-party/pjproject/.gitignore b/third-party/pjproject/.gitignore
new file mode 100644
index 000000000..5079deeb3
--- /dev/null
+++ b/third-party/pjproject/.gitignore
@@ -0,0 +1,4 @@
+source/
+**.bz2
+build.mak
+pjproject.symbols
diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile
new file mode 100644
index 000000000..310095159
--- /dev/null
+++ b/third-party/pjproject/Makefile
@@ -0,0 +1,110 @@
+.SUFFIXES:
+.PHONY: _all all _install install clean distclean echo_cflags configure
+
+ifeq ($(MAKECMDGOALS),install)
+include ../../makeopts
+else
+-include ../../makeopts
+endif
+
+include ../versions.mak
+include ../Makefile.rules
+include Makefile.rules
+
+ECHO_PREFIX := $(ECHO_PREFIX) echo '[pjproject] '
+
+ifeq ($(MAKECMDGOALS),echo_cflags)
+-include build.mak
+ECHO_PREFIX=@\#
+endif
+
+ifneq ($(PJPROJECT_BUNDLED),yes)
+all install:
+ @echo '[pjproject] Not enabled'
+else
+
+ifneq ($(findstring clean,$(MAKECMDGOALS)),clean)
+include build.mak
+endif
+
+all: _all
+install: _install
+endif
+
+ifndef $(TMPDIR)
+ifneq ($(wildcard /tmp),)
+TMPDIR=/tmp
+else
+TMPDIR=.
+endif
+endif
+
+$(TMPDIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2 : ../versions.mak
+ $(ECHO_PREFIX) Downloading $@ with $(DOWNLOAD)
+ $(CMD_PREFIX) $(DOWNLOAD) $(PJPROJECT_URL)/$(@F) > $@
+
+source/user.mak source/pjlib/include/pj/config_site.h: $(TMPDIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2 patches/config_site.h patches/user.mak
+ $(ECHO_PREFIX) Unpacking $<
+ -@rm -rf source &>/dev/null
+ -@mkdir source &>/dev/null
+ $(CMD_PREFIX) tar --strip-components=1 -C source -xjf $<
+ $(ECHO_PREFIX) Applying patches and custom files
+ $(CMD_PREFIX) ./apply_patches $(QUIET_CONFIGURE) ./patches ./source
+ $(CMD_PREFIX) cp -f ./patches/config_site.h ./source/pjlib/include/pj/
+ $(CMD_PREFIX) cp -f ./patches/user.mak ./source/
+
+build.mak: source/pjlib/include/pj/config_site.h source/user.mak Makefile.rules
+ $(ECHO_PREFIX) Configuring with $(PJPROJECT_CONFIG_OPTS)
+ $(CMD_PREFIX) (cd source ; autoconf aconfigure.ac > aconfigure && ./aconfigure $(QUIET_CONFIGURE) $(PJPROJECT_CONFIG_OPTS))
+ @sed -r -e "/prefix|export PJ_SHARED_LIBRARIES|MACHINE_NAME|OS_NAME|HOST_NAME|CC_NAME|CROSS_COMPILE|LINUX_POLL/d" source/build.mak > build.mak
+
+configure: build.mak
+
+echo_cflags: build.mak
+ @echo $(PJ_CFLAGS)
+
+source/pjlib/build/.pjlib-$(TARGET_NAME).depend: build.mak
+ $(ECHO_PREFIX) "Making dependencies"
+ +$(CMD_PREFIX) $(SUBMAKE) -C source dep
+
+source/pjlib/lib/libpj-$(TARGET_NAME).a: source/pjlib/build/.pjlib-$(TARGET_NAME).depend
+ $(ECHO_PREFIX) Compiling libs
+ +$(CMD_PREFIX) $(SUBMAKE) -C source lib $(REALLY_QUIET)
+
+pjproject.symbols: source/pjlib/lib/libpj-$(TARGET_NAME).a
+ $(ECHO_PREFIX) Generating symbols
+ $(CMD_PREFIX) nm -Pog $(PJ_LIB_FILES) | sed -n -r -e "s/.+: ([pP][jJ][^ ]+) .+/\1/gp" | sort -u > pjproject.symbols
+
+source/pjsip-apps/bin/pjsua-$(TARGET_NAME): source/pjlib/lib/libpj-$(TARGET_NAME).a
+ $(ECHO_PREFIX) Compiling apps
+ $(CMD_PREFIX) $(SUBMAKE) -C source/pjsip-apps/build pjsua pjsystest $(REALLY_QUIET)
+
+source/pjsip-apps/src/python/build/_pjsua.so: source/pjlib/lib/libpj-$(TARGET_NAME).a
+ $(ECHO_PREFIX) Compiling python bindings
+ $(CMD_PREFIX) (cd source/pjsip-apps/src/python ; python setup.py build --build-platlib=./build $(REALLY_QUIET))
+
+_all: pjproject.symbols source/pjsip-apps/bin/pjsua-$(TARGET_NAME) source/pjsip-apps/src/python/build/_pjsua.so
+
+_install: _all
+ $(ECHO_PREFIX) Installing apps and python bindings
+ @if [ ! -d "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject" ]; then \
+ $(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject"; \
+ fi;
+ $(CMD_PREFIX) $(INSTALL) -m 755 source/pjsip-apps/bin/pjsua-$(TARGET_NAME) "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/pjsua"
+ $(CMD_PREFIX) $(INSTALL) -m 755 source/pjsip-apps/bin/pjsystest-$(TARGET_NAME) "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/pjsystest"
+ $(CMD_PREFIX) $(INSTALL) -m 755 source/pjsip-apps/src/python/build/_pjsua.so "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/"
+ $(CMD_PREFIX) $(INSTALL) -m 644 source/pjsip-apps/src/python/build/pjsua.py "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject/"
+
+uninstall:
+ $(ECHO_PREFIX) Uninstalling apps and python bindings
+ $(CMD_PREFIX) rm -rf "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject"
+
+clean:
+ $(ECHO_PREFIX) Cleaning
+ -$(CMD_PREFIX) test -d source && ($(SUBMAKE) -C source clean ; find source -name *.a -delete ; rm -rf source/pjsip-apps/src/python/build) || :
+ -$(CMD_PREFIX) rm -rf pjproject.symbols
+
+distclean:
+ $(ECHO_PREFIX) Distcleaning
+ -$(CMD_PREFIX) rm -rf source pjproject.symbols pjproject-*.tar.bz2 build.mak
+
diff --git a/third-party/pjproject/Makefile.rules b/third-party/pjproject/Makefile.rules
new file mode 100644
index 000000000..d6e4be00b
--- /dev/null
+++ b/third-party/pjproject/Makefile.rules
@@ -0,0 +1,7 @@
+PJPROJECT_URL = http://www.pjsip.org/release/$(PJPROJECT_VERSION)
+
+# Even though we're not installing pjproject, we're setting prefix to /opt/pjproject to be safe
+PJPROJECT_CONFIG_OPTS = --prefix=/opt/pjproject --with-external-speex --with-external-gsm --with-external-srtp \
+ --with-external-pa --disable-video --disable-v4l2 --disable-sound --disable-resample \
+ --disable-opencore-amr --disable-ilbc-codec --without-libyuv --disable-g7221-codec \
+ --enable-epoll
diff --git a/third-party/pjproject/apply_patches b/third-party/pjproject/apply_patches
new file mode 100755
index 000000000..1b72d14b0
--- /dev/null
+++ b/third-party/pjproject/apply_patches
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+if [ "$1" = "-q" ] ; then
+ quiet=1
+ shift
+fi
+
+patchdir=${1:?You must supply a patches directory}
+sourcedir=${2?:You must supply a source directory}
+
+patchdir=`readlink -f $patchdir`
+sourcedir=`readlink -f $sourcedir`
+
+if [ ! -d "$patchdir" ] ; then
+ echo "$patchdir is not a directory" >&2
+ exit 1
+fi
+
+if [ ! -d "$sourcedir" ] ; then
+ echo "$sourcedir is not a directory" >&2
+ exit 1
+fi
+
+if [ ! "$(ls -A $patchdir/*.patch 2>/dev/null)" ] ; then
+ echo "No patches in $patchdir" >&2
+ exit 0
+fi
+
+for patchfile in $patchdir/*.patch ; do
+ patch -d $sourcedir -p1 -s -r- -f -N --dry-run -i "$patchfile" || (echo "Patchfile $(basename $patchfile) failed to apply >&2" ; exit 1) || exit 1
+done
+
+for patchfile in "$patchdir"/*.patch ; do
+ [ -z $quiet ] && echo "Applying patch $(basename $patchfile)"
+ patch -d "$sourcedir" -p1 -s -i "$patchfile" || exit 1
+done
+
+exit 0
+
diff --git a/third-party/pjproject/configure.m4 b/third-party/pjproject/configure.m4
new file mode 100644
index 000000000..3351527eb
--- /dev/null
+++ b/third-party/pjproject/configure.m4
@@ -0,0 +1,46 @@
+AC_DEFUN([PJPROJECT_SYMBOL_CHECK],
+[
+ $1_INCLUDE="$PJPROJECT_INCLUDE"
+ AC_MSG_CHECKING([for $2 declared in $3])
+
+ saved_cpp="$CPPFLAGS"
+ CPPFLAGS="$PJPROJECT_INCLUDE"
+ AC_EGREP_HEADER($2, $3, [
+ AC_MSG_RESULT(yes)
+ PBX_$1=1
+ AC_DEFINE([HAVE_$1], 1, [Define if your system has $2 declared.])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+
+ CPPGLAGS="$saved_cpp"
+ $1_INCLUDE="$PJPROJECT_INCLUDE"
+])
+
+AC_DEFUN([PJPROJECT_CONFIGURE],
+[
+ AC_MSG_CHECKING(for embedded pjproject (may have to download))
+ AC_MSG_RESULT(configuring)
+ make --quiet --no-print-directory -C $1 configure
+ if test $? -ne 0 ; then
+ AC_MSG_RESULT(failed)
+ AC_MSG_NOTICE(Unable to configure $1)
+ AC_MSG_ERROR(Run "make -C $1 NOISY_BUILD=yes configure" to see error details.)
+ fi
+
+ PJPROJECT_INCLUDE=$(make --quiet --no-print-directory -C $1 echo_cflags)
+ PJPROJECT_CFLAGS="$PJPROJECT_INCLUDE"
+ PBX_PJPROJECT=1
+ PJPROJECT_BUNDLED=yes
+ AC_DEFINE([HAVE_PJPROJECT], 1, [Define if your system has PJPROJECT])
+ AC_DEFINE([HAVE_PJPROJECT_BUNDLED], 1, [Define if your system has PJPROJECT_BUNDLED])
+ AC_MSG_CHECKING(for embedded pjproject)
+ AC_MSG_RESULT(yes)
+
+ PJPROJECT_SYMBOL_CHECK([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [pjsip_dlg_create_uas_and_inc_lock], [pjsip.h])
+ PJPROJECT_SYMBOL_CHECK([PJ_TRANSACTION_GRP_LOCK], [pjsip_tsx_create_uac2], [pjsip.h])
+ PJPROJECT_SYMBOL_CHECK([PJSIP_REPLACE_MEDIA_STREAM], [PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE], [pjmedia.h])
+ PJPROJECT_SYMBOL_CHECK([PJSIP_GET_DEST_INFO], [pjsip_get_dest_info], [pjsip.h])
+ PJPROJECT_SYMBOL_CHECK([PJ_SSL_CERT_LOAD_FROM_FILES2], [pj_ssl_cert_load_from_files2], [pjlib.h])
+ PJPROJECT_SYMBOL_CHECK([PJSIP_EXTERNAL_RESOLVER], [pjsip_endpt_set_ext_resolver], [pjsip.h])
+])
diff --git a/third-party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch b/third-party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch
new file mode 100644
index 000000000..33fc8ea4e
--- /dev/null
+++ b/third-party/pjproject/patches/0001-2.4.5-fix-for-tls-async-ops.patch
@@ -0,0 +1,224 @@
+diff --git a/pjlib/include/pj/ssl_sock.h b/pjlib/include/pj/ssl_sock.h
+index 1682bda..a69af32 100644
+--- a/pjlib/include/pj/ssl_sock.h
++++ b/pjlib/include/pj/ssl_sock.h
+@@ -864,6 +864,18 @@ PJ_DECL(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param);
+
+
+ /**
++ * Duplicate pj_ssl_sock_param.
++ *
++ * @param pool Pool to allocate memory.
++ * @param dst Destination parameter.
++ * @param src Source parameter.
++ */
++PJ_DECL(void) pj_ssl_sock_param_copy(pj_pool_t *pool,
++ pj_ssl_sock_param *dst,
++ const pj_ssl_sock_param *src);
++
++
++/**
+ * Create secure socket instance.
+ *
+ * @param pool The pool for allocating secure socket instance.
+@@ -1115,6 +1127,30 @@ PJ_DECL(pj_status_t) pj_ssl_sock_start_accept(pj_ssl_sock_t *ssock,
+
+
+ /**
++ * Same as #pj_ssl_sock_start_accept(), but application can provide
++ * a secure socket parameter, which will be used to create a new secure
++ * socket reported in \a on_accept_complete() callback when there is
++ * an incoming connection.
++ *
++ * @param ssock The secure socket.
++ * @param pool Pool used to allocate some internal data for the
++ * operation.
++ * @param localaddr Local address to bind on.
++ * @param addr_len Length of buffer containing local address.
++ * @param newsock_param Secure socket parameter for new accepted sockets.
++ *
++ * @return PJ_SUCCESS if the operation has been successful,
++ * or the appropriate error code on failure.
++ */
++PJ_DECL(pj_status_t)
++pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
++ pj_pool_t *pool,
++ const pj_sockaddr_t *local_addr,
++ int addr_len,
++ const pj_ssl_sock_param *newsock_param);
++
++
++/**
+ * Starts asynchronous socket connect() operation and SSL/TLS handshaking
+ * for this socket. Once the connection is done (either successfully or not),
+ * the \a on_connect_complete() callback will be called.
+diff --git a/pjlib/src/pj/ssl_sock_common.c b/pjlib/src/pj/ssl_sock_common.c
+index 913efee..717ab1d 100644
+--- a/pjlib/src/pj/ssl_sock_common.c
++++ b/pjlib/src/pj/ssl_sock_common.c
+@@ -19,6 +19,7 @@
+ #include <pj/ssl_sock.h>
+ #include <pj/assert.h>
+ #include <pj/errno.h>
++#include <pj/pool.h>
+ #include <pj/string.h>
+
+ /*
+@@ -48,6 +49,31 @@ PJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param)
+ }
+
+
++/*
++ * Duplicate SSL socket parameter.
++ */
++PJ_DEF(void) pj_ssl_sock_param_copy( pj_pool_t *pool,
++ pj_ssl_sock_param *dst,
++ const pj_ssl_sock_param *src)
++{
++ /* Init secure socket param */
++ pj_memcpy(dst, src, sizeof(*dst));
++ if (src->ciphers_num > 0) {
++ unsigned i;
++ dst->ciphers = (pj_ssl_cipher*)
++ pj_pool_calloc(pool, src->ciphers_num,
++ sizeof(pj_ssl_cipher));
++ for (i = 0; i < src->ciphers_num; ++i)
++ dst->ciphers[i] = src->ciphers[i];
++ }
++
++ if (src->server_name.slen) {
++ /* Server name must be null-terminated */
++ pj_strdup_with_null(pool, &dst->server_name, &src->server_name);
++ }
++}
++
++
+ PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(
+ pj_uint32_t verify_status,
+ const char *error_strings[],
+diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
+index 40a5a1e..6a701b7 100644
+--- a/pjlib/src/pj/ssl_sock_ossl.c
++++ b/pjlib/src/pj/ssl_sock_ossl.c
+@@ -141,6 +141,7 @@ struct pj_ssl_sock_t
+ pj_pool_t *pool;
+ pj_ssl_sock_t *parent;
+ pj_ssl_sock_param param;
++ pj_ssl_sock_param newsock_param;
+ pj_ssl_cert_t *cert;
+
+ pj_ssl_cert_info local_cert_info;
+@@ -1757,11 +1758,9 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
+ unsigned i;
+ pj_status_t status;
+
+- PJ_UNUSED_ARG(src_addr_len);
+-
+ /* Create new SSL socket instance */
+- status = pj_ssl_sock_create(ssock_parent->pool, &ssock_parent->param,
+- &ssock);
++ status = pj_ssl_sock_create(ssock_parent->pool,
++ &ssock_parent->newsock_param, &ssock);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+@@ -2183,20 +2182,8 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
+ return status;
+
+ /* Init secure socket param */
+- ssock->param = *param;
++ pj_ssl_sock_param_copy(pool, &ssock->param, param);
+ ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;
+- if (param->ciphers_num > 0) {
+- unsigned i;
+- ssock->param.ciphers = (pj_ssl_cipher*)
+- pj_pool_calloc(pool, param->ciphers_num,
+- sizeof(pj_ssl_cipher));
+- for (i = 0; i < param->ciphers_num; ++i)
+- ssock->param.ciphers[i] = param->ciphers[i];
+- }
+-
+- /* Server name must be null-terminated */
+- pj_strdup_with_null(pool, &ssock->param.server_name,
+- &param->server_name);
+
+ /* Finally */
+ *p_ssock = ssock;
+@@ -2617,12 +2604,36 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,
+ const pj_sockaddr_t *localaddr,
+ int addr_len)
+ {
++ return pj_ssl_sock_start_accept2(ssock, pool, localaddr, addr_len,
++ &ssock->param);
++}
++
++
++/**
++ * Same as #pj_ssl_sock_start_accept(), but application provides parameter
++ * for new accepted secure sockets.
++ */
++PJ_DEF(pj_status_t)
++pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
++ pj_pool_t *pool,
++ const pj_sockaddr_t *localaddr,
++ int addr_len,
++ const pj_ssl_sock_param *newsock_param)
++{
+ pj_activesock_cb asock_cb;
+ pj_activesock_cfg asock_cfg;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL);
+
++ /* Verify new socket parameters */
++ if (newsock_param->grp_lock != ssock->param.grp_lock ||
++ newsock_param->sock_af != ssock->param.sock_af ||
++ newsock_param->sock_type != ssock->param.sock_type)
++ {
++ return PJ_EINVAL;
++ }
++
+ /* Create socket */
+ status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0,
+ &ssock->sock);
+@@ -2691,6 +2702,7 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,
+ goto on_error;
+
+ /* Start accepting */
++ pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param);
+ status = pj_activesock_start_accept(ssock->asock, pool);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
+index a9e95fb..91d99a7 100644
+--- a/pjsip/src/pjsip/sip_transport_tls.c
++++ b/pjsip/src/pjsip/sip_transport_tls.c
+@@ -314,7 +314,7 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
+ int af, sip_ssl_method;
+ pj_uint32_t sip_ssl_proto;
+ struct tls_listener *listener;
+- pj_ssl_sock_param ssock_param;
++ pj_ssl_sock_param ssock_param, newsock_param;
+ pj_sockaddr *listener_addr;
+ pj_bool_t has_listener;
+ pj_status_t status;
+@@ -473,9 +473,14 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start2( pjsip_endpoint *endpt,
+ */
+ has_listener = PJ_FALSE;
+
+- status = pj_ssl_sock_start_accept(listener->ssock, pool,
++ pj_memcpy(&newsock_param, &ssock_param, sizeof(newsock_param));
++ newsock_param.async_cnt = 1;
++ newsock_param.cb.on_data_read = &on_data_read;
++ newsock_param.cb.on_data_sent = &on_data_sent;
++ status = pj_ssl_sock_start_accept2(listener->ssock, pool,
+ (pj_sockaddr_t*)listener_addr,
+- pj_sockaddr_get_len((pj_sockaddr_t*)listener_addr));
++ pj_sockaddr_get_len((pj_sockaddr_t*)listener_addr),
++ &newsock_param);
+ if (status == PJ_SUCCESS || status == PJ_EPENDING) {
+ pj_ssl_sock_info info;
+ has_listener = PJ_TRUE;
+--
+cgit v0.11.2
+
diff --git a/third-party/pjproject/patches/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch b/third-party/pjproject/patches/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch
new file mode 100644
index 000000000..9873abf0e
--- /dev/null
+++ b/third-party/pjproject/patches/0001-Bump-tcp-tls-and-transaction-log-levels-from-1-to-3.patch
@@ -0,0 +1,70 @@
+From a147b72df1ec150c1d733e882225db86142fb339 Mon Sep 17 00:00:00 2001
+From: George Joseph <george.joseph@fairview5.com>
+Date: Sun, 21 Feb 2016 10:01:53 -0700
+Subject: [PATCH] Bump tcp/tls and transaction log levels from 1 to 3
+
+sip_transport_tcp, sip_transport_tls and sip_transaction are printing messages
+at log level 1 or 2 for things that are transient, recoverable, possibly
+expected, or are handled with return codes. A good example of this is if we're
+trying to send an OPTIONS message to a TCP client that has disappeared. Both
+sip_transport_tcp and sip_transaction are printing "connection refused"
+messages because the remote client isn't listening. This is generally expected
+behavior and it should be up to the app caller to determine if an error message
+is warranted.
+---
+ pjsip/src/pjsip/sip_transaction.c | 4 ++--
+ pjsip/src/pjsip/sip_transport_tcp.c | 2 +-
+ pjsip/src/pjsip/sip_transport_tls.c | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
+index 46bd971..1b4fdb7 100644
+--- a/pjsip/src/pjsip/sip_transaction.c
++++ b/pjsip/src/pjsip/sip_transaction.c
+@@ -1898,7 +1898,7 @@ static void send_msg_callback( pjsip_send_state *send_state,
+
+ err =pj_strerror((pj_status_t)-sent, errmsg, sizeof(errmsg));
+
+- PJ_LOG(2,(tsx->obj_name,
++ PJ_LOG(3,(tsx->obj_name,
+ "Failed to send %s! err=%d (%s)",
+ pjsip_tx_data_get_info(send_state->tdata), -sent,
+ errmsg));
+@@ -1938,7 +1938,7 @@ static void send_msg_callback( pjsip_send_state *send_state,
+ }
+
+ } else {
+- PJ_PERROR(2,(tsx->obj_name, (pj_status_t)-sent,
++ PJ_PERROR(3,(tsx->obj_name, (pj_status_t)-sent,
+ "Temporary failure in sending %s, "
+ "will try next server",
+ pjsip_tx_data_get_info(send_state->tdata)));
+diff --git a/pjsip/src/pjsip/sip_transport_tcp.c b/pjsip/src/pjsip/sip_transport_tcp.c
+index 222cb13..1bbb324 100644
+--- a/pjsip/src/pjsip/sip_transport_tcp.c
++++ b/pjsip/src/pjsip/sip_transport_tcp.c
+@@ -164,7 +164,7 @@ static void tcp_perror(const char *sender, const char *title,
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+
+- PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
++ PJ_LOG(3,(sender, "%s: %s [code=%d]", title, errmsg, status));
+ }
+
+
+diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
+index 617d7f5..a83ac32 100644
+--- a/pjsip/src/pjsip/sip_transport_tls.c
++++ b/pjsip/src/pjsip/sip_transport_tls.c
+@@ -170,7 +170,7 @@ static void tls_perror(const char *sender, const char *title,
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+
+- PJ_LOG(1,(sender, "%s: %s [code=%d]", title, errmsg, status));
++ PJ_LOG(3,(sender, "%s: %s [code=%d]", title, errmsg, status));
+ }
+
+
+--
+2.5.0
+
diff --git a/third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch b/third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch
new file mode 100644
index 000000000..36b6c651f
--- /dev/null
+++ b/third-party/pjproject/patches/0001-ioqueue-Enable-epoll-in-aconfigure.ac.patch
@@ -0,0 +1,80 @@
+From b5c0bc905911f75e08987e6833075481fe16dab2 Mon Sep 17 00:00:00 2001
+From: George Joseph <george.joseph@fairview5.com>
+Date: Mon, 22 Feb 2016 13:05:59 -0700
+Subject: [PATCH] ioqueue: Enable epoll in aconfigure.ac
+
+Although the --enable-epoll option was being accepted, the result
+was always forced to select. This patch updates aconfigure.ac
+to properly set the value of ac_linux_poll if --enable-epoll is
+specified.
+---
+ README.txt | 1 +
+ aconfigure | 11 +++++++----
+ aconfigure.ac | 7 +++++--
+ pjlib/include/pj/compat/os_auto.h.in | 3 +++
+ 4 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/README.txt b/README.txt
+index bc45da8..48415fd 100644
+--- a/README.txt
++++ b/README.txt
+@@ -463,6 +463,7 @@ Using Default Settings
+ $ ./configure --help
+ ...
+ Optional Features:
++ --enable-epoll Use epoll on Linux instead of select
+ --disable-floating-point Disable floating point where possible
+ --disable-sound Exclude sound (i.e. use null sound)
+ --disable-small-filter Exclude small filter in resampling
+diff --git a/aconfigure.ac b/aconfigure.ac
+index 2f71abb..3e88124 100644
+--- a/aconfigure.ac
++++ b/aconfigure.ac
+@@ -410,6 +410,7 @@ dnl ######################
+ dnl # ioqueue selection
+ dnl #
+ AC_SUBST(ac_os_objs)
++AC_SUBST(ac_linux_poll)
+ AC_MSG_CHECKING([ioqueue backend])
+ AC_ARG_ENABLE(epoll,
+ AC_HELP_STRING([--enable-epoll],
+@@ -417,10 +418,13 @@ AC_ARG_ENABLE(epoll,
+ [
+ ac_os_objs=ioqueue_epoll.o
+ AC_MSG_RESULT([/dev/epoll])
++ AC_DEFINE(PJ_HAS_LINUX_EPOLL,1)
++ ac_linux_poll=epoll
+ ],
+ [
+ ac_os_objs=ioqueue_select.o
+- AC_MSG_RESULT([select()])
++ AC_MSG_RESULT([select()])
++ ac_linux_poll=select
+ ])
+
+ AC_SUBST(ac_shared_libraries)
+@@ -1879,7 +1883,6 @@ esac
+
+
+ AC_SUBST(target)
+-AC_SUBST(ac_linux_poll,select)
+ AC_SUBST(ac_host,unix)
+ AC_SUBST(ac_main_obj)
+ case $target in
+diff --git a/pjlib/include/pj/compat/os_auto.h.in b/pjlib/include/pj/compat/os_auto.h.in
+index 77980d3..c8e73b2 100644
+--- a/pjlib/include/pj/compat/os_auto.h.in
++++ b/pjlib/include/pj/compat/os_auto.h.in
+@@ -128,6 +128,9 @@
+ */
+ #undef PJ_SELECT_NEEDS_NFDS
+
++/* Was Linux epoll support enabled */
++#undef PJ_HAS_LINUX_EPOLL
++
+ /* Is errno a good way to retrieve OS errors?
+ */
+ #undef PJ_HAS_ERRNO_VAR
+--
+2.5.0
+
diff --git a/third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch b/third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch
new file mode 100644
index 000000000..001912cfe
--- /dev/null
+++ b/third-party/pjproject/patches/0001-sip_transport-Search-for-transport-even-if-listener-.patch
@@ -0,0 +1,114 @@
+From 552194179eb6deae8326eb0fef446e69240ea41b Mon Sep 17 00:00:00 2001
+From: George Joseph <george.joseph@fairview5.com>
+Date: Fri, 19 Feb 2016 17:05:53 -0700
+Subject: [PATCH] sip_transport: Search for transport even if listener was
+ specified.
+
+If a listener was specified when calling pjsip_tpmgr_acquire_transport2,
+a new transport was always created instead of using an existing one. This
+caused several issues mostly related to the remote end not expecting a new
+connection. I.E. A TCP client who registered to a server is not going to
+be listening for connections coming back from the server and refuses the
+connection.
+
+Now when pjsip_tpmgr_acquire_transport2 is called with a listener, the
+registry is still searched for an existing transport and the listener
+is used as a factory only if no existing transport can be found.
+---
+ pjsip/src/pjsip/sip_transport.c | 68 ++++++++++++++++++++---------------------
+ 1 file changed, 34 insertions(+), 34 deletions(-)
+
+diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
+index 0410324..620b9c0 100644
+--- a/pjsip/src/pjsip/sip_transport.c
++++ b/pjsip/src/pjsip/sip_transport.c
+@@ -1999,29 +1999,11 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+
+ TRACE_((THIS_FILE, "Transport %s acquired", seltp->obj_name));
+ return PJ_SUCCESS;
+-
+-
+- } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
+- sel->u.listener)
+- {
+- /* Application has requested that a specific listener is to
+- * be used. In this case, skip transport hash table lookup.
+- */
+-
+- /* Verify that the listener type matches the destination type */
+- 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;
+-
+ } else {
+
+ /*
+ * This is the "normal" flow, where application doesn't specify
+- * specific transport/listener to be used to send message to.
++ * specific transport to be used to send message to.
+ * In this case, lookup the transport from the hash table.
+ */
+ pjsip_transport_key key;
+@@ -2081,22 +2063,40 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ return PJ_SUCCESS;
+ }
+
+- /*
+- * Transport not found!
+- * Find factory that can create such transport.
+- */
+- factory = mgr->factory_list.next;
+- while (factory != &mgr->factory_list) {
+- if (factory->type == type)
+- break;
+- factory = factory->next;
+- }
++ if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
++ sel->u.listener)
++ {
++ /* Application has requested that a specific listener is to
++ * be used.
++ */
++
++ /* Verify that the listener type matches the destination type */
++ if (sel->u.listener->type != type) {
++ pj_lock_release(mgr->lock);
++ return PJSIP_ETPNOTSUITABLE;
++ }
+
+- if (factory == &mgr->factory_list) {
+- /* No factory can create the transport! */
+- pj_lock_release(mgr->lock);
+- TRACE_((THIS_FILE, "No suitable factory was found either"));
+- return PJSIP_EUNSUPTRANSPORT;
++ /* We'll use this listener to create transport */
++ factory = sel->u.listener;
++
++ } else {
++ /*
++ * Transport not found!
++ * Find factory that can create such transport.
++ */
++ factory = mgr->factory_list.next;
++ while (factory != &mgr->factory_list) {
++ if (factory->type == type)
++ break;
++ factory = factory->next;
++ }
++
++ if (factory == &mgr->factory_list) {
++ /* No factory can create the transport! */
++ pj_lock_release(mgr->lock);
++ TRACE_((THIS_FILE, "No suitable factory was found either"));
++ return PJSIP_EUNSUPTRANSPORT;
++ }
+ }
+ }
+
+--
+2.5.0
+
diff --git a/third-party/pjproject/patches/config_site.h b/third-party/pjproject/patches/config_site.h
new file mode 100644
index 000000000..544c1e85e
--- /dev/null
+++ b/third-party/pjproject/patches/config_site.h
@@ -0,0 +1,34 @@
+/*
+ * Asterisk config_site.h
+ */
+
+#include <sys/select.h>
+
+#define PJ_HAS_IPV6 1
+#define NDEBUG 1
+#define PJ_MAX_HOSTNAME (256)
+#define PJSIP_MAX_URL_SIZE (512)
+#ifdef PJ_HAS_LINUX_EPOLL
+#define PJ_IOQUEUE_MAX_HANDLES (5000)
+#else
+#define PJ_IOQUEUE_MAX_HANDLES (FD_SETSIZE)
+#endif
+#define PJ_IOQUEUE_HAS_SAFE_UNREG 1
+#define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16)
+
+#define PJ_SCANNER_USE_BITWISE 0
+#define PJ_OS_HAS_CHECK_STACK 0
+#define PJ_LOG_MAX_LEVEL 3
+#define PJ_ENABLE_EXTRA_CHECK 0
+#define PJSIP_MAX_TSX_COUNT ((64*1024)-1)
+#define PJSIP_MAX_DIALOG_COUNT ((64*1024)-1)
+#define PJSIP_UDP_SO_SNDBUF_SIZE (512*1024)
+#define PJSIP_UDP_SO_RCVBUF_SIZE (512*1024)
+#define PJ_DEBUG 0
+#define PJSIP_SAFE_MODULE 0
+#define PJ_HAS_STRICMP_ALNUM 0
+#define PJ_HASH_USE_OWN_TOLOWER 1
+#define PJSIP_UNESCAPE_IN_PLACE 1
+
+#undef PJ_TODO
+#define PJ_TODO(x)
diff --git a/third-party/pjproject/patches/user.mak b/third-party/pjproject/patches/user.mak
new file mode 100644
index 000000000..31579d19c
--- /dev/null
+++ b/third-party/pjproject/patches/user.mak
@@ -0,0 +1,2 @@
+
+CFLAGS += -fPIC -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-label -Wno-unused-function -Wno-strict-aliasing