Index: /pjproject/trunk/pjlib/include/pj/errno.h
===================================================================
--- /pjproject/trunk/pjlib/include/pj/errno.h	(revision 1079)
+++ /pjproject/trunk/pjlib/include/pj/errno.h	(revision 1080)
@@ -342,4 +342,5 @@
  *  - 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)
  */
 
Index: /pjproject/trunk/pjlib/include/pj/sock.h
===================================================================
--- /pjproject/trunk/pjlib/include/pj/sock.h	(revision 1079)
+++ /pjproject/trunk/pjlib/include/pj/sock.h	(revision 1080)
@@ -175,24 +175,4 @@
  */
 #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
@@ -277,4 +257,34 @@
 
 
+/**
+ * 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;
+
+
 /*****************************************************************************
  *
Index: /pjproject/trunk/pjmedia/build/wince-evc4/pjmedia_wince.vcp
===================================================================
--- /pjproject/trunk/pjmedia/build/wince-evc4/pjmedia_wince.vcp	(revision 1079)
+++ /pjproject/trunk/pjmedia/build/wince-evc4/pjmedia_wince.vcp	(revision 1080)
@@ -77,6 +77,6 @@
 # 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}"
Index: /pjproject/trunk/pjnath/build/pjnath.dsp
===================================================================
--- /pjproject/trunk/pjnath/build/pjnath.dsp	(revision 1080)
+++ /pjproject/trunk/pjnath/build/pjnath.dsp	(revision 1080)
@@ -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
Index: /pjproject/trunk/pjnath/build/pjnath.dsw
===================================================================
--- /pjproject/trunk/pjnath/build/pjnath.dsw	(revision 1079)
+++ /pjproject/trunk/pjnath/build/pjnath.dsw	(revision 1080)
@@ -16,5 +16,5 @@
 ###############################################################################
 
-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>
@@ -28,5 +28,5 @@
 ###############################################################################
 
-Project: "pjlib_util"="..\..\pjlib-util\build\pjlib_util.dsp" - Package Owner=<4>
+Project: "pjnath"=.\pjnath.dsp - Package Owner=<4>
 
 Package=<5>
@@ -54,4 +54,7 @@
     Project_Dep_Name pjlib_util
     End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name pjnath
+    End Project Dependency
 }}}
 
@@ -72,4 +75,7 @@
     Project_Dep_Name pjlib_util
     End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name pjnath
+    End Project Dependency
 }}}
 
Index: /pjproject/trunk/pjnath/include/pjnath.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath.h	(revision 1080)
+++ /pjproject/trunk/pjnath/include/pjnath.h	(revision 1080)
@@ -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>
Index: /pjproject/trunk/pjnath/include/pjnath/config.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/config.h	(revision 1080)
+++ /pjproject/trunk/pjnath/include/pjnath/config.h	(revision 1080)
@@ -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__ */
+
Index: /pjproject/trunk/pjnath/include/pjnath/errno.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/errno.h	(revision 1080)
+++ /pjproject/trunk/pjnath/include/pjnath/errno.h	(revision 1080)
@@ -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__ */
Index: /pjproject/trunk/pjnath/include/pjnath/ice.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/ice.h	(revision 1080)
+++ /pjproject/trunk/pjnath/include/pjnath/ice.h	(revision 1080)
@@ -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__ */
+
Index: /pjproject/trunk/pjnath/include/pjnath/stun_auth.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/stun_auth.h	(revision 1079)
+++ /pjproject/trunk/pjnath/include/pjnath/stun_auth.h	(revision 1080)
@@ -17,6 +17,6 @@
  * 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__
 
 /**
@@ -25,5 +25,5 @@
  */
 
-#include <pjlib-util/stun_msg.h>
+#include <pjnath/stun_msg.h>
 
 
@@ -33,6 +33,6 @@
 /* **************************************************************************/
 /**
- * @defgroup PJLIB_UTIL_STUN_AUTH STUN Authentication
- * @ingroup PJLIB_UTIL_STUN
+ * @defgroup PJNATH_STUN_AUTH STUN Authentication
+ * @ingroup PJNATH_STUN
  * @{
  */
