summaryrefslogtreecommitdiff
path: root/pjnath/src
diff options
context:
space:
mode:
Diffstat (limited to 'pjnath/src')
-rw-r--r--pjnath/src/pjnath/errno.c121
-rw-r--r--pjnath/src/pjnath/ice.c566
-rw-r--r--pjnath/src/pjnath/stun_auth.c22
-rw-r--r--pjnath/src/pjnath/stun_endpoint.c20
-rw-r--r--pjnath/src/pjnath/stun_msg.c84
-rw-r--r--pjnath/src/pjnath/stun_msg_dump.c12
-rw-r--r--pjnath/src/pjnath/stun_session.c49
-rw-r--r--pjnath/src/pjnath/stun_transaction.c28
-rw-r--r--pjnath/src/pjstun-client/client_main.c1
-rw-r--r--pjnath/src/pjstun-srv-test/bind_usage.c2
-rw-r--r--pjnath/src/pjstun-srv-test/server.c6
-rw-r--r--pjnath/src/pjstun-srv-test/server.h3
-rw-r--r--pjnath/src/pjstun-srv-test/turn_usage.c10
13 files changed, 808 insertions, 116 deletions
diff --git a/pjnath/src/pjnath/errno.c b/pjnath/src/pjnath/errno.c
new file mode 100644
index 00000000..bfde1bc0
--- /dev/null
+++ b/pjnath/src/pjnath/errno.c
@@ -0,0 +1,121 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjnath/errno.h>
+#include <pj/string.h>
+
+
+
+/* PJNATH's own error codes/messages
+ * MUST KEEP THIS ARRAY SORTED!!
+ * Message must be limited to 64 chars!
+ */
+#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0
+static const struct
+{
+ int code;
+ const char *msg;
+} err_str[] =
+{
+ /* STUN */
+ PJ_BUILD_ERR( PJNATH_ESTUNTOOMANYATTR, "Too many STUN attributes"),
+ PJ_BUILD_ERR( PJNATH_ESTUNUNKNOWNATTR, "Unknown STUN attribute"),
+ PJ_BUILD_ERR( PJNATH_ESTUNINADDRLEN, "Invalid STUN socket address length"),
+ PJ_BUILD_ERR( PJNATH_ESTUNIPV6NOTSUPP, "STUN IPv6 attribute not supported"),
+ PJ_BUILD_ERR( PJNATH_ESTUNNOTRESPONSE, "Expecting STUN response message"),
+ PJ_BUILD_ERR( PJNATH_ESTUNINVALIDID, "STUN transaction ID mismatch"),
+ PJ_BUILD_ERR( PJNATH_ESTUNNOHANDLER, "Unable to find STUN handler for the request"),
+ PJ_BUILD_ERR( PJNATH_ESTUNMSGINTPOS, "Found non-FINGERPRINT attr. after MESSAGE-INTEGRITY"),
+ PJ_BUILD_ERR( PJNATH_ESTUNFINGERPOS, "Found STUN attribute after FINGERPRINT"),
+ PJ_BUILD_ERR( PJNATH_ESTUNNOUSERNAME, "Missing STUN USERNAME attribute"),
+ PJ_BUILD_ERR( PJNATH_ESTUNMSGINT, "Missing/invalid STUN MESSAGE-INTEGRITY attribute"),
+ PJ_BUILD_ERR( PJNATH_ESTUNDUPATTR, "Found duplicate STUN attribute"),
+ PJ_BUILD_ERR( PJNATH_ESTUNNOREALM, "Missing STUN REALM attribute"),
+ PJ_BUILD_ERR( PJNATH_ESTUNNONCE, "Missing/stale STUN NONCE attribute value"),
+ PJ_BUILD_ERR( PJNATH_ESTUNTSXFAILED, "STUN transaction terminates with failure"),
+};
+#endif /* PJ_HAS_ERROR_STRING */
+
+
+/*
+ * pjnath_strerror()
+ */
+PJ_DEF(pj_str_t) pjnath_strerror( pj_status_t statcode,
+ char *buf, pj_size_t bufsize )
+{
+ pj_str_t errstr;
+
+#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
+
+ if (statcode >= PJNATH_ERRNO_START &&
+ statcode < PJNATH_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
+ {
+ /* Find the error in the table.
+ * Use binary search!
+ */
+ int first = 0;
+ int n = PJ_ARRAY_SIZE(err_str);
+
+ while (n > 0) {
+ int half = n/2;
+ int mid = first + half;
+
+ if (err_str[mid].code < statcode) {
+ first = mid+1;
+ n -= (half+1);
+ } else if (err_str[mid].code > statcode) {
+ n = half;
+ } else {
+ first = mid;
+ break;
+ }
+ }
+
+
+ if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
+ pj_str_t msg;
+
+ msg.ptr = (char*)err_str[first].msg;
+ msg.slen = pj_ansi_strlen(err_str[first].msg);
+
+ errstr.ptr = buf;
+ pj_strncpy_with_null(&errstr, &msg, bufsize);
+ return errstr;
+
+ }
+ }
+
+#endif /* PJ_HAS_ERROR_STRING */
+
+
+ /* Error not found. */
+ errstr.ptr = buf;
+ errstr.slen = pj_ansi_snprintf(buf, bufsize,
+ "Unknown pjlib-util error %d",
+ statcode);
+
+ return errstr;
+}
+
+
+PJ_DEF(pj_status_t) pjnath_init(void)
+{
+ return pj_register_strerror(PJNATH_ERRNO_START,
+ PJ_ERRNO_SPACE_SIZE,
+ &pjnath_strerror);
+}
diff --git a/pjnath/src/pjnath/ice.c b/pjnath/src/pjnath/ice.c
new file mode 100644
index 00000000..c92ceb5a
--- /dev/null
+++ b/pjnath/src/pjnath/ice.c
@@ -0,0 +1,566 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2005 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <pjnath/ice.h>
+#include <pjnath/errno.h>
+#include <pj/assert.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+
+static void destroy_ice(pj_ice *ice,
+ pj_status_t reason);
+static void ice_set_state(pj_ice *ice,
+ pj_ice_state new_state);
+
+
+PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *cfg,
+ const char *name,
+ int af,
+ int sock_type,
+ pj_ice **p_ice)
+{
+ pj_pool_t *pool;
+ pj_ice *ice;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(cfg && p_ice, PJ_EINVAL);
+ PJ_ASSERT_RETURN(sock_type==PJ_SOCK_DGRAM || sock_type==PJ_SOCK_STREAM,
+ PJ_EINVAL);
+
+ if (!name)
+ name = "ice%p";
+
+ pool = pj_pool_create(cfg->pf, name, 4000, 4000, NULL);
+ ice = PJ_POOL_ZALLOC_T(pool, pj_ice);
+ ice->pool = pool;
+ ice->af = af;
+ ice->sock_type = sock_type;
+
+ pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name),
+ name, ice);
+
+ status = pj_mutex_create_recursive(pool, ice->obj_name,
+ &ice->mutex);
+ if (status != PJ_SUCCESS) {
+ destroy_ice(ice, status);
+ return status;
+ }
+
+ *p_ice = ice;
+
+ return PJ_SUCCESS;
+}
+
+
+static void destroy_ice(pj_ice *ice,
+ pj_status_t reason)
+{
+ if (ice->resv_q) {
+ pj_dns_resolver_cancel_query(ice->resv_q, PJ_FALSE);
+ ice->resv_q = NULL;
+ }
+
+ if (ice->mutex) {
+ pj_mutex_destroy(ice->mutex);
+ ice->mutex = NULL;
+ }
+
+ if (ice->pool) {
+ pj_pool_t *pool = ice->pool;
+ ice->pool = NULL;
+ pj_pool_release(pool);
+ }
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_destroy(pj_ice *ice)
+{
+ destroy_ice(ice, PJ_SUCCESS);
+ return PJ_SUCCESS;
+}
+
+
+static void ice_set_state(pj_ice *ice,
+ pj_ice_state new_state)
+{
+ ice->state = new_state;
+}
+
+static void resolver_cb(void *user_data,
+ pj_status_t status,
+ pj_dns_parsed_packet *response)
+{
+ pj_assert(!"Not implemented yet!");
+}
+
+PJ_DEF(pj_status_t) pj_ice_set_srv(pj_ice *ice,
+ pj_bool_t enable_relay,
+ pj_dns_resolver *resolver,
+ const pj_str_t *domain)
+{
+ char namebuf[128];
+ char *tp_name;
+ pj_str_t name;
+ pj_status_t status;
+
+
+ /* Not implemented yet! */
+ return PJ_ENOTSUP;
+
+
+ PJ_ASSERT_RETURN(ice && resolver && domain, PJ_EINVAL);
+
+ /* Must not have a running resolver. This is because we couldn't
+ * safely cancel the query (there is a race condition situation
+ * between the callback acquiring the mutex and this function
+ * acquiring the mutex)
+ */
+ PJ_ASSERT_RETURN(ice->resv_q==NULL, PJ_EBUSY);
+
+ pj_mutex_lock(ice->mutex);
+
+ /* Reset resolver and server addresses */
+ ice->relay_enabled = enable_relay;
+ ice->resv = resolver;
+ pj_bzero(&ice->stun_srv, sizeof(ice->stun_srv));
+
+ /* Build SRV record name */
+ if (ice->sock_type == PJ_SOCK_DGRAM) {
+ tp_name = "_udp";
+ } else if (ice->sock_type == PJ_SOCK_STREAM) {
+ tp_name = "_tcp";
+ } else {
+ pj_assert(!"Invalid sock_type");
+ pj_mutex_unlock(ice->mutex);
+ return PJ_EBUG;
+ }
+
+ if (enable_relay) {
+ name.ptr = namebuf;
+ name.slen = pj_ansi_snprintf(namebuf, sizeof(namebuf),
+ "_stun-relay.%s.%.*s",
+ tp_name,
+ (int)domain->slen,
+ domain->ptr);
+ } else {
+ name.ptr = namebuf;
+ name.slen = pj_ansi_snprintf(namebuf, sizeof(namebuf),
+ "_stun.%s.%.*s",
+ tp_name,
+ (int)domain->slen,
+ domain->ptr);
+ }
+
+ if (name.slen < 1 || name.slen >= sizeof(namebuf)) {
+ pj_mutex_unlock(ice->mutex);
+ return PJ_ENAMETOOLONG;
+ }
+
+ /* Start DNS query */
+ status = pj_dns_resolver_start_query(ice->resv, &name,
+ PJ_DNS_TYPE_SRV, 0,
+ &resolver_cb,
+ ice, &ice->resv_q);
+ if (status != PJ_SUCCESS) {
+ pj_mutex_unlock(ice->mutex);
+ return status;
+ }
+
+ pj_mutex_unlock(ice->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_set_srv_addr(pj_ice *ice,
+ pj_bool_t enable_relay,
+ const pj_sockaddr_t *srv_addr,
+ unsigned addr_len)
+{
+ PJ_ASSERT_RETURN(ice && srv_addr, PJ_EINVAL);
+ /* Must not have a running resolver. This is because we couldn't
+ * safely cancel the query (there is a race condition situation
+ * between the callback acquiring the mutex and this function
+ * acquiring the mutex)
+ */
+ PJ_ASSERT_RETURN(ice->resv_q==NULL, PJ_EBUSY);
+
+ pj_mutex_lock(ice->mutex);
+
+ ice->relay_enabled = enable_relay;
+ pj_memcpy(&ice->stun_srv, srv_addr, addr_len);
+
+ pj_mutex_unlock(ice->mutex);
+
+ return PJ_SUCCESS;
+
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_add_comp(pj_ice *ice,
+ unsigned comp_id,
+ const pj_sockaddr_t *local_addr,
+ unsigned addr_len)
+{
+ pj_status_t status;
+ pj_sock_t sock;
+
+ PJ_ASSERT_RETURN(ice && local_addr && addr_len, PJ_EINVAL);
+
+ status = pj_sock_socket(ice->af, ice->sock_type, 0, &sock);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pj_sock_bind(sock, local_addr, addr_len);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pj_ice_add_sock_comp(ice, comp_id, sock);
+ if (status != PJ_SUCCESS) {
+ pj_sock_close(sock);
+ return status;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_add_sock_comp( pj_ice *ice,
+ unsigned comp_id,
+ pj_sock_t sock)
+{
+ PJ_ASSERT_RETURN(ice && sock != PJ_INVALID_SOCKET, PJ_EINVAL);
+ PJ_ASSERT_RETURN(ice->comp_cnt < PJ_ARRAY_SIZE(ice->comp), PJ_ETOOMANY);
+
+ pj_mutex_lock(ice->mutex);
+ ice->comp[ice->comp_cnt].comp_id = comp_id;
+ ice->comp[ice->comp_cnt].sock = sock;
+ ++ice->comp_cnt;
+ pj_mutex_unlock(ice->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+static pj_status_t gather_host_cands(pj_ice *ice)
+{
+ unsigned i;
+ pj_status_t status;
+
+ for (i=0; i<ice->comp_cnt; ++i) {
+ pj_ice_comp *comp = &ice->comp[i];
+ pj_sockaddr addr;
+ int addr_len;
+
+ addr_len = sizeof(addr);
+ status = pj_sock_getsockname(comp->sock, &addr, &addr_len);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (addr.ipv4.sin_addr.s_addr == 0) {
+ status = pj_gethostip(&addr.ipv4.sin_addr);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
+
+ status = pj_ice_add_cand(ice, i, PJ_ICE_CAND_TYPE_HOST, 65535,
+ NULL, &addr, &addr, NULL,
+ sizeof(pj_sockaddr_in), NULL);
+ if (status != PJ_SUCCESS)
+ return status;
+ }
+
+ return PJ_SUCCESS;
+}
+
+static pj_status_t gather_mapped_cands(pj_ice *ice)
+{
+ return PJ_ENOTSUP;
+}
+
+static pj_status_t gather_relayed_cands(pj_ice *ice)
+{
+ return PJ_ENOTSUP;
+}
+
+PJ_DEF(pj_status_t) pj_ice_start_gather(pj_ice *ice,
+ unsigned flags)
+{
+ pj_status_t status;
+
+ /* Gather host candidate */
+ status = gather_host_cands(ice);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ PJ_TODO(GATHER_MAPPED_AND_RELAYED_CANDIDATES);
+
+ ice_set_state(ice, PJ_ICE_STATE_CAND_COMPLETE);
+
+ return PJ_SUCCESS;
+}
+
+
+static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type,
+ pj_uint32_t local_pref,
+ pj_uint32_t comp_id)
+{
+ static pj_uint32_t type_pref[] =
+ {
+ PJ_ICE_HOST_PREF,
+ PJ_ICE_MAPPED_PREF,
+ PJ_ICE_PEER_MAPPED_PREF,
+ PJ_ICE_RELAYED_PREF
+ };
+
+ return ((1 << 24) * type_pref[type]) +
+ ((1 << 8) * local_pref) +
+ (256 - comp_id);
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_add_cand(pj_ice *ice,
+ unsigned comp_id,
+ pj_ice_cand_type type,
+ pj_uint16_t local_pref,
+ const pj_str_t *foundation,
+ const pj_sockaddr_t *addr,
+ const pj_sockaddr_t *base_addr,
+ const pj_sockaddr_t *srv_addr,
+ int addr_len,
+ unsigned *p_cand_id)
+{
+ pj_ice_cand *cand;
+ pj_status_t status = PJ_SUCCESS;
+
+ pj_mutex_lock(ice->mutex);
+
+ if (ice->cand_cnt >= PJ_ARRAY_SIZE(ice->cand)) {
+ status = PJ_ETOOMANY;
+ goto on_error;
+ }
+
+ cand = &ice->cand[ice->cand_cnt];
+ cand->comp_id = comp_id;
+ cand->type = type;
+ pj_strdup(ice->pool, &cand->foundation, foundation);
+ cand->prio = CALC_CAND_PRIO(type, local_pref, cand->comp_id);
+ pj_memcpy(&cand->addr, addr, addr_len);
+ pj_memcpy(&cand->base_addr, base_addr, addr_len);
+ if (srv_addr)
+ pj_memcpy(&cand->srv_addr, srv_addr, addr_len);
+ else
+ pj_bzero(&cand->srv_addr, sizeof(cand->srv_addr));
+
+ if (p_cand_id)
+ *p_cand_id = ice->cand_cnt;
+
+ ++ice->cand_cnt;
+
+on_error:
+ pj_mutex_unlock(ice->mutex);
+ return status;
+}
+
+
+PJ_DEF(unsigned) pj_ice_get_cand_cnt(pj_ice *ice)
+{
+ return ice->cand_cnt;
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_enum_cands(pj_ice *ice,
+ unsigned sort_by,
+ unsigned *p_count,
+ unsigned cand_ids[])
+{
+ unsigned i, count;
+
+ pj_mutex_lock(ice->mutex);
+
+ count = (*p_count < ice->cand_cnt) ? *p_count : ice->cand_cnt;
+ for (i=0; i<count; ++i)
+ cand_ids[i] = i;
+
+ *p_count = count;
+ pj_mutex_unlock(ice->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_get_cand(pj_ice *ice,
+ unsigned cand_id,
+ pj_ice_cand **p_cand)
+{
+ PJ_ASSERT_RETURN(ice && p_cand, PJ_EINVAL);
+ PJ_ASSERT_RETURN(cand_id <= ice->cand_cnt, PJ_EINVAL);
+
+ *p_cand = &ice->cand[cand_id];
+
+ return PJ_SUCCESS;
+}
+
+#ifndef MIN
+# define MIN(a,b) (a < b ? a : b)
+#endif
+
+#ifndef MAX
+# define MAX(a,b) (a > b ? a : b)
+#endif
+
+static pj_uint64_t CALC_CHECK_PRIO(pj_uint32_t O, pj_uint32_t A)
+{
+ return ((pj_uint64_t)1 << 32) * MIN(O, A) +
+ (pj_uint64_t)2 * MAX(O, A) + (O>A ? 1 : 0);
+}
+
+
+PJ_DEF(pj_status_t) pj_ice_create_check_list(pj_ice *ice,
+ pj_bool_t is_remote_offer,
+ unsigned rem_cand_cnt,
+ const pj_ice_cand rem_cand[])
+{
+ pj_ice_checklist *clist;
+ unsigned i, j, count;
+
+ PJ_ASSERT_RETURN(ice && rem_cand_cnt && rem_cand, PJ_EINVAL);
+
+ pj_mutex_lock(ice->mutex);
+
+ /* Create checklist */
+ clist = &ice->cklist;
+ clist->checks = pj_pool_calloc(ice->pool,
+ ice->cand_cnt * rem_cand_cnt,
+ sizeof(pj_ice_check));
+ for (i=0, count=0; i<ice->cand_cnt; ++i) {
+ for (j=0; j<rem_cand_cnt; ++j) {
+
+ pj_ice_check *c = &clist->checks[count++];
+
+ /* A local candidate is paired with a remote candidate if
+ * and only if the two candidates have the same component ID
+ * and have the same IP address version.
+ */
+ if (ice->cand[i].comp_id != rem_cand[j].comp_id ||
+ pj_strcmp(&ice->cand[i].foundation,&rem_cand[j].foundation)==0)
+ {
+ continue;
+ }
+
+ c->local_cand_id = i;
+
+ if (is_remote_offer) {
+ c->check_prio = CALC_CHECK_PRIO(rem_cand[j].prio,
+ ice->cand[i].prio);
+ } else {
+ c->check_prio = CALC_CHECK_PRIO(ice->cand[i].prio,
+ rem_cand[j].prio);
+ }
+
+ c->rem_type = rem_cand[j].type;
+ pj_strdup(ice->pool, &c->rem_foundation, &rem_cand[j].foundation);
+ c->rem_prio = rem_cand[j].prio;
+ pj_memcpy(&c->rem_addr, &rem_cand[j].addr,
+ sizeof(rem_cand[j].addr));
+ pj_memcpy(&c->rem_base_addr, &rem_cand[j].base_addr,
+ sizeof(rem_cand[j].addr));
+ }
+ }
+
+ clist->count = count;
+
+ /* Sort checklist based on priority */
+ for (i=0; i<clist->count-1; ++i) {
+ unsigned highest = i;
+ for (j=i+1; j<clist->count; ++j) {
+ if (clist->checks[j].check_prio >
+ clist->checks[highest].check_prio)
+ {
+ highest = j;
+ }
+ }
+
+ if (highest != i) {
+ pj_ice_check tmp;
+
+ pj_memcpy(&tmp, &clist->checks[i], sizeof(pj_ice_check));
+ pj_memcpy(&clist->checks[i], &clist->checks[highest],
+ sizeof(pj_ice_check));
+ pj_memcpy(&clist->checks[highest], &tmp, sizeof(pj_ice_check));
+ }
+ }
+
+ /* Prune the checklist */
+ for (i=0; i<clist->count; ++i) {
+ PJ_TODO(PRUNE_CHECKLIST);
+ }
+
+ pj_mutex_lock(ice->mutex);
+
+ return PJ_SUCCESS;
+}
+
+
+/* Start periodic check for the specified checklist */
+static pj_status_t start_periodic_check(pj_ice *ice, pj_ice_checklist *clist)
+{
+}
+
+
+/* Start ICE check */
+PJ_DEF(pj_status_t) pj_ice_start_check(pj_ice *ice)
+{
+ pj_ice_checklist *clist;
+ unsigned i, comp_id;
+ pj_str_t fnd;
+
+ PJ_ASSERT_RETURN(ice, PJ_EINVAL);
+
+ clist = &ice->cklist;
+
+ if (clist->count == 0)
+ return PJ_EICENOCHECKLIST;
+
+ /* Pickup the first pair and set the state to Waiting */
+ clist->checks[0].check_state = PJ_ICE_CHECK_STATE_WAITING;
+
+ /* Find all of the other pairs in that check list with the same
+ * component ID, but different foundations, and sets all of their
+ * states to Waiting as well.
+ */
+ comp_id = ice->cand[clist->checks[0].local_cand_id].comp_id;
+ fnd = ice->cand[clist->checks[0].local_cand_id].foundation;
+
+ for (i=1; i<clist->count; ++i) {
+ pj_ice_check *cki = &clist->checks[i];
+
+ if (ice->cand[cki->local_cand_id].comp_id != comp_id)
+ continue;
+
+ if (pj_strcmp(&ice->cand[cki->local_cand_id].foundation, &fnd)==0)
+ continue;
+
+ clist->checks[i].check_state = PJ_ICE_CHECK_STATE_WAITING;
+ }
+
+ /* Start periodic check */
+ return start_periodic_check(ice, clist);
+}
diff --git a/pjnath/src/pjnath/stun_auth.c b/pjnath/src/pjnath/stun_auth.c
index 9a94fe0d..071019b8 100644
--- a/pjnath/src/pjnath/stun_auth.c
+++ b/pjnath/src/pjnath/stun_auth.c
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjlib-util/stun_auth.h>
-#include <pjlib-util/errno.h>
+#include <pjnath/stun_auth.h>
+#include <pjnath/errno.h>
#include <pjlib-util/hmac_sha1.h>
#include <pjlib-util/sha1.h>
#include <pj/assert.h>
@@ -159,7 +159,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_UNAUTHORIZED, NULL,
&realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNMSGINT;
+ return PJNATH_ESTUNMSGINT;
}
/* Next check that USERNAME is present */
@@ -170,7 +170,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_MISSING_USERNAME, NULL,
&realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNNOUSERNAME;
+ return PJNATH_ESTUNNOUSERNAME;
}
/* Get REALM, if any */
@@ -201,7 +201,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_UNKNOWN_USERNAME, NULL,
&realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNUSERNAME;
+ return PJNATH_ESTUNUSERNAME;
}
@@ -216,7 +216,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_MISSING_REALM, NULL,
&realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNNOREALM;
+ return PJNATH_ESTUNNOREALM;
} else if (realm.slen != 0 && arealm != NULL) {
/* We want long term, and REALM is present */
@@ -227,7 +227,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_MISSING_NONCE,
NULL, &realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNNONCE;
+ return PJNATH_ESTUNNONCE;
}
/* Verify REALM matches */
@@ -237,7 +237,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_MISSING_REALM,
NULL, &realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNNOREALM;
+ return PJNATH_ESTUNNOREALM;
}
/* Valid case, will validate the message integrity later */
@@ -260,7 +260,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_MISSING_NONCE,
NULL, &realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNNONCE;
+ return PJNATH_ESTUNNONCE;
}
}
@@ -286,7 +286,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_STALE_NONCE,
NULL, &realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNNONCE;
+ return PJNATH_ESTUNNONCE;
}
}
@@ -331,7 +331,7 @@ PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,
create_challenge(pool, msg, PJ_STUN_SC_INTEGRITY_CHECK_FAILURE,
NULL, &realm, &nonce, p_response);
}
- return PJLIB_UTIL_ESTUNMSGINT;
+ return PJNATH_ESTUNMSGINT;
}
/* Everything looks okay! */
diff --git a/pjnath/src/pjnath/stun_endpoint.c b/pjnath/src/pjnath/stun_endpoint.c
index 277e385e..3be6407d 100644
--- a/pjnath/src/pjnath/stun_endpoint.c
+++ b/pjnath/src/pjnath/stun_endpoint.c
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjlib-util/stun_endpoint.h>
-#include <pjlib-util/errno.h>
+#include <pjnath/stun_endpoint.h>
+#include <pjnath/errno.h>
#include <pj/assert.h>
#include <pj/pool.h>
@@ -25,14 +25,14 @@
/*
* Create a STUN endpoint instance.
*/
-PJ_DEF(pj_status_t) pj_stun_endpoint_create( pj_pool_factory *factory,
- unsigned options,
- pj_ioqueue_t *ioqueue,
- pj_timer_heap_t *timer_heap,
- pj_stun_endpoint **p_endpt)
+PJ_DEF(pj_status_t) pj_stun_config_create( pj_pool_factory *factory,
+ unsigned options,
+ pj_ioqueue_t *ioqueue,
+ pj_timer_heap_t *timer_heap,
+ pj_stun_config **p_endpt)
{
pj_pool_t *pool;
- pj_stun_endpoint *endpt;
+ pj_stun_config *endpt;
PJ_ASSERT_RETURN(factory && p_endpt, PJ_EINVAL);
@@ -40,7 +40,7 @@ PJ_DEF(pj_status_t) pj_stun_endpoint_create( pj_pool_factory *factory,
if (!pool)
return PJ_ENOMEM;
- endpt = PJ_POOL_ZALLOC_T(pool, pj_stun_endpoint);
+ endpt = PJ_POOL_ZALLOC_T(pool, pj_stun_config);
endpt->pool = pool;
endpt->pf = factory;
endpt->options = options;
@@ -58,7 +58,7 @@ PJ_DEF(pj_status_t) pj_stun_endpoint_create( pj_pool_factory *factory,
/*
* Destroy STUN endpoint instance.
*/
-PJ_DEF(pj_status_t) pj_stun_endpoint_destroy(pj_stun_endpoint *endpt)
+PJ_DEF(pj_status_t) pj_stun_config_destroy(pj_stun_config *endpt)
{
PJ_ASSERT_RETURN(endpt, PJ_EINVAL);
diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c
index 1c750d8e..b361898f 100644
--- a/pjnath/src/pjnath/stun_msg.c
+++ b/pjnath/src/pjnath/stun_msg.c
@@ -16,9 +16,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjlib-util/stun_msg.h>
+#include <pjnath/stun_msg.h>
+#include <pjnath/errno.h>
#include <pjlib-util/crc32.h>
-#include <pjlib-util/errno.h>
#include <pjlib-util/hmac_sha1.h>
#include <pjlib-util/md5.h>
#include <pj/assert.h>
@@ -558,7 +558,7 @@ pj_stun_sockaddr_attr_create(pj_pool_t *pool,
attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr);
INIT_ATTR(attr, attr_type, STUN_GENERIC_IP_ADDR_LEN);
- pj_memcpy(&attr->addr, addr, addr_len);
+ pj_memcpy(&attr->sockaddr, addr, addr_len);
attr->xor_ed = xor_ed;
*p_attr = attr;
@@ -606,19 +606,19 @@ static pj_status_t decode_sockaddr_attr(pj_pool_t *pool,
/* Check that the attribute length is valid */
if (attr->hdr.length != STUN_GENERIC_IP_ADDR_LEN)
- return PJLIB_UTIL_ESTUNINATTRLEN;
+ return PJNATH_ESTUNINATTRLEN;
/* Check address family */
val = *(pj_uint8_t*)(buf + ATTR_HDR_LEN + 1);
/* Check address family is valid (only supports ipv4 for now) */
if (val != 1)
- return PJLIB_UTIL_ESTUNIPV6NOTSUPP;
+ return PJNATH_ESTUNIPV6NOTSUPP;
/* Get port and address */
- pj_sockaddr_in_init(&attr->addr.ipv4, NULL, 0);
- pj_memcpy(&attr->addr.ipv4.sin_port, buf+ATTR_HDR_LEN+2, 2);
- pj_memcpy(&attr->addr.ipv4.sin_addr, buf+ATTR_HDR_LEN+4, 4);
+ pj_sockaddr_in_init(&attr->sockaddr.ipv4, NULL, 0);
+ pj_memcpy(&attr->sockaddr.ipv4.sin_port, buf+ATTR_HDR_LEN+2, 2);
+ pj_memcpy(&attr->sockaddr.ipv4.sin_addr, buf+ATTR_HDR_LEN+4, 4);
/* Done */
*p_attr = attr;
@@ -644,22 +644,22 @@ static pj_status_t decode_xored_sockaddr_attr(pj_pool_t *pool,
/* Check that the attribute length is valid */
if (attr->hdr.length != STUN_GENERIC_IP_ADDR_LEN)
- return PJLIB_UTIL_ESTUNINATTRLEN;
+ return PJNATH_ESTUNINATTRLEN;
/* Check address family */
val = *(pj_uint8_t*)(buf + ATTR_HDR_LEN + 1);
/* Check address family is valid (only supports ipv4 for now) */
if (val != 1)
- return PJLIB_UTIL_ESTUNIPV6NOTSUPP;
+ return PJNATH_ESTUNIPV6NOTSUPP;
/* Get port and address */
- pj_sockaddr_in_init(&attr->addr.ipv4, NULL, 0);
- pj_memcpy(&attr->addr.ipv4.sin_port, buf+ATTR_HDR_LEN+2, 2);
- pj_memcpy(&attr->addr.ipv4.sin_addr, buf+ATTR_HDR_LEN+4, 4);
+ pj_sockaddr_in_init(&attr->sockaddr.ipv4, NULL, 0);
+ pj_memcpy(&attr->sockaddr.ipv4.sin_port, buf+ATTR_HDR_LEN+2, 2);
+ pj_memcpy(&attr->sockaddr.ipv4.sin_addr, buf+ATTR_HDR_LEN+4, 4);
- attr->addr.ipv4.sin_port ^= 0x2112;
- attr->addr.ipv4.sin_addr.s_addr ^= pj_htonl(0x2112A442);
+ attr->sockaddr.ipv4.sin_port ^= pj_htons(0x2112);
+ attr->sockaddr.ipv4.sin_addr.s_addr ^= pj_htonl(0x2112A442);
/* Done */
*p_attr = attr;
@@ -693,17 +693,17 @@ static pj_status_t encode_sockaddr_attr(const void *a, pj_uint8_t *buf,
*buf++ = '\0';
/* Family (IPv4 only for now) */
- PJ_ASSERT_RETURN(ca->addr.addr.sa_family == PJ_AF_INET, PJ_EINVAL);
+ PJ_ASSERT_RETURN(ca->sockaddr.addr.sa_family == PJ_AF_INET, PJ_EINVAL);
*buf++ = 1;
if (ca->xor_ed) {
pj_uint32_t addr;
pj_uint16_t port;
- addr = ca->addr.ipv4.sin_addr.s_addr;
- port = ca->addr.ipv4.sin_port;
+ addr = ca->sockaddr.ipv4.sin_addr.s_addr;
+ port = ca->sockaddr.ipv4.sin_port;
- port ^= 0x2112;
+ port ^= pj_htons(0x2112);
addr ^= pj_htonl(0x2112A442);
/* Port */
@@ -716,11 +716,11 @@ static pj_status_t encode_sockaddr_attr(const void *a, pj_uint8_t *buf,
} else {
/* Port */
- pj_memcpy(buf, &ca->addr.ipv4.sin_port, 2);
+ pj_memcpy(buf, &ca->sockaddr.ipv4.sin_port, 2);
buf += 2;
/* Address */
- pj_memcpy(buf, &ca->addr.ipv4.sin_addr, 4);
+ pj_memcpy(buf, &ca->sockaddr.ipv4.sin_addr, 4);
buf += 4;
}
@@ -892,7 +892,7 @@ static pj_status_t decode_empty_attr(pj_pool_t *pool,
/* Check that the attribute length is valid */
if (attr->hdr.length != ATTR_HDR_LEN)
- return PJLIB_UTIL_ESTUNINATTRLEN;
+ return PJNATH_ESTUNINATTRLEN;
/* Done */
*p_attr = attr;
@@ -992,7 +992,7 @@ static pj_status_t decode_uint_attr(pj_pool_t *pool,
/* Check that the attribute length is valid */
if (attr->hdr.length != STUN_UINT_LEN)
- return PJLIB_UTIL_ESTUNINATTRLEN;
+ return PJNATH_ESTUNINATTRLEN;
/* Done */
*p_attr = attr;
@@ -1088,7 +1088,7 @@ static pj_status_t decode_msgint_attr(pj_pool_t *pool,
/* Check that the attribute length is valid */
if (attr->hdr.length != STUN_MSG_INTEGRITY_LEN)
- return PJLIB_UTIL_ESTUNINATTRLEN;
+ return PJNATH_ESTUNINATTRLEN;
/* Done */
*p_attr = attr;
@@ -1563,18 +1563,18 @@ PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsigned pdu_len,
PJ_ASSERT_RETURN(pdu, PJ_EINVAL);
if (pdu_len < sizeof(pj_stun_msg_hdr))
- return PJLIB_UTIL_ESTUNINMSGLEN;
+ return PJNATH_ESTUNINMSGLEN;
/* First byte of STUN message is always 0x00 or 0x01. */
if (*pdu != 0x00 && *pdu != 0x01)
- return PJLIB_UTIL_ESTUNINMSGTYPE;
+ return PJNATH_ESTUNINMSGTYPE;
/* Check the PDU length */
msg_len = GET_VAL16(pdu, 2);
if ((msg_len + 20 > pdu_len) ||
((options & PJ_STUN_IS_DATAGRAM) && msg_len + 20 != pdu_len))
{
- return PJLIB_UTIL_ESTUNINMSGLEN;
+ return PJNATH_ESTUNINMSGLEN;
}
/* If magic is set, then there is great possibility that this is
@@ -1589,13 +1589,13 @@ PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsigned pdu_len,
pj_uint32_t crc;
if (attr_len != 4)
- return PJLIB_UTIL_ESTUNINATTRLEN;
+ return PJNATH_ESTUNINATTRLEN;
crc = pj_crc32_calc(pdu, msg_len + 20);
crc ^= STUN_XOR_FINGERPRINT;
if (crc != fingerprint)
- return PJLIB_UTIL_ESTUNFINGERPRINT;
+ return PJNATH_ESTUNFINGERPRINT;
}
}
@@ -1618,7 +1618,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_create_response(pj_pool_t *pool,
PJ_ASSERT_RETURN(pool && p_response, PJ_EINVAL);
PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(msg_type),
- PJLIB_UTIL_ESTUNINMSGTYPE);
+ PJNATH_ESTUNINMSGTYPE);
/* Create response or error response */
if (err_code)
@@ -1728,7 +1728,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
PJ_STUN_SC_BAD_REQUEST,
&err_msg, p_response);
}
- return PJLIB_UTIL_ESTUNINATTRLEN;
+ return PJNATH_ESTUNINATTRLEN;
}
/* Get the attribute descriptor */
@@ -1757,7 +1757,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
}
}
- return PJLIB_UTIL_ESTUNUNKNOWNATTR;
+ return PJNATH_ESTUNUNKNOWNATTR;
}
} else {
@@ -1805,7 +1805,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
PJ_STUN_SC_BAD_REQUEST,
NULL, p_response);
}
- return PJLIB_UTIL_ESTUNDUPATTR;
+ return PJNATH_ESTUNDUPATTR;
}
has_msg_int = PJ_TRUE;
@@ -1819,7 +1819,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
PJ_STUN_SC_BAD_REQUEST,
NULL, p_response);
}
- return PJLIB_UTIL_ESTUNDUPATTR;
+ return PJNATH_ESTUNDUPATTR;
}
has_fingerprint = PJ_TRUE;
} else {
@@ -1833,8 +1833,8 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
PJ_STUN_SC_BAD_REQUEST,
NULL, p_response);
}
- return has_fingerprint ? PJLIB_UTIL_ESTUNFINGERPOS :
- PJLIB_UTIL_ESTUNMSGINTPOS;
+ return has_fingerprint ? PJNATH_ESTUNFINGERPOS :
+ PJNATH_ESTUNMSGINTPOS;
}
}
@@ -1848,7 +1848,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
PJ_STUN_SC_BAD_REQUEST,
&e, p_response);
}
- return PJLIB_UTIL_ESTUNTOOMANYATTR;
+ return PJNATH_ESTUNTOOMANYATTR;
}
/* Add the attribute */
@@ -2027,12 +2027,12 @@ PJ_DEF(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,
const pj_stun_attr_hdr *attr_hdr = msg->attr[i];
/* There mustn't any attribute after FINGERPRINT */
- PJ_ASSERT_RETURN(afingerprint == NULL, PJLIB_UTIL_ESTUNFINGERPOS);
+ PJ_ASSERT_RETURN(afingerprint == NULL, PJNATH_ESTUNFINGERPOS);
if (attr_hdr->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) {
/* There mustn't be MESSAGE-INTEGRITY before */
PJ_ASSERT_RETURN(amsgint == NULL,
- PJLIB_UTIL_ESTUNMSGINTPOS);
+ PJNATH_ESTUNMSGINTPOS);
amsgint = (pj_stun_msgint_attr*) attr_hdr;
} else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) {
@@ -2070,13 +2070,13 @@ PJ_DEF(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,
if (i < msg->attr_count-2) {
/* Should not happen for message generated by us */
pj_assert(PJ_FALSE);
- return PJLIB_UTIL_ESTUNMSGINTPOS;
+ return PJNATH_ESTUNMSGINTPOS;
} else if (i == msg->attr_count-2) {
if (msg->attr[i+1]->type != PJ_STUN_ATTR_FINGERPRINT) {
/* Should not happen for message generated by us */
pj_assert(PJ_FALSE);
- return PJLIB_UTIL_ESTUNMSGINTPOS;
+ return PJNATH_ESTUNMSGINTPOS;
} else {
afingerprint = (pj_stun_fingerprint_attr*) msg->attr[i+1];
}
@@ -2086,7 +2086,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,
if (auname == NULL) {
/* Should not happen for message generated by us */
pj_assert(PJ_FALSE);
- return PJLIB_UTIL_ESTUNNOUSERNAME;
+ return PJNATH_ESTUNNOUSERNAME;
}
/* Password must be specified */
diff --git a/pjnath/src/pjnath/stun_msg_dump.c b/pjnath/src/pjnath/stun_msg_dump.c
index 0ee0ebe4..5e83958e 100644
--- a/pjnath/src/pjnath/stun_msg_dump.c
+++ b/pjnath/src/pjnath/stun_msg_dump.c
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjlib-util/stun_msg.h>
-#include <pjlib-util/errno.h>
+#include <pjnath/stun_msg.h>
+#include <pjnath/errno.h>
#include <pj/assert.h>
#include <pj/string.h>
@@ -80,13 +80,13 @@ static int print_attr(char *buffer, unsigned length,
attr = (const pj_stun_sockaddr_attr*)ahdr;
- if (attr->addr.addr.sa_family == PJ_AF_INET) {
+ if (attr->sockaddr.addr.sa_family == PJ_AF_INET) {
len = pj_ansi_snprintf(p, end-p,
", IPv4 addr=%s:%d\n",
- pj_inet_ntoa(attr->addr.ipv4.sin_addr),
- pj_ntohs(attr->addr.ipv4.sin_port));
+ pj_inet_ntoa(attr->sockaddr.ipv4.sin_addr),
+ pj_ntohs(attr->sockaddr.ipv4.sin_port));
- } else if (attr->addr.addr.sa_family == PJ_AF_INET6) {
+ } else if (attr->sockaddr.addr.sa_family == PJ_AF_INET6) {
len = pj_ansi_snprintf(p, end-p,
", IPv6 addr present\n");
} else {
diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c
index b4e7356c..9bcff549 100644
--- a/pjnath/src/pjnath/stun_session.c
+++ b/pjnath/src/pjnath/stun_session.c
@@ -16,12 +16,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjlib-util/stun_session.h>
+#include <pjnath/stun_session.h>
#include <pjlib.h>
struct pj_stun_session
{
- pj_stun_endpoint *endpt;
+ pj_stun_config *cfg;
pj_pool_t *pool;
pj_mutex_t *mutex;
pj_stun_session_cb cb;
@@ -119,7 +119,7 @@ static pj_status_t create_tdata(pj_stun_session *sess,
pj_stun_tx_data *tdata;
/* Create pool and initialize basic tdata attributes */
- pool = pj_pool_create(sess->endpt->pf, "tdata%p",
+ pool = pj_pool_create(sess->cfg->pf, "tdata%p",
TDATA_POOL_SIZE, TDATA_POOL_INC, NULL);
PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
@@ -170,7 +170,7 @@ static void destroy_tdata(pj_stun_tx_data *tdata)
tdata->client_tsx = NULL;
}
if (tdata->res_timer.id != PJ_FALSE) {
- pj_timer_heap_cancel(tdata->sess->endpt->timer_heap,
+ pj_timer_heap_cancel(tdata->sess->cfg->timer_heap,
&tdata->res_timer);
tdata->res_timer.id = PJ_FALSE;
pj_list_erase(tdata);
@@ -223,8 +223,8 @@ static pj_status_t apply_msg_options(pj_stun_session *sess,
pj_status_t status = 0;
/* The server SHOULD include a SERVER attribute in all responses */
- if (PJ_STUN_IS_RESPONSE(msg->hdr.type) ||
- PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type))
+ if (sess->srv_name.slen && (PJ_STUN_IS_RESPONSE(msg->hdr.type) ||
+ PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)))
{
pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SERVER,
&sess->srv_name);
@@ -300,7 +300,7 @@ static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx,
/* **************************************************************************/
-PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_endpoint *endpt,
+PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_config *cfg,
const char *name,
const pj_stun_session_cb *cb,
pj_bool_t fingerprint,
@@ -310,16 +310,16 @@ PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_endpoint *endpt,
pj_stun_session *sess;
pj_status_t status;
- PJ_ASSERT_RETURN(endpt && cb && p_sess, PJ_EINVAL);
+ PJ_ASSERT_RETURN(cfg && cb && p_sess, PJ_EINVAL);
if (name==NULL)
name = "sess%p";
- pool = pj_pool_create(endpt->pf, name, 4000, 4000, NULL);
+ pool = pj_pool_create(cfg->pf, name, 4000, 4000, NULL);
PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
sess = PJ_POOL_ZALLOC_T(pool, pj_stun_session);
- sess->endpt = endpt;
+ sess->cfg = cfg;
sess->pool = pool;
pj_memcpy(&sess->cb, cb, sizeof(*cb));
sess->use_fingerprint = fingerprint;
@@ -383,8 +383,11 @@ PJ_DEF(void*) pj_stun_session_get_user_data(pj_stun_session *sess)
PJ_DEF(pj_status_t) pj_stun_session_set_server_name(pj_stun_session *sess,
const pj_str_t *srv_name)
{
- PJ_ASSERT_RETURN(sess && srv_name, PJ_EINVAL);
- pj_strdup(sess->pool, &sess->srv_name, srv_name);
+ PJ_ASSERT_RETURN(sess, PJ_EINVAL);
+ if (srv_name)
+ pj_strdup(sess->pool, &sess->srv_name, srv_name);
+ else
+ sess->srv_name.slen = 0;
return PJ_SUCCESS;
}
@@ -489,14 +492,12 @@ static void dump_tx_msg(pj_stun_session *sess, const pj_stun_msg *msg,
const pj_sockaddr *dst = (const pj_sockaddr*)addr;
char buf[512];
- if (dst->sa_family == PJ_AF_INET) {
- const pj_sockaddr_in *dst4 = (const pj_sockaddr_in*)dst;
- dst_name = pj_inet_ntoa(dst4->sin_addr);
- dst_port = pj_ntohs(dst4->sin_port);
- } else if (dst->sa_family == PJ_AF_INET6) {
- const pj_sockaddr_in6 *dst6 = (const pj_sockaddr_in6*)dst;
+ if (dst->addr.sa_family == PJ_AF_INET) {
+ dst_name = pj_inet_ntoa(dst->ipv4.sin_addr);
+ dst_port = pj_ntohs(dst->ipv4.sin_port);
+ } else if (dst->addr.sa_family == PJ_AF_INET6) {
dst_name = "IPv6";
- dst_port = pj_ntohs(dst6->sin6_port);
+ dst_port = pj_ntohs(dst->ipv6.sin6_port);
} else {
LOG_ERR_(sess, "Invalid address family", PJ_EINVAL);
return;
@@ -558,7 +559,7 @@ PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess,
if (PJ_STUN_IS_REQUEST(tdata->msg->hdr.type)) {
/* Create STUN client transaction */
- status = pj_stun_client_tsx_create(sess->endpt, tdata->pool,
+ status = pj_stun_client_tsx_create(sess->cfg, tdata->pool,
&tsx_cb, &tdata->client_tsx);
PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
pj_stun_client_tsx_set_data(tdata->client_tsx, (void*)tdata);
@@ -592,10 +593,10 @@ PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess,
pj_timer_entry_init(&tdata->res_timer, PJ_TRUE, tdata,
&on_cache_timeout);
- timeout.sec = sess->endpt->res_cache_msec / 1000;
- timeout.msec = sess->endpt->res_cache_msec % 1000;
+ timeout.sec = sess->cfg->res_cache_msec / 1000;
+ timeout.msec = sess->cfg->res_cache_msec % 1000;
- status = pj_timer_heap_schedule(sess->endpt->timer_heap,
+ status = pj_timer_heap_schedule(sess->cfg->timer_heap,
&tdata->res_timer,
&timeout);
if (status != PJ_SUCCESS) {
@@ -829,7 +830,7 @@ PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL);
- tmp_pool = pj_pool_create(sess->endpt->pf, "tmpstun", 1024, 1024, NULL);
+ tmp_pool = pj_pool_create(sess->cfg->pf, "tmpstun", 1024, 1024, NULL);
if (!tmp_pool)
return PJ_ENOMEM;
diff --git a/pjnath/src/pjnath/stun_transaction.c b/pjnath/src/pjnath/stun_transaction.c
index 0000e3a6..2813f7ef 100644
--- a/pjnath/src/pjnath/stun_transaction.c
+++ b/pjnath/src/pjnath/stun_transaction.c
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjlib-util/stun_transaction.h>
-#include <pjlib-util/errno.h>
+#include <pjnath/stun_transaction.h>
+#include <pjnath/errno.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/pool.h>
@@ -31,7 +31,7 @@
struct pj_stun_client_tsx
{
char obj_name[PJ_MAX_OBJ_NAME];
- pj_stun_endpoint *endpt;
+ pj_stun_config *cfg;
pj_stun_tsx_cb cb;
void *user_data;
@@ -63,18 +63,18 @@ static void stun_perror(pj_stun_client_tsx *tsx, const char *title,
/*
* Create a STUN client transaction.
*/
-PJ_DEF(pj_status_t) pj_stun_client_tsx_create(pj_stun_endpoint *endpt,
+PJ_DEF(pj_status_t) pj_stun_client_tsx_create(pj_stun_config *cfg,
pj_pool_t *pool,
const pj_stun_tsx_cb *cb,
pj_stun_client_tsx **p_tsx)
{
pj_stun_client_tsx *tsx;
- PJ_ASSERT_RETURN(endpt && cb && p_tsx, PJ_EINVAL);
+ PJ_ASSERT_RETURN(cfg && cb && p_tsx, PJ_EINVAL);
PJ_ASSERT_RETURN(cb->on_send_msg, PJ_EINVAL);
tsx = PJ_POOL_ZALLOC_T(pool, pj_stun_client_tsx);
- tsx->endpt = endpt;
+ tsx->cfg = cfg;
pj_memcpy(&tsx->cb, cb, sizeof(*cb));
tsx->timer.cb = &retransmit_timer_callback;
@@ -97,7 +97,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx)
PJ_ASSERT_RETURN(tsx, PJ_EINVAL);
if (tsx->timer.id != 0) {
- pj_timer_heap_cancel(tsx->endpt->timer_heap, &tsx->timer);
+ pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->timer);
tsx->timer.id = 0;
}
return PJ_SUCCESS;
@@ -149,7 +149,7 @@ static pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx)
/* Calculate retransmit/timeout delay */
if (tsx->transmit_count == 0) {
tsx->retransmit_time.sec = 0;
- tsx->retransmit_time.msec = tsx->endpt->rto_msec;
+ tsx->retransmit_time.msec = tsx->cfg->rto_msec;
} else if (tsx->transmit_count < PJ_STUN_MAX_RETRANSMIT_COUNT-1) {
unsigned msec;
@@ -168,7 +168,7 @@ static pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx)
* cancel it (as opposed to when schedule_timer() failed we cannot
* cancel transmission).
*/;
- status = pj_timer_heap_schedule(tsx->endpt->timer_heap, &tsx->timer,
+ status = pj_timer_heap_schedule(tsx->cfg->timer_heap, &tsx->timer,
&tsx->retransmit_time);
if (status != PJ_SUCCESS) {
tsx->timer.id = 0;
@@ -182,7 +182,7 @@ static pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx)
status = tsx->cb.on_send_msg(tsx, tsx->last_pkt, tsx->last_pkt_size);
if (status != PJ_SUCCESS) {
if (tsx->timer.id != 0) {
- pj_timer_heap_cancel(tsx->endpt->timer_heap, &tsx->timer);
+ pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->timer);
tsx->timer.id = 0;
}
stun_perror(tsx, "STUN error sending message", status);
@@ -235,7 +235,7 @@ static void retransmit_timer_callback(pj_timer_heap_t *timer_heap,
PJ_LOG(4,(tsx->obj_name, "STUN timeout waiting for response"));
tsx->complete = PJ_TRUE;
if (tsx->cb.on_complete) {
- tsx->cb.on_complete(tsx, PJLIB_UTIL_ESTUNNOTRESPOND, NULL);
+ tsx->cb.on_complete(tsx, PJNATH_ESTUNNOTRESPOND, NULL);
}
return;
}
@@ -268,7 +268,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,
{
PJ_LOG(4,(tsx->obj_name,
"STUN rx_msg() error: not response message"));
- return PJLIB_UTIL_ESTUNNOTRESPONSE;
+ return PJNATH_ESTUNNOTRESPONSE;
}
@@ -276,7 +276,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,
* We can cancel retransmit timer now.
*/
if (tsx->timer.id) {
- pj_timer_heap_cancel(tsx->endpt->timer_heap, &tsx->timer);
+ pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->timer);
tsx->timer.id = 0;
}
@@ -300,7 +300,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,
if (err_attr == NULL) {
status = PJ_SUCCESS;
} else {
- status = PJLIB_UTIL_ESTUNTSXFAILED;
+ status = PJNATH_ESTUNTSXFAILED;
}
/* Call callback */
diff --git a/pjnath/src/pjstun-client/client_main.c b/pjnath/src/pjstun-client/client_main.c
index be65b516..9bb249f1 100644
--- a/pjnath/src/pjstun-client/client_main.c
+++ b/pjnath/src/pjstun-client/client_main.c
@@ -16,6 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <pjnath.h>
#include <pjlib-util.h>
#include <pjlib.h>
diff --git a/pjnath/src/pjstun-srv-test/bind_usage.c b/pjnath/src/pjstun-srv-test/bind_usage.c
index fc10fb91..3c1825f9 100644
--- a/pjnath/src/pjstun-srv-test/bind_usage.c
+++ b/pjnath/src/pjstun-srv-test/bind_usage.c
@@ -85,7 +85,7 @@ PJ_DEF(pj_status_t) pj_stun_bind_usage_create(pj_stun_server *srv,
pj_bzero(&sess_cb, sizeof(sess_cb));
sess_cb.on_send_msg = &sess_on_send_msg;
sess_cb.on_rx_request = &sess_on_rx_request;
- status = pj_stun_session_create(si->endpt, "bind%p", &sess_cb, PJ_FALSE,
+ status = pj_stun_session_create(si->cfg, "bind%p", &sess_cb, PJ_FALSE,
&bu->session);
if (status != PJ_SUCCESS) {
pj_stun_usage_destroy(bu->usage);
diff --git a/pjnath/src/pjstun-srv-test/server.c b/pjnath/src/pjstun-srv-test/server.c
index 5fdb233e..d0fe426d 100644
--- a/pjnath/src/pjstun-srv-test/server.c
+++ b/pjnath/src/pjstun-srv-test/server.c
@@ -83,8 +83,8 @@ PJ_DEF(pj_status_t) pj_stun_server_create(pj_pool_factory *pf,
if (status != PJ_SUCCESS)
goto on_error;
- status = pj_stun_endpoint_create(srv->si.pf, 0, srv->si.ioqueue,
- srv->si.timer_heap, &srv->si.endpt);
+ status = pj_stun_config_create(srv->si.pf, 0, srv->si.ioqueue,
+ srv->si.timer_heap, &srv->si.cfg);
if (status != PJ_SUCCESS)
goto on_error;
@@ -174,7 +174,7 @@ PJ_DEF(pj_status_t) pj_stun_server_destroy(pj_stun_server *srv)
srv->threads[i] = NULL;
}
- pj_stun_endpoint_destroy(srv->si.endpt);
+ pj_stun_config_destroy(srv->si.cfg);
pj_timer_heap_destroy(srv->si.timer_heap);
pj_ioqueue_destroy(srv->si.ioqueue);
pj_pool_release(srv->pool);
diff --git a/pjnath/src/pjstun-srv-test/server.h b/pjnath/src/pjstun-srv-test/server.h
index a88d87c2..6c61da39 100644
--- a/pjnath/src/pjstun-srv-test/server.h
+++ b/pjnath/src/pjstun-srv-test/server.h
@@ -19,6 +19,7 @@
#ifndef __STUN_SERVER_H__
#define __STUN_SERVER_H__
+#include <pjnath.h>
#include <pjlib-util.h>
#include <pjlib.h>
@@ -30,7 +31,7 @@ typedef struct pj_stun_server pj_stun_server;
typedef struct pj_stun_server_info
{
pj_pool_factory *pf;
- pj_stun_endpoint *endpt;
+ pj_stun_config *cfg;
pj_ioqueue_t *ioqueue;
pj_timer_heap_t *timer_heap;
unsigned thread_cnt;
diff --git a/pjnath/src/pjstun-srv-test/turn_usage.c b/pjnath/src/pjstun-srv-test/turn_usage.c
index e3d2e595..c1f83d15 100644
--- a/pjnath/src/pjstun-srv-test/turn_usage.c
+++ b/pjnath/src/pjstun-srv-test/turn_usage.c
@@ -69,7 +69,7 @@ static pj_status_t client_handle_stun_msg(struct turn_client *client,
struct turn_usage
{
pj_pool_factory *pf;
- pj_stun_endpoint *endpt;
+ pj_stun_config *cfg;
pj_ioqueue_t *ioqueue;
pj_timer_heap_t *timer_heap;
pj_pool_t *pool;
@@ -165,7 +165,7 @@ PJ_DEF(pj_status_t) pj_stun_turn_usage_create(pj_stun_server *srv,
tu->pool = pool;
tu->type = type;
tu->pf = si->pf;
- tu->endpt = si->endpt;
+ tu->cfg = si->cfg;
tu->ioqueue = si->ioqueue;
tu->timer_heap = si->timer_heap;
tu->next_port = START_PORT;
@@ -197,7 +197,7 @@ PJ_DEF(pj_status_t) pj_stun_turn_usage_create(pj_stun_server *srv,
pj_bzero(&sess_cb, sizeof(sess_cb));
sess_cb.on_send_msg = &tu_sess_on_send_msg;
sess_cb.on_rx_request = &tu_sess_on_rx_request;
- status = pj_stun_session_create(si->endpt, "turns%p", &sess_cb, PJ_FALSE,
+ status = pj_stun_session_create(si->cfg, "turns%p", &sess_cb, PJ_FALSE,
&tu->default_session);
if (status != PJ_SUCCESS) {
pj_stun_usage_destroy(tu->usage);
@@ -208,6 +208,8 @@ PJ_DEF(pj_status_t) pj_stun_turn_usage_create(pj_stun_server *srv,
sd->tu = tu;
pj_stun_session_set_user_data(tu->default_session, sd);
+ pj_stun_session_set_server_name(tu->default_session, NULL);
+
/* Create mutex */
status = pj_mutex_create_recursive(pool, "turn%p", &tu->mutex);
if (status != PJ_SUCCESS) {
@@ -620,7 +622,7 @@ static pj_status_t client_create(struct turn_usage *tu,
sess_cb.on_send_msg = &client_sess_on_send_msg;
sess_cb.on_rx_request = &client_sess_on_rx_msg;
sess_cb.on_rx_indication = &client_sess_on_rx_msg;
- status = pj_stun_session_create(tu->endpt, client->obj_name,
+ status = pj_stun_session_create(tu->cfg, client->obj_name,
&sess_cb, PJ_FALSE,
&client->session);
if (status != PJ_SUCCESS) {