mirror of
https://github.com/archlinuxarm/PKGBUILDs.git
synced 2025-02-16 23:57:11 +00:00
added community/pjproject-savoirfairelinux
This commit is contained in:
parent
a5766c4b70
commit
8bc511597b
14 changed files with 4811 additions and 0 deletions
86
community/pjproject-savoirfairelinux/PKGBUILD
Normal file
86
community/pjproject-savoirfairelinux/PKGBUILD
Normal file
|
@ -0,0 +1,86 @@
|
|||
# Maintainer: Baptiste Jonglez <baptiste--aur at jonglez dot org>
|
||||
|
||||
# ALARM: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
# - patch from Fedora to fix ARM build
|
||||
# - autoconf for patch
|
||||
|
||||
_pkgname=pjproject
|
||||
pkgname=${_pkgname}-savoirfairelinux
|
||||
pkgver=2.6
|
||||
pkgrel=6
|
||||
pkgdesc="Open source SIP stack and media stack, built with patches from SavoirFaire Linux (mostly GnuTLS support)"
|
||||
arch=('i686' 'x86_64')
|
||||
url="http://www.pjsip.org/"
|
||||
license=('GPL')
|
||||
depends=('util-linux' 'gnutls' 'portaudio' 'speex' 'alsa-lib' 'libsamplerate' 'ffmpeg' 'libsrtp' 'opus')
|
||||
provides=("${_pkgname}=${pkgver}")
|
||||
conflicts=("${_pkgname}")
|
||||
source=("http://www.pjsip.org/release/${pkgver}/${_pkgname}-${pkgver}.tar.bz2"
|
||||
endianness.patch
|
||||
gnutls.patch
|
||||
notestsapps.patch
|
||||
fix_base64.patch
|
||||
ipv6.patch
|
||||
ice_config.patch
|
||||
multiple_listeners.patch
|
||||
pj_ice_sess.patch
|
||||
fix_turn_fallback.patch
|
||||
fix_ioqueue_ipv6_sendto.patch
|
||||
add_dtls_transport.patch
|
||||
rfc6062.patch
|
||||
pjproject-sse2.patch)
|
||||
sha256sums=('2f5a1da1c174d845871c758bd80fbb580fca7799d3cfaa0d3c4e082b5161c7b4'
|
||||
'294d9fba18a8c903979de2c9b531a3ca32a28f90658bf0613a32ebfa7d5e3a69'
|
||||
'8dedb243a390af62741d4e3c0ea6b7f970cd6d67934f03d7ef8b69c745a6523b'
|
||||
'f88f3e73d2f62ae60d93e84e08f98da7d5febe93f1f390286cafa106178c4f27'
|
||||
'25c808206aa5028f29f66ea5364b93be94d0d5feac7d97165cd4ba3493aae6ec'
|
||||
'fdf64f3260aecbbc5433ae784e12dde462f1a15361f14c5cd0f7be0a3d13f802'
|
||||
'12fa1dd99fda01e49df862e02f3ae64f1d31290400236bd50fa930fd20f3b799'
|
||||
'7aabc43556456085ca1bb9e17ef11ae5f4701dd392028335a65c06fd2bc1f6f8'
|
||||
'62ae6bb0bca51196e82984d6b0851a87421307ab0631d92e32966d2a656e7349'
|
||||
'5289671ee86618d665556e5591ef5409354611a6cc0512bfe4100bc6b94fea67'
|
||||
'15524714c2bb48612b6504864b279fc56af1d756a197a8afc8141556889cfb70'
|
||||
'5b901de12d49d79aba8777f3c7b59d703603be5ed2e1be6696f5d01be584e739'
|
||||
'21b1cf20d343e283498ace80ede97ce00062697a26c71ece09cea38a0278ad24'
|
||||
'8413201293d22b11d4294c2741c53f2db875a86434cbc0a8bacf2ad71f1adc7a')
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${_pkgname}-${pkgver}"
|
||||
for patch in endianness.patch gnutls.patch notestsapps.patch fix_base64.patch \
|
||||
ipv6.patch ice_config.patch multiple_listeners.patch \
|
||||
pj_ice_sess.patch fix_turn_fallback.patch \
|
||||
fix_ioqueue_ipv6_sendto.patch add_dtls_transport.patch \
|
||||
rfc6062.patch pjproject-sse2.patch
|
||||
do
|
||||
msg2 "Applying patch $patch"
|
||||
patch -p1 < ../"$patch"
|
||||
done
|
||||
autoconf aconfigure.ac > aconfigure
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${_pkgname}-${pkgver}"
|
||||
export CXXFLAGS="${CXXFLAGS} -DNDEBUG -fPIC -DPJSIP_MAX_PKT_LEN=8000"
|
||||
export CFLAGS="${CXXFLAGS}"
|
||||
./configure \
|
||||
--prefix=/usr \
|
||||
--enable-shared \
|
||||
--enable-ssl=gnutls \
|
||||
--with-external-speex \
|
||||
--with-external-srtp \
|
||||
--with-external-pa \
|
||||
--with-external-gsm \
|
||||
--enable-ext-sound \
|
||||
--disable-oss \
|
||||
--disable-opencore-amr \
|
||||
--disable-v4l2 \
|
||||
--disable-video \
|
||||
--disable-sound
|
||||
make dep
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${_pkgname}-${pkgver}"
|
||||
make DESTDIR="${pkgdir}" install
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
--- a/pjsip/src/pjsip/sip_transport.c
|
||||
+++ b/pjsip/src/pjsip/sip_transport.c
|
||||
@@ -183,6 +183,13 @@
|
||||
PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE
|
||||
},
|
||||
{
|
||||
+ PJSIP_TRANSPORT_DTLS,
|
||||
+ 5061,
|
||||
+ {"DTLS", 4},
|
||||
+ "DTLS transport",
|
||||
+ PJSIP_TRANSPORT_SECURE
|
||||
+ },
|
||||
+ {
|
||||
PJSIP_TRANSPORT_SCTP,
|
||||
5060,
|
||||
{"SCTP", 4},
|
||||
@@ -224,6 +231,13 @@
|
||||
"TLS IPv6 transport",
|
||||
PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE
|
||||
},
|
||||
+ {
|
||||
+ PJSIP_TRANSPORT_DTLS6,
|
||||
+ 5061,
|
||||
+ {"DTLS", 4},
|
||||
+ "DTLS IPv6 transport",
|
||||
+ PJSIP_TRANSPORT_SECURE
|
||||
+ },
|
||||
};
|
||||
|
||||
static void tp_state_callback(pjsip_transport *tp,
|
||||
@@ -249,7 +263,7 @@
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,
|
||||
const char *tp_name,
|
||||
- int def_port,
|
||||
+ int def_port,
|
||||
int *p_tp_type)
|
||||
{
|
||||
unsigned i;
|
||||
--- a/pjsip/include/pjsip/sip_types.h
|
||||
+++ b/pjsip/include/pjsip/sip_types.h
|
||||
@@ -73,6 +73,9 @@
|
||||
/** TLS. */
|
||||
PJSIP_TRANSPORT_TLS,
|
||||
|
||||
+ /** DTLS. */
|
||||
+ PJSIP_TRANSPORT_DTLS,
|
||||
+
|
||||
/** SCTP. */
|
||||
PJSIP_TRANSPORT_SCTP,
|
||||
|
||||
@@ -95,7 +98,10 @@
|
||||
PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6,
|
||||
|
||||
/** TLS over IPv6 */
|
||||
- PJSIP_TRANSPORT_TLS6 = PJSIP_TRANSPORT_TLS + PJSIP_TRANSPORT_IPV6
|
||||
+ PJSIP_TRANSPORT_TLS6 = PJSIP_TRANSPORT_TLS + PJSIP_TRANSPORT_IPV6,
|
||||
+
|
||||
+ /** DTLS over IPv6 */
|
||||
+ PJSIP_TRANSPORT_DTLS6 = PJSIP_TRANSPORT_DTLS + PJSIP_TRANSPORT_IPV6
|
||||
|
||||
} pjsip_transport_type_e;
|
||||
|
19
community/pjproject-savoirfairelinux/endianness.patch
Normal file
19
community/pjproject-savoirfairelinux/endianness.patch
Normal file
|
@ -0,0 +1,19 @@
|
|||
diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h
|
||||
index 10f86fd..4ace1bc 100644
|
||||
--- a/pjlib/include/pj/config.h
|
||||
+++ b/pjlib/include/pj/config.h
|
||||
@@ -245,7 +245,13 @@
|
||||
# define PJ_M_NAME "armv4"
|
||||
# define PJ_HAS_PENTIUM 0
|
||||
# if !PJ_IS_LITTLE_ENDIAN && !PJ_IS_BIG_ENDIAN
|
||||
-# error Endianness must be declared for this processor
|
||||
+# if defined(__GNUC__)
|
||||
+# include <endian.h>
|
||||
+# define PJ_IS_LITTLE_ENDIAN __BYTE_ORDER__ == __LITTLE_ENDIAN__
|
||||
+# define PJ_IS_BIG_ENDIAN __BYTE_ORDER__ == __BIG_ENDIAN__
|
||||
+# else
|
||||
+# error Endianness must be declared for this processor
|
||||
+# endif
|
||||
# endif
|
||||
|
||||
#elif defined (PJ_M_POWERPC) || defined(__powerpc) || defined(__powerpc__) || \
|
20
community/pjproject-savoirfairelinux/fix_base64.patch
Normal file
20
community/pjproject-savoirfairelinux/fix_base64.patch
Normal file
|
@ -0,0 +1,20 @@
|
|||
--- a/pjlib-util/src/pjlib-util/base64.c 2017-05-03 10:29:07.200417026 -0400
|
||||
+++ b/pjlib-util/src/pjlib-util/base64.c 2017-05-03 10:28:30.344335390 -0400
|
||||
@@ -131,7 +131,7 @@
|
||||
|
||||
PJ_ASSERT_RETURN(input && out && out_len, PJ_EINVAL);
|
||||
|
||||
- while (buf[len-1] == '=' && len)
|
||||
+ while (len && buf[len-1] == '=')
|
||||
--len;
|
||||
|
||||
PJ_ASSERT_RETURN(*out_len >= PJ_BASE64_TO_BASE256_LEN(len),
|
||||
@@ -161,7 +161,7 @@
|
||||
out[j++] = (pj_uint8_t)(((c[2] & 0x03)<<6) | (c[3] & 0x3F));
|
||||
}
|
||||
|
||||
- pj_assert(j < *out_len);
|
||||
+ pj_assert(j <= *out_len);
|
||||
*out_len = j;
|
||||
|
||||
return PJ_SUCCESS;
|
|
@ -0,0 +1,19 @@
|
|||
--- a/pjlib/src/pj/ioqueue_common_abs.c 2015-11-05 23:18:46.000000000 -0500
|
||||
+++ b/pjlib/src/pj/ioqueue_common_abs.c 2016-10-21 13:49:09.183662433 -0400
|
||||
@@ -1048,5 +1048,6 @@
|
||||
* Check that address storage can hold the address parameter.
|
||||
*/
|
||||
- PJ_ASSERT_RETURN(addrlen <= (int)sizeof(pj_sockaddr_in), PJ_EBUG);
|
||||
+ PJ_ASSERT_RETURN((((pj_sockaddr*)addr)->addr.sa_family == pj_AF_INET() && addrlen <= (int)sizeof(pj_sockaddr_in)) ||
|
||||
+ (((pj_sockaddr*)addr)->addr.sa_family == pj_AF_INET6() && addrlen <= (int)sizeof(pj_sockaddr_in6)), PJ_EBUG);
|
||||
|
||||
/*
|
||||
--- a/pjlib/src/pj/ioqueue_common_abs.h 2013-02-21 06:18:36.000000000 -0500
|
||||
+++ b/pjlib/src/pj/ioqueue_common_abs.h 2016-10-21 14:04:04.148928591 -0400
|
||||
@@ -64,5 +64,5 @@
|
||||
pj_ssize_t written;
|
||||
unsigned flags;
|
||||
- pj_sockaddr_in rmt_addr;
|
||||
+ pj_sockaddr rmt_addr;
|
||||
int rmt_addrlen;
|
||||
};
|
53
community/pjproject-savoirfairelinux/fix_turn_fallback.patch
Normal file
53
community/pjproject-savoirfairelinux/fix_turn_fallback.patch
Normal file
|
@ -0,0 +1,53 @@
|
|||
--- a/pjnath/src/pjnath/turn_session.c 2016-09-19 18:21:09.073614574 -0400
|
||||
+++ b/pjnath/src/pjnath/turn_session.c 2016-09-19 18:21:30.648631620 -0400
|
||||
@@ -653,3 +653,3 @@
|
||||
|
||||
- cnt = PJ_TURN_MAX_DNS_SRV_CNT;
|
||||
+ cnt = 1;
|
||||
ai = (pj_addrinfo*)
|
||||
--- a/pjnath/src/pjnath/ice_strans.c 2016-09-19 18:36:04.180104330 -0400
|
||||
+++ b/pjnath/src/pjnath/ice_strans.c 2016-09-19 18:37:10.614136809 -0400
|
||||
@@ -1304,2 +1304,5 @@
|
||||
|
||||
+ if (!comp->turn[n].sock)
|
||||
+ continue;
|
||||
+
|
||||
/* Gather remote addresses for this component */
|
||||
@@ -1995,4 +1998,37 @@
|
||||
sess_init_update(comp->ice_st);
|
||||
|
||||
+ } else if ((old_state == PJ_TURN_STATE_RESOLVING || old_state == PJ_TURN_STATE_ALLOCATING) &&
|
||||
+ new_state >= PJ_TURN_STATE_DEALLOCATING)
|
||||
+ {
|
||||
+ pj_ice_sess_cand *cand = NULL;
|
||||
+ unsigned i;
|
||||
+
|
||||
+ /* DNS resolution has failed! */
|
||||
+ ++comp->turn[tp_idx].err_cnt;
|
||||
+
|
||||
+ /* Unregister ourself from the TURN relay */
|
||||
+ pj_turn_sock_set_user_data(turn_sock, NULL);
|
||||
+ comp->turn[tp_idx].sock = NULL;
|
||||
+
|
||||
+ /* Wait until initialization completes */
|
||||
+ pj_grp_lock_acquire(comp->ice_st->grp_lock);
|
||||
+
|
||||
+ /* Find relayed candidate in the component */
|
||||
+ for (i=0; i<comp->cand_cnt; ++i) {
|
||||
+ if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED &&
|
||||
+ comp->cand_list[i].transport_id == data->transport_id)
|
||||
+ {
|
||||
+ cand = &comp->cand_list[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ pj_assert(cand != NULL);
|
||||
+
|
||||
+ pj_grp_lock_release(comp->ice_st->grp_lock);
|
||||
+
|
||||
+ cand->status = old_state == PJ_TURN_STATE_RESOLVING ? PJ_ERESOLVE : PJ_EINVALIDOP;
|
||||
+
|
||||
+ sess_init_update(comp->ice_st);
|
||||
+
|
||||
} else if (new_state >= PJ_TURN_STATE_DEALLOCATING) {
|
||||
pj_turn_session_info info;
|
3295
community/pjproject-savoirfairelinux/gnutls.patch
Normal file
3295
community/pjproject-savoirfairelinux/gnutls.patch
Normal file
File diff suppressed because it is too large
Load diff
46
community/pjproject-savoirfairelinux/ice_config.patch
Normal file
46
community/pjproject-savoirfairelinux/ice_config.patch
Normal file
|
@ -0,0 +1,46 @@
|
|||
Description:
|
||||
Increase PJ_ICE_MAX_CAND to 256. Upstream's default, 16, is
|
||||
not enough to handle cases with numerous local/remote candidates
|
||||
like the case when multiple hosts in IPv6 and IPv4 exists.
|
||||
Tests show that 40 entries are needed with 5 local host IPs.
|
||||
.
|
||||
Increase PJ_ICE_MAX_CHECKS, which would be way too low for the
|
||||
number of candidates.
|
||||
.
|
||||
Increase PJ_ICE_MAX_STUN to 3:
|
||||
- One for IPv4
|
||||
- One for IPv6
|
||||
- One set by the user
|
||||
.
|
||||
Increase PJ_ICE_COMP_BITS so that we can have more components:
|
||||
- 2 Audio components
|
||||
- 2 Video components
|
||||
Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
|
||||
--- a/pjnath/include/pjnath/config.h
|
||||
+++ b/pjnath/include/pjnath/config.h
|
||||
@@ -233,3 +233,3 @@
|
||||
#ifndef PJ_ICE_MAX_CAND
|
||||
-# define PJ_ICE_MAX_CAND 16
|
||||
+# define PJ_ICE_MAX_CAND 256
|
||||
#endif
|
||||
@@ -243,3 +243,3 @@
|
||||
#ifndef PJ_ICE_ST_MAX_CAND
|
||||
-# define PJ_ICE_ST_MAX_CAND 8
|
||||
+# define PJ_ICE_ST_MAX_CAND 32
|
||||
#endif
|
||||
@@ -254,3 +254,3 @@
|
||||
#ifndef PJ_ICE_MAX_STUN
|
||||
-# define PJ_ICE_MAX_STUN 2
|
||||
+# define PJ_ICE_MAX_STUN 3
|
||||
#endif
|
||||
@@ -274,3 +274,3 @@
|
||||
#ifndef PJ_ICE_COMP_BITS
|
||||
-# define PJ_ICE_COMP_BITS 1
|
||||
+# define PJ_ICE_COMP_BITS 2
|
||||
#endif
|
||||
@@ -325,3 +325,3 @@
|
||||
#ifndef PJ_ICE_MAX_CHECKS
|
||||
-# define PJ_ICE_MAX_CHECKS 32
|
||||
+# define PJ_ICE_MAX_CHECKS 150
|
||||
#endif
|
11
community/pjproject-savoirfairelinux/ipv6.patch
Normal file
11
community/pjproject-savoirfairelinux/ipv6.patch
Normal file
|
@ -0,0 +1,11 @@
|
|||
--- a/pjlib/include/pj/config.h
|
||||
+++ b/pjlib/include/pj/config.h
|
||||
@@ -549,7 +549,7 @@
|
||||
* Default: 0 (disabled, for now)
|
||||
*/
|
||||
#ifndef PJ_HAS_IPV6
|
||||
-# define PJ_HAS_IPV6 0
|
||||
+# define PJ_HAS_IPV6 1
|
||||
#endif
|
||||
|
||||
/**
|
|
@ -0,0 +1,66 @@
|
|||
diff --git a/pjproject/pjsip/src/pjsip/sip_transport.c b/pjproject_new/pjsip/src/pjsip/sip_transport.c
|
||||
index 4b2cc1a..22e3603 100644
|
||||
--- a/pjsip/src/pjsip/sip_transport.c
|
||||
+++ b/pjsip/src/pjsip/sip_transport.c
|
||||
@@ -1248,22 +1248,22 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_register_tpfactory( pjsip_tpmgr *mgr,
|
||||
|
||||
pj_lock_acquire(mgr->lock);
|
||||
|
||||
- /* Check that no factory with the same type has been registered. */
|
||||
+ /* Check that no factory with the same type and bound address has been registered. */
|
||||
status = PJ_SUCCESS;
|
||||
for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {
|
||||
- if (p->type == tpf->type) {
|
||||
- status = PJSIP_ETYPEEXISTS;
|
||||
- break;
|
||||
- }
|
||||
- if (p == tpf) {
|
||||
- status = PJ_EEXISTS;
|
||||
- break;
|
||||
- }
|
||||
+ if (p->type == tpf->type && !pj_sockaddr_cmp(&tpf->local_addr, &p->local_addr)) {
|
||||
+ status = PJSIP_ETYPEEXISTS;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (p == tpf) {
|
||||
+ status = PJ_EEXISTS;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (status != PJ_SUCCESS) {
|
||||
- pj_lock_release(mgr->lock);
|
||||
- return status;
|
||||
+ pj_lock_release(mgr->lock);
|
||||
+ return status;
|
||||
}
|
||||
|
||||
pj_list_insert_before(&mgr->factory_list, tpf);
|
||||
@@ -2047,13 +2047,11 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
|
||||
pj_memcpy(&key.rem_addr, remote, addr_len);
|
||||
|
||||
transport = (pjsip_transport*)
|
||||
- pj_hash_get(mgr->table, &key, key_len, NULL);
|
||||
-
|
||||
+ pj_hash_get(mgr->table, &key, key_len, NULL);
|
||||
+ unsigned flag = pjsip_transport_get_flag_from_type(type);
|
||||
if (transport == NULL) {
|
||||
- unsigned flag = pjsip_transport_get_flag_from_type(type);
|
||||
const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;
|
||||
|
||||
-
|
||||
/* Ignore address for loop transports. */
|
||||
if (type == PJSIP_TRANSPORT_LOOP ||
|
||||
type == PJSIP_TRANSPORT_LOOP_DGRAM)
|
||||
@@ -2135,6 +2135,11 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
|
||||
}
|
||||
|
||||
} else {
|
||||
+ /* Make sure we don't use another factory than the one given if secure flag is set */
|
||||
+ if (flag & PJSIP_TRANSPORT_SECURE) {
|
||||
+ TRACE_((THIS_FILE, "Can't create new TLS transport with no provided suitable TLS listener."));
|
||||
+ return PJSIP_ETPNOTSUITABLE;
|
||||
+ }
|
||||
|
||||
/* Find factory with type matches the destination type */
|
||||
factory = mgr->factory_list.next;
|
97
community/pjproject-savoirfairelinux/notestsapps.patch
Normal file
97
community/pjproject-savoirfairelinux/notestsapps.patch
Normal file
|
@ -0,0 +1,97 @@
|
|||
diff --git a/Makefile b/Makefile
|
||||
index 33a4e6b..a486eb7 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -4,7 +4,7 @@ include build/host-$(HOST_NAME).mak
|
||||
include version.mak
|
||||
|
||||
LIB_DIRS = pjlib/build pjlib-util/build pjnath/build third_party/build pjmedia/build pjsip/build
|
||||
-DIRS = $(LIB_DIRS) pjsip-apps/build $(EXTRA_DIRS)
|
||||
+DIRS = $(LIB_DIRS) $(EXTRA_DIRS)
|
||||
|
||||
ifdef MINSIZE
|
||||
MAKE_FLAGS := MINSIZE=1
|
||||
diff --git a/pjlib-util/build/Makefile b/pjlib-util/build/Makefile
|
||||
index cb601cb..862a78a 100644
|
||||
--- a/pjlib-util/build/Makefile
|
||||
+++ b/pjlib-util/build/Makefile
|
||||
@@ -54,7 +54,6 @@ export UTIL_TEST_OBJS += xml.o encryption.o stun.o resolver_test.o test.o \
|
||||
export UTIL_TEST_CFLAGS += $(_CFLAGS)
|
||||
export UTIL_TEST_CXXFLAGS += $(_CXXFLAGS)
|
||||
export UTIL_TEST_LDFLAGS += $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS)
|
||||
-export UTIL_TEST_EXE:=pjlib-util-test-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
|
||||
export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
|
||||
diff --git a/pjlib/build/Makefile b/pjlib/build/Makefile
|
||||
index 1e64950..a75fa65 100644
|
||||
--- a/pjlib/build/Makefile
|
||||
+++ b/pjlib/build/Makefile
|
||||
@@ -56,7 +56,6 @@ export TEST_OBJS += activesock.o atomic.o echo_clt.o errno.o exception.o \
|
||||
export TEST_CFLAGS += $(_CFLAGS)
|
||||
export TEST_CXXFLAGS += $(_CXXFLAGS)
|
||||
export TEST_LDFLAGS += $(PJLIB_LDLIB) $(_LDFLAGS)
|
||||
-export TEST_EXE := pjlib-test-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
|
||||
export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
|
||||
diff --git a/pjmedia/build/Makefile b/pjmedia/build/Makefile
|
||||
index 8012cb7..2ca283a 100644
|
||||
--- a/pjmedia/build/Makefile
|
||||
+++ b/pjmedia/build/Makefile
|
||||
@@ -165,7 +165,6 @@ export PJMEDIA_TEST_LDFLAGS += $(PJMEDIA_CODEC_LDLIB) \
|
||||
$(PJLIB_UTIL_LDLIB) \
|
||||
$(PJNATH_LDLIB) \
|
||||
$(_LDFLAGS)
|
||||
-export PJMEDIA_TEST_EXE:=pjmedia-test-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
|
||||
export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
|
||||
diff --git a/pjnath/build/Makefile b/pjnath/build/Makefile
|
||||
index 1bc08b5..109f79b 100644
|
||||
--- a/pjnath/build/Makefile
|
||||
+++ b/pjnath/build/Makefile
|
||||
@@ -54,7 +54,6 @@ export PJNATH_TEST_OBJS += ice_test.o stun.o sess_auth.o server.o concur_test.o
|
||||
export PJNATH_TEST_CFLAGS += $(_CFLAGS)
|
||||
export PJNATH_TEST_CXXFLAGS += $(_CXXFLAGS)
|
||||
export PJNATH_TEST_LDFLAGS += $(PJNATH_LDLIB) $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS)
|
||||
-export PJNATH_TEST_EXE:=pjnath-test-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
|
||||
###############################################################################
|
||||
@@ -65,7 +64,6 @@ export PJTURN_CLIENT_OBJS += client_main.o
|
||||
export PJTURN_CLIENT_CFLAGS += $(_CFLAGS)
|
||||
export PJTURN_CLIENT_CXXFLAGS += $(_CXXFLAGS)
|
||||
export PJTURN_CLIENT_LDFLAGS += $(PJNATH_LDLIB) $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS)
|
||||
-export PJTURN_CLIENT_EXE:=pjturn-client-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
###############################################################################
|
||||
# Defines for building TURN server application
|
||||
@@ -76,7 +74,6 @@ export PJTURN_SRV_OBJS += allocation.o auth.o listener_udp.o \
|
||||
export PJTURN_SRV_CFLAGS += $(_CFLAGS)
|
||||
export PJTURN_SRV_CXXFLAGS += $(_CXXFLAGS)
|
||||
export PJTURN_SRV_LDFLAGS += $(PJNATH_LDLIB) $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS)
|
||||
-export PJTURN_SRV_EXE:=pjturn-srv-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
|
||||
|
||||
diff --git a/pjsip/build/Makefile b/pjsip/build/Makefile
|
||||
index d2a5c2a..7e2ec60 100644
|
||||
--- a/pjsip/build/Makefile
|
||||
+++ b/pjsip/build/Makefile
|
||||
@@ -165,7 +165,6 @@ export PJSUA2_TEST_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
|
||||
export PJSUA2_TEST_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS)
|
||||
export PJSUA2_TEST_CXXFLAGS = $(PJSUA2_LIB_CFLAGS)
|
||||
export PJSUA2_TEST_LDFLAGS += $(PJ_LDXXFLAGS) $(PJ_LDXXLIBS) $(LDFLAGS)
|
||||
-export PJSUA2_TEST_EXE := pjsua2-test-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
|
||||
|
||||
@@ -195,7 +194,6 @@ export TEST_LDFLAGS += $(PJSIP_LDLIB) \
|
||||
$(PJLIB_UTIL_LDLIB) \
|
||||
$(PJNATH_LDLIB) \
|
||||
$(_LDFLAGS)
|
||||
-export TEST_EXE := pjsip-test-$(TARGET_NAME)$(HOST_EXE)
|
||||
|
||||
|
||||
export CC_OUT CC AR RANLIB HOST_MV HOST_RM HOST_RMDIR HOST_MKDIR OBJEXT LD LDOUT
|
29
community/pjproject-savoirfairelinux/pj_ice_sess.patch
Normal file
29
community/pjproject-savoirfairelinux/pj_ice_sess.patch
Normal file
|
@ -0,0 +1,29 @@
|
|||
Description: Expose the ice session to allow adding candidates.
|
||||
.
|
||||
Ring has other ways than stun to determine its IP address.
|
||||
.
|
||||
See ice_transport.cpp for usage details.
|
||||
Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
|
||||
|
||||
--- a/pjnath/include/pjnath/ice_strans.h
|
||||
+++ b/pjnath/include/pjnath/ice_strans.h
|
||||
@@ -845,6 +845,8 @@ PJ_DECL(pj_status_t) pj_ice_strans_sendt
|
||||
int dst_addr_len);
|
||||
|
||||
|
||||
+PJ_DECL(pj_ice_sess *) pj_ice_strans_get_ice_sess(pj_ice_strans *ice_st);
|
||||
+
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
--- a/pjnath/src/pjnath/ice_strans.c
|
||||
+++ b/pjnath/src/pjnath/ice_strans.c
|
||||
@@ -1243,6 +1243,11 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto
|
||||
return PJ_EINVALIDOP;
|
||||
}
|
||||
|
||||
+PJ_DECL(pj_ice_sess *) pj_ice_strans_get_ice_sess( pj_ice_strans *ice_st )
|
||||
+{
|
||||
+ return ice_st->ice;
|
||||
+}
|
||||
+
|
88
community/pjproject-savoirfairelinux/pjproject-sse2.patch
Normal file
88
community/pjproject-savoirfairelinux/pjproject-sse2.patch
Normal file
|
@ -0,0 +1,88 @@
|
|||
diff -rupN pjproject-2.6/aconfigure.ac pjproject-2.6-new/aconfigure.ac
|
||||
--- pjproject-2.6/aconfigure.ac 2017-01-25 12:23:08.000000000 +0100
|
||||
+++ pjproject-2.6-new/aconfigure.ac 2017-09-01 18:52:24.843876152 +0200
|
||||
@@ -5,12 +5,7 @@ host_orig="$host"
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
-AC_CONFIG_HEADER([pjlib/include/pj/compat/os_auto.h
|
||||
- pjlib/include/pj/compat/m_auto.h
|
||||
- pjmedia/include/pjmedia/config_auto.h
|
||||
- pjmedia/include/pjmedia-codec/config_auto.h
|
||||
- pjsip/include/pjsip/sip_autoconf.h
|
||||
- ])
|
||||
+AC_CONFIG_HEADERS([pjlib/include/pj/compat/os_auto.h pjlib/include/pj/compat/m_auto.h pjmedia/include/pjmedia/config_auto.h pjmedia/include/pjmedia-codec/config_auto.h pjsip/include/pjsip/sip_autoconf.h])
|
||||
AC_CONFIG_FILES([build.mak
|
||||
build/os-auto.mak
|
||||
build/cc-auto.mak
|
||||
@@ -1785,6 +1780,24 @@ AC_SUBST(ac_no_webrtc)
|
||||
AC_SUBST(ac_webrtc_instset)
|
||||
AC_SUBST(ac_webrtc_cflags)
|
||||
AC_SUBST(ac_webrtc_ldflags)
|
||||
+
|
||||
+AC_MSG_CHECKING(for available instruction set)
|
||||
+AC_LINK_IFELSE([
|
||||
+ AC_LANG_PROGRAM([[
|
||||
+ #include <xmmintrin.h>
|
||||
+ __m128 testfunc(float *a, float *b) {
|
||||
+ return _mm_add_ps(_mm_loadu_ps(a), _mm_loadu_ps(b));
|
||||
+ }
|
||||
+ ]])],
|
||||
+ [
|
||||
+ instrset=sse2
|
||||
+ ],
|
||||
+ [
|
||||
+ instrset=generic
|
||||
+ ]
|
||||
+)
|
||||
+AC_MSG_RESULT($instrset)
|
||||
+
|
||||
AC_ARG_ENABLE(libwebrtc,
|
||||
AS_HELP_STRING([--disable-libwebrtc],
|
||||
[Exclude libwebrtc in the build]),
|
||||
@@ -1840,7 +1853,7 @@ AC_ARG_ENABLE(libwebrtc,
|
||||
ac_webrtc_cflags="-msse2"
|
||||
;;
|
||||
*win32* | *w32* | *darwin* | *linux*)
|
||||
- ac_webrtc_instset=sse2
|
||||
+ ac_webrtc_instset=$instrset
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
diff -rupN pjproject-2.6/third_party/build/os-auto.mak.in pjproject-2.6-new/third_party/build/os-auto.mak.in
|
||||
--- pjproject-2.6/third_party/build/os-auto.mak.in 2016-12-22 10:33:55.000000000 +0100
|
||||
+++ pjproject-2.6-new/third_party/build/os-auto.mak.in 2017-09-01 18:52:24.846876150 +0200
|
||||
@@ -104,8 +104,7 @@ else ifneq ($(findstring mips,@ac_webrtc
|
||||
else # Generic fixed point
|
||||
WEBRTC_SRC = \
|
||||
modules/audio_processing/aecm/aecm_core_c.o \
|
||||
- modules/audio_processing/ns/nsx_core_c.o \
|
||||
- common_audio/signal_processing/complex_fft.o
|
||||
+ modules/audio_processing/ns/nsx_core_c.o
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
diff -rupN pjproject-2.6/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_core.c pjproject-2.6-new/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_core.c
|
||||
--- pjproject-2.6/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_core.c 2016-08-29 10:44:54.000000000 +0200
|
||||
+++ pjproject-2.6-new/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_core.c 2017-09-01 18:52:24.847876149 +0200
|
||||
@@ -1478,7 +1478,7 @@ AecCore* WebRtcAec_CreateAec() {
|
||||
WebRtcAec_ComfortNoise = ComfortNoise;
|
||||
WebRtcAec_SubbandCoherence = SubbandCoherence;
|
||||
|
||||
-#if defined(WEBRTC_ARCH_X86_FAMILY)
|
||||
+#if defined(WEBRTC_ARCH_X86_FAMILY) && defined(__SSE2__)
|
||||
if (WebRtc_GetCPUInfo(kSSE2)) {
|
||||
WebRtcAec_InitAec_SSE2();
|
||||
}
|
||||
diff -rupN pjproject-2.6/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_rdft.c pjproject-2.6-new/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_rdft.c
|
||||
--- pjproject-2.6/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_rdft.c 2016-08-25 03:36:33.000000000 +0200
|
||||
+++ pjproject-2.6-new/third_party/webrtc/src/webrtc/modules/audio_processing/aec/aec_rdft.c 2017-09-01 18:52:24.848876148 +0200
|
||||
@@ -571,7 +571,7 @@ void aec_rdft_init(void) {
|
||||
cftfsub_128 = cftfsub_128_C;
|
||||
cftbsub_128 = cftbsub_128_C;
|
||||
bitrv2_128 = bitrv2_128_C;
|
||||
-#if defined(WEBRTC_ARCH_X86_FAMILY)
|
||||
+#if defined(WEBRTC_ARCH_X86_FAMILY) && defined(__SSE2__)
|
||||
if (WebRtc_GetCPUInfo(kSSE2)) {
|
||||
aec_rdft_init_sse2();
|
||||
}
|
919
community/pjproject-savoirfairelinux/rfc6062.patch
Normal file
919
community/pjproject-savoirfairelinux/rfc6062.patch
Normal file
|
@ -0,0 +1,919 @@
|
|||
Copyright (c) 2017 Savoir-faire Linux Inc.
|
||||
|
||||
turn: rfc 6062 support
|
||||
|
||||
Current implementation of TURN and STUN doesn't support TCP as a valid
|
||||
peer connection. This connection is defined by the rfc 6062.
|
||||
This patch is an implementation proposal of this rfc into PJNATH.
|
||||
Modifications are API backware compatible, not ABI.
|
||||
Users must rebuild their code.
|
||||
|
||||
Written by
|
||||
Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
on behalf of Savoir-faire Linux.
|
||||
|
||||
----
|
||||
|
||||
--- a/pjnath/include/pjnath/config.h
|
||||
+++ b/pjnath/include/pjnath/config.h
|
||||
@@ -220,6 +220,14 @@
|
||||
# define PJ_TURN_KEEP_ALIVE_SEC 15
|
||||
#endif
|
||||
|
||||
+/**
|
||||
+ * Maximal number of TCP data connection that a client can open/accept with
|
||||
+ * peers.
|
||||
+ */
|
||||
+#ifndef PJ_TURN_MAX_TCP_CNX
|
||||
+# define PJ_TURN_MAX_TCP_CNX 32
|
||||
+#endif
|
||||
+
|
||||
|
||||
/* **************************************************************************
|
||||
* ICE CONFIGURATION
|
||||
--- a/pjnath/include/pjnath/stun_msg.h
|
||||
+++ b/pjnath/include/pjnath/stun_msg.h
|
||||
@@ -92,6 +92,21 @@
|
||||
*/
|
||||
PJ_STUN_CHANNEL_BIND_METHOD = 9,
|
||||
|
||||
+ /*
|
||||
+ * STUN/TURN Connect as defined by RFC 6062
|
||||
+ */
|
||||
+ PJ_STUN_CONNECT_METHOD = 10,
|
||||
+
|
||||
+ /*
|
||||
+ * STUN/TURN ConnectionBind as defined by RFC 6062
|
||||
+ */
|
||||
+ PJ_STUN_CONNECTION_BIND_METHOD = 11,
|
||||
+
|
||||
+ /*
|
||||
+ * STUN/TURN ConnectionAttempt as defined by RFC 6062
|
||||
+ */
|
||||
+ PJ_STUN_CONNECTION_ATTEMPT_METHOD = 12,
|
||||
+
|
||||
/**
|
||||
* All known methods.
|
||||
*/
|
||||
@@ -261,6 +276,16 @@
|
||||
*/
|
||||
PJ_STUN_DATA_INDICATION = 0x0017,
|
||||
|
||||
+ /**
|
||||
+ * STUN/TURN ConnectBind Request
|
||||
+ */
|
||||
+ PJ_STUN_CONNECTION_BIND_REQUEST = 0x000b,
|
||||
+
|
||||
+ /**
|
||||
+ * TURN ConnectionAttempt indication
|
||||
+ */
|
||||
+ PJ_STUN_CONNECTION_ATTEMPT_INDICATION = 0x001c,
|
||||
+
|
||||
|
||||
/**
|
||||
* TURN CreatePermission request
|
||||
@@ -333,6 +358,7 @@
|
||||
PJ_STUN_ATTR_XOR_REFLECTED_FROM = 0x0023,/**< XOR-REFLECTED-FROM */
|
||||
PJ_STUN_ATTR_PRIORITY = 0x0024,/**< PRIORITY */
|
||||
PJ_STUN_ATTR_USE_CANDIDATE = 0x0025,/**< USE-CANDIDATE */
|
||||
+ PJ_STUN_ATTR_CONNECTION_ID = 0x002a,/**< CONNECTION-ID */
|
||||
PJ_STUN_ATTR_ICMP = 0x0030,/**< ICMP (TURN) */
|
||||
|
||||
PJ_STUN_ATTR_END_MANDATORY_ATTR,
|
||||
--- a/pjnath/include/pjnath/stun_session.h
|
||||
+++ b/pjnath/include/pjnath/stun_session.h
|
||||
@@ -751,6 +751,13 @@
|
||||
pj_stun_tx_data *tdata);
|
||||
|
||||
|
||||
+PJ_DEF(void) pj_stun_session_get_server_cred(
|
||||
+ pj_stun_session *sess,
|
||||
+ pj_pool_t *pool, pj_str_t *nonce, pj_str_t *realm);
|
||||
+
|
||||
+PJ_DEF(void) pj_stun_session_set_server_cred(
|
||||
+ pj_stun_session *sess, const pj_str_t *nonce, pj_str_t *realm);
|
||||
+
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
--- a/pjnath/include/pjnath/turn_session.h
|
||||
+++ b/pjnath/include/pjnath/turn_session.h
|
||||
@@ -184,6 +184,12 @@
|
||||
PJ_TURN_STATE_ALLOCATING,
|
||||
|
||||
/**
|
||||
+ * TURN session has issued CONNECTION-BIND request and is waiting for response
|
||||
+ * from the TURN server.
|
||||
+ */
|
||||
+ PJ_TURN_STATE_CONNECTION_BINDING,
|
||||
+
|
||||
+ /**
|
||||
* TURN session has successfully allocated relay resoruce and now is
|
||||
* ready to be used.
|
||||
*/
|
||||
@@ -298,6 +304,21 @@
|
||||
pj_turn_state_t old_state,
|
||||
pj_turn_state_t new_state);
|
||||
|
||||
+ /**
|
||||
+ * Notification when TURN session get a ConnectionAttempt indication.
|
||||
+ *
|
||||
+ * @param sess The TURN session.
|
||||
+ * @param conn_id The connection-id to use for connection binding.
|
||||
+ * @param peer_addr Peer address that tried to connect on the TURN server.
|
||||
+ * @param addr_len Length of the peer address.
|
||||
+
|
||||
+ */
|
||||
+ void (*on_peer_connection)(pj_turn_session *sess,
|
||||
+ pj_uint32_t conn_id,
|
||||
+ const pj_sockaddr_t *peer_addr,
|
||||
+ unsigned addr_len,
|
||||
+ pj_status_t status);
|
||||
+
|
||||
} pj_turn_session_cb;
|
||||
|
||||
|
||||
@@ -339,6 +360,14 @@
|
||||
*/
|
||||
int af;
|
||||
|
||||
+ /**
|
||||
+ * Type of connection to from TURN server to peer.
|
||||
+ *
|
||||
+ * Supported values: PJ_TURN_TP_UDP (rfc 5766), PJ_TURN_TP_TLS (rfc 6062)
|
||||
+ *
|
||||
+ * Default is PJ_TURN_TP_UDP.
|
||||
+ */
|
||||
+ pj_turn_tp_type peer_conn_type;
|
||||
|
||||
} pj_turn_alloc_param;
|
||||
|
||||
@@ -741,6 +770,15 @@
|
||||
pj_size_t pkt_len,
|
||||
pj_size_t *parsed_len);
|
||||
|
||||
+/**
|
||||
+ * rfc6062
|
||||
+ */
|
||||
+PJ_DEF(void) pj_turn_session_get_server_cred(
|
||||
+ pj_turn_session *sess,
|
||||
+ pj_pool_t *pool, pj_str_t *nonce, pj_str_t *realm);
|
||||
+
|
||||
+PJ_DEF(void) pj_turn_session_set_server_cred(
|
||||
+ pj_turn_session *sess, const pj_str_t *nonce, pj_str_t *realm);
|
||||
|
||||
/**
|
||||
* @}
|
||||
--- a/pjnath/include/pjnath/turn_sock.h
|
||||
+++ b/pjnath/include/pjnath/turn_sock.h
|
||||
@@ -98,6 +98,23 @@
|
||||
pj_turn_state_t old_state,
|
||||
pj_turn_state_t new_state);
|
||||
|
||||
+ /**
|
||||
+ * Notification when TURN session get a ConnectionAttempt indication.
|
||||
+ *
|
||||
+ * @param turn_sock The TURN client transport.
|
||||
+ * @param conn_id The connection-id to use for connection binding.
|
||||
+ * @param peer_addr Peer address that tried to connect on the TURN server.
|
||||
+ * @param addr_len Length of the peer address.
|
||||
+ * @param status PJ_SUCCESS when connection is made, or any errors
|
||||
+ * if the connection has failed (or if the peer has
|
||||
+ * disconnected after an established connection).
|
||||
+ */
|
||||
+ void (*on_peer_connection)(pj_turn_sock *turn_sock,
|
||||
+ pj_uint32_t conn_id,
|
||||
+ const pj_sockaddr_t *peer_addr,
|
||||
+ unsigned addr_len,
|
||||
+ pj_status_t status);
|
||||
+
|
||||
} pj_turn_sock_cb;
|
||||
|
||||
|
||||
@@ -446,6 +463,13 @@
|
||||
const pj_sockaddr_t *peer,
|
||||
unsigned addr_len);
|
||||
|
||||
+/**
|
||||
+ * RFC 6062
|
||||
+ */
|
||||
+PJ_DECL(pj_status_t) pj_turn_connect_peer(pj_turn_sock *sock,
|
||||
+ pj_uint32_t conn_id,
|
||||
+ const pj_sockaddr_t *peer_addr,
|
||||
+ unsigned addr_len);
|
||||
|
||||
/**
|
||||
* @}
|
||||
--- a/pjnath/src/pjnath/stun_msg.c
|
||||
+++ b/pjnath/src/pjnath/stun_msg.c
|
||||
@@ -45,6 +45,9 @@
|
||||
"Data", /* 7 */
|
||||
"CreatePermission", /* 8 */
|
||||
"ChannelBind", /* 9 */
|
||||
+ "Connect", /* 10 */
|
||||
+ "ConnectionBind", /* 11 */
|
||||
+ "ConnectionAttempt", /* 12 */
|
||||
};
|
||||
|
||||
static struct
|
||||
@@ -476,11 +479,11 @@
|
||||
NULL
|
||||
},
|
||||
{
|
||||
- /* ID 0x002a is not assigned */
|
||||
- NULL,
|
||||
- NULL,
|
||||
- NULL,
|
||||
- NULL
|
||||
+ /* PJ_STUN_ATTR_CONNECTION_ID, */
|
||||
+ "CONNECTION-ID",
|
||||
+ &decode_uint_attr,
|
||||
+ &encode_uint_attr,
|
||||
+ &clone_uint_attr
|
||||
},
|
||||
{
|
||||
/* ID 0x002b is not assigned */
|
||||
--- a/pjnath/src/pjnath/stun_session.c
|
||||
+++ b/pjnath/src/pjnath/stun_session.c
|
||||
@@ -1511,3 +1511,14 @@
|
||||
return status;
|
||||
}
|
||||
|
||||
+PJ_DEF(void) pj_stun_session_get_server_cred(pj_stun_session *sess, pj_pool_t *pool, pj_str_t *nonce, pj_str_t *realm)
|
||||
+{
|
||||
+ pj_strdup(pool, nonce, &sess->next_nonce);
|
||||
+ pj_strdup(pool, realm, &sess->server_realm);
|
||||
+}
|
||||
+
|
||||
+PJ_DEF(void) pj_stun_session_set_server_cred(pj_stun_session *sess, const pj_str_t *nonce, pj_str_t *realm)
|
||||
+{
|
||||
+ pj_strdup(sess->pool, &sess->next_nonce, nonce);
|
||||
+ pj_strdup(sess->pool, &sess->server_realm, realm);
|
||||
+}
|
||||
--- a/pjnath/src/pjnath/turn_session.c
|
||||
+++ b/pjnath/src/pjnath/turn_session.c
|
||||
@@ -42,6 +42,7 @@
|
||||
"Resolving",
|
||||
"Resolved",
|
||||
"Allocating",
|
||||
+ "TcpBinding",
|
||||
"Ready",
|
||||
"Deallocating",
|
||||
"Deallocated",
|
||||
@@ -208,6 +209,7 @@
|
||||
PJ_DEF(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm)
|
||||
{
|
||||
pj_bzero(prm, sizeof(*prm));
|
||||
+ prm->peer_conn_type = PJ_TURN_TP_UDP;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -403,6 +405,11 @@
|
||||
sess->pending_destroy = PJ_TRUE;
|
||||
can_destroy = PJ_FALSE;
|
||||
break;
|
||||
+ case PJ_TURN_STATE_CONNECTION_BINDING:
|
||||
+ /* We need to wait until connection binding complete */
|
||||
+ sess->pending_destroy = PJ_TRUE;
|
||||
+ can_destroy = PJ_FALSE;
|
||||
+ break;
|
||||
case PJ_TURN_STATE_READY:
|
||||
/* Send REFRESH with LIFETIME=0 */
|
||||
can_destroy = PJ_FALSE;
|
||||
@@ -719,6 +726,9 @@
|
||||
PJ_ASSERT_RETURN(sess->state>PJ_TURN_STATE_NULL &&
|
||||
sess->state<=PJ_TURN_STATE_RESOLVED,
|
||||
PJ_EINVALIDOP);
|
||||
+ PJ_ASSERT_RETURN(param->peer_conn_type == PJ_TURN_TP_UDP ||
|
||||
+ param->peer_conn_type == PJ_TURN_TP_TCP,
|
||||
+ PJ_EINVAL);
|
||||
|
||||
/* Verify address family in allocation param */
|
||||
if (param && param->af) {
|
||||
@@ -756,7 +766,7 @@
|
||||
/* MUST include REQUESTED-TRANSPORT attribute */
|
||||
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
|
||||
PJ_STUN_ATTR_REQ_TRANSPORT,
|
||||
- PJ_STUN_SET_RT_PROTO(PJ_TURN_TP_UDP));
|
||||
+ PJ_STUN_SET_RT_PROTO(param->peer_conn_type));
|
||||
|
||||
/* Include BANDWIDTH if requested */
|
||||
if (sess->alloc_param.bandwidth > 0) {
|
||||
@@ -994,6 +1004,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ /* rfc6062: direct send if peer connection is TCP */
|
||||
+ if (sess->alloc_param.peer_conn_type == PJ_TURN_TP_TCP) {
|
||||
+ status = sess->cb.on_send_pkt(sess, pkt, pkt_len,
|
||||
+ addr, addr_len);
|
||||
+ goto on_return;
|
||||
+ }
|
||||
+
|
||||
/* See if the peer is bound to a channel number */
|
||||
ch = lookup_ch_by_addr(sess, addr, pj_sockaddr_get_len(addr),
|
||||
PJ_FALSE, PJ_FALSE);
|
||||
@@ -1670,6 +1687,33 @@
|
||||
|
||||
sess = (pj_turn_session*)pj_stun_session_get_user_data(stun);
|
||||
|
||||
+ if (msg->hdr.type == PJ_STUN_CONNECTION_ATTEMPT_INDICATION) {
|
||||
+ pj_stun_uint_attr *connection_id_attr;
|
||||
+ /* Get CONNECTION-ID attribute */
|
||||
+ connection_id_attr = (pj_stun_uint_attr*)
|
||||
+ pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_CONNECTION_ID, 0);
|
||||
+
|
||||
+ /* Get XOR-PEER-ADDRESS attribute */
|
||||
+ peer_attr = (pj_stun_xor_peer_addr_attr*)
|
||||
+ pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
|
||||
+
|
||||
+ /* Must have both XOR-PEER-ADDRESS and CONNECTION-ID attributes */
|
||||
+ if (!peer_attr || !connection_id_attr) {
|
||||
+ PJ_LOG(4,(sess->obj_name,
|
||||
+ "Received ConnectionAttempt indication with missing attributes"));
|
||||
+ return PJ_EINVALIDOP;
|
||||
+ }
|
||||
+
|
||||
+ /* Notify application */
|
||||
+ if (sess->cb.on_peer_connection) {
|
||||
+ (*sess->cb.on_peer_connection)(sess, connection_id_attr->value,
|
||||
+ &peer_attr->sockaddr,
|
||||
+ pj_sockaddr_get_len(&peer_attr->sockaddr),
|
||||
+ PJ_SUCCESS);
|
||||
+ }
|
||||
+ return PJ_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
/* Expecting Data Indication only */
|
||||
if (msg->hdr.type != PJ_STUN_DATA_INDICATION) {
|
||||
PJ_LOG(4,(sess->obj_name, "Unexpected STUN %s indication",
|
||||
@@ -2089,3 +2133,16 @@
|
||||
pj_grp_lock_release(sess->grp_lock);
|
||||
}
|
||||
|
||||
+PJ_DEF(void) pj_turn_session_get_server_cred(pj_turn_session *sess,
|
||||
+ pj_pool_t *pool, pj_str_t *nonce,
|
||||
+ pj_str_t *realm)
|
||||
+{
|
||||
+ pj_stun_session_get_server_cred(sess->stun, pool, nonce, realm);
|
||||
+}
|
||||
+
|
||||
+PJ_DEF(void) pj_turn_session_set_server_cred(pj_turn_session *sess,
|
||||
+ const pj_str_t *nonce,
|
||||
+ pj_str_t *realm)
|
||||
+{
|
||||
+ pj_stun_session_set_server_cred(sess->stun, nonce, realm);
|
||||
+}
|
||||
--- a/pjnath/src/pjnath/turn_sock.c
|
||||
+++ b/pjnath/src/pjnath/turn_sock.c
|
||||
@@ -35,9 +35,29 @@
|
||||
|
||||
enum { MAX_BIND_RETRY = 100 };
|
||||
|
||||
+enum { CONNECTION_USED = (1<<0), /* TCP connection slot is used or free */
|
||||
+ CONNECTION_READY = (1<<1) /* TCP connection bind and ready to use for data transfer */
|
||||
+};
|
||||
|
||||
#define INIT 0x1FFFFFFF
|
||||
|
||||
+/**
|
||||
+ * pj_turn_tcp_data_connection contains information on TCP connection open between
|
||||
+ * the client and the turn server, conveying data from/to a specific peer.
|
||||
+ * notes: part of RFC 6062 support
|
||||
+ */
|
||||
+typedef struct pj_turn_tcp_data_connection
|
||||
+{
|
||||
+ pj_uint32_t id; /* identity of this connection as given by the TURN server */
|
||||
+ pj_uint32_t flags; /* 0 or CONNECTION_USED */
|
||||
+ pj_sockaddr peer_addr; /* mapped address of connected peer */
|
||||
+ unsigned peer_addr_len;
|
||||
+ pj_activesock_t *active_tcp_sock; /* socket between client and TURN server */
|
||||
+ pj_ioqueue_op_key_t send_key;
|
||||
+ pj_stun_session *stun_sess; /* STUN session used to send ConnectBind msg */
|
||||
+ pj_turn_sock *turn_sock; /* up link */
|
||||
+} pj_turn_tcp_data_connection;
|
||||
+
|
||||
struct pj_turn_sock
|
||||
{
|
||||
pj_pool_t *pool;
|
||||
@@ -59,6 +79,11 @@
|
||||
pj_turn_tp_type conn_type;
|
||||
pj_activesock_t *active_sock;
|
||||
pj_ioqueue_op_key_t send_key;
|
||||
+
|
||||
+ /* RFC 6062 */
|
||||
+ pj_stun_auth_cred cred; /* saved from control connection */
|
||||
+ pj_size_t tcp_cnx_count; /* number of elements in tcp_cnx */
|
||||
+ pj_turn_tcp_data_connection tcp_cnx[PJ_TURN_MAX_TCP_CNX]; /* peer dedicated data connections throught the TURN server */
|
||||
};
|
||||
|
||||
|
||||
@@ -82,6 +107,12 @@
|
||||
static void turn_on_state(pj_turn_session *sess,
|
||||
pj_turn_state_t old_state,
|
||||
pj_turn_state_t new_state);
|
||||
+static void turn_on_peer_connection(pj_turn_session *sess,
|
||||
+ pj_uint32_t conn_id,
|
||||
+ const pj_sockaddr_t *peer_addr,
|
||||
+ unsigned addr_len,
|
||||
+ pj_status_t status);
|
||||
+
|
||||
|
||||
static pj_bool_t on_data_read(pj_activesock_t *asock,
|
||||
void *data,
|
||||
@@ -97,6 +127,26 @@
|
||||
static void destroy(pj_turn_sock *turn_sock);
|
||||
static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e);
|
||||
|
||||
+static pj_bool_t on_peer_data_read(pj_activesock_t *asock,
|
||||
+ void *data,
|
||||
+ pj_size_t size,
|
||||
+ pj_status_t status,
|
||||
+ pj_size_t *remainder);
|
||||
+static pj_bool_t on_peer_connect_complete(pj_activesock_t *asock,
|
||||
+ pj_status_t status);
|
||||
+static pj_status_t on_tcp_stun_send_msg(pj_stun_session *sess,
|
||||
+ void *token,
|
||||
+ const void *pkt,
|
||||
+ pj_size_t pkt_size,
|
||||
+ const pj_sockaddr_t *dst_addr,
|
||||
+ unsigned addr_len);
|
||||
+static void on_tcp_stun_request_complete(pj_stun_session *sess,
|
||||
+ pj_status_t status,
|
||||
+ void *token,
|
||||
+ pj_stun_tx_data *tdata,
|
||||
+ const pj_stun_msg *response,
|
||||
+ const pj_sockaddr_t *src_addr,
|
||||
+ unsigned src_addr_len);
|
||||
|
||||
/* Init config */
|
||||
PJ_DEF(void) pj_turn_sock_cfg_default(pj_turn_sock_cfg *cfg)
|
||||
@@ -193,6 +243,7 @@
|
||||
sess_cb.on_channel_bound = &turn_on_channel_bound;
|
||||
sess_cb.on_rx_data = &turn_on_rx_data;
|
||||
sess_cb.on_state = &turn_on_state;
|
||||
+ sess_cb.on_peer_connection = &turn_on_peer_connection;
|
||||
status = pj_turn_session_create(cfg, pool->obj_name, af, conn_type,
|
||||
turn_sock->grp_lock, &sess_cb, 0,
|
||||
turn_sock, &turn_sock->sess);
|
||||
@@ -238,6 +289,9 @@
|
||||
pj_turn_session_shutdown(turn_sock->sess);
|
||||
if (turn_sock->active_sock)
|
||||
pj_activesock_close(turn_sock->active_sock);
|
||||
+ for (int i=0; i < turn_sock->tcp_cnx_count; ++i) {
|
||||
+ pj_activesock_close(turn_sock->tcp_cnx[i].active_tcp_sock);
|
||||
+ }
|
||||
pj_grp_lock_dec_ref(turn_sock->grp_lock);
|
||||
pj_grp_lock_release(turn_sock->grp_lock);
|
||||
}
|
||||
@@ -302,6 +356,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
+static void peer_cnx_fail(pj_turn_tcp_data_connection *tcp_cnx,
|
||||
+ const char *title, pj_status_t status)
|
||||
+{
|
||||
+ pj_turn_sock *turn_sock = tcp_cnx->turn_sock;
|
||||
+
|
||||
+ show_err(turn_sock, title, status);
|
||||
+ if (tcp_cnx->stun_sess) {
|
||||
+ pj_stun_session_destroy(tcp_cnx->stun_sess);
|
||||
+ tcp_cnx->stun_sess = NULL;
|
||||
+ }
|
||||
+ if (tcp_cnx->active_tcp_sock) {
|
||||
+ for (int i=0; i < turn_sock->tcp_cnx_count; ++i) {
|
||||
+ if (&turn_sock->tcp_cnx[i] == tcp_cnx) {
|
||||
+ turn_on_peer_connection(turn_sock->sess, tcp_cnx->id,
|
||||
+ &tcp_cnx->peer_addr,
|
||||
+ tcp_cnx->peer_addr_len,
|
||||
+ PJ_EEOF);
|
||||
+ pj_activesock_close(tcp_cnx->active_tcp_sock);
|
||||
+ tcp_cnx->active_tcp_sock = NULL;
|
||||
+ tcp_cnx->flags = 0;
|
||||
+ if (i == turn_sock->tcp_cnx_count-1)
|
||||
+ --turn_sock->tcp_cnx_count;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Set user data.
|
||||
*/
|
||||
@@ -411,6 +489,9 @@
|
||||
|
||||
/* Set credental */
|
||||
if (cred) {
|
||||
+ // save credentials for peer/TCP connections
|
||||
+ if (param->peer_conn_type == PJ_TURN_TP_TCP)
|
||||
+ pj_memcpy(&turn_sock->cred, cred, sizeof(turn_sock->cred));
|
||||
status = pj_turn_session_set_credential(turn_sock->sess, cred);
|
||||
if (status != PJ_SUCCESS) {
|
||||
sess_fail(turn_sock, "Error setting credential", status);
|
||||
@@ -676,11 +757,35 @@
|
||||
return PJ_EINVALIDOP;
|
||||
}
|
||||
|
||||
- PJ_UNUSED_ARG(dst_addr);
|
||||
- PJ_UNUSED_ARG(dst_addr_len);
|
||||
+ /* With TCP peer connection filter by address
|
||||
+ * if packet is for the server or the peer
|
||||
+ */
|
||||
+ pj_activesock_t *asock = NULL;
|
||||
+ pj_turn_session_info info;
|
||||
+ pj_turn_session_get_info(turn_sock->sess, &info);
|
||||
+ if (pj_sockaddr_cmp(&info.server, dst_addr) &&
|
||||
+ turn_sock->alloc_param.peer_conn_type == PJ_TURN_TP_TCP) {
|
||||
+ for (int i=0; i < turn_sock->tcp_cnx_count; ++i) {
|
||||
+ pj_turn_tcp_data_connection *tcp_cnx = &turn_sock->tcp_cnx[i];
|
||||
+ if ((tcp_cnx->flags & CONNECTION_READY) == 0)
|
||||
+ continue;
|
||||
+ if (!pj_sockaddr_cmp(&tcp_cnx->peer_addr, dst_addr)) {
|
||||
+ asock = tcp_cnx->active_tcp_sock;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!asock) {
|
||||
+ status = PJ_ENOTFOUND;
|
||||
+ show_err(turn_sock, "socket send()", status);
|
||||
+ return status;
|
||||
+ }
|
||||
+ } else {
|
||||
+ asock = turn_sock->active_sock;
|
||||
+ }
|
||||
|
||||
- status = pj_activesock_send(turn_sock->active_sock, &turn_sock->send_key,
|
||||
+ status = pj_activesock_send(asock, &turn_sock->send_key,
|
||||
pkt, &len, 0);
|
||||
+
|
||||
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
|
||||
show_err(turn_sock, "socket send()", status);
|
||||
}
|
||||
@@ -927,4 +1032,365 @@
|
||||
}
|
||||
}
|
||||
|
||||
+static void turn_on_peer_connection(pj_turn_session *sess,
|
||||
+ pj_uint32_t conn_id,
|
||||
+ const pj_sockaddr_t *peer_addr,
|
||||
+ unsigned addr_len,
|
||||
+ pj_status_t status)
|
||||
+{
|
||||
+ pj_turn_sock *turn_sock = (pj_turn_sock*) pj_turn_session_get_user_data(sess);
|
||||
+ if (turn_sock == NULL || turn_sock->is_destroying) {
|
||||
+ /* We've been destroyed */
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (turn_sock->cb.on_peer_connection) {
|
||||
+ (*turn_sock->cb.on_peer_connection)(turn_sock, conn_id,
|
||||
+ peer_addr, addr_len,
|
||||
+ status);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+PJ_DECL(pj_status_t) pj_turn_connect_peer(pj_turn_sock *turn_sock,
|
||||
+ pj_uint32_t conn_id,
|
||||
+ const pj_sockaddr_t *peer_addr,
|
||||
+ unsigned addr_len)
|
||||
+{
|
||||
+ pj_status_t status;
|
||||
+ pj_turn_tcp_data_connection *new_tcp_cnx = NULL;
|
||||
+
|
||||
+ for (int i=0; i < turn_sock->tcp_cnx_count; ++i) {
|
||||
+ pj_turn_tcp_data_connection *tcp_cnx = &turn_sock->tcp_cnx[i];
|
||||
+ if ((tcp_cnx->flags & CONNECTION_USED) == 0) {
|
||||
+ new_tcp_cnx = tcp_cnx;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (tcp_cnx->id == conn_id)
|
||||
+ // TODO: need log
|
||||
+ return PJ_EINVAL; // TODO: need better error code
|
||||
+ }
|
||||
+
|
||||
+ if (!new_tcp_cnx) {
|
||||
+ if (turn_sock->tcp_cnx_count == PJ_TURN_MAX_TCP_CNX) {
|
||||
+ // TODO: need log
|
||||
+ return PJ_ETOOMANY;
|
||||
+ }
|
||||
+ new_tcp_cnx = &turn_sock->tcp_cnx[turn_sock->tcp_cnx_count++];
|
||||
+ }
|
||||
+
|
||||
+ /* Initialize this TCP connection slot */
|
||||
+ pj_bzero(new_tcp_cnx, sizeof(*new_tcp_cnx));
|
||||
+ new_tcp_cnx->id = conn_id;
|
||||
+ new_tcp_cnx->flags = CONNECTION_USED;
|
||||
+ new_tcp_cnx->turn_sock = turn_sock;
|
||||
+ pj_sockaddr_cp(&new_tcp_cnx->peer_addr, peer_addr);
|
||||
+ new_tcp_cnx->peer_addr_len = addr_len;
|
||||
+
|
||||
+ pj_ioqueue_op_key_init(&new_tcp_cnx->send_key,
|
||||
+ sizeof(new_tcp_cnx->send_key));
|
||||
+
|
||||
+ /* Initiate a new TCP connection on TURN server
|
||||
+ * that will become the peer data connection */
|
||||
+ pj_turn_session_info info;
|
||||
+ int sock_type;
|
||||
+ pj_sock_t sock;
|
||||
+ pj_activesock_cfg asock_cfg;
|
||||
+ pj_activesock_cb asock_cb;
|
||||
+ pj_sockaddr bound_addr, *cfg_bind_addr;
|
||||
+ pj_uint16_t max_bind_retry;
|
||||
+
|
||||
+ /* Get server address from session info */
|
||||
+ pj_turn_session_get_info(turn_sock->sess, &info);
|
||||
+
|
||||
+ assert(turn_sock->conn_type == PJ_TURN_TP_TCP);
|
||||
+ sock_type = pj_SOCK_STREAM();
|
||||
+
|
||||
+ /* Init socket */
|
||||
+ status = pj_sock_socket(turn_sock->af, sock_type, 0, &sock);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_turn_sock_destroy(turn_sock);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ /* Bind socket */
|
||||
+ cfg_bind_addr = &turn_sock->setting.bound_addr;
|
||||
+ max_bind_retry = MAX_BIND_RETRY;
|
||||
+ if (turn_sock->setting.port_range &&
|
||||
+ turn_sock->setting.port_range < max_bind_retry)
|
||||
+ {
|
||||
+ max_bind_retry = turn_sock->setting.port_range;
|
||||
+ }
|
||||
+ pj_sockaddr_init(turn_sock->af, &bound_addr, NULL, 0);
|
||||
+ if (cfg_bind_addr->addr.sa_family == pj_AF_INET() ||
|
||||
+ cfg_bind_addr->addr.sa_family == pj_AF_INET6())
|
||||
+ {
|
||||
+ pj_sockaddr_cp(&bound_addr, cfg_bind_addr);
|
||||
+ }
|
||||
+ status = pj_sock_bind_random(sock, &bound_addr,
|
||||
+ turn_sock->setting.port_range,
|
||||
+ max_bind_retry);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_turn_sock_destroy(turn_sock);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ /* Apply socket buffer size */
|
||||
+ if (turn_sock->setting.so_rcvbuf_size > 0) {
|
||||
+ unsigned sobuf_size = turn_sock->setting.so_rcvbuf_size;
|
||||
+ status = pj_sock_setsockopt_sobuf(sock, pj_SO_RCVBUF(),
|
||||
+ PJ_TRUE, &sobuf_size);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_perror(3, turn_sock->obj_name, status,
|
||||
+ "Failed setting SO_RCVBUF");
|
||||
+ } else {
|
||||
+ if (sobuf_size < turn_sock->setting.so_rcvbuf_size) {
|
||||
+ PJ_LOG(4, (turn_sock->obj_name,
|
||||
+ "Warning! Cannot set SO_RCVBUF as configured,"
|
||||
+ " now=%d, configured=%d", sobuf_size,
|
||||
+ turn_sock->setting.so_rcvbuf_size));
|
||||
+ } else {
|
||||
+ PJ_LOG(5, (turn_sock->obj_name, "SO_RCVBUF set to %d",
|
||||
+ sobuf_size));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (turn_sock->setting.so_sndbuf_size > 0) {
|
||||
+ unsigned sobuf_size = turn_sock->setting.so_sndbuf_size;
|
||||
+ status = pj_sock_setsockopt_sobuf(sock, pj_SO_SNDBUF(),
|
||||
+ PJ_TRUE, &sobuf_size);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_perror(3, turn_sock->obj_name, status,
|
||||
+ "Failed setting SO_SNDBUF");
|
||||
+ } else {
|
||||
+ if (sobuf_size < turn_sock->setting.so_sndbuf_size) {
|
||||
+ PJ_LOG(4, (turn_sock->obj_name,
|
||||
+ "Warning! Cannot set SO_SNDBUF as configured,"
|
||||
+ " now=%d, configured=%d", sobuf_size,
|
||||
+ turn_sock->setting.so_sndbuf_size));
|
||||
+ } else {
|
||||
+ PJ_LOG(5, (turn_sock->obj_name, "SO_SNDBUF set to %d",
|
||||
+ sobuf_size));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Create active socket */
|
||||
+ pj_activesock_cfg_default(&asock_cfg);
|
||||
+ asock_cfg.grp_lock = turn_sock->grp_lock;
|
||||
+
|
||||
+ pj_bzero(&asock_cb, sizeof(asock_cb));
|
||||
+ asock_cb.on_data_read = &on_peer_data_read;
|
||||
+ asock_cb.on_connect_complete = &on_peer_connect_complete;
|
||||
+ status = pj_activesock_create(turn_sock->pool, sock,
|
||||
+ sock_type, &asock_cfg,
|
||||
+ turn_sock->cfg.ioqueue, &asock_cb,
|
||||
+ new_tcp_cnx,
|
||||
+ &new_tcp_cnx->active_tcp_sock);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_turn_sock_destroy(turn_sock);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ char addrtxt[PJ_INET6_ADDRSTRLEN+8];
|
||||
+ PJ_LOG(5,(turn_sock->pool->obj_name,
|
||||
+ "Connecting to %s",
|
||||
+ pj_sockaddr_print(&info.server, addrtxt,
|
||||
+ sizeof(addrtxt), 3)));
|
||||
+
|
||||
+ status = pj_activesock_start_connect(new_tcp_cnx->active_tcp_sock,
|
||||
+ turn_sock->pool,
|
||||
+ &info.server,
|
||||
+ pj_sockaddr_get_len(&info.server));
|
||||
+ if (status == PJ_SUCCESS) {
|
||||
+ on_peer_connect_complete(new_tcp_cnx->active_tcp_sock, PJ_SUCCESS);
|
||||
+ } else if (status != PJ_EPENDING) {
|
||||
+ pj_perror(3, turn_sock->pool->obj_name, status,
|
||||
+ "Failed to connect to %s",
|
||||
+ pj_sockaddr_print(&info.server, addrtxt,
|
||||
+ sizeof(addrtxt), 3));
|
||||
+ pj_turn_sock_destroy(turn_sock);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ return PJ_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static pj_bool_t on_peer_data_read(pj_activesock_t *asock,
|
||||
+ void *data,
|
||||
+ pj_size_t size,
|
||||
+ pj_status_t status,
|
||||
+ pj_size_t *remainder)
|
||||
+{
|
||||
+ pj_turn_tcp_data_connection *tcp_cnx;
|
||||
+ pj_turn_sock *turn_sock;
|
||||
+
|
||||
+ tcp_cnx = (pj_turn_tcp_data_connection*) pj_activesock_get_user_data(asock);
|
||||
+ pj_assert(tcp_cnx && tcp_cnx->turn_sock);
|
||||
+ turn_sock = tcp_cnx->turn_sock;
|
||||
+
|
||||
+ pj_grp_lock_acquire(turn_sock->grp_lock);
|
||||
+
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ peer_cnx_fail(tcp_cnx, "Peer connection closed", status);
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return PJ_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ *remainder = size;
|
||||
+ pj_uint8_t* pkt = data;
|
||||
+ while (*remainder > 0) {
|
||||
+ if ((tcp_cnx->flags & CONNECTION_READY) != 0) {
|
||||
+ if (turn_sock->cb.on_rx_data)
|
||||
+ turn_sock->cb.on_rx_data(turn_sock, pkt, *remainder,
|
||||
+ &tcp_cnx->peer_addr,
|
||||
+ tcp_cnx->peer_addr_len);
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ *remainder = 0;
|
||||
+ return PJ_TRUE;
|
||||
+ }
|
||||
|
||||
+ /* STUN session waiting for ConnectBind response */
|
||||
+ pj_size_t parsed_len;
|
||||
+ unsigned options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK;
|
||||
+ status = pj_stun_session_on_rx_pkt(tcp_cnx->stun_sess, pkt, size,
|
||||
+ options, NULL, &parsed_len,
|
||||
+ &tcp_cnx->peer_addr,
|
||||
+ tcp_cnx->peer_addr_len);
|
||||
+
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ peer_cnx_fail(tcp_cnx, "Peer connection closed", status);
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return PJ_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ PJ_LOG(3, ("rfc6062",
|
||||
+ "parsed STUN msg (read %zu byte(s) over %zu), status=%u",
|
||||
+ parsed_len, size, status));
|
||||
+
|
||||
+ pkt += parsed_len;
|
||||
+ *remainder -= parsed_len;
|
||||
+ }
|
||||
+
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+
|
||||
+ return PJ_TRUE;
|
||||
+}
|
||||
+
|
||||
+static pj_bool_t on_peer_connect_complete(pj_activesock_t *asock,
|
||||
+ pj_status_t status)
|
||||
+{
|
||||
+ pj_turn_tcp_data_connection *tcp_cnx;
|
||||
+ pj_turn_sock *turn_sock;
|
||||
+
|
||||
+ PJ_LOG(1, ("rfc6062", "peer data connection %s", status == PJ_SUCCESS ? "ready" : "failed"));
|
||||
+
|
||||
+ tcp_cnx = (pj_turn_tcp_data_connection*) pj_activesock_get_user_data(asock);
|
||||
+ if (!tcp_cnx)
|
||||
+ return PJ_FALSE;
|
||||
+
|
||||
+ turn_sock = tcp_cnx->turn_sock;
|
||||
+ pj_assert(turn_sock);
|
||||
+
|
||||
+ pj_grp_lock_acquire(turn_sock->grp_lock);
|
||||
+
|
||||
+ PJ_LOG(3, ("rfc6062", "peer data connection %s", status == PJ_SUCCESS ? "ready" : "failed"));
|
||||
+
|
||||
+ // TODO: handle failures
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return PJ_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* start pending read operation */
|
||||
+ status = pj_activesock_start_read(asock, turn_sock->pool,
|
||||
+ turn_sock->setting.max_pkt_size, 0);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ // TODO: error handling
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return PJ_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Create a temporary STUN session to send the ConnectBind request */
|
||||
+ pj_stun_session_cb stun_cb;
|
||||
+ pj_bzero(&stun_cb, sizeof(stun_cb));
|
||||
+ stun_cb.on_send_msg = &on_tcp_stun_send_msg;
|
||||
+ stun_cb.on_request_complete = &on_tcp_stun_request_complete;
|
||||
+ status = pj_stun_session_create(&turn_sock->cfg, NULL,
|
||||
+ &stun_cb, PJ_FALSE, NULL,
|
||||
+ &tcp_cnx->stun_sess);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return PJ_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ pj_stun_session_set_user_data(tcp_cnx->stun_sess, tcp_cnx);
|
||||
+
|
||||
+ /* Copy credentials from control connection */
|
||||
+ pj_stun_session_set_credential(tcp_cnx->stun_sess, PJ_STUN_AUTH_LONG_TERM, &turn_sock->cred);
|
||||
+ pj_str_t server_nonce, server_realm;
|
||||
+ pj_turn_session_get_server_cred(turn_sock->sess, turn_sock->pool, &server_nonce, &server_realm);
|
||||
+ pj_stun_session_set_server_cred(tcp_cnx->stun_sess, &server_nonce, &server_realm);
|
||||
+
|
||||
+ /* Send ConnectBind request */
|
||||
+ pj_stun_tx_data *tdata;
|
||||
+ status = pj_stun_session_create_req(tcp_cnx->stun_sess, PJ_STUN_CONNECTION_BIND_REQUEST,
|
||||
+ PJ_STUN_MAGIC, NULL, &tdata);
|
||||
+ if (status != PJ_SUCCESS) {
|
||||
+ pj_stun_session_destroy(tcp_cnx->stun_sess);
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return PJ_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* MUST include REQUESTED-TRANSPORT attribute */
|
||||
+ pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg, PJ_STUN_ATTR_CONNECTION_ID, tcp_cnx->id);
|
||||
+
|
||||
+ PJ_LOG(3, ("rfc6062", "bind TCP connection id=%x", tcp_cnx->id));
|
||||
+ status = pj_stun_session_send_msg(tcp_cnx->stun_sess, tcp_cnx, PJ_FALSE, PJ_FALSE,
|
||||
+ &tcp_cnx->peer_addr, tcp_cnx->peer_addr_len,
|
||||
+ tdata);
|
||||
+ if (status != PJ_SUCCESS && status != PJ_EPENDING) {
|
||||
+ pj_stun_session_destroy(tcp_cnx->stun_sess);
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ pj_grp_lock_release(turn_sock->grp_lock);
|
||||
+ return PJ_TRUE;
|
||||
+}
|
||||
+
|
||||
+static pj_status_t on_tcp_stun_send_msg(pj_stun_session *sess,
|
||||
+ void *token,
|
||||
+ const void *pkt,
|
||||
+ pj_size_t pkt_size,
|
||||
+ const pj_sockaddr_t *dst_addr,
|
||||
+ unsigned addr_len)
|
||||
+{
|
||||
+ pj_status_t status;
|
||||
+ pj_turn_tcp_data_connection *tcp_cnx = (pj_turn_tcp_data_connection*) token;
|
||||
+ pj_assert(tcp_cnx != NULL && tcp_cnx->turn_sock != NULL);
|
||||
+
|
||||
+ pj_grp_lock_acquire(tcp_cnx->turn_sock->grp_lock);
|
||||
+ status = pj_activesock_send(tcp_cnx->active_tcp_sock, &tcp_cnx->send_key, pkt, &pkt_size, 0);
|
||||
+ pj_grp_lock_release(tcp_cnx->turn_sock->grp_lock);
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+static void on_tcp_stun_request_complete(pj_stun_session *sess,
|
||||
+ pj_status_t status,
|
||||
+ void *token,
|
||||
+ pj_stun_tx_data *tdata,
|
||||
+ const pj_stun_msg *response,
|
||||
+ const pj_sockaddr_t *src_addr,
|
||||
+ unsigned src_addr_len)
|
||||
+{
|
||||
+ pj_turn_tcp_data_connection *tcp_cnx = (pj_turn_tcp_data_connection*) token;
|
||||
+ pj_assert(tcp_cnx != NULL && tcp_cnx->turn_sock != NULL);
|
||||
+
|
||||
+ pj_grp_lock_acquire(tcp_cnx->turn_sock->grp_lock);
|
||||
+ pj_stun_session_destroy(tcp_cnx->stun_sess);
|
||||
+ tcp_cnx->stun_sess = NULL;
|
||||
+ tcp_cnx->flags |= CONNECTION_READY;
|
||||
+ PJ_LOG(3, ("rfc6062", "peer data connection bind %s", status == PJ_SUCCESS ? "succeed" : "failed"));
|
||||
+ pj_grp_lock_release(tcp_cnx->turn_sock->grp_lock);
|
||||
+}
|
||||
|
Loading…
Reference in a new issue