@@ -272,4 +272,4 @@
 
 
-#endif	/* __PJLIB_UTIL_STUN_AUTH_H__ */
-
+#endif	/* __PJNATH_STUN_AUTH_H__ */
+
Index: /pjproject/trunk/pjnath/include/pjnath/stun_doc.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/stun_doc.h	(revision 1079)
+++ /pjproject/trunk/pjnath/include/pjnath/stun_doc.h	(revision 1080)
@@ -25,6 +25,6 @@
 
 /**
- * @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.
@@ -55,5 +55,5 @@
  @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.
 
@@ -66,5 +66,5 @@
  @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
@@ -75,9 +75,9 @@
  @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
@@ -89,5 +89,5 @@
  @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).
Index: /pjproject/trunk/pjnath/include/pjnath/stun_endpoint.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/stun_endpoint.h	(revision 1079)
+++ /pjproject/trunk/pjnath/include/pjnath/stun_endpoint.h	(revision 1080)
@@ -17,13 +17,13 @@
  * 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>
 
 
@@ -33,7 +33,7 @@
 /* **************************************************************************/
 /**
- * @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
  * @{
  */
@@ -44,5 +44,5 @@
  * can send or receive STUN messages.
  */
-typedef struct pj_stun_endpoint
+typedef struct pj_stun_config
 {
     /**
@@ -87,5 +87,5 @@
     unsigned		 res_cache_msec;
 
-} pj_stun_endpoint;
+} pj_stun_config;
 
 
@@ -94,14 +94,14 @@
  * 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);
 
 
@@ -114,4 +114,4 @@
 
 
-#endif	/* __PJLIB_UTIL_STUN_ENDPOINT_H__ */
+#endif	/* __PJNATH_STUN_CONFIG_H__ */
 
Index: /pjproject/trunk/pjnath/include/pjnath/stun_msg.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 1079)
+++ /pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 1080)
@@ -17,6 +17,6 @@
  * 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__
 
 /**
@@ -25,5 +25,5 @@
  */
 
-#include <pjlib-util/types.h>
+#include <pjnath/types.h>
 #include <pj/sock.h>
 
@@ -34,7 +34,7 @@
 /* **************************************************************************/
 /**
- * @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
  * @{
  */
@@ -530,11 +530,7 @@
 
     /**
-     * The socket address (as a union)
-     */
-    union {
-	pj_sockaddr	    addr;   /**< Generic socket address.    */
-	pj_sockaddr_in	    ipv4;   /**< IPv4 socket address.	    */
-	pj_sockaddr_in6	    ipv6;   /**< IPv6 socket address.	    */
-    } addr;
+     * The socket address
+     */
+    pj_sockaddr		sockaddr;
 
 } pj_stun_sockaddr_attr;
@@ -1536,4 +1532,4 @@
 
 
-#endif	/* __PJLIB_UTIL_STUN_MSG_H__ */
-
+#endif	/* __PJNATH_STUN_MSG_H__ */
+
Index: /pjproject/trunk/pjnath/include/pjnath/stun_session.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/stun_session.h	(revision 1079)
+++ /pjproject/trunk/pjnath/include/pjnath/stun_session.h	(revision 1080)
@@ -17,11 +17,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
-#ifndef __PJLIB_UTIL_STUN_SESSION_H__
-#define __PJLIB_UTIL_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>
+#ifndef __PJNATH_STUN_SESSION_H__
+#define __PJNATH_STUN_SESSION_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>
@@ -32,7 +32,7 @@
 /* **************************************************************************/
 /**
- * @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
  * @{
  */
@@ -157,5 +157,5 @@
  * 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.
@@ -166,5 +166,5 @@
  * @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,
@@ -369,4 +369,4 @@
 PJ_END_DECL
 
-#endif	/* __PJLIB_UTIL_STUN_SESSION_H__ */
-
+#endif	/* __PJNATH_STUN_SESSION_H__ */
+
Index: /pjproject/trunk/pjnath/include/pjnath/stun_transaction.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/stun_transaction.h	(revision 1079)
+++ /pjproject/trunk/pjnath/include/pjnath/stun_transaction.h	(revision 1080)
@@ -17,6 +17,6 @@
  * 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__
 
 /**
@@ -25,6 +25,6 @@
  */
 
