diff options
33 files changed, 1651 insertions, 212 deletions
diff --git a/pjlib/include/pj/errno.h b/pjlib/include/pj/errno.h index 6ff304d6..71ba69fd 100644 --- a/pjlib/include/pj/errno.h +++ b/pjlib/include/pj/errno.h @@ -341,6 +341,7 @@ PJ_DECL(pj_status_t) pj_register_strerror(pj_status_t start_code, * - PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE) * - PJSIP_SIMPLE_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*2) * - PJLIB_UTIL_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*3) + * - PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4) */ diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h index e7bcee13..d2da570c 100644 --- a/pjlib/include/pj/sock.h +++ b/pjlib/include/pj/sock.h @@ -175,26 +175,6 @@ typedef enum pj_socket_sd_type */ #define PJ_INVALID_SOCKET (-1) -/** - * Structure describing a generic socket address. - * If PJ_SOCKADDR_HAS_LEN is not zero, then sa_zero_len member is added - * to this struct. As far the application is concerned, the value of - * this member will always be zero. Internally, PJLIB may modify the value - * before calling OS socket API, and reset the value back to zero before - * returning the struct to application. - */ -typedef struct pj_sockaddr -{ -#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 - pj_uint8_t sa_zero_len; - pj_uint8_t sa_family; -#else - pj_uint16_t sa_family; /**< Common data: address family. */ -#endif - char sa_data[14]; /**< Address data. */ -} pj_sockaddr; - - #undef s_addr /** @@ -276,6 +256,36 @@ typedef struct pj_sockaddr_in6 } pj_sockaddr_in6; +/** + * This structure describes common attributes found in transport addresses. + * If PJ_SOCKADDR_HAS_LEN is not zero, then sa_zero_len member is added + * to this struct. As far the application is concerned, the value of + * this member will always be zero. Internally, PJLIB may modify the value + * before calling OS socket API, and reset the value back to zero before + * returning the struct to application. + */ +typedef struct pj_addr_hdr +{ +#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0 + pj_uint8_t sa_zero_len; + pj_uint8_t sa_family; +#else + pj_uint16_t sa_family; /**< Common data: address family. */ +#endif +} pj_addr_hdr; + + +/** + * This union describes a generic socket address. + */ +typedef union pj_sockaddr +{ + pj_addr_hdr addr; /**< Generic transport address. */ + pj_sockaddr_in ipv4; /**< IPv4 transport address. */ + pj_sockaddr_in6 ipv6; /**< IPv6 transport address. */ +} pj_sockaddr; + + /***************************************************************************** * * SOCKET ADDRESS MANIPULATION. diff --git a/pjmedia/build/wince-evc4/pjmedia_wince.vcp b/pjmedia/build/wince-evc4/pjmedia_wince.vcp index d90b39f8..69c3d049 100644 --- a/pjmedia/build/wince-evc4/pjmedia_wince.vcp +++ b/pjmedia/build/wince-evc4/pjmedia_wince.vcp @@ -76,8 +76,8 @@ BSC32=bscmake.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir "output/pjmedia_emulatorDbg" -# PROP Intermediate_Dir "output/pjmedia_emulatorDbg" +# PROP Output_Dir "./output/pjmedia_emulatorDbg" +# PROP Intermediate_Dir "./output/pjmedia_emulatorDbg" # PROP CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}" # PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" # PROP Target_Dir "" diff --git a/pjnath/build/pjnath.dsp b/pjnath/build/pjnath.dsp new file mode 100644 index 00000000..74af4bf2 --- /dev/null +++ b/pjnath/build/pjnath.dsp @@ -0,0 +1,174 @@ +# Microsoft Developer Studio Project File - Name="pjnath" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=pjnath - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pjnath.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pjnath.mak" CFG="pjnath - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pjnath - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "pjnath - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pjnath - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "./output/pjnath-i386-win32-vc6-release"
+# PROP BASE Intermediate_Dir "./output/pjnath-i386-win32-vc6-release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "./output/pjnath-i386-win32-vc6-release"
+# 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" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"../lib/pjnath-i386-win32-vc6-release.lib"
+
+!ELSEIF "$(CFG)" == "pjnath - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "./output/pjnath-i386-win32-vc6-debug"
+# PROP BASE Intermediate_Dir "./output/pjnath-i386-win32-vc6-debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "./output/pjnath-i386-win32-vc6-debug"
+# PROP Intermediate_Dir "./output/pjnath-i386-win32-vc6-debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"../lib/pjnath-i386-win32-vc6-debug.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "pjnath - Win32 Release"
+# Name "pjnath - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\src\pjnath\errno.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\pjnath\ice.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\pjnath\stun_auth.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\pjnath\stun_endpoint.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\pjnath\stun_msg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\pjnath\stun_msg_dump.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\pjnath\stun_session.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\pjnath\stun_transaction.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\include\pjnath\config.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\errno.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\ice.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\stun_auth.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\stun_doc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\stun_endpoint.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\stun_msg.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\stun_session.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\stun_transaction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\turn_client.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjnath\types.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/pjnath/build/pjnath.dsw b/pjnath/build/pjnath.dsw index 2105962e..03b80cd2 100644 --- a/pjnath/build/pjnath.dsw +++ b/pjnath/build/pjnath.dsw @@ -15,7 +15,7 @@ Package=<4> ###############################################################################
-Project: "pjlib_test"=..\..\pjlib\build\pjlib_test.dsp - Package Owner=<4>
+Project: "pjlib_util"="..\..\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
Package=<5>
{{{
@@ -27,7 +27,7 @@ Package=<4> ###############################################################################
-Project: "pjlib_util"="..\..\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
+Project: "pjnath"=.\pjnath.dsp - Package Owner=<4>
Package=<5>
{{{
@@ -53,6 +53,9 @@ Package=<4> Begin Project Dependency
Project_Dep_Name pjlib_util
End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name pjnath
+ End Project Dependency
}}}
###############################################################################
@@ -71,6 +74,9 @@ Package=<4> Begin Project Dependency
Project_Dep_Name pjlib_util
End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name pjnath
+ End Project Dependency
}}}
###############################################################################
diff --git a/pjnath/include/pjnath.h b/pjnath/include/pjnath.h new file mode 100644 index 00000000..7562120a --- /dev/null +++ b/pjnath/include/pjnath.h @@ -0,0 +1,27 @@ +/* $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/config.h> +#include <pjnath/errno.h> +#include <pjnath/stun_auth.h> +#include <pjnath/stun_endpoint.h> +#include <pjnath/stun_msg.h> +#include <pjnath/stun_session.h> +#include <pjnath/stun_transaction.h> +#include <pjnath/types.h> diff --git a/pjnath/include/pjnath/config.h b/pjnath/include/pjnath/config.h new file mode 100644 index 00000000..fc3e004e --- /dev/null +++ b/pjnath/include/pjnath/config.h @@ -0,0 +1,65 @@ +/* $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 + */ +#ifndef __PJNATH_CONFIG_H__ +#define __PJNATH_CONFIG_H__ + + +/** + * @file config.h + * @brief Compile time settings + */ + +/** + * @defgroup PJNATH_CONFIG Configuration + * @ingroup PJNATH + * @{ + */ + +/* ************************************************************************** + * STUN CLIENT CONFIGURATION + */ + +/** + * Maximum number of attributes in the STUN packet (for the old STUN + * library). + * + * Default: 16 + */ +#ifndef PJSTUN_MAX_ATTR +# define PJSTUN_MAX_ATTR 16 +#endif + + +/** + * Maximum number of attributes in the STUN packet (for the new STUN + * library). + * + * Default: 16 + */ +#ifndef PJ_STUN_MAX_ATTR +# define PJ_STUN_MAX_ATTR 16 +#endif + + +/** + * @} + */ + +#endif /* __PJNATH_CONFIG_H__ */ + diff --git a/pjnath/include/pjnath/errno.h b/pjnath/include/pjnath/errno.h new file mode 100644 index 00000000..cbefee85 --- /dev/null +++ b/pjnath/include/pjnath/errno.h @@ -0,0 +1,152 @@ +/* $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 + */ +#ifndef __PJNATH_ERRNO_H__ +#define __PJNATH_ERRNO_H__ + + +#include <pj/errno.h> + +/** + * @defgroup PJNATH_ERROR NAT Helper Error Codes + * @ingroup PJNATH + * @{ + */ + +/** + * Start of error code relative to PJ_ERRNO_START_USER. + * This value is 370000. + */ +#define PJNATH_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*4) + + + +/************************************************************ + * NEW STUN ERROR + ***********************************************************/ +/* Messaging errors */ +#define PJNATH_ESTUNINATTRLEN -1 +#define PJNATH_ESTUNINMSGLEN -1 +#define PJNATH_ESTUNINMSGTYPE -1 +#define PJNATH_ESTUNFINGERPRINT -1 +#define PJNATH_ESTUNNOTRESPOND -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. + */ +#define PJNATH_ESTUNNOTRESPONSE (PJNATH_ERRNO_START+114)/* 370114 */ +/** + * @hideinitializer + * STUN transaction ID mismatch. + */ +#define PJNATH_ESTUNINVALIDID (PJNATH_ERRNO_START+115)/* 370115 */ +/** + * @hideinitializer + * Unable to find handler for the request. + */ +#define PJNATH_ESTUNNOHANDLER (PJNATH_ERRNO_START+116)/* 370116 */ +/** + * @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. + */ +#define PJNATH_ESTUNMSGINTPOS (PJNATH_ERRNO_START+118)/* 370118 */ +/** + * @hideinitializer + * Found attribute after FINGERPRINT. This is not valid since FINGERPRINT + * MUST be the last attribute in the message. + */ +#define PJNATH_ESTUNFINGERPOS (PJNATH_ERRNO_START+119)/* 370119 */ +/** + * @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. + */ +#define PJNATH_ESTUNNOUSERNAME (PJNATH_ERRNO_START+120)/* 370120 */ +/** + * @hideinitializer + * Unknown STUN username/credential. + */ +#define PJNATH_ESTUNUSERNAME (PJNATH_ERRNO_START+121)/* 370121 */ +/** + * @hideinitializer + * Missing/invalidSTUN MESSAGE-INTEGRITY attribute. + */ +#define PJNATH_ESTUNMSGINT (PJNATH_ERRNO_START+122)/* 370122 */ +/** + * @hideinitializer + * Found duplicate STUN attribute. + */ +#define PJNATH_ESTUNDUPATTR (PJNATH_ERRNO_START+123)/* 370123 */ +/** + * @hideinitializer + * Missing STUN REALM attribute. + */ +#define PJNATH_ESTUNNOREALM (PJNATH_ERRNO_START+124)/* 370124 */ +/** + * @hideinitializer + * Missing/stale STUN NONCE attribute value. + */ +#define PJNATH_ESTUNNONCE (PJNATH_ERRNO_START+125)/* 370125 */ +/** + * @hideinitializer + * STUN transaction terminates with failure. + */ +#define PJNATH_ESTUNTSXFAILED (PJNATH_ERRNO_START+126)/* 370126 */ + + +//#define PJ_STATUS_FROM_STUN_CODE(code) (PJNATH_ERRNO_START+code) + + +/** + * @hideinitializer + * No ICE checklist is formed. + */ +#define PJ_EICENOCHECKLIST -1 + + + +/** + * @} + */ + +#endif /* __PJNATH_ERRNO_H__ */ diff --git a/pjnath/include/pjnath/ice.h b/pjnath/include/pjnath/ice.h new file mode 100644 index 00000000..3277dc77 --- /dev/null +++ b/pjnath/include/pjnath/ice.h @@ -0,0 +1,253 @@ +/* $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 + */ +#ifndef __PJNATH_ICE_SOCK_H__ +#define __PJNATH_ICE_SOCK_H__ + +/** + * @file ice_sock.h + * @brief ICE socket. + */ +#include <pjnath/types.h> +#include <pjnath/stun_endpoint.h> +#include <pjlib-util/resolver.h> +#include <pj/sock.h> + +PJ_BEGIN_DECL + + +/* **************************************************************************/ +/** + * @defgroup PJNATH_ICE_SOCK ICE Socket + * @brief High level ICE socket abstraction. + * @ingroup PJNATH + * @{ + */ + +/** + * This enumeration describes the type of an ICE candidate. + */ +typedef enum pj_ice_cand_type +{ + PJ_ICE_CAND_TYPE_HOST, + PJ_ICE_CAND_TYPE_MAPPED, + PJ_ICE_CAND_TYPE_PEER_MAPPED, + PJ_ICE_CAND_TYPE_RELAYED +} pj_ice_cand_type; + +/** + * + */ +enum pj_ice_type_pref +{ + PJ_ICE_HOST_PREF = 126, + PJ_ICE_MAPPED_PREF = 100, + PJ_ICE_PEER_MAPPED_PREF = 110, + PJ_ICE_RELAYED_PREF = 0 +}; + +typedef struct pj_ice pj_ice; + + +#define PJ_ICE_MAX_CAND 32 +#define PJ_ICE_MAX_COMP 8 + + +/** + * ICE component + */ +typedef struct pj_ice_comp +{ + unsigned comp_id; + pj_sock_t sock; +} pj_ice_comp; + + +/** + * This structure describes an ICE candidate. + */ +typedef struct pj_ice_cand +{ + pj_uint32_t comp_id; + pj_ice_cand_type type; + pj_str_t foundation; + pj_uint32_t prio; + pj_sockaddr addr; + pj_sockaddr base_addr; + pj_sockaddr srv_addr; +} pj_ice_cand; + +typedef enum pj_ice_check_state +{ + PJ_ICE_CHECK_STATE_FROZEN, + PJ_ICE_CHECK_STATE_WAITING, + PJ_ICE_CHECK_STATE_IN_PROGRESS, + PJ_ICE_CHECK_STATE_SUCCEEDED, + PJ_ICE_CHECK_STATE_FAILED +} pj_ice_check_state; + + +typedef struct pj_ice_check +{ + unsigned local_cand_id; + pj_uint64_t check_prio; + pj_ice_check_state check_state; + + pj_ice_cand_type rem_type; + pj_str_t rem_foundation; + pj_uint32_t rem_prio; + pj_sockaddr rem_addr; + pj_sockaddr rem_base_addr; +} pj_ice_check; + + +typedef enum pj_ice_checklist_state +{ + PJ_ICE_CHECKLIST_ST_IDLE, + PJ_ICE_CHECKLIST_ST_RUNNING, + PJ_ICE_CHECKLIST_ST_COMPLETED +} pj_ice_checklist_state; + +typedef struct pj_ice_checklist +{ + pj_ice_checklist_state state; + unsigned count; + pj_ice_check *checks; +} pj_ice_checklist; + + +/** + * ICE sock callback. + */ +typedef struct pj_ice_cb +{ + pj_bool_t (*on_found_cand)(pj_ice *sock, + pj_ice_cand_type type, + const pj_sockaddr_t *addr, + int addr_len); +} pj_ice_cb; + + +typedef enum pj_ice_state +{ + PJ_ICE_STATE_INIT, + PJ_ICE_STATE_GATHERING, + PJ_ICE_STATE_CAND_COMPLETE, + PJ_ICE_STATE_CHECKING, + PJ_ICE_STATE_COMPLETE, + PJ_ICE_STATE_RESV_ERROR +} pj_ice_state; + +/** + * ICE structure. + */ +struct pj_ice +{ + char obj_name[PJ_MAX_OBJ_NAME]; + + pj_pool_t *pool; + pj_mutex_t *mutex; + int af; + int sock_type; + + pj_ice_state state; + + /* Components */ + unsigned comp_cnt; + pj_ice_comp comp[PJ_ICE_MAX_COMP]; + + /* Local candidates */ + unsigned cand_cnt; + pj_ice_cand cand[PJ_ICE_MAX_CAND]; + + /* Checklist */ + pj_ice_checklist cklist; + + /* STUN servers */ + pj_dns_resolver *resv; + pj_dns_async_query *resv_q; + pj_bool_t relay_enabled; + pj_sockaddr stun_srv; +}; + + +PJ_DECL(pj_status_t) pj_ice_create(pj_stun_config *cfg, + const char *name, + int af, + int sock_type, + pj_ice **p_ice); +PJ_DECL(pj_status_t) pj_ice_destroy(pj_ice *ice); +PJ_DECL(pj_status_t) pj_ice_set_srv(pj_ice *ice, + pj_bool_t enable_relay, + pj_dns_resolver *resolver, + const pj_str_t *domain); +PJ_DECL(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_DECL(pj_status_t) pj_ice_add_comp(pj_ice *ice, + unsigned comp_id, + const pj_sockaddr_t *local_addr, + unsigned addr_len); +PJ_DECL(pj_status_t) pj_ice_add_sock_comp(pj_ice *ice, + unsigned comp_id, + pj_sock_t sock); + +PJ_DECL(pj_status_t) pj_ice_start_gather(pj_ice *ice, + unsigned flags); + +PJ_DECL(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 *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 sort_by, + unsigned *p_count, + unsigned cand_ids[]); +PJ_DECL(unsigned) pj_ice_get_default_cand(pj_ice *ice, + 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_create_check_list(pj_ice *ice, + pj_bool_t is_remote_offer, + unsigned rem_cand_cnt, + const pj_ice_cand rem_cand[]); + +PJ_DECL(pj_status_t) pj_ice_start_check(pj_ice *ice); + + +/** + * @} + */ + + +PJ_END_DECL + + +#endif /* __PJNATH_ICE_SOCK_H__ */ + diff --git a/pjnath/include/pjnath/stun_auth.h b/pjnath/include/pjnath/stun_auth.h index 49b2acbb..e30ebc95 100644 --- a/pjnath/include/pjnath/stun_auth.h +++ b/pjnath/include/pjnath/stun_auth.h @@ -16,15 +16,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __PJLIB_UTIL_STUN_AUTH_H__ -#define __PJLIB_UTIL_STUN_AUTH_H__ +#ifndef __PJNATH_STUN_AUTH_H__ +#define __PJNATH_STUN_AUTH_H__ /** * @file stun_auth.h * @brief STUN authentication. */ -#include <pjlib-util/stun_msg.h> +#include <pjnath/stun_msg.h> PJ_BEGIN_DECL @@ -32,8 +32,8 @@ PJ_BEGIN_DECL /* **************************************************************************/ /** - * @defgroup PJLIB_UTIL_STUN_AUTH STUN Authentication - * @ingroup PJLIB_UTIL_STUN + * @defgroup PJNATH_STUN_AUTH STUN Authentication + * @ingroup PJNATH_STUN * @{ */ @@ -271,5 +271,5 @@ void pj_stun_calc_md5_key(pj_uint8_t digest[16], PJ_END_DECL -#endif /* __PJLIB_UTIL_STUN_AUTH_H__ */ +#endif /* __PJNATH_STUN_AUTH_H__ */ diff --git a/pjnath/include/pjnath/stun_doc.h b/pjnath/include/pjnath/stun_doc.h index 612bf1a7..7b5e6511 100644 --- a/pjnath/include/pjnath/stun_doc.h +++ b/pjnath/include/pjnath/stun_doc.h @@ -24,8 +24,8 @@ */ /** - * @defgroup PJLIB_UTIL_STUN STUN and TURN - * @ingroup PJLIB_UTIL + * @defgroup PJNATH_STUN STUN and TURN + * @ingroup PJNATH This is the implementation of STUN/TURN in PJLIB-UTIL library. @@ -54,7 +54,7 @@ @subsection stun_msg_sec Messaging and Parsing - The lowest layer of the STUN implementation is the @ref PJLIB_UTIL_STUN_MSG + The lowest layer of the STUN implementation is the @ref PJNATH_STUN_MSG component. This part is responsible for encoding and decoding STUN messages. This layer only implements message representation and parsing. In particular, @@ -65,7 +65,7 @@ @subsection stun_endpt_sec Endpoint - The @ref PJLIB_UTIL_STUN_ENDPOINT is used by the library to put together + The @ref PJNATH_STUN_ENDPOINT is used by the library to put together common settings for all STUN objects. For example, the STUN endpoint has a reference of timer heap to poll all STUN timers, reference to ioqueue to poll network events for STUN servers, and some common settings used by @@ -74,11 +74,11 @@ @subsection stun_clt_tsx_sec Client Transaction - The @ref PJLIB_UTIL_STUN_TRANSACTION is used to manage outgoing STUN request, + The @ref PJNATH_STUN_TRANSACTION is used to manage outgoing STUN request, for example to retransmit the request and to notify application about the completion of the request. - The @ref PJLIB_UTIL_STUN_TRANSACTION does not use any networking operations, + The @ref PJNATH_STUN_TRANSACTION does not use any networking operations, but instead application must supply the transaction with a callback to be used by the transaction to send outgoing requests. This way the STUN transaction is made more generic and can work with different types of @@ -88,7 +88,7 @@ @subsection stun_srv_sec Server Components - The @ref PJLIB_UTIL_STUN_SERVER is used for: + The @ref PJNATH_STUN_SERVER is used for: - implementing STUN servers, and/or - implementing server side STUN handling (for example for ICE). diff --git a/pjnath/include/pjnath/stun_endpoint.h b/pjnath/include/pjnath/stun_endpoint.h index b341309a..d9a32b5c 100644 --- a/pjnath/include/pjnath/stun_endpoint.h +++ b/pjnath/include/pjnath/stun_endpoint.h @@ -16,15 +16,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __PJLIB_UTIL_STUN_ENDPOINT_H__ -#define __PJLIB_UTIL_STUN_ENDPOINT_H__ +#ifndef __PJNATH_STUN_CONFIG_H__ +#define __PJNATH_STUN_CONFIG_H__ /** - * @file stun_endpoint.h + * @file stun_config.h * @brief STUN endpoint. */ -#include <pjlib-util/stun_msg.h> +#include <pjnath/stun_msg.h> PJ_BEGIN_DECL @@ -32,9 +32,9 @@ PJ_BEGIN_DECL /* **************************************************************************/ /** - * @defgroup PJLIB_UTIL_STUN_ENDPOINT STUN Endpoint + * @defgroup PJNATH_STUN_ENDPOINT STUN Endpoint * @brief Management of incoming and outgoing STUN transactions. - * @ingroup PJLIB_UTIL_STUN + * @ingroup PJNATH_STUN * @{ */ @@ -43,7 +43,7 @@ PJ_BEGIN_DECL * server STUN transactions, and it needs to be initialized before application * can send or receive STUN messages. */ -typedef struct pj_stun_endpoint +typedef struct pj_stun_config { /** * Pool factory to be used by the STUN endpoint and all objects created @@ -86,23 +86,23 @@ typedef struct pj_stun_endpoint */ unsigned res_cache_msec; -} pj_stun_endpoint; +} pj_stun_config; /** * Create a STUN endpoint instance. */ -PJ_DECL(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_DECL(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); /** * Destroy STUN endpoint instance. */ -PJ_DECL(pj_status_t) pj_stun_endpoint_destroy(pj_stun_endpoint *endpt); +PJ_DECL(pj_status_t) pj_stun_config_destroy(pj_stun_config *endpt); /** @@ -113,5 +113,5 @@ PJ_DECL(pj_status_t) pj_stun_endpoint_destroy(pj_stun_endpoint *endpt); PJ_END_DECL -#endif /* __PJLIB_UTIL_STUN_ENDPOINT_H__ */ +#endif /* __PJNATH_STUN_CONFIG_H__ */ diff --git a/pjnath/include/pjnath/stun_msg.h b/pjnath/include/pjnath/stun_msg.h index ae66c2d1..ae076295 100644 --- a/pjnath/include/pjnath/stun_msg.h +++ b/pjnath/include/pjnath/stun_msg.h @@ -16,15 +16,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __PJLIB_UTIL_STUN_MSG_H__ -#define __PJLIB_UTIL_STUN_MSG_H__ +#ifndef __PJNATH_STUN_MSG_H__ +#define __PJNATH_STUN_MSG_H__ /** * @file stun_msg.h * @brief STUN message components. */ -#include <pjlib-util/types.h> +#include <pjnath/types.h> #include <pj/sock.h> @@ -33,9 +33,9 @@ PJ_BEGIN_DECL /* **************************************************************************/ /** - * @defgroup PJLIB_UTIL_STUN_MSG STUN Message Representation and Parsing + * @defgroup PJNATH_STUN_MSG STUN Message Representation and Parsing * @brief Low-level representation and parsing of STUN messages. - * @ingroup PJLIB_UTIL_STUN + * @ingroup PJNATH_STUN * @{ */ @@ -529,13 +529,9 @@ typedef struct pj_stun_sockaddr_attr pj_bool_t xor_ed; /** - * The socket address (as a union) + * The socket address */ - union { - pj_sockaddr addr; /**< Generic socket address. */ - pj_sockaddr_in ipv4; /**< IPv4 socket address. */ - pj_sockaddr_in6 ipv6; /**< IPv6 socket address. */ - } addr; + pj_sockaddr sockaddr; } pj_stun_sockaddr_attr; @@ -1535,5 +1531,5 @@ PJ_DECL(pj_status_t) pj_stun_msg_add_binary_attr(pj_pool_t *pool, PJ_END_DECL -#endif /* __PJLIB_UTIL_STUN_MSG_H__ */ +#endif /* __PJNATH_STUN_MSG_H__ */ diff --git a/pjnath/include/pjnath/stun_session.h b/pjnath/include/pjnath/stun_session.h index fa18dc3a..5f5bda30 100644 --- a/pjnath/include/pjnath/stun_session.h +++ b/pjnath/include/pjnath/stun_session.h @@ -16,13 +16,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __PJLIB_UTIL_STUN_SESSION_H__ -#define __PJLIB_UTIL_STUN_SESSION_H__ +#ifndef __PJNATH_STUN_SESSION_H__ +#define __PJNATH_STUN_SESSION_H__ -#include <pjlib-util/stun_msg.h> -#include <pjlib-util/stun_auth.h> -#include <pjlib-util/stun_endpoint.h> -#include <pjlib-util/stun_transaction.h> +#include <pjnath/stun_msg.h> +#include <pjnath/stun_auth.h> +#include <pjnath/stun_endpoint.h> +#include <pjnath/stun_transaction.h> #include <pj/list.h> #include <pj/timer.h> @@ -31,9 +31,9 @@ PJ_BEGIN_DECL /* **************************************************************************/ /** - * @defgroup PJLIB_UTIL_STUN_SESSION STUN Client/Server Session + * @defgroup PJNATH_STUN_SESSION STUN Client/Server Session * @brief STUN client and server session - * @ingroup PJLIB_UTIL_STUN + * @ingroup PJNATH_STUN * @{ */ @@ -156,7 +156,7 @@ struct pj_stun_tx_data /** * Create a STUN session. * - * @param endpt The STUN endpoint, to be used to register timers etc. + * @param cfg The STUN endpoint, to be used to register timers etc. * @param name Optional name to be associated with this instance. The * name will be used for example for logging purpose. * @param cb Session callback. @@ -165,7 +165,7 @@ struct pj_stun_tx_data * * @return PJ_SUCCESS on success, or the appropriate error code. */ -PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_endpoint *endpt, +PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_config *cfg, const char *name, const pj_stun_session_cb *cb, pj_bool_t fingerprint, @@ -368,5 +368,5 @@ PJ_DECL(void) pj_stun_msg_destroy_tdata(pj_stun_session *sess, PJ_END_DECL -#endif /* __PJLIB_UTIL_STUN_SESSION_H__ */ +#endif /* __PJNATH_STUN_SESSION_H__ */ diff --git a/pjnath/include/pjnath/stun_transaction.h b/pjnath/include/pjnath/stun_transaction.h index c7a5bf93..f4858863 100644 --- a/pjnath/include/pjnath/stun_transaction.h +++ b/pjnath/include/pjnath/stun_transaction.h @@ -16,16 +16,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __PJLIB_UTIL_STUN_TRANSACTION_H__ -#define __PJLIB_UTIL_STUN_TRANSACTION_H__ +#ifndef __PJNATH_STUN_TRANSACTION_H__ +#define __PJNATH_STUN_TRANSACTION_H__ /** * @file stun_transaction.h * @brief STUN transaction */ -#include <pjlib-util/stun_msg.h> -#include <pjlib-util/stun_endpoint.h> +#include <pjnath/stun_msg.h> +#include <pjnath/stun_endpoint.h> PJ_BEGIN_DECL @@ -33,16 +33,16 @@ PJ_BEGIN_DECL /* **************************************************************************/ /** - * @defgroup PJLIB_UTIL_STUN_TRANSACTION STUN Client Transaction + * @defgroup PJNATH_STUN_TRANSACTION STUN Client Transaction * @brief STUN client transaction - * @ingroup PJLIB_UTIL_STUN + * @ingroup PJNATH_STUN * @{ * - The @ref PJLIB_UTIL_STUN_TRANSACTION is used to manage outgoing STUN request, + The @ref PJNATH_STUN_TRANSACTION is used to manage outgoing STUN request, for example to retransmit the request and to notify application about the completion of the request. - The @ref PJLIB_UTIL_STUN_TRANSACTION does not use any networking operations, + The @ref PJNATH_STUN_TRANSACTION does not use any networking operations, but instead application must supply the transaction with a callback to be used by the transaction to send outgoing requests. This way the STUN transaction is made more generic and can work with different types of @@ -100,7 +100,7 @@ typedef struct pj_stun_tsx_cb * ensure the reliability of the request by periodically retransmitting * the request, if necessary. * - * @param endpt The STUN endpoint, which will be used to retrieve + * @param cfg The STUN endpoint, which will be used to retrieve * various settings for the transaction. * @param pool Pool to be used to allocate memory from. * @param cb Callback structure, to be used by the transaction @@ -110,7 +110,7 @@ typedef struct pj_stun_tsx_cb * * @return PJ_SUCCESS on success, or the appropriate error code. */ -PJ_DECL(pj_status_t) pj_stun_client_tsx_create( pj_stun_endpoint *endpt, +PJ_DECL(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); @@ -213,5 +213,5 @@ PJ_DECL(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx, PJ_END_DECL -#endif /* __PJLIB_UTIL_STUN_TRANSACTION_H__ */ +#endif /* __PJNATH_STUN_TRANSACTION_H__ */ diff --git a/pjnath/include/pjnath/turn_client.h b/pjnath/include/pjnath/turn_client.h index 83d8d2d6..b9cfacc0 100644 --- a/pjnath/include/pjnath/turn_client.h +++ b/pjnath/include/pjnath/turn_client.h @@ -16,24 +16,24 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __PJLIB_UTIL_TURN_CLIENT_H__ -#define __PJLIB_UTIL_TURN_CLIENT_H__ +#ifndef __PJNATH_TURN_CLIENT_H__ +#define __PJNATH_TURN_CLIENT_H__ /** * @file turn_client.h * @brief TURN client session. */ -#include <pjlib-util/stun_msg.h> +#include <pjnath/stun_msg.h> PJ_BEGIN_DECL /** - * @defgroup PJLIB_UTIL_TURN_CLIENT TURN Client Session + * @defgroup PJNATH_TURN_CLIENT TURN Client Session * @brief Management of STUN/TURN client session - * @ingroup PJLIB_UTIL_STUN + * @ingroup PJNATH_STUN * @{ */ @@ -128,5 +128,5 @@ PJ_DECL(pj_status_t) pj_turn_client_create(pj_stun_endpoint *endpt, PJ_END_DECL -#endif /* __PJLIB_UTIL_TURN_CLIENT_H__ */ +#endif /* __PJNATH_TURN_CLIENT_H__ */ diff --git a/pjnath/include/pjnath/types.h b/pjnath/include/pjnath/types.h new file mode 100644 index 00000000..d39da89e --- /dev/null +++ b/pjnath/include/pjnath/types.h @@ -0,0 +1,63 @@ +/* $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 + */ +#ifndef __PJNATH_TYPES_H__ +#define __PJNATH_TYPES_H__ + +/** + * @file types.h + * @brief PJNATH types. + */ + +#include <pj/types.h> +#include <pjnath/config.h> + +/** + * @defgroup PJNATH NAT Helper Library + */ + +/** + * @mainpage NAT Helper Library + * + * \n + * \n + * \n + * This is the documentation of PJNATH, an auxiliary library providing + * NAT helper functionalities such as STUN and ICE. + * + * 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 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) { diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 2229a2ba..62382169 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -567,7 +567,7 @@ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr, tdata->tp_info.transport = tr; pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len); tdata->tp_info.dst_addr_len = addr_len; - if (((pj_sockaddr*)addr)->sa_family == PJ_AF_INET) { + if (((pj_sockaddr*)addr)->addr.sa_family == PJ_AF_INET) { const char *str_addr; str_addr = pj_inet_ntoa(((pj_sockaddr_in*)addr)->sin_addr); pj_ansi_strcpy(tdata->tp_info.dst_name, str_addr); @@ -1361,7 +1361,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr, /* For datagram INET transports, try lookup with zero address. */ else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && - (remote_addr->sa_family == PJ_AF_INET)) + (remote_addr->addr.sa_family == PJ_AF_INET)) { pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; diff --git a/pjsip/src/pjsip/sip_transport_tcp.c b/pjsip/src/pjsip/sip_transport_tcp.c index 8aa679d4..481387c0 100644 --- a/pjsip/src/pjsip/sip_transport_tcp.c +++ b/pjsip/src/pjsip/sip_transport_tcp.c @@ -786,7 +786,7 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory, addr_len && p_transport, PJ_EINVAL); /* Check that address is a sockaddr_in */ - PJ_ASSERT_RETURN(rem_addr->sa_family == PJ_AF_INET && + PJ_ASSERT_RETURN(rem_addr->addr.sa_family == PJ_AF_INET && addr_len == sizeof(pj_sockaddr_in), PJ_EINVAL); diff --git a/pjsip/src/pjsip/sip_transport_udp.c b/pjsip/src/pjsip/sip_transport_udp.c index 216f2cf0..48d2b2d5 100644 --- a/pjsip/src/pjsip/sip_transport_udp.c +++ b/pjsip/src/pjsip/sip_transport_udp.c @@ -469,7 +469,7 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt, tp->base.key.type = PJSIP_TRANSPORT_UDP; /* Remote address is left zero (except the family) */ - tp->base.key.rem_addr.sa_family = PJ_AF_INET; + tp->base.key.rem_addr.addr.sa_family = PJ_AF_INET; /* Type name. */ tp->base.type_name = "UDP"; |