summaryrefslogtreecommitdiff
path: root/pjnath
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-03-24 13:00:30 +0000
committerBenny Prijono <bennylp@teluu.com>2007-03-24 13:00:30 +0000
commit37562c4e5773361453cbac8c75ebe533abb147fb (patch)
treeb6317c069434236676ccef002e96175767179171 /pjnath
parent9f7d26408a37e2b085da1df5ad84794d72a7cd0e (diff)
ICE (work in progress): implement error codes
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1101 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjnath')
-rw-r--r--pjnath/build/pjnath.dsp4
-rw-r--r--pjnath/include/pjnath.h1
-rw-r--r--pjnath/include/pjnath/errno.h133
-rw-r--r--pjnath/include/pjnath/ice.h22
-rw-r--r--pjnath/include/pjnath/stun_msg.h1
-rw-r--r--pjnath/include/pjnath/types.h33
-rw-r--r--pjnath/src/pjnath/errno.c86
-rw-r--r--pjnath/src/pjnath/ice.c305
-rw-r--r--pjnath/src/pjnath/ice_stream_transport.c28
-rw-r--r--pjnath/src/pjnath/stun_auth.c18
-rw-r--r--pjnath/src/pjnath/stun_msg.c42
-rw-r--r--pjnath/src/pjnath/stun_transaction.c7
12 files changed, 296 insertions, 384 deletions
diff --git a/pjnath/build/pjnath.dsp b/pjnath/build/pjnath.dsp
index 83bc6a23..4ea74abd 100644
--- a/pjnath/build/pjnath.dsp
+++ b/pjnath/build/pjnath.dsp
@@ -41,8 +41,8 @@ RSC=rc.exe
# PROP Intermediate_Dir "./output/pjnath-i386-win32-vc6-release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
-# SUBTRACT CPP /YX
+# ADD CPP /nologo /MD /W4 /GX /O1 /Ob2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
+# SUBTRACT CPP /Z<none> /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
diff --git a/pjnath/include/pjnath.h b/pjnath/include/pjnath.h
index 8574631d..68eab315 100644
--- a/pjnath/include/pjnath.h
+++ b/pjnath/include/pjnath.h
@@ -27,3 +27,4 @@
#include <pjnath/stun_session.h>
#include <pjnath/stun_transaction.h>
#include <pjnath/types.h>
+
diff --git a/pjnath/include/pjnath/errno.h b/pjnath/include/pjnath/errno.h
index 7fbd9837..c5a2afa5 100644
--- a/pjnath/include/pjnath/errno.h
+++ b/pjnath/include/pjnath/errno.h
@@ -23,7 +23,7 @@
#include <pj/errno.h>
/**
- * @defgroup PJNATH_ERROR NAT Helper Error Codes
+ * @defgroup PJNATH_ERROR NAT Helper Library Error Codes
* @ingroup PJNATH
* @{
*/
@@ -35,154 +35,119 @@
#define PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4)
-
/************************************************************
- * NEW STUN ERROR
+ * STUN MESSAGING ERRORS
***********************************************************/
-/* Messaging errors */
-#define PJNATH_ESTUNINATTRLEN -1
-#define PJNATH_ESTUNINMSGLEN -1
-#define PJNATH_ESTUNINMSGTYPE -1
-#define PJNATH_ESTUNFINGERPRINT -1
-#define PJNATH_ESTUNNOTRESPOND -1
-#define PJNATH_ESTUNNOXORMAP -1
/**
- * @hideinitializer
- * Too many STUN attributes.
- */
-#define PJNATH_ESTUNTOOMANYATTR (PJNATH_ERRNO_START+110)/* 370110 */
-/**
- * @hideinitializer
- * Unknown STUN attribute. This error happens when the decoder encounters
- * mandatory attribute type which it doesn't understand.
- */
-#define PJNATH_ESTUNUNKNOWNATTR (PJNATH_ERRNO_START+111)/* 370111 */
-/**
- * @hideinitializer
- * Invalid STUN socket address length.
- */
-#define PJNATH_ESTUNINADDRLEN (PJNATH_ERRNO_START+112)/* 370112 */
-/**
- * @hideinitializer
- * STUN IPv6 attribute not supported
- */
-#define PJNATH_ESTUNIPV6NOTSUPP (PJNATH_ERRNO_START+113)/* 370113 */
-/**
- * @hideinitializer
- * Expecting STUN response message.
+ * Map STUN error code (300-699) into pj_status_t error space.
*/
-#define PJNATH_ESTUNNOTRESPONSE (PJNATH_ERRNO_START+114)/* 370114 */
-/**
- * @hideinitializer
- * STUN transaction ID mismatch.
- */
-#define PJNATH_ESTUNINVALIDID (PJNATH_ERRNO_START+115)/* 370115 */
+#define PJ_STATUS_FROM_STUN_CODE(code) (PJNATH_ERRNO_START+code)
+
/**
* @hideinitializer
- * Unable to find handler for the request.
+ * Invalid STUN message length.
*/
-#define PJNATH_ESTUNNOHANDLER (PJNATH_ERRNO_START+116)/* 370116 */
+#define PJNATH_EINSTUNMSGLEN (PJNATH_ERRNO_START+1) /* 370001 */
/**
* @hideinitializer
- * Found non-FINGERPRINT attribute after MESSAGE-INTEGRITY. This is not
- * valid since MESSAGE-INTEGRITY MUST be the last attribute or the
- * attribute right before FINGERPRINT before the message.
+ * Invalid or unexpected STUN message type
*/
-#define PJNATH_ESTUNMSGINTPOS (PJNATH_ERRNO_START+118)/* 370118 */
+#define PJNATH_EINSTUNMSGTYPE (PJNATH_ERRNO_START+2) /* 370002 */
/**
* @hideinitializer
- * Found attribute after FINGERPRINT. This is not valid since FINGERPRINT
- * MUST be the last attribute in the message.
+ * STUN transaction has timed out
*/
-#define PJNATH_ESTUNFINGERPOS (PJNATH_ERRNO_START+119)/* 370119 */
+#define PJNATH_ESTUNTIMEDOUT (PJNATH_ERRNO_START+3) /* 370003 */
+
+
+
/**
* @hideinitializer
- * Missing STUN USERNAME attribute.
- * When credential is included in the STUN message (MESSAGE-INTEGRITY is
- * present), the USERNAME attribute must be present in the message.
+ * Too many STUN attributes.
*/
-#define PJNATH_ESTUNNOUSERNAME (PJNATH_ERRNO_START+120)/* 370120 */
+#define PJNATH_ESTUNTOOMANYATTR (PJNATH_ERRNO_START+21) /* 370021 */
/**
* @hideinitializer
- * Unknown STUN username/credential.
+ * Invalid STUN attribute length.
*/
-#define PJNATH_ESTUNUSERNAME (PJNATH_ERRNO_START+121)/* 370121 */
+#define PJNATH_ESTUNINATTRLEN (PJNATH_ERRNO_START+22) /* 370022 */
/**
* @hideinitializer
- * Missing/invalidSTUN MESSAGE-INTEGRITY attribute.
+ * Found duplicate STUN attribute.
*/
-#define PJNATH_ESTUNMSGINT (PJNATH_ERRNO_START+122)/* 370122 */
+#define PJNATH_ESTUNDUPATTR (PJNATH_ERRNO_START+23) /* 370023 */
+
/**
* @hideinitializer
- * Found duplicate STUN attribute.
+ * STUN FINGERPRINT verification failed
*/
-#define PJNATH_ESTUNDUPATTR (PJNATH_ERRNO_START+123)/* 370123 */
+#define PJNATH_ESTUNFINGERPRINT (PJNATH_ERRNO_START+30) /* 370030 */
/**
* @hideinitializer
- * Missing STUN REALM attribute.
+ * Invalid STUN attribute after MESSAGE-INTEGRITY.
*/
-#define PJNATH_ESTUNNOREALM (PJNATH_ERRNO_START+124)/* 370124 */
+#define PJNATH_ESTUNMSGINTPOS (PJNATH_ERRNO_START+31) /* 370031 */
/**
* @hideinitializer
- * Missing/stale STUN NONCE attribute value.
+ * Invalid STUN attribute after FINGERPRINT.
*/
-#define PJNATH_ESTUNNONCE (PJNATH_ERRNO_START+125)/* 370125 */
+#define PJNATH_ESTUNFINGERPOS (PJNATH_ERRNO_START+33) /* 370033 */
+
+
/**
* @hideinitializer
- * STUN transaction terminates with failure.
+ * STUN (XOR-)MAPPED-ADDRESS attribute not found
*/
-#define PJNATH_ESTUNTSXFAILED (PJNATH_ERRNO_START+126)/* 370126 */
+#define PJNATH_ESTUNNOMAPPEDADDR (PJNATH_ERRNO_START+40) /* 370040 */
/**
* @hideinitializer
- * STUN mapped address attribute not found
+ * STUN IPv6 attribute not supported
*/
-#define PJNATH_ESTUNNOMAPPEDADDR (PJNATH_ERRNO_START+127)/* 370127 */
+#define PJNATH_ESTUNIPV6NOTSUPP (PJNATH_ERRNO_START+41) /* 370041 */
-//#define PJ_STATUS_FROM_STUN_CODE(code) (PJNATH_ERRNO_START+code)
+/************************************************************
+ * ICE ERROR CODES
+ ***********************************************************/
+
/**
* @hideinitializer
- * No ICE checklist is formed.
- */
-#define PJ_EICENOCHECKLIST -1
-/**
- * @hideinitializer
- * No suitable default ICE candidate for the component.
+ * ICE session not available
*/
-#define PJ_EICENOCAND -1
+#define PJNATH_ENOICE (PJNATH_ERRNO_START+80) /* 370080 */
/**
* @hideinitializer
- * Invalid ICE component ID
+ * ICE check is in progress
*/
-#define PJ_EICEINCOMPID -1
+#define PJNATH_EICEINPROGRESS (PJNATH_ERRNO_START+81) /* 370081 */
/**
* @hideinitializer
- * Invalid ICE candidate ID
+ * All ICE checklists failed
*/
-#define PJ_EICEINCANDID -1
+#define PJNATH_EICEFAILED (PJNATH_ERRNO_START+82) /* 370082 */
/**
* @hideinitializer
- * ICE session not available
+ * Invalid ICE component ID
*/
-#define PJ_ENOICE -1
+#define PJNATH_EICEINCOMPID (PJNATH_ERRNO_START+86) /* 370086 */
/**
* @hideinitializer
- * ICE check is in progress
+ * Invalid ICE candidate ID
*/
-#define PJ_EICEINPROGRESS -1
+#define PJNATH_EICEINCANDID (PJNATH_ERRNO_START+87) /* 370087 */
/**
* @hideinitializer
* Missing ICE SDP attribute
*/
-#define PJ_EICEMISSINGSDP -1
+#define PJNATH_EICEMISSINGSDP (PJNATH_ERRNO_START+90) /* 370090 */
/**
* @hideinitializer
* Invalid SDP "candidate" attribute
*/
-#define PJ_EICEINCANDSDP -1
+#define PJNATH_EICEINCANDSDP (PJNATH_ERRNO_START+91) /* 370091 */
diff --git a/pjnath/include/pjnath/ice.h b/pjnath/include/pjnath/ice.h
index 8aa77cbc..10faa21f 100644
--- a/pjnath/include/pjnath/ice.h
+++ b/pjnath/include/pjnath/ice.h
@@ -96,7 +96,7 @@ typedef struct pj_ice_cand
pj_uint32_t prio;
pj_sockaddr addr;
pj_sockaddr base_addr;
- pj_sockaddr srv_addr;
+ pj_sockaddr rel_addr;
pj_stun_session *stun_sess;
} pj_ice_cand;
@@ -204,20 +204,19 @@ struct pj_ice
pj_ice_checklist clist;
/* Valid list */
- unsigned valid_cnt;
- unsigned valid_list[PJ_ICE_MAX_CHECKS];
+ pj_ice_checklist valid_list;
};
PJ_DECL(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
const char *name,
pj_ice_role role,
+ unsigned comp_cnt,
const pj_ice_cb *cb,
const pj_str_t *local_ufrag,
const pj_str_t *local_passwd,
pj_ice **p_ice);
PJ_DECL(pj_status_t) pj_ice_destroy(pj_ice *ice);
-PJ_DECL(pj_status_t) pj_ice_add_comp(pj_ice *ice, unsigned comp_id);
PJ_DECL(pj_status_t) pj_ice_add_cand(pj_ice *ice,
unsigned comp_id,
pj_ice_cand_type type,
@@ -225,20 +224,13 @@ PJ_DECL(pj_status_t) pj_ice_add_cand(pj_ice *ice,
const pj_str_t *foundation,
const pj_sockaddr_t *addr,
const pj_sockaddr_t *base_addr,
- const pj_sockaddr_t *srv_addr,
+ const pj_sockaddr_t *rel_addr,
int addr_len,
unsigned *cand_id);
-PJ_DECL(unsigned) pj_ice_get_cand_cnt(pj_ice *ice);
-PJ_DECL(pj_status_t) pj_ice_enum_cands(pj_ice *ice,
- unsigned *p_count,
- unsigned cand_ids[]);
-PJ_DECL(pj_status_t) pj_ice_get_default_cand(pj_ice *ice,
- unsigned comp_id,
- int *cand_id);
-PJ_DECL(pj_status_t) pj_ice_get_cand(pj_ice *ice,
- unsigned cand_id,
- pj_ice_cand **p_cand);
+PJ_DECL(pj_status_t) pj_ice_find_default_cand(pj_ice *ice,
+ unsigned comp_id,
+ int *cand_id);
PJ_DECL(pj_status_t) pj_ice_create_check_list(pj_ice *ice,
const pj_str_t *rem_ufrag,
diff --git a/pjnath/include/pjnath/stun_msg.h b/pjnath/include/pjnath/stun_msg.h
index 08e5672d..3362703c 100644
--- a/pjnath/include/pjnath/stun_msg.h
+++ b/pjnath/include/pjnath/stun_msg.h
@@ -383,7 +383,6 @@ typedef enum pj_stun_status
PJ_STUN_SC_NO_BINDING = 437, /**< No Binding. */
PJ_STUN_SC_STALE_NONCE = 438, /**< Stale Nonce */
PJ_STUN_SC_TRANSITIONING = 439, /**< Transitioning. */
- PJ_STUN_SC_WRONG_USERNAME = 441, /**< Wrong Username. */
PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO = 442, /**< Unsupported Transport or
Protocol */
PJ_STUN_SC_INVALID_IP_ADDR = 443, /**< Invalid IP Address */
diff --git a/pjnath/include/pjnath/types.h b/pjnath/include/pjnath/types.h
index d39da89e..0d9dc61c 100644
--- a/pjnath/include/pjnath/types.h
+++ b/pjnath/include/pjnath/types.h
@@ -29,8 +29,27 @@
/**
* @defgroup PJNATH NAT Helper Library
+ * @{
*/
+PJ_BEGIN_DECL
+
+/**
+ * Initialize pjnath library.
+ *
+ * @return Initialization status.
+ */
+PJ_DECL(pj_status_t) pjnath_init(void);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+/* Doxygen documentation below: */
+
/**
* @mainpage NAT Helper Library
*
@@ -43,20 +62,6 @@
* Please go to the <A HREF="modules.htm"><B>Modules</B></A> page for list
* of modules.
*
- *
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
- * \n
*/
#endif /* __PJNATH_TYPES_H__ */
diff --git a/pjnath/src/pjnath/errno.c b/pjnath/src/pjnath/errno.c
index bfde1bc0..7ac88922 100644
--- a/pjnath/src/pjnath/errno.c
+++ b/pjnath/src/pjnath/errno.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pjnath/errno.h>
+#include <pjnath/stun_msg.h>
#include <pj/string.h>
@@ -32,22 +33,31 @@ static const struct
const char *msg;
} err_str[] =
{
- /* STUN */
+ /* STUN related error codes */
+ PJ_BUILD_ERR( PJNATH_EINSTUNMSGLEN, "Invalid STUN message length"),
+ PJ_BUILD_ERR( PJNATH_EINSTUNMSGTYPE, "Invalid or unexpected STUN message type"),
+ PJ_BUILD_ERR( PJNATH_ESTUNTIMEDOUT, "STUN transaction has timed out"),
+
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_ESTUNINATTRLEN, "Invalid STUN attribute length"),
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"),
+
+ PJ_BUILD_ERR( PJNATH_ESTUNFINGERPRINT, "STUN FINGERPRINT verification failed"),
+ PJ_BUILD_ERR( PJNATH_ESTUNMSGINTPOS, "Invalid STUN attribute after MESSAGE-INTEGRITY"),
+ PJ_BUILD_ERR( PJNATH_ESTUNFINGERPOS, "Invalid STUN attribute after FINGERPRINT"),
+
+ PJ_BUILD_ERR( PJNATH_ESTUNNOMAPPEDADDR, "STUN (XOR-)MAPPED-ADDRESS attribute not found"),
+ PJ_BUILD_ERR( PJNATH_ESTUNIPV6NOTSUPP, "STUN IPv6 attribute not supported"),
+
+ /* ICE related errors */
+ PJ_BUILD_ERR( PJNATH_ENOICE, "ICE session not available"),
+ PJ_BUILD_ERR( PJNATH_EICEINPROGRESS, "ICE check is in progress"),
+ PJ_BUILD_ERR( PJNATH_EICEFAILED, "All ICE checklists failed"),
+ PJ_BUILD_ERR( PJNATH_EICEINCOMPID, "Invalid ICE component ID"),
+ PJ_BUILD_ERR( PJNATH_EICEINCANDID, "Invalid ICE candidate ID"),
+ PJ_BUILD_ERR( PJNATH_EICEMISSINGSDP, "Missing ICE SDP attribute"),
+ PJ_BUILD_ERR( PJNATH_EICEINCANDSDP, "Invalid SDP \"candidate\" attribute"),
+
};
#endif /* PJ_HAS_ERROR_STRING */
@@ -55,8 +65,8 @@ static const struct
/*
* pjnath_strerror()
*/
-PJ_DEF(pj_str_t) pjnath_strerror( pj_status_t statcode,
- char *buf, pj_size_t bufsize )
+static pj_str_t pjnath_strerror(pj_status_t statcode,
+ char *buf, pj_size_t bufsize )
{
pj_str_t errstr;
@@ -106,8 +116,35 @@ PJ_DEF(pj_str_t) pjnath_strerror( pj_status_t statcode,
/* Error not found. */
errstr.ptr = buf;
errstr.slen = pj_ansi_snprintf(buf, bufsize,
- "Unknown pjlib-util error %d",
+ "Unknown pjnath error %d",
statcode);
+ if (errstr.slen < 0) errstr.slen = 0;
+ else if (errstr.slen > (int)bufsize) errstr.slen = bufsize;
+
+ return errstr;
+}
+
+
+static pj_str_t pjnath_strerror2(pj_status_t statcode,
+ char *buf, pj_size_t bufsize )
+{
+ int stun_code = statcode - PJ_STATUS_FROM_STUN_CODE(0);
+ const pj_str_t cmsg = pj_stun_get_err_reason(stun_code);
+ pj_str_t errstr;
+
+ if (cmsg.slen == 0) {
+ /* Not found */
+ errstr.ptr = buf;
+ errstr.slen = pj_ansi_snprintf(buf, bufsize,
+ "Unknown STUN err-code %d",
+ stun_code);
+ } else {
+ errstr.ptr = buf;
+ pj_strncpy(&errstr, &cmsg, bufsize);
+ }
+
+ if (errstr.slen < 0) errstr.slen = 0;
+ else if (errstr.slen > (int)bufsize) errstr.slen = bufsize;
return errstr;
}
@@ -115,7 +152,16 @@ PJ_DEF(pj_str_t) pjnath_strerror( pj_status_t statcode,
PJ_DEF(pj_status_t) pjnath_init(void)
{
- return pj_register_strerror(PJNATH_ERRNO_START,
- PJ_ERRNO_SPACE_SIZE,
- &pjnath_strerror);
+ pj_status_t status;
+
+ status = pj_register_strerror(PJNATH_ERRNO_START, 299,
+ &pjnath_strerror);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pj_register_strerror(PJ_STATUS_FROM_STUN_CODE(300),
+ 699 - 300,
+ &pjnath_strerror2);
+ return status;
}
+
diff --git a/pjnath/src/pjnath/ice.c b/pjnath/src/pjnath/ice.c
index 9ab50262..50f911f5 100644
--- a/pjnath/src/pjnath/ice.c
+++ b/pjnath/src/pjnath/ice.c
@@ -57,7 +57,8 @@ static const char *clist_state_name[] =
};
#define CHECK_NAME_LEN 128
-#define LOG(expr) PJ_LOG(4,expr)
+#define LOG4(expr) PJ_LOG(4,expr)
+#define LOG5(expr) PJ_LOG(4,expr)
#define GET_LCAND_ID(cand) (cand - ice->lcand)
#define GET_CHECK_ID(chk) (chk - ice->clist.checks)
@@ -135,6 +136,7 @@ static pj_bool_t stun_auth_verify_nonce(const pj_stun_msg *msg,
PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
const char *name,
pj_ice_role role,
+ unsigned comp_cnt,
const pj_ice_cb *cb,
const pj_str_t *local_ufrag,
const pj_str_t *local_passwd,
@@ -170,8 +172,12 @@ PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
pj_memcpy(&ice->cb, cb, sizeof(*cb));
pj_memcpy(&ice->stun_cfg, stun_cfg, sizeof(*stun_cfg));
- for (i=0; i<PJ_ICE_MAX_COMP; ++i) {
- ice->comp[i].nominated_check_id = -1;
+ ice->comp_cnt = comp_cnt;
+ for (i=0; i<comp_cnt; ++i) {
+ pj_ice_comp *comp;
+ comp = &ice->comp[i];
+ comp->comp_id = i+1;
+ comp->nominated_check_id = -1;
}
if (local_ufrag == NULL) {
@@ -192,8 +198,8 @@ PJ_DEF(pj_status_t) pj_ice_create(pj_stun_config *stun_cfg,
/* Done */
*p_ice = ice;
- LOG((ice->obj_name, "ICE stream session created, role is %s agent",
- (ice->role==PJ_ICE_ROLE_CONTROLLING ? "controlling" : "controlled")));
+ LOG4((ice->obj_name, "ICE stream session created, role is %s agent",
+ (ice->role==PJ_ICE_ROLE_CONTROLLING ? "controlling" : "controlled")));
return PJ_SUCCESS;
}
@@ -208,11 +214,7 @@ static void destroy_ice(pj_ice *ice,
unsigned i;
if (reason == PJ_SUCCESS) {
- LOG((ice->obj_name, "Destroying ICE session"));
- }
-
- for (i=0; i<ice->comp_cnt; ++i) {
- /* Nothing to do */
+ LOG4((ice->obj_name, "Destroying ICE session"));
}
for (i=0; i<ice->lcand_cnt; ++i) {
@@ -250,39 +252,11 @@ PJ_DEF(pj_status_t) pj_ice_destroy(pj_ice *ice)
/* Find component by ID */
static pj_ice_comp *find_comp(const pj_ice *ice, unsigned comp_id)
{
- unsigned i;
- for (i=0; i<ice->comp_cnt; ++i) {
- if (ice->comp[i].comp_id == comp_id)
- return (pj_ice_comp *) &ice->comp[i];
- }
-
- return NULL;
+ pj_assert(comp_id > 0 && comp_id <= ice->comp_cnt);
+ return (pj_ice_comp*) &ice->comp[comp_id-1];
}
-/* Add a new component */
-PJ_DEF(pj_status_t) pj_ice_add_comp(pj_ice *ice, unsigned comp_id)
-{
- pj_ice_comp *comp;
-
- PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL);
- PJ_ASSERT_RETURN(ice->comp_cnt < PJ_ARRAY_SIZE(ice->comp), PJ_ETOOMANY);
- PJ_ASSERT_RETURN(comp_id==ice->comp_cnt+1, PJ_EICEINCOMPID);
- PJ_ASSERT_RETURN(find_comp(ice, comp_id) == NULL, PJ_EEXISTS);
-
- pj_mutex_lock(ice->mutex);
-
- comp = &ice->comp[ice->comp_cnt];
- comp->comp_id = comp_id;
- comp->nominated_check_id = -1;
-
- /* Done */
- ice->comp_cnt++;
- pj_mutex_unlock(ice->mutex);
-
- return PJ_SUCCESS;
-}
-
static pj_status_t stun_auth_get_auth(void *user_data,
pj_pool_t *pool,
pj_str_t *realm,
@@ -356,7 +330,7 @@ static pj_status_t stun_auth_get_password(const pj_stun_msg *msg,
/* Incoming response is authenticated with TX credential */
/* Verify username */
if (pj_strcmp(username, &ice->tx_uname) != 0)
- return -1;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNKNOWN_USERNAME);
*data_type = 0;
*data = ice->tx_pass;
@@ -407,9 +381,9 @@ static pj_uint32_t CALC_CAND_PRIO(pj_ice_cand_type type,
PJ_ICE_RELAYED_PREF
};
- return ((1 << 24) * type_pref[type]) +
- ((1 << 8) * local_pref) +
- (256 - comp_id);
+ return ((type_pref[type] & 0xFF) << 24) +
+ ((local_pref & 0xFFFF) << 8) +
+ (((256 - comp_id) & 0xFF) << 0);
}
@@ -423,7 +397,7 @@ PJ_DEF(pj_status_t) pj_ice_add_cand(pj_ice *ice,
const pj_str_t *foundation,
const pj_sockaddr_t *addr,
const pj_sockaddr_t *base_addr,
- const pj_sockaddr_t *srv_addr,
+ const pj_sockaddr_t *rel_addr,
int addr_len,
unsigned *p_cand_id)
{
@@ -452,10 +426,10 @@ PJ_DEF(pj_status_t) pj_ice_add_cand(pj_ice *ice,
lcand->prio = CALC_CAND_PRIO(type, local_pref, lcand->comp_id);
pj_memcpy(&lcand->addr, addr, addr_len);
pj_memcpy(&lcand->base_addr, base_addr, addr_len);
- if (srv_addr)
- pj_memcpy(&lcand->srv_addr, srv_addr, addr_len);
+ if (rel_addr)
+ pj_memcpy(&lcand->rel_addr, rel_addr, addr_len);
else
- pj_bzero(&lcand->srv_addr, sizeof(lcand->srv_addr));
+ pj_bzero(&lcand->rel_addr, sizeof(lcand->rel_addr));
/* Init STUN callbacks */
pj_bzero(&sess_cb, sizeof(sess_cb));
@@ -492,7 +466,7 @@ PJ_DEF(pj_status_t) pj_ice_add_cand(pj_ice *ice,
pj_ansi_strcpy(tmp, pj_inet_ntoa(lcand->addr.ipv4.sin_addr));
- LOG((ice->obj_name,
+ LOG4((ice->obj_name,
"Candidate %d added: comp_id=%d, type=%s, foundation=%.*s, "
"addr=%s:%d, base=%s:%d, prio=0x%x (%u)",
ice->lcand_cnt,
@@ -517,36 +491,9 @@ on_error:
}
-PJ_DEF(unsigned) pj_ice_get_cand_cnt(pj_ice *ice)
-{
- return ice->lcand_cnt;
-}
-
-
-PJ_DEF(pj_status_t) pj_ice_enum_cands(pj_ice *ice,
- unsigned *p_count,
- unsigned cand_ids[])
-{
- unsigned i, count;
-
- PJ_ASSERT_RETURN(ice && p_count && *p_count && cand_ids, PJ_EINVAL);
-
- pj_mutex_lock(ice->mutex);
-
- count = (*p_count < ice->lcand_cnt) ? *p_count : ice->lcand_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_default_cand(pj_ice *ice,
- unsigned comp_id,
- int *cand_id)
+PJ_DEF(pj_status_t) pj_ice_find_default_cand(pj_ice *ice,
+ unsigned comp_id,
+ int *cand_id)
{
unsigned i;
@@ -557,12 +504,11 @@ PJ_DEF(pj_status_t) pj_ice_get_default_cand(pj_ice *ice,
pj_mutex_lock(ice->mutex);
/* First find in valid list if we have nominated pair */
- for (i=0; i<ice->valid_cnt; ++i) {
- pj_ice_cand *lcand;
+ for (i=0; i<ice->valid_list.count; ++i) {
+ pj_ice_check *check = &ice->valid_list.checks[i];
- lcand = ice->clist.checks[ice->valid_list[i]].lcand;
- if (lcand->comp_id==comp_id) {
- *cand_id = GET_LCAND_ID(lcand);
+ if (check->lcand->comp_id == comp_id) {
+ *cand_id = GET_LCAND_ID(check->lcand);
pj_mutex_unlock(ice->mutex);
return PJ_SUCCESS;
}
@@ -608,22 +554,10 @@ PJ_DEF(pj_status_t) pj_ice_get_default_cand(pj_ice *ice,
pj_mutex_unlock(ice->mutex);
pj_assert(!"Should have a candidate by now");
- return PJ_EICENOCAND;
+ return PJ_EBUG;
}
-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->lcand_cnt, PJ_EINVAL);
-
- *p_cand = &ice->lcand[cand_id];
-
- return PJ_SUCCESS;
-}
-
#ifndef MIN
# define MIN(a,b) (a < b ? a : b)
#endif
@@ -689,25 +623,10 @@ static void dump_checklist(const char *title, const pj_ice *ice,
unsigned i;
char buffer[CHECK_NAME_LEN];
- LOG((ice->obj_name, "%s", title));
+ LOG4((ice->obj_name, "%s", title));
for (i=0; i<clist->count; ++i) {
const pj_ice_check *c = &clist->checks[i];
- LOG((ice->obj_name, " %s (%s, state=%s)",
- dump_check(buffer, sizeof(buffer), ice, c),
- (c->nominated ? "nominated" : "not nominated"),
- check_state_name[c->state]));
- }
-}
-
-static void dump_valid_list(const char *title, const pj_ice *ice)
-{
- unsigned i;
- char buffer[CHECK_NAME_LEN];
-
- LOG((ice->obj_name, "%s", title));
- for (i=0; i<ice->valid_cnt; ++i) {
- const pj_ice_check *c = &ice->clist.checks[ice->valid_list[i]];
- LOG((ice->obj_name, " %s (%s, state=%s)",
+ LOG4((ice->obj_name, " %s (%s, state=%s)",
dump_check(buffer, sizeof(buffer), ice, c),
(c->nominated ? "nominated" : "not nominated"),
check_state_name[c->state]));
@@ -726,7 +645,7 @@ static void check_set_state(pj_ice *ice, pj_ice_check *check,
pj_assert(check->state < PJ_ICE_CHECK_STATE_SUCCEEDED);
- LOG((ice->obj_name, "Check %s: state changed from %s to %s",
+ LOG5((ice->obj_name, "Check %s: state changed from %s to %s",
dump_check(buf, sizeof(buf), ice, check),
check_state_name[check->state],
check_state_name[st]));
@@ -738,7 +657,7 @@ static void clist_set_state(pj_ice *ice, pj_ice_checklist *clist,
pj_ice_checklist_state st)
{
if (clist->state != st) {
- LOG((ice->obj_name, "Checklist: state changed from %s to %s",
+ LOG5((ice->obj_name, "Checklist: state changed from %s to %s",
clist_state_name[clist->state],
clist_state_name[st]));
clist->state = st;
@@ -769,32 +688,6 @@ static void sort_checklist(pj_ice_checklist *clist)
}
}
-/* Sort valid list based on priority */
-static void sort_valid_list(pj_ice *ice)
-{
- unsigned i;
-
- for (i=0; i<ice->valid_cnt-1; ++i) {
- unsigned j, highest = i;
- pj_ice_check *ci = &ice->clist.checks[ice->valid_list[i]];
-
- for (j=i+1; j<ice->valid_cnt; ++j) {
- pj_ice_check *cj = &ice->clist.checks[ice->valid_list[j]];
-
- if (cj->prio > ci->prio) {
- highest = j;
- }
- }
-
- if (highest != i) {
- unsigned tmp = ice->valid_list[i];
- ice->valid_list[i] = ice->valid_list[j];
- ice->valid_list[j] = tmp;
- }
- }
-}
-
-
enum
{
SOCKADDR_EQUAL = 0,
@@ -865,7 +758,7 @@ static void prune_checklist(pj_ice *ice, pj_ice_checklist *clist)
/* Found duplicate, remove it */
char buf[CHECK_NAME_LEN];
- LOG((ice->obj_name, "Check %s pruned",
+ LOG5((ice->obj_name, "Check %s pruned",
dump_check(buf, sizeof(buf), ice, &clist->checks[j])));
pj_array_erase(clist->checks, sizeof(clist->checks[0]),
@@ -889,11 +782,10 @@ static void on_ice_complete(pj_ice *ice, pj_status_t status)
ice->ice_status = status;
/* Log message */
- LOG((ice->obj_name, "ICE process complete, status=%s",
+ LOG4((ice->obj_name, "ICE process complete, status=%s",
pj_strerror(status, errmsg, sizeof(errmsg)).ptr));
- dump_checklist("Dumping checklist", ice, &ice->clist);
- dump_valid_list("Dumping valid list", ice);
+ dump_checklist("Valid list", ice, &ice->valid_list);
/* Call callback */
(*ice->cb.on_ice_complete)(ice, status);
@@ -921,7 +813,7 @@ static pj_bool_t on_check_complete(pj_ice *ice,
if (check->err_code==PJ_SUCCESS && check->nominated) {
pj_ice_comp *comp;
- LOG((ice->obj_name, "Check %d is successful and nominated",
+ LOG5((ice->obj_name, "Check %d is successful and nominated",
GET_CHECK_ID(check)));
for (i=0; i<ice->clist.count; ++i) {
@@ -930,7 +822,7 @@ static pj_bool_t on_check_complete(pj_ice *ice,
(c->state==PJ_ICE_CHECK_STATE_FROZEN ||
c->state==PJ_ICE_CHECK_STATE_WAITING))
{
- LOG((ice->obj_name,
+ LOG5((ice->obj_name,
"Check %d to be failed because state is %s",
i, check_state_name[c->state]));
check_set_state(ice, c, PJ_ICE_CHECK_STATE_FAILED,
@@ -981,22 +873,6 @@ static pj_bool_t on_check_complete(pj_ice *ice,
/* TODO */
-#if 0
- /* For now, just see if we have a valid pair in component 1 and
- * just terminate ICE.
- */
- for (i=0; i<ice->valid_cnt; ++i) {
- pj_ice_check *c = &ice->clist.checks[ice->valid_list[i]];
- if (c->lcand->comp_id == 1)
- break;
- }
-
- if (i != ice->valid_cnt) {
- /* ICE succeeded */
- on_ice_complete(ice, PJ_SUCCESS);
- return PJ_TRUE;
- }
-#else
/* See if all components have nominated pair. If they do, then mark
* ICE processing as success, otherwise wait.
*/
@@ -1009,7 +885,6 @@ static pj_bool_t on_check_complete(pj_ice *ice,
on_ice_complete(ice, PJ_SUCCESS);
return PJ_TRUE;
}
-#endif
/*
* See if all checks in the checklist have completed. If we do,
@@ -1024,7 +899,7 @@ static pj_bool_t on_check_complete(pj_ice *ice,
if (i == ice->clist.count) {
/* All checks have completed */
- on_ice_complete(ice, -1);
+ on_ice_complete(ice, PJNATH_EICEFAILED);
return PJ_TRUE;
}
@@ -1166,7 +1041,7 @@ static pj_status_t perform_check(pj_ice *ice, pj_ice_checklist *clist,
rcand = check->rcand;
comp = find_comp(ice, lcand->comp_id);
- LOG((ice->obj_name,
+ LOG5((ice->obj_name,
"Sending connectivity check for check %s",
dump_check(buffer, sizeof(buffer), ice, check)));
@@ -1238,7 +1113,7 @@ static pj_status_t start_periodic_check(pj_timer_heap_t *th,
/* Set checklist state to Running */
clist_set_state(ice, clist, PJ_ICE_CHECKLIST_ST_RUNNING);
- LOG((ice->obj_name, "Starting checklist periodic check"));
+ LOG5((ice->obj_name, "Starting checklist periodic check"));
/* Send STUN Binding request for check with highest priority on
* Waiting state.
@@ -1306,14 +1181,13 @@ PJ_DEF(pj_status_t) pj_ice_start_check(pj_ice *ice)
unsigned i;
PJ_ASSERT_RETURN(ice, PJ_EINVAL);
+ /* Checklist must be created */
+ PJ_ASSERT_RETURN(ice->clist.count > 0, PJ_EINVALIDOP);
- LOG((ice->obj_name, "Starting ICE check.."));
+ LOG4((ice->obj_name, "Starting ICE check.."));
clist = &ice->clist;
- if (clist->count == 0)
- return PJ_EICENOCHECKLIST;
-
/* Pickup the first pair and set the state to Waiting */
clist->checks[0].state = PJ_ICE_CHECK_STATE_WAITING;
cand0 = clist->checks[0].lcand;
@@ -1362,9 +1236,8 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
{
struct req_data *rd = (struct req_data*) tdata->user_data;
pj_ice *ice;
- pj_ice_check *check;
- const pj_ice_cand *lcand;
- const pj_ice_cand *rcand;
+ pj_ice_check *check, *new_check;
+ pj_ice_cand *lcand;
pj_ice_checklist *clist;
pj_stun_xor_mapped_addr_attr *xaddr;
char buffer[CHECK_NAME_LEN];
@@ -1378,10 +1251,12 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
pj_mutex_lock(ice->mutex);
- lcand = check->lcand;
- rcand = check->rcand;
+ /* Init lcand to NULL. lcand will be found from the mapped address
+ * found in the response.
+ */
+ lcand = NULL;
- LOG((ice->obj_name,
+ LOG4((ice->obj_name,
"Check %s%s: connectivity check %s",
dump_check(buffer, sizeof(buffer), ice, check),
(check->nominated ? " (nominated)" : " (not nominated)"),
@@ -1402,29 +1277,32 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
*/
PJ_TODO(ICE_CHECK_RESPONSE_SOURCE_ADDRESS);
- /* Get the STUN MAPPED-ADDRESS attribute. */
+ /* Get the STUN XOR-MAPPED-ADDRESS attribute. */
xaddr = (pj_stun_xor_mapped_addr_attr*)
pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR,0);
if (!xaddr) {
check_set_state(ice, check, PJ_ICE_CHECK_STATE_FAILED,
- PJNATH_ESTUNNOXORMAP);
+ PJNATH_ESTUNNOMAPPEDADDR);
on_check_complete(ice, check);
pj_mutex_unlock(ice->mutex);
return;
}
- /* If the transport address returned in XOR-MAPPED-ADDRESS does not match
- * any of the local candidates that the agent knows about, the mapped
- * address represents a new candidate - a peer reflexive candidate.
- */
+ /* Find local candidate that matches the XOR-MAPPED-ADDRESS */
+ pj_assert(lcand == NULL);
for (i=0; i<ice->lcand_cnt; ++i) {
if (sockaddr_cmp(&xaddr->sockaddr, &ice->lcand[i].addr) == 0) {
/* Match */
+ lcand = &ice->lcand[i];
break;
}
}
- if (i == ice->lcand_cnt) {
+ /* If the transport address returned in XOR-MAPPED-ADDRESS does not match
+ * any of the local candidates that the agent knows about, the mapped
+ * address represents a new candidate - a peer reflexive candidate.
+ */
+ if (lcand == NULL) {
unsigned cand_id;
char buf[32];
pj_str_t foundation;
@@ -1450,14 +1328,23 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
lcand = &ice->lcand[cand_id];
}
- /* Sets the state of the pair that generated the check to succeeded. */
- check_set_state(ice, check, PJ_ICE_CHECK_STATE_SUCCEEDED, PJ_SUCCESS);
-
- /* This is a valid pair, so add this to the valid list */
- ice->valid_list[ice->valid_cnt++] = rd->ckid;
+ /* Add pair to valid list */
+ new_check = &ice->valid_list.checks[ice->valid_list.count++];
+ new_check->lcand = lcand;
+ new_check->rcand = check->rcand;
+ new_check->prio = CALC_CHECK_PRIO(ice, lcand, check->rcand);
+ new_check->state = PJ_ICE_CHECK_STATE_SUCCEEDED;
+ new_check->nominated = check->nominated;
+ new_check->err_code = PJ_SUCCESS;
/* Sort valid_list */
- sort_valid_list(ice);
+ sort_checklist(&ice->valid_list);
+
+
+ /* Sets the state of the original pair that generated the check to
+ * succeeded.
+ */
+ check_set_state(ice, check, PJ_ICE_CHECK_STATE_SUCCEEDED, PJ_SUCCESS);
/* Inform about check completion.
* This may terminate ICE processing.
@@ -1515,7 +1402,9 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
pj_mutex_unlock(ice->mutex);
}
-
+/* This callback is called by the STUN session associated with a candidate
+ * when it receives incoming request.
+ */
static pj_status_t on_stun_rx_request(pj_stun_session *sess,
const pj_uint8_t *pkt,
unsigned pkt_len,
@@ -1540,18 +1429,14 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
/* Reject any requests except Binding request */
if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) {
- pj_str_t err_msg = pj_str("Expecting Binding Request only");
status = pj_stun_session_create_response(sess, msg,
PJ_STUN_SC_BAD_REQUEST,
- &err_msg, &tdata);
- if (status != PJ_SUCCESS) {
+ NULL, &tdata);
+ if (status != PJ_SUCCESS)
return status;
- }
-
- status = pj_stun_session_send_msg(sess, PJ_TRUE,
- src_addr, src_addr_len, tdata);
- return status;
+ return pj_stun_session_send_msg(sess, PJ_TRUE,
+ src_addr, src_addr_len, tdata);
}
@@ -1566,7 +1451,7 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
ap = (pj_stun_priority_attr*)
pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_PRIORITY, 0);
if (ap == 0) {
- LOG((ice->obj_name, "Received Binding request with no PRIORITY"));
+ LOG5((ice->obj_name, "Received Binding request with no PRIORITY"));
pj_mutex_unlock(ice->mutex);
return PJ_SUCCESS;
}
@@ -1626,7 +1511,7 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
"f%p",
rcand->foundation.ptr);
- LOG((ice->obj_name,
+ LOG4((ice->obj_name,
"Added new remote candidate from the request: %s:%d",
pj_inet_ntoa(rcand->addr.ipv4.sin_addr),
(int)pj_ntohs(rcand->addr.ipv4.sin_port)));
@@ -1678,14 +1563,14 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
if (c->state == PJ_ICE_CHECK_STATE_FROZEN ||
c->state == PJ_ICE_CHECK_STATE_WAITING)
{
- LOG((ice->obj_name, "Performing triggered check for check %d",i));
+ LOG5((ice->obj_name, "Performing triggered check for check %d",i));
perform_check(ice, &ice->clist, i);
} else if (c->state == PJ_ICE_CHECK_STATE_IN_PROGRESS) {
/* Should retransmit here, but how??
* TODO
*/
- LOG((ice->obj_name, "Triggered check for check %d not performed "
+ LOG5((ice->obj_name, "Triggered check for check %d not performed "
"because it's in progress", i));
} else if (c->state == PJ_ICE_CHECK_STATE_SUCCEEDED) {
/* Check complete for this component.
@@ -1693,7 +1578,7 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
*/
pj_bool_t complete;
- LOG((ice->obj_name, "Triggered check for check %d not performed "
+ LOG5((ice->obj_name, "Triggered check for check %d not performed "
"because it's completed", i));
complete = on_check_complete(ice, c);
@@ -1721,12 +1606,12 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
c->nominated = (uc != NULL);
c->err_code = PJ_SUCCESS;
- LOG((ice->obj_name, "New triggered check added: %d",
+ LOG4((ice->obj_name, "New triggered check added: %d",
ice->clist.count));
perform_check(ice, &ice->clist, ice->clist.count++);
} else {
- LOG((ice->obj_name, "Error: unable to perform triggered check: "
+ LOG4((ice->obj_name, "Error: unable to perform triggered check: "
"TOO MANY CHECKS IN CHECKLIST!"));
}
@@ -1771,12 +1656,12 @@ PJ_DEF(pj_status_t) pj_ice_send_data( pj_ice *ice,
comp = find_comp(ice, comp_id);
if (comp == NULL) {
- status = PJ_EICEINCOMPID;
+ status = PJNATH_EICEINCOMPID;
goto on_return;
}
if (comp->nominated_check_id == -1) {
- status = PJ_EICEINPROGRESS;
+ status = PJNATH_EICEINPROGRESS;
goto on_return;
}
@@ -1812,7 +1697,7 @@ PJ_DEF(pj_status_t) pj_ice_on_rx_pkt( pj_ice *ice,
comp = find_comp(ice, comp_id);
if (comp == NULL) {
- status = PJ_EICEINCOMPID;
+ status = PJNATH_EICEINCOMPID;
goto on_return;
}
diff --git a/pjnath/src/pjnath/ice_stream_transport.c b/pjnath/src/pjnath/ice_stream_transport.c
index 1462ff25..c479a3df 100644
--- a/pjnath/src/pjnath/ice_stream_transport.c
+++ b/pjnath/src/pjnath/ice_stream_transport.c
@@ -364,13 +364,13 @@ PJ_DEF(pj_status_t) pj_ice_st_add_comp(pj_ice_st *ice_st,
PJ_ASSERT_RETURN(ice_st->comp_cnt < PJ_ICE_MAX_COMP, PJ_ETOOMANY);
/* Component ID must be valid */
- PJ_ASSERT_RETURN(comp_id <= PJ_ICE_MAX_COMP, PJ_EICEINCOMPID);
+ PJ_ASSERT_RETURN(comp_id <= PJ_ICE_MAX_COMP, PJNATH_EICEINCOMPID);
/* First component ID must be 1, second must be 2, etc., and
* they must be registered in order.
*/
PJ_ASSERT_RETURN(ice_st->comps[comp_id-1] == ice_st->comp_cnt,
- PJ_EICEINCOMPID);
+ PJNATH_EICEINCOMPID);
/* All in order, add the component. */
ice_st->comps[ice_st->comp_cnt++] = comp_id;
@@ -407,7 +407,7 @@ PJ_DEF(pj_status_t) pj_ice_st_add_host_interface(pj_ice_st *ice_st,
PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL);
/* Check that component ID present */
- PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJ_EICEINCOMPID);
+ PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID);
/* Can't add new interface while ICE is running */
PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EBUSY);
@@ -578,20 +578,14 @@ PJ_DEF(pj_status_t) pj_ice_st_init_ice(pj_ice_st *ice_st,
/* Create! */
status = pj_ice_create(&ice_st->stun_cfg, ice_st->obj_name, role,
- &ice_cb, local_ufrag, local_passwd, &ice_st->ice);
+ ice_st->comp_cnt, &ice_cb,
+ local_ufrag, local_passwd, &ice_st->ice);
if (status != PJ_SUCCESS)
return status;
/* Associate user data */
ice_st->ice->user_data = (void*)ice_st;
- /* Add components */
- for (i=0; i<ice_st->comp_cnt; ++i) {
- status = pj_ice_add_comp(ice_st->ice, ice_st->comps[i]);
- if (status != PJ_SUCCESS)
- goto on_error;
- }
-
/* Add candidates */
for (i=0; i<ice_st->itf_cnt; ++i) {
pj_ice_st_interface *is= ice_st->itfs[i];
@@ -626,20 +620,16 @@ PJ_DEF(pj_status_t) pj_ice_st_enum_cands(pj_ice_st *ice_st,
{
unsigned i, cnt;
pj_ice_cand *pcand;
- pj_status_t status;
PJ_ASSERT_RETURN(ice_st && count && cand, PJ_EINVAL);
PJ_ASSERT_RETURN(ice_st->ice, PJ_EINVALIDOP);
- cnt = pj_ice_get_cand_cnt(ice_st->ice);
+ cnt = ice_st->ice->lcand_cnt;
cnt = (cnt > *count) ? *count : cnt;
*count = 0;
for (i=0; i<cnt; ++i) {
- status = pj_ice_get_cand(ice_st->ice, i, &pcand);
- if (status != PJ_SUCCESS)
- return status;
-
+ pcand = &ice_st->ice->lcand[i];
pj_memcpy(&cand[i], pcand, sizeof(pj_ice_cand));
}
@@ -688,7 +678,7 @@ PJ_DEF(pj_status_t) pj_ice_st_send_data( pj_ice_st *ice_st,
pj_size_t data_len)
{
if (!ice_st->ice)
- return PJ_ENOICE;
+ return PJNATH_ENOICE;
return pj_ice_send_data(ice_st->ice, comp_id, data, data_len);
}
@@ -752,7 +742,7 @@ static pj_status_t on_tx_pkt(pj_ice *ice,
}
}
if (is == NULL) {
- return PJ_EICEINCANDID;
+ return PJNATH_EICEINCANDID;
}
pkt_size = size;
diff --git a/pjnath/src/pjnath/stun_auth.c b/pjnath/src/pjnath/stun_auth.c
index 2602bf8d..15f226dc 100644
--- a/pjnath/src/pjnath/stun_auth.c
+++ b/pjnath/src/pjnath/stun_auth.c
@@ -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 PJNATH_ESTUNMSGINT;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_INTEGRITY_CHECK_FAILURE);
}
/* 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 PJNATH_ESTUNNOUSERNAME;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_USERNAME);
}
/* Get REALM, if any */
@@ -202,7 +202,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 PJNATH_ESTUNUSERNAME;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNKNOWN_USERNAME);
}
@@ -217,7 +217,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 PJNATH_ESTUNNOREALM;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_REALM);
} else if (realm.slen != 0 && arealm != NULL) {
/* We want long term, and REALM is present */
@@ -228,7 +228,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 PJNATH_ESTUNNONCE;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_NONCE);
}
/* Verify REALM matches */
@@ -238,7 +238,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 PJNATH_ESTUNNOREALM;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_REALM);
}
/* Valid case, will validate the message integrity later */
@@ -261,7 +261,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 PJNATH_ESTUNNONCE;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_NONCE);
}
}
@@ -288,7 +288,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 PJNATH_ESTUNNONCE;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_NONCE);
}
}
@@ -333,7 +333,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 PJNATH_ESTUNMSGINT;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_INTEGRITY_CHECK_FAILURE);
}
/* Everything looks okay! */
diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c
index 2fdd9027..bd32c6ba 100644
--- a/pjnath/src/pjnath/stun_msg.c
+++ b/pjnath/src/pjnath/stun_msg.c
@@ -64,7 +64,6 @@ static struct
{ PJ_STUN_SC_NO_BINDING, "No Binding"},
{ PJ_STUN_SC_STALE_NONCE, "Stale Nonce"},
{ PJ_STUN_SC_TRANSITIONING, "Active Destination Already Set"},
- { PJ_STUN_SC_WRONG_USERNAME, "Wrong Username"},
{ PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO, "Unsupported Transport Protocol"},
{ PJ_STUN_SC_INVALID_IP_ADDR, "Invalid IP Address"},
{ PJ_STUN_SC_INVALID_PORT, "Invalid Port"},
@@ -513,6 +512,8 @@ PJ_DEF(const char*) pj_stun_get_attr_name(unsigned attr_type)
*/
PJ_DEF(pj_str_t) pj_stun_get_err_reason(int err_code)
{
+#if 0
+ /* Find error using linear search */
unsigned i;
for (i=0; i<PJ_ARRAY_SIZE(stun_err_msg_map); ++i) {
@@ -520,6 +521,33 @@ PJ_DEF(pj_str_t) pj_stun_get_err_reason(int err_code)
return pj_str((char*)stun_err_msg_map[i].err_msg);
}
return pj_str(NULL);
+#else
+ /* Find error message using binary search */
+ int first = 0;
+ int n = PJ_ARRAY_SIZE(stun_err_msg_map);
+
+ while (n > 0) {
+ int half = n/2;
+ int mid = first + half;
+
+ if (stun_err_msg_map[mid].err_code < err_code) {
+ first = mid+1;
+ n -= (half+1);
+ } else if (stun_err_msg_map[mid].err_code > err_code) {
+ n = half;
+ } else {
+ first = mid;
+ break;
+ }
+ }
+
+
+ if (stun_err_msg_map[first].err_code == err_code) {
+ return pj_str((char*)stun_err_msg_map[first].err_msg);
+ } else {
+ return pj_str(NULL);
+ }
+#endif
}
@@ -1579,18 +1607,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 PJNATH_ESTUNINMSGLEN;
+ return PJNATH_EINSTUNMSGLEN;
/* First byte of STUN message is always 0x00 or 0x01. */
if (*pdu != 0x00 && *pdu != 0x01)
- return PJNATH_ESTUNINMSGTYPE;
+ return PJNATH_EINSTUNMSGTYPE;
/* 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 PJNATH_ESTUNINMSGLEN;
+ return PJNATH_EINSTUNMSGLEN;
}
/* If magic is set, then there is great possibility that this is
@@ -1634,7 +1662,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),
- PJNATH_ESTUNINMSGTYPE);
+ PJNATH_EINSTUNMSGTYPE);
/* Create response or error response */
if (err_code)
@@ -1773,7 +1801,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
}
}
- return PJNATH_ESTUNUNKNOWNATTR;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNKNOWN_ATTRIBUTE);
}
} else {
@@ -2102,7 +2130,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 PJNATH_ESTUNNOUSERNAME;
+ return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_USERNAME);
}
/* Password must be specified */
diff --git a/pjnath/src/pjnath/stun_transaction.c b/pjnath/src/pjnath/stun_transaction.c
index 2813f7ef..07ce69d7 100644
--- a/pjnath/src/pjnath/stun_transaction.c
+++ b/pjnath/src/pjnath/stun_transaction.c
@@ -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, PJNATH_ESTUNNOTRESPOND, NULL);
+ tsx->cb.on_complete(tsx, PJNATH_ESTUNTIMEDOUT, 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 PJNATH_ESTUNNOTRESPONSE;
+ return PJNATH_EINSTUNMSGTYPE;
}
@@ -300,7 +300,8 @@ 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 = PJNATH_ESTUNTSXFAILED;
+ status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_class * 100 +
+ err_attr->number);
}
/* Call callback */