-#include <pjlib-util/stun_msg.h>
-#include <pjlib-util/stun_endpoint.h>
+#include <pjnath/stun_msg.h>
+#include <pjnath/stun_endpoint.h>
 
 
@@ -34,14 +34,14 @@
 /* **************************************************************************/
 /**
- * @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
@@ -101,5 +101,5 @@
  * 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.
@@ -111,5 +111,5 @@
  * @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,
@@ -214,4 +214,4 @@
 
 
-#endif	/* __PJLIB_UTIL_STUN_TRANSACTION_H__ */
-
+#endif	/* __PJNATH_STUN_TRANSACTION_H__ */
+
Index: /pjproject/trunk/pjnath/include/pjnath/turn_client.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/turn_client.h	(revision 1079)
+++ /pjproject/trunk/pjnath/include/pjnath/turn_client.h	(revision 1080)
@@ -17,6 +17,6 @@
  * 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__
 
 /**
@@ -25,5 +25,5 @@
  */
 
-#include <pjlib-util/stun_msg.h>
+#include <pjnath/stun_msg.h>
 
 
@@ -32,7 +32,7 @@
 
 /**
- * @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
  * @{
  */
@@ -129,4 +129,4 @@
 
 
-#endif	/* __PJLIB_UTIL_TURN_CLIENT_H__ */
+#endif	/* __PJNATH_TURN_CLIENT_H__ */
 
Index: /pjproject/trunk/pjnath/include/pjnath/types.h
===================================================================
--- /pjproject/trunk/pjnath/include/pjnath/types.h	(revision 1080)
+++ /pjproject/trunk/pjnath/include/pjnath/types.h	(revision 1080)
@@ -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__ */
+
Index: /pjproject/trunk/pjnath/src/pjnath/errno.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/errno.c	(revision 1080)
+++ /pjproject/trunk/pjnath/src/pjnath/errno.c	(revision 1080)
@@ -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);
+}
Index: /pjproject/trunk/pjnath/src/pjnath/ice.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/ice.c	(revision 1080)
+++ /pjproject/trunk/pjnath/src/pjnath/ice.c	(revision 1080)
@@ -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);
+}
Index: /pjproject/trunk/pjnath/src/pjnath/stun_auth.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_auth.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_auth.c	(revision 1080)
@@ -17,6 +17,6 @@
  * 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>
@@ -160,5 +160,5 @@
 			     &realm, &nonce, p_response);
 	}
-	return PJLIB_UTIL_ESTUNMSGINT;
+	return PJNATH_ESTUNMSGINT;
     }
 
@@ -171,5 +171,5 @@
 			     &realm, &nonce, p_response);
 	}
-	return PJLIB_UTIL_ESTUNNOUSERNAME;
+	return PJNATH_ESTUNNOUSERNAME;
     }
 
@@ -202,5 +202,5 @@
 			     &realm, &nonce, p_response);
 	}
-	return PJLIB_UTIL_ESTUNUSERNAME;
+	return PJNATH_ESTUNUSERNAME;
     }
 
@@ -217,5 +217,5 @@
 			     &realm, &nonce, p_response);
 	}
-	return PJLIB_UTIL_ESTUNNOREALM;
+	return PJNATH_ESTUNNOREALM;
 
     } else if (realm.slen != 0 && arealm != NULL) {
@@ -228,5 +228,5 @@
 				 NULL, &realm, &nonce, p_response);
 	    }
-	    return PJLIB_UTIL_ESTUNNONCE;
+	    return PJNATH_ESTUNNONCE;
 	}
 
@@ -238,5 +238,5 @@
 				 NULL, &realm, &nonce, p_response);
 	    }
-	    return PJLIB_UTIL_ESTUNNOREALM;
+	    return PJNATH_ESTUNNOREALM;
 	}
 
@@ -261,5 +261,5 @@
 				 NULL, &realm, &nonce, p_response);
 	    }
-	    return PJLIB_UTIL_ESTUNNONCE;
+	    return PJNATH_ESTUNNONCE;
 	}
     }
@@ -287,5 +287,5 @@
 				 NULL, &realm, &nonce, p_response);
 	    }
-	    return PJLIB_UTIL_ESTUNNONCE;
+	    return PJNATH_ESTUNNONCE;
 	}
     }
@@ -332,5 +332,5 @@
 			     NULL, &realm, &nonce, p_response);
 	}
-	return PJLIB_UTIL_ESTUNMSGINT;
+	return PJNATH_ESTUNMSGINT;
     }
 
Index: /pjproject/trunk/pjnath/src/pjnath/stun_endpoint.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_endpoint.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_endpoint.c	(revision 1080)
@@ -17,6 +17,6 @@
  * 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>
@@ -26,12 +26,12 @@
  * 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);
@@ -41,5 +41,5 @@
 	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;
@@ -59,5 +59,5 @@
  * 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);
Index: /pjproject/trunk/pjnath/src/pjnath/stun_msg.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_msg.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_msg.c	(revision 1080)
@@ -17,7 +17,7 @@
  * 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>
@@ -559,5 +559,5 @@
     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;
 
@@ -607,5 +607,5 @@
     /* 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 */
@@ -614,10 +614,10 @@
     /* 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 */
@@ -645,5 +645,5 @@
     /* 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 */
@@ -652,13 +652,13 @@
     /* 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);
-
-    attr->addr.ipv4.sin_port ^= 0x2112;
-    attr->addr.ipv4.sin_addr.s_addr ^= pj_htonl(0x2112A442);
+    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->sockaddr.ipv4.sin_port ^= pj_htons(0x2112);
+    attr->sockaddr.ipv4.sin_addr.s_addr ^= pj_htonl(0x2112A442);
 
     /* Done */
@@ -694,5 +694,5 @@
 
     /* 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;
 
@@ -701,8 +701,8 @@
 	pj_uint16_t port;
 
-	addr = ca->addr.ipv4.sin_addr.s_addr;
-	port = ca->addr.ipv4.sin_port;
-
-	port ^= 0x2112;
+	addr = ca->sockaddr.ipv4.sin_addr.s_addr;
+	port = ca->sockaddr.ipv4.sin_port;
+
+	port ^= pj_htons(0x2112);
 	addr ^= pj_htonl(0x2112A442);
 
@@ -717,9 +717,9 @@
     } 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;
     }
@@ -893,5 +893,5 @@
     /* Check that the attribute length is valid */
     if (attr->hdr.length != ATTR_HDR_LEN)
-	return PJLIB_UTIL_ESTUNINATTRLEN;
+	return PJNATH_ESTUNINATTRLEN;
 
     /* Done */
@@ -993,5 +993,5 @@
     /* Check that the attribute length is valid */
     if (attr->hdr.length != STUN_UINT_LEN)
-	return PJLIB_UTIL_ESTUNINATTRLEN;
+	return PJNATH_ESTUNINATTRLEN;
 
     /* Done */
@@ -1089,5 +1089,5 @@
     /* Check that the attribute length is valid */
     if (attr->hdr.length != STUN_MSG_INTEGRITY_LEN)
-	return PJLIB_UTIL_ESTUNINATTRLEN;
+	return PJNATH_ESTUNINATTRLEN;
 
     /* Done */
@@ -1564,9 +1564,9 @@
 
     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 */
@@ -1575,5 +1575,5 @@
 	((options & PJ_STUN_IS_DATAGRAM) && msg_len + 20 != pdu_len))
     {
-	return PJLIB_UTIL_ESTUNINMSGLEN;
+	return PJNATH_ESTUNINMSGLEN;
     }
 
@@ -1590,5 +1590,5 @@
 
 	    if (attr_len != 4)
-		return PJLIB_UTIL_ESTUNINATTRLEN;
+		return PJNATH_ESTUNINATTRLEN;
 
 	    crc = pj_crc32_calc(pdu, msg_len + 20);
@@ -1596,5 +1596,5 @@
 
 	    if (crc != fingerprint)
-		return PJLIB_UTIL_ESTUNFINGERPRINT;
+		return PJNATH_ESTUNFINGERPRINT;
 	}
     }
@@ -1619,5 +1619,5 @@
 
     PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(msg_type), 
-		     PJLIB_UTIL_ESTUNINMSGTYPE);
+		     PJNATH_ESTUNINMSGTYPE);
 
     /* Create response or error response */
@@ -1729,5 +1729,5 @@
 					    &err_msg, p_response);
 	    }
-	    return PJLIB_UTIL_ESTUNINATTRLEN;
+	    return PJNATH_ESTUNINATTRLEN;
 	}
 
@@ -1758,5 +1758,5 @@
 		}
 
-		return PJLIB_UTIL_ESTUNUNKNOWNATTR;
+		return PJNATH_ESTUNUNKNOWNATTR;
 	    }
 
@@ -1806,5 +1806,5 @@
 						    NULL, p_response);
 		    }
-		    return PJLIB_UTIL_ESTUNDUPATTR;
+		    return PJNATH_ESTUNDUPATTR;
 		}
 		has_msg_int = PJ_TRUE;
@@ -1820,5 +1820,5 @@
 						    NULL, p_response);
 		    }
-		    return PJLIB_UTIL_ESTUNDUPATTR;
+		    return PJNATH_ESTUNDUPATTR;
 		}
 		has_fingerprint = PJ_TRUE;
@@ -1834,6 +1834,6 @@
 						    NULL, p_response);
 		    }
-		    return has_fingerprint ? PJLIB_UTIL_ESTUNFINGERPOS :
-					     PJLIB_UTIL_ESTUNMSGINTPOS;
+		    return has_fingerprint ? PJNATH_ESTUNFINGERPOS :
+					     PJNATH_ESTUNMSGINTPOS;
 		}
 	    }
@@ -1849,5 +1849,5 @@
 						&e, p_response);
 		}
-		return PJLIB_UTIL_ESTUNTOOMANYATTR;
+		return PJNATH_ESTUNTOOMANYATTR;
 	    }
 
@@ -2028,10 +2028,10 @@
 
 	/* 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;
 
@@ -2071,5 +2071,5 @@
 	    /* 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)  {
@@ -2077,5 +2077,5 @@
 		/* 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];
@@ -2087,5 +2087,5 @@
 	    /* Should not happen for message generated by us */
 	    pj_assert(PJ_FALSE);
-	    return PJLIB_UTIL_ESTUNNOUSERNAME;
+	    return PJNATH_ESTUNNOUSERNAME;
 	}
 
Index: /pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c	(revision 1080)
@@ -17,6 +17,6 @@
  * 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>
@@ -81,11 +81,11 @@
 	    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));
-
-	    } else if (attr->addr.addr.sa_family == PJ_AF_INET6) {
+				       pj_inet_ntoa(attr->sockaddr.ipv4.sin_addr),
+				       pj_ntohs(attr->sockaddr.ipv4.sin_port));
+
+	    } else if (attr->sockaddr.addr.sa_family == PJ_AF_INET6) {
 		len = pj_ansi_snprintf(p, end-p,
 				       ", IPv6 addr present\n");
Index: /pjproject/trunk/pjnath/src/pjnath/stun_session.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_session.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_session.c	(revision 1080)
@@ -17,10 +17,10 @@
  * 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;
@@ -120,5 +120,5 @@
 
     /* 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);
@@ -171,5 +171,5 @@
     }
     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;
@@ -224,6 +224,6 @@
 
     /* 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,
@@ -301,5 +301,5 @@
 /* **************************************************************************/
 
-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,
@@ -311,14 +311,14 @@
     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));
@@ -384,6 +384,9 @@
 						    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;
 }
@@ -490,12 +493,10 @@
     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);
@@ -559,5 +560,5 @@
 
 	/* 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);
@@ -593,8 +594,8 @@
 				&on_cache_timeout);
 
-	    timeout.sec = sess->endpt->res_cache_msec / 1000;
-	    timeout.msec = sess->endpt->res_cache_msec % 1000;
-
-	    status = pj_timer_heap_schedule(sess->endpt->timer_heap, 
+	    timeout.sec = sess->cfg->res_cache_msec / 1000;
+	    timeout.msec = sess->cfg->res_cache_msec % 1000;
+
+	    status = pj_timer_heap_schedule(sess->cfg->timer_heap, 
 					    &tdata->res_timer,
 					    &timeout);
@@ -830,5 +831,5 @@
     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;
Index: /pjproject/trunk/pjnath/src/pjnath/stun_transaction.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjnath/stun_transaction.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjnath/stun_transaction.c	(revision 1080)
@@ -17,6 +17,6 @@
  * 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>
@@ -32,5 +32,5 @@
 {
     char		 obj_name[PJ_MAX_OBJ_NAME];
-    pj_stun_endpoint	*endpt;
+    pj_stun_config	*cfg;
     pj_stun_tsx_cb	 cb;
     void		*user_data;
@@ -64,5 +64,5 @@
  * 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,
@@ -71,9 +71,9 @@
     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));
 
@@ -98,5 +98,5 @@
 
     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;
     }
@@ -150,5 +150,5 @@
 	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) {
@@ -169,5 +169,5 @@
 	 * 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) {
@@ -183,5 +183,5 @@
     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;
 	}
@@ -236,5 +236,5 @@
 	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;
@@ -269,5 +269,5 @@
 	PJ_LOG(4,(tsx->obj_name, 
 		  "STUN rx_msg() error: not response message"));
-	return PJLIB_UTIL_ESTUNNOTRESPONSE;
+	return PJNATH_ESTUNNOTRESPONSE;
     }
 
@@ -277,5 +277,5 @@
      */
     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;
     }
@@ -301,5 +301,5 @@
 	status = PJ_SUCCESS;
     } else {
-	status = PJLIB_UTIL_ESTUNTSXFAILED;
+	status = PJNATH_ESTUNTSXFAILED;
     }
 
Index: /pjproject/trunk/pjnath/src/pjstun-client/client_main.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjstun-client/client_main.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjstun-client/client_main.c	(revision 1080)
@@ -17,4 +17,5 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  */
+#include <pjnath.h>
 #include <pjlib-util.h>
 #include <pjlib.h>
Index: /pjproject/trunk/pjnath/src/pjstun-srv-test/bind_usage.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjstun-srv-test/bind_usage.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjstun-srv-test/bind_usage.c	(revision 1080)
@@ -86,5 +86,5 @@
     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) {
Index: /pjproject/trunk/pjnath/src/pjstun-srv-test/server.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjstun-srv-test/server.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjstun-srv-test/server.c	(revision 1080)
@@ -84,6 +84,6 @@
 	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;
@@ -175,5 +175,5 @@
     }
 
-    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);
Index: /pjproject/trunk/pjnath/src/pjstun-srv-test/server.h
===================================================================
--- /pjproject/trunk/pjnath/src/pjstun-srv-test/server.h	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjstun-srv-test/server.h	(revision 1080)
@@ -20,4 +20,5 @@
 #define __STUN_SERVER_H__
 
+#include <pjnath.h>
 #include <pjlib-util.h>
 #include <pjlib.h>
@@ -31,5 +32,5 @@
 {
     pj_pool_factory	*pf;
-    pj_stun_endpoint	*endpt;
+    pj_stun_config	*cfg;
     pj_ioqueue_t	*ioqueue;
     pj_timer_heap_t	*timer_heap;
Index: /pjproject/trunk/pjnath/src/pjstun-srv-test/turn_usage.c
===================================================================
--- /pjproject/trunk/pjnath/src/pjstun-srv-test/turn_usage.c	(revision 1079)
+++ /pjproject/trunk/pjnath/src/pjstun-srv-test/turn_usage.c	(revision 1080)
@@ -70,5 +70,5 @@
 {
     pj_pool_factory	*pf;
-    pj_stun_endpoint	*endpt;
+    pj_stun_config	*cfg;
     pj_ioqueue_t	*ioqueue;
     pj_timer_heap_t	*timer_heap;
@@ -166,5 +166,5 @@
     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;
@@ -198,5 +198,5 @@
     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) {
@@ -208,4 +208,6 @@
     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 */
@@ -621,5 +623,5 @@
     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);
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transport.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 1079)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 1080)
@@ -568,5 +568,5 @@
     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);
@@ -1362,5 +1362,5 @@
 	     */
 	    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;
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c	(revision 1079)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c	(revision 1080)
@@ -787,5 +787,5 @@
 
     /* 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);
 
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c	(revision 1079)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c	(revision 1080)
@@ -470,5 +470,5 @@
 
     /* 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. */
