diff options
author | Benny Prijono <bennylp@teluu.com> | 2008-04-09 09:38:12 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2008-04-09 09:38:12 +0000 |
commit | d0b1cc04536aa71c104dc3b14ae0f6f4ffb36066 (patch) | |
tree | e74dae3fac329ce74fba07ada0e6a3080b94e584 | |
parent | 02ca90e766f49bf2c03e784669220f838eb19805 (diff) |
More ticket #485: huge changeset to support TURN TCP. Please see ticket #485 for the details
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1913 74dad513-b988-da41-8d7b-12977e46ad98
24 files changed, 3518 insertions, 883 deletions
diff --git a/build.symbian/pjnath.mmp b/build.symbian/pjnath.mmp index 00a821e6..ecdc991e 100644 --- a/build.symbian/pjnath.mmp +++ b/build.symbian/pjnath.mmp @@ -38,6 +38,8 @@ SOURCE stun_msg.c SOURCE stun_msg_dump.c SOURCE stun_session.c SOURCE stun_transaction.c +SOURCE turn_session.c +SOURCE turn_sock.c // // Include files diff --git a/pjnath/build/Makefile b/pjnath/build/Makefile index 9dd0b2db..9887aee7 100644 --- a/pjnath/build/Makefile +++ b/pjnath/build/Makefile @@ -32,7 +32,7 @@ export PJNATH_SRCDIR = ../src/pjnath export PJNATH_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ errno.o ice_session.o ice_strans.o nat_detect.o stun_auth.o \ stun_msg.o stun_msg_dump.o stun_session.o stun_transaction.o \ - turn_session.o turn_udp.o + turn_session.o turn_sock.o export PJNATH_CFLAGS += $(_CFLAGS) ############################################################################### diff --git a/pjnath/build/pjnath.dsp b/pjnath/build/pjnath.dsp index 302893f9..615a8d81 100644 --- a/pjnath/build/pjnath.dsp +++ b/pjnath/build/pjnath.dsp @@ -129,7 +129,7 @@ SOURCE=..\src\pjnath\turn_session.c # End Source File
# Begin Source File
-SOURCE=..\src\pjnath\turn_udp.c
+SOURCE=..\src\pjnath\turn_sock.c
# End Source File
# End Group
# Begin Group "Header Files"
@@ -185,7 +185,7 @@ SOURCE=..\include\pjnath\turn_session.h # End Source File
# Begin Source File
-SOURCE=..\include\pjnath\turn_udp.h
+SOURCE=..\include\pjnath\turn_sock.h
# End Source File
# Begin Source File
diff --git a/pjnath/build/pjnath.vcproj b/pjnath/build/pjnath.vcproj index 766f1846..9be22ce5 100644 --- a/pjnath/build/pjnath.vcproj +++ b/pjnath/build/pjnath.vcproj @@ -324,7 +324,7 @@ >
</File>
<File
- RelativePath="..\src\pjnath\turn_udp.c"
+ RelativePath="..\src\pjnath\turn_sock.c"
>
</File>
</Filter>
@@ -385,7 +385,7 @@ >
</File>
<File
- RelativePath="..\include\pjnath\turn_udp.h"
+ RelativePath="..\include\pjnath\turn_sock.h"
>
</File>
<File
diff --git a/pjnath/build/pjturn_srv.dsp b/pjnath/build/pjturn_srv.dsp index 01316e48..466c7104 100644 --- a/pjnath/build/pjturn_srv.dsp +++ b/pjnath/build/pjturn_srv.dsp @@ -95,6 +95,10 @@ SOURCE="..\src\pjturn-srv\auth.c" # End Source File
# Begin Source File
+SOURCE="..\src\pjturn-srv\listener_tcp.c"
+# End Source File
+# Begin Source File
+
SOURCE="..\src\pjturn-srv\listener_udp.c"
# End Source File
# Begin Source File
diff --git a/pjnath/build/wince-evc4/pjnath_wince.vcp b/pjnath/build/wince-evc4/pjnath_wince.vcp index 3c544689..4088a14d 100644 --- a/pjnath/build/wince-evc4/pjnath_wince.vcp +++ b/pjnath/build/wince-evc4/pjnath_wince.vcp @@ -585,8 +585,12 @@ DEP_CPP_ERRNO=\ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -598,10 +602,12 @@ DEP_CPP_ERRNO=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -1254,8 +1260,12 @@ DEP_CPP_ICE_S=\ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -1267,10 +1277,12 @@ DEP_CPP_ICE_S=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -1977,8 +1989,12 @@ DEP_CPP_ICE_ST=\ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -1990,10 +2006,13 @@ DEP_CPP_ICE_ST=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\socket.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -3448,13 +3467,18 @@ DEP_CPP_STUN_=\ DEP_CPP_STUN_=\
"..\..\..\pjlib-util\include\pjlib-util\hmac_sha1.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\md5.h"\
"..\..\..\pjlib-util\include\pjlib-util\sha1.h"\
"..\..\..\pjlib\include\pj\addr_resolv.h"\
"..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -3466,10 +3490,12 @@ DEP_CPP_STUN_=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -4138,14 +4164,18 @@ DEP_CPP_STUN_M=\ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
"..\..\..\pjlib-util\include\pjlib-util\crc32.h"\
"..\..\..\pjlib-util\include\pjlib-util\hmac_sha1.h"\
- "..\..\..\pjlib-util\include\pjlib-util\md5.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\sha1.h"\
"..\..\..\pjlib-util\include\pjlib-util\types.h"\
"..\..\..\pjlib\include\pj\addr_resolv.h"\
"..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -4157,10 +4187,12 @@ DEP_CPP_STUN_M=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -4819,8 +4851,12 @@ DEP_CPP_STUN_MS=\ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -4832,10 +4868,12 @@ DEP_CPP_STUN_MS=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -5480,8 +5518,12 @@ DEP_CPP_STUN_S=\ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -5493,10 +5535,12 @@ DEP_CPP_STUN_S=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -5531,6 +5575,7 @@ DEP_CPP_STUN_S=\ "..\..\..\pjlib\include\pj\unicode.h"\
"..\..\..\pjlib\include\pjlib.h"\
"..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
"..\..\include\pjnath\stun_auth.h"\
"..\..\include\pjnath\stun_config.h"\
"..\..\include\pjnath\stun_msg.h"\
@@ -6155,8 +6200,12 @@ DEP_CPP_STUN_T=\ "..\..\..\pjlib\include\pj\array.h"\
"..\..\..\pjlib\include\pj\assert.h"\
"..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
"..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
"..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
"..\..\..\pjlib\include\pj\compat\ctype.h"\
"..\..\..\pjlib\include\pj\compat\errno.h"\
"..\..\..\pjlib\include\pj\compat\high_precision.h"\
@@ -6168,10 +6217,12 @@ DEP_CPP_STUN_T=\ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
"..\..\..\pjlib\include\pj\compat\os_rtems.h"\
"..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
"..\..\..\pjlib\include\pj\compat\os_win32.h"\
"..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
"..\..\..\pjlib\include\pj\compat\setjmp.h"\
"..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
"..\..\..\pjlib\include\pj\compat\string.h"\
"..\..\..\pjlib\include\pj\config.h"\
"..\..\..\pjlib\include\pj\config_site.h"\
@@ -6547,6 +6598,1590 @@ DEP_CPP_STUN_T=\ !ENDIF
# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\pjnath\turn_session.c
+
+!IF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Release"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Debug"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Release"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Debug"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4T) Release"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4T) Debug"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE x86) Release"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE x86) Debug"
+
+DEP_CPP_TURN_=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\errno.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\pjnath\turn_sock.c
+
+!IF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Release"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Debug"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Release"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Debug"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4T) Release"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4T) Debug"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE x86) Release"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE x86) Debug"
+
+DEP_CPP_TURN_S=\
+ "..\..\..\pjlib-util\include\pjlib-util\config.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\dns.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\
+ "..\..\..\pjlib-util\include\pjlib-util\types.h"\
+ "..\..\..\pjlib\include\pj\addr_resolv.h"\
+ "..\..\..\pjlib\include\pj\array.h"\
+ "..\..\..\pjlib\include\pj\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\assert.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_codew.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\
+ "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\
+ "..\..\..\pjlib\include\pj\compat\ctype.h"\
+ "..\..\..\pjlib\include\pj\compat\errno.h"\
+ "..\..\..\pjlib\include\pj\compat\high_precision.h"\
+ "..\..\..\pjlib\include\pj\compat\m_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_auto.h"\
+ "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux.h"\
+ "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\
+ "..\..\..\pjlib\include\pj\compat\os_palmos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_rtems.h"\
+ "..\..\..\pjlib\include\pj\compat\os_sunos.h"\
+ "..\..\..\pjlib\include\pj\compat\os_symbian.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32.h"\
+ "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\
+ "..\..\..\pjlib\include\pj\compat\setjmp.h"\
+ "..\..\..\pjlib\include\pj\compat\size_t.h"\
+ "..\..\..\pjlib\include\pj\compat\stdarg.h"\
+ "..\..\..\pjlib\include\pj\compat\string.h"\
+ "..\..\..\pjlib\include\pj\config.h"\
+ "..\..\..\pjlib\include\pj\config_site.h"\
+ "..\..\..\pjlib\include\pj\config_site_sample.h"\
+ "..\..\..\pjlib\include\pj\ctype.h"\
+ "..\..\..\pjlib\include\pj\errno.h"\
+ "..\..\..\pjlib\include\pj\except.h"\
+ "..\..\..\pjlib\include\pj\fifobuf.h"\
+ "..\..\..\pjlib\include\pj\file_access.h"\
+ "..\..\..\pjlib\include\pj\file_io.h"\
+ "..\..\..\pjlib\include\pj\guid.h"\
+ "..\..\..\pjlib\include\pj\hash.h"\
+ "..\..\..\pjlib\include\pj\ioqueue.h"\
+ "..\..\..\pjlib\include\pj\ip_helper.h"\
+ "..\..\..\pjlib\include\pj\list.h"\
+ "..\..\..\pjlib\include\pj\list_i.h"\
+ "..\..\..\pjlib\include\pj\lock.h"\
+ "..\..\..\pjlib\include\pj\log.h"\
+ "..\..\..\pjlib\include\pj\os.h"\
+ "..\..\..\pjlib\include\pj\pool.h"\
+ "..\..\..\pjlib\include\pj\pool_alt.h"\
+ "..\..\..\pjlib\include\pj\pool_buf.h"\
+ "..\..\..\pjlib\include\pj\pool_i.h"\
+ "..\..\..\pjlib\include\pj\rand.h"\
+ "..\..\..\pjlib\include\pj\rbtree.h"\
+ "..\..\..\pjlib\include\pj\sock.h"\
+ "..\..\..\pjlib\include\pj\sock_select.h"\
+ "..\..\..\pjlib\include\pj\string.h"\
+ "..\..\..\pjlib\include\pj\string_i.h"\
+ "..\..\..\pjlib\include\pj\timer.h"\
+ "..\..\..\pjlib\include\pj\types.h"\
+ "..\..\..\pjlib\include\pj\unicode.h"\
+ "..\..\..\pjlib\include\pjlib.h"\
+ "..\..\include\pjnath\config.h"\
+ "..\..\include\pjnath\stun_auth.h"\
+ "..\..\include\pjnath\stun_config.h"\
+ "..\..\include\pjnath\stun_msg.h"\
+ "..\..\include\pjnath\stun_session.h"\
+ "..\..\include\pjnath\stun_transaction.h"\
+ "..\..\include\pjnath\turn_session.h"\
+ "..\..\include\pjnath\turn_sock.h"\
+ "..\..\include\pjnath\types.h"\
+
+
+!ENDIF
+
+# End Source File
# End Group
# Begin Group "Header Files"
@@ -6597,6 +8232,14 @@ SOURCE=..\..\include\pjnath\stun_transaction.h # End Source File
# Begin Source File
+SOURCE=..\..\include\pjnath\turn_session.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\pjnath\turn_sock.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\pjnath\types.h
# End Source File
# End Group
diff --git a/pjnath/include/pjnath.h b/pjnath/include/pjnath.h index f8e4d73d..962aeba0 100644 --- a/pjnath/include/pjnath.h +++ b/pjnath/include/pjnath.h @@ -28,6 +28,6 @@ #include <pjnath/stun_session.h> #include <pjnath/stun_transaction.h> #include <pjnath/turn_session.h> -#include <pjnath/turn_udp.h> +#include <pjnath/turn_sock.h> #include <pjnath/types.h> diff --git a/pjnath/include/pjnath/stun_session.h b/pjnath/include/pjnath/stun_session.h index 187064ed..821e765b 100644 --- a/pjnath/include/pjnath/stun_session.h +++ b/pjnath/include/pjnath/stun_session.h @@ -64,6 +64,15 @@ typedef struct pj_stun_session_cb * Callback to be called by the STUN session to send outgoing message. * * @param sess The STUN session. + * @param token The token associated with this outgoing message + * and was set by the application. This token was + * set by application in pj_stun_session_send_msg() + * for outgoing messages that are initiated by the + * application, or in pj_stun_session_on_rx_pkt() + * if this message is a response that was internally + * generated by the STUN session (for example, an + * 401/Unauthorized response). Application may use + * this facility for any purposes. * @param pkt Packet to be sent. * @param pkt_size Size of the packet to be sent. * @param dst_addr The destination address. @@ -73,13 +82,17 @@ typedef struct pj_stun_session_cb * packet sending. */ pj_status_t (*on_send_msg)(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, unsigned addr_len); /** - * Callback to be called on incoming STUN request message. In the + * Callback to be called on incoming STUN request message. This function + * is called when application calls pj_stun_session_on_rx_pkt() and when + * the STUN session has detected that the incoming STUN message is a + * STUN request message. In the * callback processing, application MUST create a response by calling * pj_stun_session_create_response() function and send the response * with pj_stun_session_send_msg() function, before returning from @@ -89,6 +102,8 @@ typedef struct pj_stun_session_cb * @param pkt Pointer to the original STUN packet. * @param pkt_len Length of the STUN packet. * @param rdata Data containing incoming request message. + * @param token The token that was set by the application when + * calling pj_stun_session_on_rx_pkt() function. * @param src_addr Source address of the packet. * @param src_addr_len Length of the source address. * @@ -100,12 +115,17 @@ typedef struct pj_stun_session_cb const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_rx_data *rdata, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len); /** * Callback to be called when response is received or the transaction - * has timed out. + * has timed out. This callback is called either when application calls + * pj_stun_session_on_rx_pkt() with the packet containing a STUN + * response for the client transaction, or when the internal timer of + * the STUN client transaction has timed-out before a STUN response is + * received. * * @param sess The STUN session. * @param status Status of the request. If the value if not @@ -115,6 +135,10 @@ typedef struct pj_stun_session_cb * Note that when the status is not success, the * response may contain non-NULL value if the * response contains STUN ERROR-CODE attribute. + * @param token The token that was set by the application when + * calling pj_stun_session_send_msg() function. + * Please not that this token IS NOT the token + * that was given in pj_stun_session_on_rx_pkt(). * @param tdata The original STUN request. * @param response The response message, on successful transaction, * or otherwise MAY BE NULL if status is not success. @@ -127,6 +151,7 @@ typedef struct pj_stun_session_cb */ void (*on_request_complete)(pj_stun_session *sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, @@ -134,12 +159,29 @@ typedef struct pj_stun_session_cb /** - * Type of callback to be called on incoming STUN indication. + * Callback to be called on incoming STUN request message. This function + * is called when application calls pj_stun_session_on_rx_pkt() and when + * the STUN session has detected that the incoming STUN message is a + * STUN indication message. + * + * @param sess The STUN session. + * @param pkt Pointer to the original STUN packet. + * @param pkt_len Length of the STUN packet. + * @param msg The parsed STUN indication. + * @param token The token that was set by the application when + * calling pj_stun_session_on_rx_pkt() function. + * @param src_addr Source address of the packet. + * @param src_addr_len Length of the source address. + * + * @return The return value of this callback will be + * returned back to pj_stun_session_on_rx_pkt() + * function. */ pj_status_t (*on_rx_indication)(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_msg *msg, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len); @@ -177,9 +219,10 @@ struct pj_stun_tx_data pj_stun_session *sess; /**< The STUN session. */ pj_stun_msg *msg; /**< The STUN message. */ - void *user_data; /**< Arbitrary application data. */ + void *token; /**< The token. */ pj_stun_client_tsx *client_tsx; /**< Client STUN transaction. */ + pj_bool_t retransmit; /**< Retransmit request? */ pj_uint32_t msg_magic; /**< Message magic. */ pj_uint8_t msg_key[12]; /**< Message/transaction key. */ @@ -368,7 +411,21 @@ PJ_DECL(pj_status_t) pj_stun_session_create_res(pj_stun_session *sess, * to actually send the message to the wire. * * @param sess The STUN session instance. - * @param cache_res If PJ_TRUE then response will be cached. + * @param token Optional token which will be given back to application in + * \a on_send_msg() callback and \a on_request_complete() + * callback, if the message is a STUN request message. + * Internally this function will put the token in the + * \a token field of pj_stun_tx_data, hence it will + * overwrite any value that the application puts there. + * @param cache_res If the message is a response message for an incoming + * request, specify PJ_TRUE to instruct the STUN session + * to cache this response for subsequent incoming request + * retransmission. Otherwise this parameter will be ignored + * for non-response message. + * @param retransmit If the message is a request message, specify whether the + * request should be retransmitted. Normally application will + * specify TRUE if the underlying transport is UDP and FALSE + * if the underlying transport is TCP or TLS. * @param dst_addr The destination socket address. * @param addr_len Length of destination address. * @param tdata The STUN transmit data containing the STUN message to @@ -377,13 +434,18 @@ PJ_DECL(pj_status_t) pj_stun_session_create_res(pj_stun_session *sess, * @return PJ_SUCCESS on success, or the appropriate error code. */ PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess, + void *token, pj_bool_t cache_res, + pj_bool_t retransmit, const pj_sockaddr_t *dst_addr, unsigned addr_len, pj_stun_tx_data *tdata); /** - * Create and send STUN response message. + * This is a utility function to create and send response for an incoming + * STUN request. Internally this function calls pj_stun_session_create_res() + * and pj_stun_session_send_msg(). It is provided here as a matter of + * convenience. * * @param sess The STUN session instance. * @param rdata The STUN request message to be responded. @@ -395,6 +457,12 @@ PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess, * creating error response. If the value is NULL and the * \a err_code is non-zero, then default error message will * be used. + * @param token Optional token which will be given back to application in + * \a on_send_msg() callback and \a on_request_complete() + * callback, if the message is a STUN request message. + * Internally this function will put the token in the + * \a token field of pj_stun_tx_data, hence it will + * overwrite any value that the application puts there. * @param cache Specify whether session should cache this response for * future request retransmission. If TRUE, subsequent request * retransmission will be handled by the session and it @@ -409,6 +477,7 @@ PJ_DECL(pj_status_t) pj_stun_session_respond(pj_stun_session *sess, const pj_stun_rx_data *rdata, unsigned code, const char *err_msg, + void *token, pj_bool_t cache, const pj_sockaddr_t *dst_addr, unsigned addr_len); @@ -468,7 +537,14 @@ PJ_DECL(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess, * @param parsed_len Optional pointer to receive the size of the parsed * STUN message (useful if packet is received via a * stream oriented protocol). - * @param src_addr The source address of the packet. + * @param token Optional token which will be given back to application + * in the \a on_rx_request(), \a on_rx_indication() and + * \a on_send_msg() callbacks. The token can be used to + * associate processing or incoming request or indication + * with some context. + * @param src_addr The source address of the packet, which will also + * be given back to application callbacks, along with + * source address length. * @param src_addr_len Length of the source address. * * @return PJ_SUCCESS on success, or the appropriate error code. @@ -477,6 +553,7 @@ PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, const void *packet, pj_size_t pkt_size, unsigned options, + void *token, unsigned *parsed_len, const pj_sockaddr_t *src_addr, unsigned src_addr_len); diff --git a/pjnath/include/pjnath/turn_session.h b/pjnath/include/pjnath/turn_session.h index 8a93414a..0c0f3cef 100644 --- a/pjnath/include/pjnath/turn_session.h +++ b/pjnath/include/pjnath/turn_session.h @@ -55,12 +55,29 @@ typedef struct pj_turn_session pj_turn_session; #define PJ_TURN_PEER_HTABLE_SIZE 8 -/** TURN transport types */ +/** + * TURN transport types, which will be used both to specify the connection + * type for reaching TURN server and the type of allocation transport to be + * requested to server (the REQUESTED-TRANSPORT attribute). + */ typedef enum pj_turn_tp_type { - PJ_TURN_TP_UDP = 17, /**< UDP. */ - PJ_TURN_TP_TCP = 6, /**< TCP. */ - PJ_TURN_TP_TLS = 256 /**< TLS. */ + /** + * UDP transport, which value corresponds to IANA protocol number. + */ + PJ_TURN_TP_UDP = 17, + + /** + * TCP transport, which value corresponds to IANA protocol number. + */ + PJ_TURN_TP_TCP = 6, + + /** + * TLS transport. The TLS transport will only be used as the connection + * type to reach the server and never as the allocation transport type. + */ + PJ_TURN_TP_TLS = 255 + } pj_turn_tp_type; @@ -220,6 +237,18 @@ typedef struct pj_turn_session_info /** + * Create default pj_turn_alloc_param. + */ +PJ_DECL(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm); + +/** + * Duplicate pj_turn_alloc_param. + */ +PJ_DECL(void) pj_turn_alloc_param_copy(pj_pool_t *pool, + pj_turn_alloc_param *dst, + const pj_turn_alloc_param *src); + +/** * Get TURN state name. */ PJ_DECL(const char*) pj_turn_state_name(pj_turn_state_t state); @@ -239,7 +268,13 @@ PJ_DECL(pj_status_t) pj_turn_session_create(pj_stun_config *cfg, /** - * Destroy TURN client session. + * Shutdown TURN client session. + */ +PJ_DECL(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess); + + +/** + * Forcefully destroy the TURN session. */ PJ_DECL(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess); diff --git a/pjnath/include/pjnath/turn_udp.h b/pjnath/include/pjnath/turn_sock.h index 2c701590..91bf9e20 100644 --- a/pjnath/include/pjnath/turn_udp.h +++ b/pjnath/include/pjnath/turn_sock.h @@ -16,11 +16,11 @@ * 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_TURN_UDP_H__ -#define __PJNATH_TURN_UDP_H__ +#ifndef __PJNATH_turn_sock_H__ +#define __PJNATH_turn_sock_H__ /** - * @file turn_udp.h + * @file turn_sock.h * @brief TURN relay using UDP client as transport protocol */ #include <pjnath/turn_session.h> @@ -31,20 +31,20 @@ PJ_BEGIN_DECL /* **************************************************************************/ /** - * @defgroup PJNATH_TURN_UDP TURN UDP client - * @brief TURN relay using UDP client as transport protocol + * @defgroup PJNATH_TURN_UDP TURN TCP client + * @brief TURN relay using TCP client as transport protocol * @ingroup PJNATH_STUN * @{ */ /** - * Opaque declaration for TURN UDP client. + * Opaque declaration for TURN TCP client. */ -typedef struct pj_turn_udp pj_turn_udp; +typedef struct pj_turn_sock pj_turn_sock; -typedef struct pj_turn_udp_cb +typedef struct pj_turn_sock_cb { /** * Notification when incoming data has been received, either through @@ -52,7 +52,7 @@ typedef struct pj_turn_udp_cb * * This callback is mandatory. */ - void (*on_rx_data)(pj_turn_udp *udp_rel, + void (*on_rx_data)(pj_turn_sock *turn_sock, const pj_uint8_t *pkt, unsigned pkt_len, const pj_sockaddr_t *peer_addr, @@ -63,59 +63,60 @@ typedef struct pj_turn_udp_cb * implement this callback to know that the TURN session is no longer * available. */ - void (*on_state)(pj_turn_udp *udp_rel, pj_turn_state_t old_state, + void (*on_state)(pj_turn_sock *turn_sock, pj_turn_state_t old_state, pj_turn_state_t new_state); -} pj_turn_udp_cb; +} pj_turn_sock_cb; /** * Create. */ -PJ_DECL(pj_status_t) pj_turn_udp_create(pj_stun_config *cfg, - int af, - const pj_turn_udp_cb *cb, - unsigned options, - void *user_data, - pj_turn_udp **p_udp_rel); +PJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg, + int af, + pj_turn_tp_type conn_type, + const pj_turn_sock_cb *cb, + unsigned options, + void *user_data, + pj_turn_sock **p_turn_sock); /** * Destroy. */ -PJ_DECL(void) pj_turn_udp_destroy(pj_turn_udp *udp_rel); +PJ_DECL(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock); /** * Set user data. */ -PJ_DECL(pj_status_t) pj_turn_udp_set_user_data(pj_turn_udp *udp_rel, +PJ_DECL(pj_status_t) pj_turn_sock_set_user_data(pj_turn_sock *turn_sock, void *user_data); /** * Get user data. */ -PJ_DECL(void*) pj_turn_udp_get_user_data(pj_turn_udp *udp_rel); +PJ_DECL(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock); /** * Get info. */ -PJ_DECL(pj_status_t) pj_turn_udp_get_info(pj_turn_udp *udp_rel, +PJ_DECL(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock, pj_turn_session_info *info); /** * Initialize. */ -PJ_DECL(pj_status_t) pj_turn_udp_init(pj_turn_udp *udp_rel, - const pj_str_t *domain, - int default_port, - pj_dns_resolver *resolver, - const pj_stun_auth_cred *cred, - const pj_turn_alloc_param *param); +PJ_DECL(pj_status_t) pj_turn_sock_init(pj_turn_sock *turn_sock, + const pj_str_t *domain, + int default_port, + pj_dns_resolver *resolver, + const pj_stun_auth_cred *cred, + const pj_turn_alloc_param *param); /** * Send packet. */ -PJ_DECL(pj_status_t) pj_turn_udp_sendto(pj_turn_udp *udp_rel, +PJ_DECL(pj_status_t) pj_turn_sock_sendto(pj_turn_sock *turn_sock, const pj_uint8_t *pkt, unsigned pkt_len, const pj_sockaddr_t *addr, @@ -124,7 +125,7 @@ PJ_DECL(pj_status_t) pj_turn_udp_sendto(pj_turn_udp *udp_rel, /** * Bind a peer address to a channel number. */ -PJ_DECL(pj_status_t) pj_turn_udp_bind_channel(pj_turn_udp *udp_rel, +PJ_DECL(pj_status_t) pj_turn_sock_bind_channel(pj_turn_sock *turn_sock, const pj_sockaddr_t *peer, unsigned addr_len); @@ -137,5 +138,5 @@ PJ_DECL(pj_status_t) pj_turn_udp_bind_channel(pj_turn_udp *udp_rel, PJ_END_DECL -#endif /* __PJNATH_TURN_UDP_H__ */ +#endif /* __PJNATH_turn_sock_H__ */ diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c index 5ecac387..8b0538d8 100644 --- a/pjnath/src/pjnath/ice_session.c +++ b/pjnath/src/pjnath/ice_session.c @@ -113,6 +113,7 @@ static void handle_incoming_check(pj_ice_sess *ice, /* These are the callbacks registered to the STUN sessions */ static pj_status_t on_stun_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -121,10 +122,12 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_rx_data *rdata, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len); static void on_stun_request_complete(pj_stun_session *stun_sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, @@ -133,6 +136,7 @@ static pj_status_t on_stun_rx_indication(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_msg *msg, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len); @@ -1392,7 +1396,6 @@ static pj_status_t perform_check(pj_ice_sess *ice, rd->ice = ice; rd->clist = clist; rd->ckid = check_id; - check->tdata->user_data = (void*) rd; /* Add PRIORITY */ prio = CALC_CAND_PRIO(ice, PJ_ICE_CAND_TYPE_PRFLX, 65535, @@ -1424,8 +1427,8 @@ static pj_status_t perform_check(pj_ice_sess *ice, */ /* Initiate STUN transaction to send the request */ - status = pj_stun_session_send_msg(comp->stun_sess, PJ_FALSE, - &rcand->addr, + status = pj_stun_session_send_msg(comp->stun_sess, (void*)rd, PJ_FALSE, + PJ_TRUE, &rcand->addr, sizeof(pj_sockaddr_in), check->tdata); if (status != PJ_SUCCESS) { check->tdata = NULL; @@ -1644,6 +1647,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice) * STUN session also doesn't have a transport, remember?! */ static pj_status_t on_stun_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -1651,6 +1655,9 @@ static pj_status_t on_stun_send_msg(pj_stun_session *sess, { stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); pj_ice_sess *ice = sd->ice; + + PJ_UNUSED_ARG(token); + return (*ice->cb.on_tx_pkt)(ice, sd->comp_id, pkt, pkt_size, dst_addr, addr_len); @@ -1660,12 +1667,13 @@ static pj_status_t on_stun_send_msg(pj_stun_session *sess, /* This callback is called when outgoing STUN request completed */ static void on_stun_request_complete(pj_stun_session *stun_sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { - struct req_data *rd = (struct req_data*) tdata->user_data; + struct req_data *rd = (struct req_data*) token; pj_ice_sess *ice; pj_ice_sess_check *check, *new_check; pj_ice_sess_cand *lcand; @@ -1905,6 +1913,7 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_rx_data *rdata, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { @@ -1920,17 +1929,14 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess, PJ_UNUSED_ARG(pkt); PJ_UNUSED_ARG(pkt_len); + PJ_UNUSED_ARG(token); /* Reject any requests except Binding request */ if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) { - status = pj_stun_session_create_res(sess, rdata, - PJ_STUN_SC_BAD_REQUEST, - NULL, &tdata); - if (status != PJ_SUCCESS) - return status; - - return pj_stun_session_send_msg(sess, PJ_TRUE, - src_addr, src_addr_len, tdata); + pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, + NULL, NULL, PJ_TRUE, + src_addr, src_addr_len); + return PJ_SUCCESS; } @@ -1994,13 +2000,9 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess, pj_ice_sess_change_role(ice, PJ_ICE_SESS_ROLE_CONTROLLED); } else { /* Generate 487 response */ - status = pj_stun_session_create_res(sess, rdata, - PJ_STUN_SC_ROLE_CONFLICT, - NULL, &tdata); - if (status == PJ_SUCCESS) { - pj_stun_session_send_msg(sess, PJ_TRUE, - src_addr, src_addr_len, tdata); - } + pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, + NULL, NULL, PJ_TRUE, + src_addr, src_addr_len); pj_mutex_unlock(ice->mutex); return PJ_SUCCESS; } @@ -2010,13 +2012,9 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess, { if (pj_cmp_timestamp(&ice->tie_breaker, &role_attr->value) < 0) { /* Generate 487 response */ - status = pj_stun_session_create_res(sess, rdata, - PJ_STUN_SC_ROLE_CONFLICT, - NULL, &tdata); - if (status == PJ_SUCCESS) { - pj_stun_session_send_msg(sess, PJ_TRUE, - src_addr, src_addr_len, tdata); - } + pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, + NULL, NULL, PJ_TRUE, + src_addr, src_addr_len); pj_mutex_unlock(ice->mutex); return PJ_SUCCESS; } else { @@ -2040,7 +2038,7 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess, PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, src_addr, src_addr_len); - status = pj_stun_session_send_msg(sess, PJ_TRUE, + status = pj_stun_session_send_msg(sess, NULL, PJ_TRUE, PJ_TRUE, src_addr, src_addr_len, tdata); @@ -2286,6 +2284,7 @@ static pj_status_t on_stun_rx_indication(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_msg *msg, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { @@ -2293,6 +2292,7 @@ static pj_status_t on_stun_rx_indication(pj_stun_session *sess, PJ_UNUSED_ARG(pkt); PJ_UNUSED_ARG(pkt_len); PJ_UNUSED_ARG(msg); + PJ_UNUSED_ARG(token); PJ_UNUSED_ARG(src_addr); PJ_UNUSED_ARG(src_addr_len); @@ -2367,7 +2367,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, PJ_STUN_IS_DATAGRAM); if (stun_status == PJ_SUCCESS) { status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size, - PJ_STUN_IS_DATAGRAM, + PJ_STUN_IS_DATAGRAM, NULL, NULL, src_addr, src_addr_len); if (status != PJ_SUCCESS) { pj_strerror(status, ice->tmp.errmsg, sizeof(ice->tmp.errmsg)); diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c index d554f12e..7266e079 100644 --- a/pjnath/src/pjnath/ice_strans.c +++ b/pjnath/src/pjnath/ice_strans.c @@ -60,12 +60,14 @@ static void destroy_ice_st(pj_ice_strans *ice_st, pj_status_t reason); /* STUN session callback */ static pj_status_t stun_on_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, unsigned addr_len); static void stun_on_request_complete(pj_stun_session *sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, @@ -490,7 +492,7 @@ static void on_read_complete(pj_ioqueue_key_t *key, status = pj_stun_session_on_rx_pkt(comp->stun_sess, comp->pkt, bytes_read, PJ_STUN_IS_DATAGRAM, NULL, - &comp->src_addr, + NULL, &comp->src_addr, comp->src_addr_len); } else if (ice_st->ice) { PJ_TODO(DISTINGUISH_BETWEEN_LOCAL_AND_RELAY); @@ -600,8 +602,6 @@ static void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te) /* tdata->user_data is NULL for keep-alive */ //tdata->user_data = NULL; - // We need this to support mapped address change - tdata->user_data = &comp->cand_list[j]; ++comp->pending_cnt; @@ -609,8 +609,8 @@ static void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te) PJ_LOG(5,(ice_st->obj_name, "Sending STUN keep-alive from %s;%d", pj_inet_ntoa(comp->local_addr.ipv4.sin_addr), pj_ntohs(comp->local_addr.ipv4.sin_port))); - status = pj_stun_session_send_msg(comp->stun_sess, PJ_FALSE, - &ice_st->stun_srv, + status = pj_stun_session_send_msg(comp->stun_sess, &comp->cand_list[j], + PJ_FALSE, PJ_TRUE, &ice_st->stun_srv, sizeof(pj_sockaddr_in), tdata); if (status != PJ_SUCCESS) { --comp->pending_cnt; @@ -700,9 +700,8 @@ static pj_status_t get_stun_mapped_addr(pj_ice_strans *ice_st, if (status != PJ_SUCCESS) return status; - /* Attach alias instance to tdata */ + /* Will be attached to tdata in send_msg() */ cand = &comp->cand_list[comp->cand_cnt]; - tdata->user_data = (void*)cand; /* Add pending count first, since stun_on_request_complete() * may be called before this function completes @@ -720,8 +719,8 @@ static pj_status_t get_stun_mapped_addr(pj_ice_strans *ice_st, ++comp->cand_cnt; /* Send STUN binding request */ - status = pj_stun_session_send_msg(comp->stun_sess, PJ_FALSE, - &ice_st->stun_srv, + status = pj_stun_session_send_msg(comp->stun_sess, (void*)cand, PJ_FALSE, + PJ_TRUE, &ice_st->stun_srv, sizeof(pj_sockaddr_in), tdata); if (status != PJ_SUCCESS) { --comp->pending_cnt; @@ -1078,6 +1077,7 @@ static void ice_rx_data(pj_ice_sess *ice, * Callback called by STUN session to send outgoing packet. */ static pj_status_t stun_on_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t size, const pj_sockaddr_t *dst_addr, @@ -1087,6 +1087,8 @@ static pj_status_t stun_on_send_msg(pj_stun_session *sess, pj_ssize_t pkt_size; pj_status_t status; + PJ_UNUSED_ARG(token); + comp = (pj_ice_strans_comp*) pj_stun_session_get_user_data(sess); pkt_size = size; status = pj_ioqueue_sendto(comp->key, &comp->write_op, @@ -1102,6 +1104,7 @@ static pj_status_t stun_on_send_msg(pj_stun_session *sess, */ static void stun_on_request_complete(pj_stun_session *sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, @@ -1115,8 +1118,10 @@ static void stun_on_request_complete(pj_stun_session *sess, char ip[20]; comp = (pj_ice_strans_comp*) pj_stun_session_get_user_data(sess); - cand = (pj_ice_strans_cand*) tdata->user_data; + cand = (pj_ice_strans_cand*) token; + PJ_UNUSED_ARG(token); + PJ_UNUSED_ARG(tdata); PJ_UNUSED_ARG(src_addr); PJ_UNUSED_ARG(src_addr_len); diff --git a/pjnath/src/pjnath/nat_detect.c b/pjnath/src/pjnath/nat_detect.c index d5062a38..7eef39ec 100644 --- a/pjnath/src/pjnath/nat_detect.c +++ b/pjnath/src/pjnath/nat_detect.c @@ -113,11 +113,13 @@ static void on_read_complete(pj_ioqueue_key_t *key, pj_ssize_t bytes_read); static void on_request_complete(pj_stun_session *sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, unsigned src_addr_len); static pj_status_t on_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -414,7 +416,8 @@ static void on_read_complete(pj_ioqueue_key_t *key, } else if (bytes_read > 0) { pj_stun_session_on_rx_pkt(sess->stun_sess, sess->rx_pkt, bytes_read, PJ_STUN_IS_DATAGRAM|PJ_STUN_CHECK_PACKET, - NULL, &sess->src_addr, sess->src_addr_len); + NULL, NULL, + &sess->src_addr, sess->src_addr_len); } @@ -438,6 +441,7 @@ on_return: * Callback to send outgoing packet from STUN session. */ static pj_status_t on_send_msg(pj_stun_session *stun_sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -447,6 +451,8 @@ static pj_status_t on_send_msg(pj_stun_session *stun_sess, pj_ssize_t pkt_len; pj_status_t status; + PJ_UNUSED_ARG(token); + sess = (nat_detect_session*) pj_stun_session_get_user_data(stun_sess); pkt_len = pkt_size; @@ -462,6 +468,7 @@ static pj_status_t on_send_msg(pj_stun_session *stun_sess, */ static void on_request_complete(pj_stun_session *stun_sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, @@ -474,6 +481,7 @@ static void on_request_complete(pj_stun_session *stun_sess, int cmp; unsigned test_id; + PJ_UNUSED_ARG(token); PJ_UNUSED_ARG(tdata); PJ_UNUSED_ARG(src_addr); PJ_UNUSED_ARG(src_addr_len); @@ -812,8 +820,8 @@ static pj_status_t send_test(nat_detect_session *sess, pj_ntohs(sess->cur_server->sin_port))); /* Send the request */ - status = pj_stun_session_send_msg(sess->stun_sess, PJ_TRUE, - sess->cur_server, + status = pj_stun_session_send_msg(sess->stun_sess, NULL, PJ_TRUE, + PJ_TRUE, sess->cur_server, sizeof(pj_sockaddr_in), sess->result[test_id].tdata); if (status != PJ_SUCCESS) diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c index 160ee1a6..6545c750 100644 --- a/pjnath/src/pjnath/stun_session.c +++ b/pjnath/src/pjnath/stun_session.c @@ -349,7 +349,8 @@ static pj_status_t handle_auth_challenge(pj_stun_session *sess, PJ_LOG(4,(SNAME(sess), "Retrying request with new authentication")); /* Retry the request */ - status = pj_stun_session_send_msg(sess, PJ_TRUE, src_addr, + status = pj_stun_session_send_msg(sess, request->token, PJ_TRUE, + request->retransmit, src_addr, src_addr_len, tdata); } else { @@ -377,9 +378,8 @@ static void stun_tsx_on_complete(pj_stun_client_tsx *tsx, src_addr_len, ¬ify_user); if (notify_user && sess->cb.on_request_complete) { - (*sess->cb.on_request_complete)(sess, status, tdata, - response, - src_addr, src_addr_len); + (*sess->cb.on_request_complete)(sess, status, tdata->token, tdata, + response, src_addr, src_addr_len); } /* Destroy the transmit data. This will remove the transaction @@ -397,8 +397,9 @@ static pj_status_t stun_tsx_on_send_msg(pj_stun_client_tsx *tsx, tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); - return tdata->sess->cb.on_send_msg(tdata->sess, stun_pkt, pkt_size, - tdata->dst_addr, tdata->addr_len); + return tdata->sess->cb.on_send_msg(tdata->sess, tdata->token, stun_pkt, + pkt_size, tdata->dst_addr, + tdata->addr_len); } /* **************************************************************************/ @@ -730,7 +731,9 @@ static void dump_tx_msg(pj_stun_session *sess, const pj_stun_msg *msg, PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, + void *token, pj_bool_t cache_res, + pj_bool_t retransmit, const pj_sockaddr_t *server, unsigned addr_len, pj_stun_tx_data *tdata) @@ -743,6 +746,9 @@ PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, tdata->max_len = PJ_STUN_MAX_PKT_LEN; tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len); + tdata->token = token; + tdata->retransmit = retransmit; + /* Start locking the session now */ pj_lock_acquire(sess->lock); @@ -787,7 +793,7 @@ PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, tdata->dst_addr = server; /* Send the request! */ - status = pj_stun_client_tsx_send_msg(tdata->client_tsx, PJ_TRUE, + status = pj_stun_client_tsx_send_msg(tdata->client_tsx, retransmit, tdata->pkt, tdata->pkt_size); if (status != PJ_SUCCESS && status != PJ_EPENDING) { pj_stun_msg_destroy_tdata(sess, tdata); @@ -828,8 +834,8 @@ PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, } /* Otherwise for non-request message, send directly to transport. */ - status = sess->cb.on_send_msg(sess, tdata->pkt, tdata->pkt_size, - server, addr_len); + status = sess->cb.on_send_msg(sess, token, tdata->pkt, + tdata->pkt_size, server, addr_len); if (status != PJ_SUCCESS && status != PJ_EPENDING) { LOG_ERR_(sess, "Error sending STUN request", status); @@ -854,6 +860,7 @@ PJ_DEF(pj_status_t) pj_stun_session_respond( pj_stun_session *sess, const pj_stun_rx_data *rdata, unsigned code, const char *errmsg, + void *token, pj_bool_t cache, const pj_sockaddr_t *dst_addr, unsigned addr_len) @@ -868,7 +875,8 @@ PJ_DEF(pj_status_t) pj_stun_session_respond( pj_stun_session *sess, if (status != PJ_SUCCESS) return status; - return pj_stun_session_send_msg(sess, cache, dst_addr, addr_len, tdata); + return pj_stun_session_send_msg(sess, token, cache, PJ_FALSE, + dst_addr, addr_len, tdata); } @@ -887,8 +895,8 @@ PJ_DEF(pj_status_t) pj_stun_session_cancel_req( pj_stun_session *sess, pj_lock_acquire(sess->lock); if (notify) { - (sess->cb.on_request_complete)(sess, notify_status, tdata, NULL, - NULL, 0); + (sess->cb.on_request_complete)(sess, notify_status, tdata->token, + tdata, NULL, NULL, 0); } /* Just destroy tdata. This will destroy the transaction as well */ @@ -920,7 +928,7 @@ PJ_DEF(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess, /* Send response */ -static pj_status_t send_response(pj_stun_session *sess, +static pj_status_t send_response(pj_stun_session *sess, void *token, pj_pool_t *pool, pj_stun_msg *response, const pj_stun_req_cred_info *auth_info, pj_bool_t retransmission, @@ -953,13 +961,15 @@ static pj_status_t send_response(pj_stun_session *sess, dump_tx_msg(sess, response, out_len, addr); /* Send packet */ - status = sess->cb.on_send_msg(sess, out_pkt, out_len, addr, addr_len); + status = sess->cb.on_send_msg(sess, token, out_pkt, out_len, + addr, addr_len); return status; } /* Authenticate incoming message */ static pj_status_t authenticate_req(pj_stun_session *sess, + void *token, const pj_uint8_t *pkt, unsigned pkt_len, pj_stun_rx_data *rdata, @@ -981,8 +991,8 @@ static pj_status_t authenticate_req(pj_stun_session *sess, &response); if (status != PJ_SUCCESS && response != NULL) { PJ_LOG(5,(SNAME(sess), "Message authentication failed")); - send_response(sess, tmp_pool, response, &rdata->info, PJ_FALSE, - src_addr, src_addr_len); + send_response(sess, token, tmp_pool, response, &rdata->info, + PJ_FALSE, src_addr, src_addr_len); } return status; @@ -1070,8 +1080,8 @@ static pj_status_t check_cached_response(pj_stun_session *sess, PJ_LOG(5,(SNAME(sess), "Request retransmission, sending cached response")); - send_response(sess, tmp_pool, t->msg, &t->auth_info, PJ_TRUE, - src_addr, src_addr_len); + send_response(sess, t->token, tmp_pool, t->msg, &t->auth_info, + PJ_TRUE, src_addr, src_addr_len); return PJ_SUCCESS; } @@ -1081,6 +1091,7 @@ static pj_status_t check_cached_response(pj_stun_session *sess, /* Handle incoming request */ static pj_status_t on_incoming_request(pj_stun_session *sess, unsigned options, + void *token, pj_pool_t *tmp_pool, const pj_uint8_t *in_pkt, unsigned in_pkt_len, @@ -1102,8 +1113,9 @@ static pj_status_t on_incoming_request(pj_stun_session *sess, * is specified in the option. */ if ((options & PJ_STUN_NO_AUTHENTICATE) == 0) { - status = authenticate_req(sess, (const pj_uint8_t*) in_pkt, in_pkt_len, - &rdata, tmp_pool, src_addr, src_addr_len); + status = authenticate_req(sess, token, (const pj_uint8_t*) in_pkt, + in_pkt_len,&rdata, tmp_pool, src_addr, + src_addr_len); if (status != PJ_SUCCESS) { return status; } @@ -1112,7 +1124,7 @@ static pj_status_t on_incoming_request(pj_stun_session *sess, /* Distribute to handler, or respond with Bad Request */ if (sess->cb.on_rx_request) { status = (*sess->cb.on_rx_request)(sess, in_pkt, in_pkt_len, &rdata, - src_addr, src_addr_len); + token, src_addr, src_addr_len); } else { pj_str_t err_text; pj_stun_msg *response; @@ -1122,7 +1134,7 @@ static pj_status_t on_incoming_request(pj_stun_session *sess, PJ_STUN_SC_BAD_REQUEST, &err_text, &response); if (status == PJ_SUCCESS && response) { - status = send_response(sess, tmp_pool, response, + status = send_response(sess, token, tmp_pool, response, NULL, PJ_FALSE, src_addr, src_addr_len); } } @@ -1133,6 +1145,7 @@ static pj_status_t on_incoming_request(pj_stun_session *sess, /* Handle incoming indication */ static pj_status_t on_incoming_indication(pj_stun_session *sess, + void *token, pj_pool_t *tmp_pool, const pj_uint8_t *in_pkt, unsigned in_pkt_len, @@ -1145,7 +1158,7 @@ static pj_status_t on_incoming_indication(pj_stun_session *sess, /* Distribute to handler */ if (sess->cb.on_rx_indication) { return (*sess->cb.on_rx_indication)(sess, in_pkt, in_pkt_len, msg, - src_addr, src_addr_len); + token, src_addr, src_addr_len); } else { return PJ_SUCCESS; } @@ -1156,6 +1169,7 @@ PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, const void *packet, pj_size_t pkt_size, unsigned options, + void *token, unsigned *parsed_len, const pj_sockaddr_t *src_addr, unsigned src_addr_len) @@ -1180,7 +1194,7 @@ PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, if (status != PJ_SUCCESS) { LOG_ERR_(sess, "STUN msg_decode() error", status); if (response) { - send_response(sess, tmp_pool, response, NULL, + send_response(sess, token, tmp_pool, response, NULL, PJ_FALSE, src_addr, src_addr_len); } pj_pool_release(tmp_pool); @@ -1217,13 +1231,13 @@ PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { - status = on_incoming_request(sess, options, tmp_pool, + status = on_incoming_request(sess, options, token, tmp_pool, (const pj_uint8_t*) packet, pkt_size, msg, src_addr, src_addr_len); } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) { - status = on_incoming_indication(sess, tmp_pool, + status = on_incoming_indication(sess, token, tmp_pool, (const pj_uint8_t*) packet, pkt_size, msg, src_addr, src_addr_len); diff --git a/pjnath/src/pjnath/turn_session.c b/pjnath/src/pjnath/turn_session.c index 0e91ca09..354b9661 100644 --- a/pjnath/src/pjnath/turn_session.c +++ b/pjnath/src/pjnath/turn_session.c @@ -110,17 +110,18 @@ struct pj_turn_session * Prototypes. */ static void sess_shutdown(pj_turn_session *sess, - pj_bool_t notify, pj_status_t status); static void do_destroy(pj_turn_session *sess); static void send_refresh(pj_turn_session *sess, int lifetime); static pj_status_t stun_on_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, unsigned addr_len); static void stun_on_request_complete(pj_stun_session *sess, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, @@ -129,6 +130,7 @@ static pj_status_t stun_on_rx_indication(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_msg *msg, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len); static void dns_srv_resolver_cb(void *user_data, @@ -144,7 +146,26 @@ static struct peer *lookup_peer_by_chnum(pj_turn_session *sess, static void on_timer_event(pj_timer_heap_t *th, pj_timer_entry *e); -/** +/* + * Create default pj_turn_alloc_param. + */ +PJ_DEF(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm) +{ + pj_bzero(prm, sizeof(*prm)); +} + +/* + * Duplicate pj_turn_alloc_param. + */ +PJ_DEF(void) pj_turn_alloc_param_copy( pj_pool_t *pool, + pj_turn_alloc_param *dst, + const pj_turn_alloc_param *src) +{ + PJ_UNUSED_ARG(pool); + pj_memcpy(dst, src, sizeof(*dst)); +} + +/* * Get TURN state name. */ PJ_DEF(const char*) pj_turn_state_name(pj_turn_state_t state) @@ -285,6 +306,9 @@ static void set_state(pj_turn_session *sess, enum pj_turn_state_t state) { pj_turn_state_t old_state = sess->state; + if (state==sess->state) + return; + PJ_LOG(4,(sess->obj_name, "State changed %s --> %s", state_names[old_state], state_names[state])); sess->state = state; @@ -298,13 +322,10 @@ static void set_state(pj_turn_session *sess, enum pj_turn_state_t state) * Notify application and shutdown the TURN session. */ static void sess_shutdown(pj_turn_session *sess, - pj_bool_t notify, pj_status_t status) { pj_bool_t can_destroy = PJ_TRUE; - PJ_UNUSED_ARG(notify); - PJ_LOG(4,(sess->obj_name, "Request to shutdown in state %s, cause:%d", state_names[sess->state], status)); @@ -360,13 +381,13 @@ static void sess_shutdown(pj_turn_session *sess, /* * Public API to destroy TURN client session. */ -PJ_DEF(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess) +PJ_DEF(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess) { PJ_ASSERT_RETURN(sess, PJ_EINVAL); pj_lock_acquire(sess->lock); - sess_shutdown(sess, PJ_FALSE, PJ_SUCCESS); + sess_shutdown(sess, PJ_SUCCESS); pj_lock_release(sess->lock); @@ -374,6 +395,17 @@ PJ_DEF(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess) } +/** + * Forcefully destroy the TURN session. + */ +PJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess) +{ + set_state(sess, PJ_TURN_STATE_DEALLOCATED); + sess_shutdown(sess, PJ_SUCCESS); + return PJ_SUCCESS; +} + + /* * Get TURN session info. */ @@ -464,7 +496,11 @@ PJ_DEF(pj_status_t) pj_turn_session_set_server( pj_turn_session *sess, sess->default_port = (pj_uint16_t)default_port; } + PJ_LOG(5,(sess->obj_name, "Resolving %.*s%.*s with DNS SRV", + (int)res_name.slen, res_name.ptr, + (int)domain->slen, domain->ptr)); set_state(sess, PJ_TURN_STATE_RESOLVING); + status = pj_dns_srv_resolve(domain, &res_name, default_port, sess->pool, resolver, opt, sess, &dns_srv_resolver_cb, &sess->dns_async); @@ -488,6 +524,9 @@ PJ_DEF(pj_status_t) pj_turn_session_set_server( pj_turn_session *sess, ai = (pj_addrinfo*) pj_pool_calloc(sess->pool, cnt, sizeof(pj_addrinfo)); + PJ_LOG(5,(sess->obj_name, "Resolving %.*s with DNS A", + (int)domain->slen, domain->ptr)); + status = pj_getaddrinfo(sess->af, domain, &cnt, ai); if (status != PJ_SUCCESS) goto on_return; @@ -538,17 +577,19 @@ PJ_DEF(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess, const pj_turn_alloc_param *param) { pj_stun_tx_data *tdata; + pj_bool_t retransmit; pj_status_t status; PJ_ASSERT_RETURN(sess, PJ_EINVAL); - PJ_ASSERT_RETURN(sess->state>PJ_TURN_STATE_NULL && sess->state<=PJ_TURN_STATE_RESOLVED, + PJ_ASSERT_RETURN(sess->state>PJ_TURN_STATE_NULL && + sess->state<=PJ_TURN_STATE_RESOLVED, PJ_EINVALIDOP); pj_lock_acquire(sess->lock); if (sess->state < PJ_TURN_STATE_RESOLVED) { - if (param && param != &sess->alloc_param) - pj_memcpy(&sess->alloc_param, param, sizeof(*param)); + if (param && param != &sess->alloc_param) + pj_turn_alloc_param_copy(sess->pool, &sess->alloc_param, param); sess->pending_alloc = PJ_TRUE; PJ_LOG(4,(sess->obj_name, "Pending ALLOCATE in state %s", @@ -594,7 +635,9 @@ PJ_DEF(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess, /* Send request */ set_state(sess, PJ_TURN_STATE_ALLOCATING); - status = pj_stun_session_send_msg(sess->stun, PJ_FALSE, sess->srv_addr, + retransmit = (sess->tp_type == PJ_TURN_TP_UDP); + status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, + retransmit, sess->srv_addr, pj_sockaddr_get_len(sess->srv_addr), tdata); if (status != PJ_SUCCESS) { @@ -636,7 +679,9 @@ static void send_refresh(pj_turn_session *sess, int lifetime) set_state(sess, PJ_TURN_STATE_DEALLOCATING); } - status = pj_stun_session_send_msg(sess->stun, PJ_FALSE, sess->srv_addr, + status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, + (sess->tp_type==PJ_TURN_TP_UDP), + sess->srv_addr, pj_sockaddr_get_len(sess->srv_addr), tdata); if (status != PJ_SUCCESS) @@ -647,7 +692,7 @@ static void send_refresh(pj_turn_session *sess, int lifetime) on_error: if (lifetime == 0) { set_state(sess, PJ_TURN_STATE_DEALLOCATED); - sess_shutdown(sess, PJ_FALSE, status); + sess_shutdown(sess, status); } } @@ -724,7 +769,8 @@ PJ_DEF(pj_status_t) pj_turn_session_sendto( pj_turn_session *sess, PJ_STUN_ATTR_DATA, pkt, pkt_len); /* Send the indication */ - status = pj_stun_session_send_msg(sess->stun, PJ_FALSE, sess->srv_addr, + status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, + PJ_FALSE, sess->srv_addr, pj_sockaddr_get_len(sess->srv_addr), tdata); } @@ -763,11 +809,6 @@ PJ_DEF(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess, peer = lookup_peer_by_addr(sess, peer_adr, addr_len, PJ_TRUE, PJ_FALSE); pj_assert(peer); - /* Associate peer data structure with tdata for future reference - * when we receive the ChannelBind response. - */ - tdata->user_data = peer; - if (peer->ch_id != PJ_TURN_INVALID_CHANNEL) { /* Channel is already bound. This is a refresh request. */ ch_num = peer->ch_id; @@ -787,8 +828,12 @@ PJ_DEF(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess, PJ_STUN_ATTR_PEER_ADDR, PJ_TRUE, peer_adr, addr_len); - /* Send the request */ - status = pj_stun_session_send_msg(sess->stun, PJ_FALSE, sess->srv_addr, + /* Send the request, associate peer data structure with tdata + * for future reference when we receive the ChannelBind response. + */ + status = pj_stun_session_send_msg(sess->stun, peer, PJ_FALSE, + (sess->tp_type==PJ_TURN_TP_UDP), + sess->srv_addr, pj_sockaddr_get_len(sess->srv_addr), tdata); @@ -828,7 +873,7 @@ PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, if (is_datagram) options |= PJ_STUN_IS_DATAGRAM; status=pj_stun_session_on_rx_pkt(sess->stun, pkt, pkt_len, - options, NULL, + options, NULL, NULL, sess->srv_addr, pj_sockaddr_get_len(sess->srv_addr)); @@ -882,6 +927,7 @@ on_return: * This is a callback from STUN session to send outgoing packet. */ static pj_status_t stun_on_send_msg(pj_stun_session *stun, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -889,6 +935,8 @@ static pj_status_t stun_on_send_msg(pj_stun_session *stun, { pj_turn_session *sess; + PJ_UNUSED_ARG(token); + sess = (pj_turn_session*) pj_stun_session_get_user_data(stun); return (*sess->cb.on_send_pkt)(sess, pkt, pkt_size, dst_addr, addr_len); @@ -927,7 +975,7 @@ static void on_session_fail( pj_turn_session *sess, { set_state(sess, PJ_TURN_STATE_DEALLOCATED); - sess_shutdown(sess, PJ_TRUE, status); + sess_shutdown(sess, status); return; } @@ -936,7 +984,7 @@ static void on_session_fail( pj_turn_session *sess, */ if (method==PJ_STUN_REFRESH_METHOD) { set_state(sess, PJ_TURN_STATE_DEALLOCATED); - sess_shutdown(sess, PJ_TRUE, status); + sess_shutdown(sess, status); return; } @@ -975,9 +1023,8 @@ static void on_allocate_success(pj_turn_session *sess, /* If LIFETIME is zero, this is a deallocation */ if (lf_attr->value == 0) { - pj_bool_t notify = sess->state < PJ_TURN_STATE_DEALLOCATING; set_state(sess, PJ_TURN_STATE_DEALLOCATED); - sess_shutdown(sess, notify, PJ_SUCCESS); + sess_shutdown(sess, PJ_SUCCESS); return; } @@ -1068,6 +1115,7 @@ static void on_allocate_success(pj_turn_session *sess, */ static void stun_on_request_complete(pj_stun_session *stun, pj_status_t status, + void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, @@ -1145,7 +1193,7 @@ static void stun_on_request_complete(pj_stun_session *stun, PJ_STUN_IS_SUCCESS_RESPONSE(response->hdr.type)) { /* Successful ChannelBind response */ - struct peer *peer = (struct peer*)tdata->user_data; + struct peer *peer = (struct peer*)token; pj_assert(peer->ch_id != PJ_TURN_INVALID_CHANNEL); peer->bound = PJ_TRUE; @@ -1191,6 +1239,7 @@ static pj_status_t stun_on_rx_indication(pj_stun_session *stun, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_msg *msg, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { @@ -1198,6 +1247,7 @@ static pj_status_t stun_on_rx_indication(pj_stun_session *stun, pj_stun_peer_addr_attr *peer_attr; pj_stun_data_attr *data_attr; + PJ_UNUSED_ARG(token); PJ_UNUSED_ARG(pkt); PJ_UNUSED_ARG(pkt_len); PJ_UNUSED_ARG(src_addr); @@ -1253,7 +1303,7 @@ static void dns_srv_resolver_cb(void *user_data, /* Check failure */ if (status != PJ_SUCCESS) { - sess_shutdown(sess, PJ_TRUE, status); + sess_shutdown(sess, status); return; } @@ -1262,7 +1312,7 @@ static void dns_srv_resolver_cb(void *user_data, unsigned j; for (j=0; j<rec->entry[i].server.addr_count && cnt<MAX_SRV_CNT; ++j) { - pj_sockaddr_in *addr = &sess->srv_addr[cnt].ipv4; + pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4; addr->sin_family = sess->af; addr->sin_port = pj_htons(rec->entry[i].port); @@ -1274,7 +1324,7 @@ static void dns_srv_resolver_cb(void *user_data, sess->srv_addr_cnt = (pj_uint16_t)cnt; /* Set current server */ - sess->srv_addr = &sess->srv_addr[0]; + sess->srv_addr = &sess->srv_addr_list[0]; /* Set state to PJ_TURN_STATE_RESOLVED */ set_state(sess, PJ_TURN_STATE_RESOLVED); @@ -1414,9 +1464,10 @@ static void on_timer_event(pj_timer_heap_t *th, pj_timer_entry *e) PJ_STUN_ATTR_DATA, NULL, 0); /* Send the indication */ - pj_stun_session_send_msg(sess->stun, PJ_FALSE, sess->srv_addr, - pj_sockaddr_get_len(sess->srv_addr), - tdata); + pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, + PJ_FALSE, sess->srv_addr, + pj_sockaddr_get_len(sess->srv_addr), + tdata); } } diff --git a/pjnath/src/pjnath/turn_sock.c b/pjnath/src/pjnath/turn_sock.c new file mode 100644 index 00000000..0a3c5465 --- /dev/null +++ b/pjnath/src/pjnath/turn_sock.c @@ -0,0 +1,654 @@ +/* $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/turn_sock.h> +#include <pj/assert.h> +#include <pj/errno.h> +#include <pj/lock.h> +#include <pj/log.h> +#include <pj/pool.h> +#include <pj/ioqueue.h> + +enum +{ + TIMER_NONE, + TIMER_DESTROY +}; + +#define INIT 0x1FFFFFFF + +struct pj_turn_sock +{ + pj_pool_t *pool; + const char *obj_name; + pj_turn_session *sess; + pj_turn_sock_cb cb; + void *user_data; + + pj_lock_t *lock; + + pj_turn_alloc_param alloc_param; + pj_stun_config cfg; + + pj_bool_t destroy_request; + pj_timer_entry timer; + + int af; + pj_turn_tp_type conn_type; + pj_sock_t sock; + pj_ioqueue_key_t *key; + pj_ioqueue_op_key_t read_key; + pj_ioqueue_op_key_t send_key; + pj_uint8_t pkt[PJ_TURN_MAX_PKT_LEN]; +}; + + +/* + * Callback prototypes. + */ +static pj_status_t turn_on_send_pkt(pj_turn_session *sess, + const pj_uint8_t *pkt, + unsigned pkt_len, + const pj_sockaddr_t *dst_addr, + unsigned dst_addr_len); +static void turn_on_channel_bound(pj_turn_session *sess, + const pj_sockaddr_t *peer_addr, + unsigned addr_len, + unsigned ch_num); +static void turn_on_rx_data(pj_turn_session *sess, + const pj_uint8_t *pkt, + unsigned pkt_len, + const pj_sockaddr_t *peer_addr, + unsigned addr_len); +static void turn_on_state(pj_turn_session *sess, + pj_turn_state_t old_state, + pj_turn_state_t new_state); +static void on_read_complete(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_read); +static void on_connect_complete(pj_ioqueue_key_t *key, + pj_status_t status); + + +static void destroy(pj_turn_sock *turn_sock); +static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e); + + +/* + * Create. + */ +PJ_DEF(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg, + int af, + pj_turn_tp_type conn_type, + const pj_turn_sock_cb *cb, + unsigned options, + void *user_data, + pj_turn_sock **p_turn_sock) +{ + pj_turn_sock *turn_sock; + pj_turn_session_cb sess_cb; + pj_pool_t *pool; + const char *name_tmpl; + pj_status_t status; + + PJ_ASSERT_RETURN(cfg && p_turn_sock, PJ_EINVAL); + PJ_ASSERT_RETURN(af==pj_AF_INET() || af==pj_AF_INET6(), PJ_EINVAL); + PJ_ASSERT_RETURN(options==0, PJ_EINVAL); + + switch (conn_type) { + case PJ_TURN_TP_UDP: + name_tmpl = "udprel%p"; + break; + case PJ_TURN_TP_TCP: + name_tmpl = "tcprel%p"; + break; + default: + PJ_ASSERT_RETURN(!"Invalid TURN conn_type", PJ_EINVAL); + name_tmpl = "tcprel%p"; + break; + } + + /* Create and init basic data structure */ + pool = pj_pool_create(cfg->pf, name_tmpl, 1000, 1000, NULL); + turn_sock = PJ_POOL_ZALLOC_T(pool, pj_turn_sock); + turn_sock->pool = pool; + turn_sock->obj_name = pool->obj_name; + turn_sock->user_data = user_data; + turn_sock->af = af; + turn_sock->conn_type = conn_type; + + /* Copy STUN config (this contains ioqueue, timer heap, etc.) */ + pj_memcpy(&turn_sock->cfg, cfg, sizeof(*cfg)); + + /* Set callback */ + if (cb) { + pj_memcpy(&turn_sock->cb, cb, sizeof(*cb)); + } + + /* Create lock */ + status = pj_lock_create_recursive_mutex(pool, turn_sock->obj_name, + &turn_sock->lock); + if (status != PJ_SUCCESS) { + destroy(turn_sock); + return status; + } + + /* Init timer */ + pj_timer_entry_init(&turn_sock->timer, TIMER_NONE, turn_sock, &timer_cb); + + /* Init TURN session */ + pj_bzero(&sess_cb, sizeof(sess_cb)); + sess_cb.on_send_pkt = &turn_on_send_pkt; + sess_cb.on_channel_bound = &turn_on_channel_bound; + sess_cb.on_rx_data = &turn_on_rx_data; + sess_cb.on_state = &turn_on_state; + status = pj_turn_session_create(cfg, pool->obj_name, af, conn_type, + &sess_cb, turn_sock, 0, &turn_sock->sess); + if (status != PJ_SUCCESS) { + destroy(turn_sock); + return status; + } + + /* Note: socket and ioqueue will be created later once the TURN server + * has been resolved. + */ + + *p_turn_sock = turn_sock; + return PJ_SUCCESS; +} + +/* + * Destroy. + */ +static void destroy(pj_turn_sock *turn_sock) +{ + if (turn_sock->lock) { + pj_lock_acquire(turn_sock->lock); + } + + if (turn_sock->sess) { + pj_turn_session_set_user_data(turn_sock->sess, NULL); + pj_turn_session_shutdown(turn_sock->sess); + turn_sock->sess = NULL; + } + + if (turn_sock->key) { + pj_ioqueue_unregister(turn_sock->key); + turn_sock->key = NULL; + turn_sock->sock = 0; + } else if (turn_sock->sock) { + pj_sock_close(turn_sock->sock); + turn_sock->sock = 0; + } + + if (turn_sock->lock) { + pj_lock_release(turn_sock->lock); + pj_lock_destroy(turn_sock->lock); + turn_sock->lock = NULL; + } + + if (turn_sock->pool) { + pj_pool_t *pool = turn_sock->pool; + turn_sock->pool = NULL; + pj_pool_release(pool); + } +} + + +PJ_DEF(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock) +{ + pj_lock_acquire(turn_sock->lock); + turn_sock->destroy_request = PJ_TRUE; + + if (turn_sock->sess) { + pj_turn_session_shutdown(turn_sock->sess); + /* This will ultimately call our state callback, and when + * session state is DESTROYING we will schedule a timer to + * destroy ourselves. + */ + pj_lock_release(turn_sock->lock); + } else { + pj_lock_release(turn_sock->lock); + destroy(turn_sock); + } + +} + + +/* Timer callback */ +static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e) +{ + pj_turn_sock *turn_sock = (pj_turn_sock*)e->user_data; + int eid = e->id; + + PJ_UNUSED_ARG(th); + + e->id = TIMER_NONE; + + switch (eid) { + case TIMER_DESTROY: + PJ_LOG(5,(turn_sock->obj_name, "Destroying TURN")); + destroy(turn_sock); + break; + default: + pj_assert(!"Invalid timer id"); + break; + } +} + + +/* Display error */ +static void show_err(pj_turn_sock *turn_sock, const char *title, + pj_status_t status) +{ + char errmsg[PJ_ERR_MSG_SIZE]; + + if (status != PJ_SUCCESS) { + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(4,(turn_sock->obj_name, "%s: %s", title, errmsg)); + } else { + PJ_LOG(4,(turn_sock->obj_name, "%s", title, errmsg)); + } +} + +/* On error, terminate session */ +static void sess_fail(pj_turn_sock *turn_sock, const char *title, + pj_status_t status) +{ + show_err(turn_sock, title, status); + pj_turn_session_destroy(turn_sock->sess); +} + +/* + * Set user data. + */ +PJ_DEF(pj_status_t) pj_turn_sock_set_user_data( pj_turn_sock *turn_sock, + void *user_data) +{ + turn_sock->user_data = user_data; + return PJ_SUCCESS; +} + +/* + * Get user data. + */ +PJ_DEF(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock) +{ + return turn_sock->user_data; +} + +/** + * Get info. + */ +PJ_DEF(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock, + pj_turn_session_info *info) +{ + PJ_ASSERT_RETURN(turn_sock && info, PJ_EINVAL); + + if (turn_sock->sess) { + return pj_turn_session_get_info(turn_sock->sess, info); + } else { + pj_bzero(info, sizeof(*info)); + info->state = PJ_TURN_STATE_NULL; + return PJ_SUCCESS; + } +} + +/* + * Initialize. + */ +PJ_DEF(pj_status_t) pj_turn_sock_init(pj_turn_sock *turn_sock, + const pj_str_t *domain, + int default_port, + pj_dns_resolver *resolver, + const pj_stun_auth_cred *cred, + const pj_turn_alloc_param *param) +{ + pj_status_t status; + + PJ_ASSERT_RETURN(turn_sock && domain, PJ_EINVAL); + PJ_ASSERT_RETURN(turn_sock->sess, PJ_EINVALIDOP); + + /* Copy alloc param. We will call session_alloc() only after the + * server address has been resolved. + */ + if (param) { + pj_turn_alloc_param_copy(turn_sock->pool, &turn_sock->alloc_param, param); + } else { + pj_turn_alloc_param_default(&turn_sock->alloc_param); + } + + /* Set credental */ + if (cred) { + status = pj_turn_session_set_cred(turn_sock->sess, cred); + if (status != PJ_SUCCESS) { + sess_fail(turn_sock, "Error setting credential", status); + return status; + } + } + + /* Resolve server */ + status = pj_turn_session_set_server(turn_sock->sess, domain, default_port, + resolver); + if (status != PJ_SUCCESS) { + sess_fail(turn_sock, "Error setting TURN server", status); + return status; + } + + /* Done for now. The next work will be done when session state moved + * to RESOLVED state. + */ + + return PJ_SUCCESS; +} + +/* + * Send packet. + */ +PJ_DEF(pj_status_t) pj_turn_sock_sendto( pj_turn_sock *turn_sock, + const pj_uint8_t *pkt, + unsigned pkt_len, + const pj_sockaddr_t *addr, + unsigned addr_len) +{ + PJ_ASSERT_RETURN(turn_sock && addr && addr_len, PJ_EINVAL); + + if (turn_sock->sess == NULL) + return PJ_EINVALIDOP; + + return pj_turn_session_sendto(turn_sock->sess, pkt, pkt_len, + addr, addr_len); +} + +/* + * Bind a peer address to a channel number. + */ +PJ_DEF(pj_status_t) pj_turn_sock_bind_channel( pj_turn_sock *turn_sock, + const pj_sockaddr_t *peer, + unsigned addr_len) +{ + PJ_ASSERT_RETURN(turn_sock && peer && addr_len, PJ_EINVAL); + PJ_ASSERT_RETURN(turn_sock->sess != NULL, PJ_EINVALIDOP); + + return pj_turn_session_bind_channel(turn_sock->sess, peer, addr_len); +} + + +/* + * Notification when outgoing TCP socket has been connected. + */ +static void on_connect_complete(pj_ioqueue_key_t *key, + pj_status_t status) +{ + pj_turn_sock *turn_sock; + + turn_sock = (pj_turn_sock*) pj_ioqueue_get_user_data(key); + + if (status != PJ_SUCCESS) { + sess_fail(turn_sock, "TCP connect() error", status); + return; + } + + if (turn_sock->conn_type != PJ_TURN_TP_UDP) { + PJ_LOG(5,(turn_sock->obj_name, "TCP connected")); + } + + /* Kick start pending read operation */ + pj_ioqueue_op_key_init(&turn_sock->read_key, sizeof(turn_sock->read_key)); + on_read_complete(turn_sock->key, &turn_sock->read_key, INIT); + + /* Init send_key */ + pj_ioqueue_op_key_init(&turn_sock->send_key, sizeof(turn_sock->send_key)); + + /* Send Allocate request */ + status = pj_turn_session_alloc(turn_sock->sess, &turn_sock->alloc_param); + if (status != PJ_SUCCESS) { + sess_fail(turn_sock, "Error sending ALLOCATE", status); + return; + } +} + +/* + * Notification from ioqueue when incoming UDP packet is received. + */ +static void on_read_complete(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_read) +{ + enum { MAX_RETRY = 10 }; + pj_turn_sock *turn_sock; + int retry = 0; + pj_status_t status; + + turn_sock = (pj_turn_sock*) pj_ioqueue_get_user_data(key); + pj_lock_acquire(turn_sock->lock); + + do { + if (bytes_read == INIT) { + /* Special instruction to initialize pending read() */ + } else if (bytes_read > 0 && turn_sock->sess) { + /* Report incoming packet to TURN session */ + pj_turn_session_on_rx_pkt(turn_sock->sess, turn_sock->pkt, + bytes_read, + turn_sock->conn_type == PJ_TURN_TP_UDP); + } else if (bytes_read <= 0 && turn_sock->conn_type != PJ_TURN_TP_UDP) { + sess_fail(turn_sock, "TCP connection closed", -bytes_read); + goto on_return; + } + + /* Read next packet */ + bytes_read = sizeof(turn_sock->pkt); + status = pj_ioqueue_recv(turn_sock->key, op_key, + turn_sock->pkt, &bytes_read, 0); + + if (status != PJ_EPENDING && status != PJ_SUCCESS) { + char errmsg[PJ_ERR_MSG_SIZE]; + + pj_strerror(status, errmsg, sizeof(errmsg)); + sess_fail(turn_sock, "Socket recv() error", status); + goto on_return; + } + + } while (status != PJ_EPENDING && status != PJ_ECANCELLED && + ++retry < MAX_RETRY); + +on_return: + pj_lock_release(turn_sock->lock); +} + + +/* + * Callback from TURN session to send outgoing packet. + */ +static pj_status_t turn_on_send_pkt(pj_turn_session *sess, + const pj_uint8_t *pkt, + unsigned pkt_len, + const pj_sockaddr_t *dst_addr, + unsigned dst_addr_len) +{ + pj_turn_sock *turn_sock = (pj_turn_sock*) + pj_turn_session_get_user_data(sess); + pj_ssize_t len = pkt_len; + pj_status_t status; + + if (turn_sock == NULL) { + /* We've been destroyed */ + pj_assert(!"We should shutdown gracefully"); + return PJ_EINVALIDOP; + } + + PJ_UNUSED_ARG(dst_addr); + PJ_UNUSED_ARG(dst_addr_len); + + status = pj_ioqueue_send(turn_sock->key, &turn_sock->send_key, + pkt, &len, 0); + if (status != PJ_SUCCESS && status != PJ_EPENDING) { + show_err(turn_sock, "socket send()", status); + } + + return status; +} + + +/* + * Callback from TURN session when a channel is successfully bound. + */ +static void turn_on_channel_bound(pj_turn_session *sess, + const pj_sockaddr_t *peer_addr, + unsigned addr_len, + unsigned ch_num) +{ + PJ_UNUSED_ARG(sess); + PJ_UNUSED_ARG(peer_addr); + PJ_UNUSED_ARG(addr_len); + PJ_UNUSED_ARG(ch_num); +} + + +/* + * Callback from TURN session upon incoming data. + */ +static void turn_on_rx_data(pj_turn_session *sess, + const pj_uint8_t *pkt, + unsigned pkt_len, + const pj_sockaddr_t *peer_addr, + unsigned addr_len) +{ + pj_turn_sock *turn_sock = (pj_turn_sock*) + pj_turn_session_get_user_data(sess); + if (turn_sock == NULL) { + /* We've been destroyed */ + return; + } + + if (turn_sock->cb.on_rx_data) { + (*turn_sock->cb.on_rx_data)(turn_sock, pkt, pkt_len, + peer_addr, addr_len); + } +} + + +/* + * Callback from TURN session when state has changed + */ +static void turn_on_state(pj_turn_session *sess, + pj_turn_state_t old_state, + pj_turn_state_t new_state) +{ + pj_turn_sock *turn_sock = (pj_turn_sock*) + pj_turn_session_get_user_data(sess); + pj_status_t status; + + if (turn_sock == NULL) { + /* We've been destroyed */ + return; + } + + if (new_state == PJ_TURN_STATE_RESOLVED) { + /* + * Once server has been resolved, initiate outgoing TCP + * connection to the server. + */ + pj_turn_session_info info; + char addrtxt[PJ_INET6_ADDRSTRLEN+8]; + int sock_type; + pj_ioqueue_callback ioq_cb; + + /* Close existing connection, if any. This happens when + * we're switching to alternate TURN server when either TCP + * connection or ALLOCATE request failed. + */ + if (turn_sock->key) { + pj_ioqueue_unregister(turn_sock->key); + turn_sock->key = NULL; + turn_sock->sock = 0; + } else if (turn_sock->sock) { + pj_sock_close(turn_sock->sock); + turn_sock->sock = 0; + } + + /* Get server address from session info */ + pj_turn_session_get_info(sess, &info); + + if (turn_sock->conn_type == PJ_TURN_TP_UDP) + sock_type = pj_SOCK_DGRAM(); + else + sock_type = pj_SOCK_STREAM(); + + /* Init socket */ + status = pj_sock_socket(turn_sock->af, sock_type, 0, + &turn_sock->sock); + if (status != PJ_SUCCESS) { + pj_turn_sock_destroy(turn_sock); + return; + } + + /* Register to ioqeuue */ + pj_bzero(&ioq_cb, sizeof(ioq_cb)); + ioq_cb.on_read_complete = &on_read_complete; + ioq_cb.on_connect_complete = &on_connect_complete; + status = pj_ioqueue_register_sock(turn_sock->pool, turn_sock->cfg.ioqueue, + turn_sock->sock, turn_sock, + &ioq_cb, &turn_sock->key); + if (status != PJ_SUCCESS) { + pj_turn_sock_destroy(turn_sock); + return; + } + + PJ_LOG(5,(turn_sock->pool->obj_name, + "Connecting to %s", + pj_sockaddr_print(&info.server, addrtxt, + sizeof(addrtxt), 3))); + + /* Initiate non-blocking connect */ + status = pj_ioqueue_connect(turn_sock->key, &info.server, + pj_sockaddr_get_len(&info.server)); + if (status == PJ_SUCCESS) { + on_connect_complete(turn_sock->key, PJ_SUCCESS); + } else if (status != PJ_EPENDING) { + pj_turn_sock_destroy(turn_sock); + return; + } + + /* Done for now. Subsequent work will be done in + * on_connect_complete() callback. + */ + } + + if (turn_sock->cb.on_state) { + (*turn_sock->cb.on_state)(turn_sock, old_state, new_state); + } + + if (new_state >= PJ_TURN_STATE_DESTROYING && turn_sock->sess) { + pj_time_val delay = {0, 0}; + + turn_sock->sess = NULL; + pj_turn_session_set_user_data(sess, NULL); + + if (turn_sock->timer.id) { + pj_timer_heap_cancel(turn_sock->cfg.timer_heap, &turn_sock->timer); + turn_sock->timer.id = 0; + } + + turn_sock->timer.id = TIMER_DESTROY; + pj_timer_heap_schedule(turn_sock->cfg.timer_heap, &turn_sock->timer, + &delay); + } +} + + diff --git a/pjnath/src/pjnath/turn_udp.c b/pjnath/src/pjnath/turn_udp.c deleted file mode 100644 index a58e816b..00000000 --- a/pjnath/src/pjnath/turn_udp.c +++ /dev/null @@ -1,500 +0,0 @@ -/* $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/turn_udp.h> -#include <pj/assert.h> -#include <pj/errno.h> -#include <pj/lock.h> -#include <pj/log.h> -#include <pj/pool.h> -#include <pj/ioqueue.h> - -enum -{ - TIMER_NONE, - TIMER_DESTROY -}; - -struct pj_turn_udp -{ - pj_pool_t *pool; - pj_turn_session *sess; - pj_turn_udp_cb cb; - void *user_data; - - pj_lock_t *lock; - - pj_bool_t destroy_request; - pj_timer_heap_t *timer_heap; - pj_timer_entry timer; - - pj_sock_t sock; - pj_ioqueue_key_t *key; - pj_ioqueue_op_key_t read_key; - pj_uint8_t pkt[PJ_TURN_MAX_PKT_LEN]; - pj_sockaddr src_addr; - int src_addr_len; -}; - - -/* - * Callback prototypes. - */ -static pj_status_t turn_on_send_pkt(pj_turn_session *sess, - const pj_uint8_t *pkt, - unsigned pkt_len, - const pj_sockaddr_t *dst_addr, - unsigned dst_addr_len); -static void turn_on_channel_bound(pj_turn_session *sess, - const pj_sockaddr_t *peer_addr, - unsigned addr_len, - unsigned ch_num); -static void turn_on_rx_data(pj_turn_session *sess, - const pj_uint8_t *pkt, - unsigned pkt_len, - const pj_sockaddr_t *peer_addr, - unsigned addr_len); -static void turn_on_state(pj_turn_session *sess, - pj_turn_state_t old_state, - pj_turn_state_t new_state); -static void on_read_complete(pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_ssize_t bytes_read); - - -static void destroy(pj_turn_udp *udp_rel); -static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e); - - -/* - * Create. - */ -PJ_DEF(pj_status_t) pj_turn_udp_create( pj_stun_config *cfg, - int af, - const pj_turn_udp_cb *cb, - unsigned options, - void *user_data, - pj_turn_udp **p_udp_rel) -{ - pj_turn_udp *udp_rel; - pj_turn_session_cb sess_cb; - pj_ioqueue_callback ioq_cb; - pj_pool_t *pool; - pj_status_t status; - - PJ_ASSERT_RETURN(cfg && p_udp_rel, PJ_EINVAL); - PJ_ASSERT_RETURN(options==0, PJ_EINVAL); - - /* Create and init basic data structure */ - pool = pj_pool_create(cfg->pf, "udprel%p", 1000, 1000, NULL); - udp_rel = PJ_POOL_ZALLOC_T(pool, pj_turn_udp); - udp_rel->pool = pool; - udp_rel->user_data = user_data; - - if (cb) { - pj_memcpy(&udp_rel->cb, cb, sizeof(*cb)); - } - - /* Create lock */ - status = pj_lock_create_recursive_mutex(pool, pool->obj_name, - &udp_rel->lock); - if (status != PJ_SUCCESS) { - destroy(udp_rel); - return status; - } - - /* Init timer */ - udp_rel->timer_heap = cfg->timer_heap; - pj_timer_entry_init(&udp_rel->timer, TIMER_NONE, udp_rel, &timer_cb); - - /* Init socket */ - status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &udp_rel->sock); - if (status != PJ_SUCCESS) { - destroy(udp_rel); - return status; - } - - /* Bind to any */ - pj_sockaddr_init(af, &udp_rel->src_addr, NULL, 0); - status = pj_sock_bind(udp_rel->sock, &udp_rel->src_addr, - pj_sockaddr_get_len(&udp_rel->src_addr)); - if (status != PJ_SUCCESS) { - destroy(udp_rel); - return status; - } - - /* Register to ioqeuue */ - pj_bzero(&ioq_cb, sizeof(ioq_cb)); - ioq_cb.on_read_complete = &on_read_complete; - status = pj_ioqueue_register_sock(udp_rel->pool, cfg->ioqueue, - udp_rel->sock, udp_rel, - &ioq_cb, &udp_rel->key); - if (status != PJ_SUCCESS) { - destroy(udp_rel); - return status; - } - - /* Init TURN session */ - pj_bzero(&sess_cb, sizeof(sess_cb)); - sess_cb.on_send_pkt = &turn_on_send_pkt; - sess_cb.on_channel_bound = &turn_on_channel_bound; - sess_cb.on_rx_data = &turn_on_rx_data; - sess_cb.on_state = &turn_on_state; - status = pj_turn_session_create(cfg, "turn%p", af, PJ_TURN_TP_UDP, - &sess_cb, udp_rel, 0, &udp_rel->sess); - if (status != PJ_SUCCESS) { - destroy(udp_rel); - return status; - } - - /* Kick start pending read operation */ - pj_ioqueue_op_key_init(&udp_rel->read_key, sizeof(udp_rel->read_key)); - on_read_complete(udp_rel->key, &udp_rel->read_key, 0); - - *p_udp_rel = udp_rel; - return PJ_SUCCESS; -} - -/* - * Destroy. - */ -static void destroy(pj_turn_udp *udp_rel) -{ - if (udp_rel->lock) { - pj_lock_acquire(udp_rel->lock); - } - - if (udp_rel->sess) { - pj_turn_session_set_user_data(udp_rel->sess, NULL); - pj_turn_session_destroy(udp_rel->sess); - udp_rel->sess = NULL; - } - - if (udp_rel->key) { - pj_ioqueue_unregister(udp_rel->key); - udp_rel->key = NULL; - udp_rel->sock = 0; - } else if (udp_rel->sock) { - pj_sock_close(udp_rel->sock); - udp_rel->sock = 0; - } - - if (udp_rel->lock) { - pj_lock_release(udp_rel->lock); - pj_lock_destroy(udp_rel->lock); - udp_rel->lock = NULL; - } - - if (udp_rel->pool) { - pj_pool_t *pool = udp_rel->pool; - udp_rel->pool = NULL; - pj_pool_release(pool); - } -} - -PJ_DEF(void) pj_turn_udp_destroy(pj_turn_udp *udp_rel) -{ - pj_lock_acquire(udp_rel->lock); - udp_rel->destroy_request = PJ_TRUE; - - if (udp_rel->sess) { - pj_turn_session_destroy(udp_rel->sess); - /* This will ultimately call our state callback, and when - * session state is DESTROYING we will schedule a timer to - * destroy ourselves. - */ - pj_lock_release(udp_rel->lock); - } else { - pj_lock_release(udp_rel->lock); - destroy(udp_rel); - } - -} - -/* Timer callback */ -static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e) -{ - pj_turn_udp *udp_rel = (pj_turn_udp*)e->user_data; - int eid = e->id; - - PJ_UNUSED_ARG(th); - - e->id = TIMER_NONE; - - switch (eid) { - case TIMER_DESTROY: - destroy(udp_rel); - break; - default: - pj_assert(!"Invalid timer id"); - break; - } -} - - -/* - * Set user data. - */ -PJ_DEF(pj_status_t) pj_turn_udp_set_user_data( pj_turn_udp *udp_rel, - void *user_data) -{ - udp_rel->user_data = user_data; - return PJ_SUCCESS; -} - -/* - * Get user data. - */ -PJ_DEF(void*) pj_turn_udp_get_user_data(pj_turn_udp *udp_rel) -{ - return udp_rel->user_data; -} - -/** - * Get info. - */ -PJ_DEF(pj_status_t) pj_turn_udp_get_info(pj_turn_udp *udp_rel, - pj_turn_session_info *info) -{ - PJ_ASSERT_RETURN(udp_rel && info, PJ_EINVAL); - - if (udp_rel->sess) { - return pj_turn_session_get_info(udp_rel->sess, info); - } else { - pj_bzero(info, sizeof(*info)); - info->state = PJ_TURN_STATE_NULL; - return PJ_SUCCESS; - } -} - -/* - * Initialize. - */ -PJ_DEF(pj_status_t) pj_turn_udp_init( pj_turn_udp *udp_rel, - const pj_str_t *domain, - int default_port, - pj_dns_resolver *resolver, - const pj_stun_auth_cred *cred, - const pj_turn_alloc_param *param) -{ - pj_status_t status; - - PJ_ASSERT_RETURN(udp_rel && domain, PJ_EINVAL); - PJ_ASSERT_RETURN(udp_rel->sess, PJ_EINVALIDOP); - - status = pj_turn_session_set_server(udp_rel->sess, domain, default_port, - resolver); - if (status != PJ_SUCCESS) - return status; - - if (cred) { - status = pj_turn_session_set_cred(udp_rel->sess, cred); - if (status != PJ_SUCCESS) - return status; - } - - status = pj_turn_session_alloc(udp_rel->sess, param); - if (status != PJ_SUCCESS) - return status; - - return PJ_SUCCESS; -} - -/* - * Send packet. - */ -PJ_DEF(pj_status_t) pj_turn_udp_sendto( pj_turn_udp *udp_rel, - const pj_uint8_t *pkt, - unsigned pkt_len, - const pj_sockaddr_t *addr, - unsigned addr_len) -{ - PJ_ASSERT_RETURN(udp_rel && addr && addr_len, PJ_EINVAL); - - if (udp_rel->sess == NULL) - return PJ_EINVALIDOP; - - return pj_turn_session_sendto(udp_rel->sess, pkt, pkt_len, - addr, addr_len); -} - -/* - * Bind a peer address to a channel number. - */ -PJ_DEF(pj_status_t) pj_turn_udp_bind_channel( pj_turn_udp *udp_rel, - const pj_sockaddr_t *peer, - unsigned addr_len) -{ - PJ_ASSERT_RETURN(udp_rel && peer && addr_len, PJ_EINVAL); - PJ_ASSERT_RETURN(udp_rel->sess != NULL, PJ_EINVALIDOP); - - return pj_turn_session_bind_channel(udp_rel->sess, peer, addr_len); -} - - -/* - * Notification from ioqueue when incoming UDP packet is received. - */ -static void on_read_complete(pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_ssize_t bytes_read) -{ - enum { MAX_RETRY = 10 }; - pj_turn_udp *udp_rel; - int retry = 0; - pj_status_t status; - - udp_rel = (pj_turn_udp*) pj_ioqueue_get_user_data(key); - pj_lock_acquire(udp_rel->lock); - - do { - /* Report incoming packet to TURN session */ - if (bytes_read > 0 && udp_rel->sess) { - pj_turn_session_on_rx_pkt(udp_rel->sess, udp_rel->pkt, - bytes_read, PJ_TRUE); - } - - /* Read next packet */ - bytes_read = sizeof(udp_rel->pkt); - udp_rel->src_addr_len = sizeof(udp_rel->src_addr); - status = pj_ioqueue_recvfrom(udp_rel->key, op_key, - udp_rel->pkt, &bytes_read, 0, - &udp_rel->src_addr, - &udp_rel->src_addr_len); - - if (status != PJ_EPENDING && status != PJ_SUCCESS) { - char errmsg[PJ_ERR_MSG_SIZE]; - - pj_strerror(status, errmsg, sizeof(errmsg)); - PJ_LOG(4,(udp_rel->pool->obj_name, - "ioqueue recvfrom error: %s", errmsg)); - - bytes_read = -status; - } - - } while (status != PJ_EPENDING && status != PJ_ECANCELLED && - ++retry < MAX_RETRY); - - pj_lock_release(udp_rel->lock); -} - - -/* - * Callback from TURN session to send outgoing packet. - */ -static pj_status_t turn_on_send_pkt(pj_turn_session *sess, - const pj_uint8_t *pkt, - unsigned pkt_len, - const pj_sockaddr_t *dst_addr, - unsigned dst_addr_len) -{ - pj_turn_udp *udp_rel = (pj_turn_udp*) - pj_turn_session_get_user_data(sess); - pj_ssize_t len = pkt_len; - - if (udp_rel == NULL) { - /* We've been destroyed */ - pj_assert(!"We should shutdown gracefully"); - return PJ_EINVALIDOP; - } - - return pj_sock_sendto(udp_rel->sock, pkt, &len, 0, - dst_addr, dst_addr_len); -} - - -/* - * Callback from TURN session when a channel is successfully bound. - */ -static void turn_on_channel_bound(pj_turn_session *sess, - const pj_sockaddr_t *peer_addr, - unsigned addr_len, - unsigned ch_num) -{ - PJ_UNUSED_ARG(sess); - PJ_UNUSED_ARG(peer_addr); - PJ_UNUSED_ARG(addr_len); - PJ_UNUSED_ARG(ch_num); -} - - -/* - * Callback from TURN session upon incoming data. - */ -static void turn_on_rx_data(pj_turn_session *sess, - const pj_uint8_t *pkt, - unsigned pkt_len, - const pj_sockaddr_t *peer_addr, - unsigned addr_len) -{ - pj_turn_udp *udp_rel = (pj_turn_udp*) - pj_turn_session_get_user_data(sess); - if (udp_rel == NULL) { - /* We've been destroyed */ - return; - } - - if (udp_rel->cb.on_rx_data) { - (*udp_rel->cb.on_rx_data)(udp_rel, pkt, pkt_len, - peer_addr, addr_len); - } -} - - -/* - * Callback from TURN session when state has changed - */ -static void turn_on_state(pj_turn_session *sess, - pj_turn_state_t old_state, - pj_turn_state_t new_state) -{ - pj_turn_udp *udp_rel = (pj_turn_udp*) - pj_turn_session_get_user_data(sess); - if (udp_rel == NULL) { - /* We've been destroyed */ - return; - } - - if (udp_rel->cb.on_state) { - (*udp_rel->cb.on_state)(udp_rel, old_state, new_state); - } - - if (new_state >= PJ_TURN_STATE_DESTROYING && udp_rel->sess) { - - udp_rel->sess = NULL; - // Always destroy the session regardless whether application - // has called pj_turn_udp_destroy() or not. This is to handle - // the case when Allocate request fails. - //if (udp_rel->destroy_request) { - if (1) { - pj_time_val delay = {0, 0}; - - pj_turn_session_set_user_data(sess, NULL); - - if (udp_rel->timer.id != TIMER_NONE) { - pj_timer_heap_cancel(udp_rel->timer_heap, &udp_rel->timer); - } - - udp_rel->timer.id = TIMER_DESTROY; - pj_timer_heap_schedule(udp_rel->timer_heap, &udp_rel->timer, - &delay); - } - } -} - - diff --git a/pjnath/src/pjturn-client/client_main.c b/pjnath/src/pjturn-client/client_main.c index 4a2eea1b..0ec61160 100644 --- a/pjnath/src/pjturn-client/client_main.c +++ b/pjnath/src/pjturn-client/client_main.c @@ -48,7 +48,7 @@ static struct global pj_thread_t *thread; pj_bool_t quit; - pj_turn_udp *udp_rel; + pj_turn_sock *relay; pj_sockaddr relay_addr; struct peer peer[2]; @@ -56,22 +56,23 @@ static struct global static struct options { - char *srv_addr; - char *srv_port; - char *realm; - char *user_name; - char *password; - pj_bool_t use_fingerprint; + pj_bool_t use_tcp; + char *srv_addr; + char *srv_port; + char *realm; + char *user_name; + char *password; + pj_bool_t use_fingerprint; } o; static int worker_thread(void *unused); -static void turn_on_rx_data(pj_turn_udp *udp_rel, +static void turn_on_rx_data(pj_turn_sock *relay, const pj_uint8_t *pkt, unsigned pkt_len, const pj_sockaddr_t *peer_addr, unsigned addr_len); -static void turn_on_state(pj_turn_udp *udp_rel, pj_turn_state_t old_state, +static void turn_on_state(pj_turn_sock *relay, pj_turn_state_t old_state, pj_turn_state_t new_state); @@ -155,9 +156,9 @@ static int shutdown() pj_thread_destroy(g.thread); g.thread = NULL; } - if (g.udp_rel) { - pj_turn_udp_destroy(g.udp_rel); - g.udp_rel = NULL; + if (g.relay) { + pj_turn_sock_destroy(g.relay); + g.relay = NULL; } for (i=0; i<PJ_ARRAY_SIZE(g.peer); ++i) { if (g.peer[i].sock) { @@ -242,12 +243,12 @@ static int worker_thread(void *unused) static pj_status_t create_relay(void) { - pj_turn_udp_cb rel_cb; + pj_turn_sock_cb rel_cb; pj_stun_auth_cred cred; pj_str_t srv; pj_status_t status; - if (g.udp_rel) { + if (g.relay) { PJ_LOG(1,(THIS_FILE, "Relay already created")); return -1; } @@ -255,8 +256,10 @@ static pj_status_t create_relay(void) pj_bzero(&rel_cb, sizeof(rel_cb)); rel_cb.on_rx_data = &turn_on_rx_data; rel_cb.on_state = &turn_on_state; - CHECK( pj_turn_udp_create(&g.stun_config, pj_AF_INET(), &rel_cb, 0, - NULL, &g.udp_rel) ); + CHECK( pj_turn_sock_create(&g.stun_config, pj_AF_INET(), + (o.use_tcp? PJ_TURN_TP_TCP : PJ_TURN_TP_UDP), + &rel_cb, 0, + NULL, &g.relay) ); if (o.user_name) { pj_bzero(&cred, sizeof(cred)); @@ -271,7 +274,7 @@ static pj_status_t create_relay(void) } srv = pj_str(o.srv_addr); - CHECK( pj_turn_udp_init(g.udp_rel, /* the relay */ + CHECK( pj_turn_sock_init(g.relay, /* the relay */ &srv, /* srv addr */ (o.srv_port?atoi(o.srv_port):PJ_STUN_PORT),/* def port */ NULL, /* resolver */ @@ -284,13 +287,13 @@ static pj_status_t create_relay(void) static void destroy_relay(void) { - if (g.udp_rel) { - pj_turn_udp_destroy(g.udp_rel); + if (g.relay) { + pj_turn_sock_destroy(g.relay); } } -static void turn_on_rx_data(pj_turn_udp *udp_rel, +static void turn_on_rx_data(pj_turn_sock *relay, const pj_uint8_t *pkt, unsigned pkt_len, const pj_sockaddr_t *peer_addr, @@ -305,7 +308,7 @@ static void turn_on_rx_data(pj_turn_udp *udp_rel, } -static void turn_on_state(pj_turn_udp *udp_rel, pj_turn_state_t old_state, +static void turn_on_state(pj_turn_sock *relay, pj_turn_state_t old_state, pj_turn_state_t new_state) { PJ_LOG(3,(THIS_FILE, "State %s --> %s", pj_turn_state_name(old_state), @@ -313,11 +316,11 @@ static void turn_on_state(pj_turn_udp *udp_rel, pj_turn_state_t old_state, if (new_state == PJ_TURN_STATE_READY) { pj_turn_session_info info; - pj_turn_udp_get_info(udp_rel, &info); + pj_turn_sock_get_info(relay, &info); pj_memcpy(&g.relay_addr, &info.relay_addr, sizeof(pj_sockaddr)); - } else if (new_state > PJ_TURN_STATE_READY && g.udp_rel) { + } else if (new_state > PJ_TURN_STATE_READY && g.relay) { PJ_LOG(3,(THIS_FILE, "Relay shutting down..")); - g.udp_rel = NULL; + g.relay = NULL; } } @@ -326,8 +329,8 @@ static void menu(void) pj_turn_session_info info; char client_state[20], relay_addr[80], peer0_addr[80], peer1_addr[80]; - if (g.udp_rel) { - pj_turn_udp_get_info(g.udp_rel, &info); + if (g.relay) { + pj_turn_sock_get_info(g.relay, &info); strcpy(client_state, pj_turn_state_name(info.state)); if (info.state >= PJ_TURN_STATE_READY) pj_sockaddr_print(&info.relay_addr, relay_addr, sizeof(relay_addr), 3); @@ -357,7 +360,7 @@ static void menu(void) printf("| x Delete allocation | Address: %-21s |\n", peer1_addr); puts("+-----------------------------------+ |"); - puts("| q Quit d Dump | 1 Send data to relay adderss |"); + puts("| q Quit d Dump | 1 Send data to relay adderss |"); puts("+-----------------------------------+--------------------------------+"); printf(">>> "); fflush(stdout); @@ -384,7 +387,7 @@ static void console_main(void) pj_pool_factory_dump(&g.cp.factory, PJ_TRUE); break; case 's': - if (g.udp_rel == NULL) { + if (g.relay == NULL) { puts("Error: no relay"); continue; } @@ -394,7 +397,7 @@ static void console_main(void) peer = &g.peer[1]; strcpy(input, "Hello from client"); - status = pj_turn_udp_sendto(g.udp_rel, (const pj_uint8_t*)input, + status = pj_turn_sock_sendto(g.relay, (const pj_uint8_t*)input, strlen(input)+1, &peer->addr, pj_sockaddr_get_len(&peer->addr)); @@ -402,7 +405,7 @@ static void console_main(void) my_perror("turn_udp_sendto() failed", status); break; case 'b': - if (g.udp_rel == NULL) { + if (g.relay == NULL) { puts("Error: no relay"); continue; } @@ -411,13 +414,16 @@ static void console_main(void) else peer = &g.peer[1]; - status = pj_turn_udp_bind_channel(g.udp_rel, &peer->addr, + status = pj_turn_sock_bind_channel(g.relay, &peer->addr, pj_sockaddr_get_len(&peer->addr)); if (status != PJ_SUCCESS) my_perror("turn_udp_bind_channel() failed", status); break; + case 'd': + pj_pool_factory_dump(&g.cp.factory, PJ_TRUE); + break; case 'x': - if (g.udp_rel == NULL) { + if (g.relay == NULL) { puts("Error: no relay"); continue; } @@ -425,7 +431,7 @@ static void console_main(void) break; case '0': case '1': - if (g.udp_rel == NULL) { + if (g.relay == NULL) { puts("No relay"); break; } @@ -450,10 +456,11 @@ static void usage(void) puts("where TARGET is \"host[:port]\""); puts(""); puts("and OPTIONS:"); - puts(" --realm, -r Set realm of the credential"); - puts(" --username, -u Set username of the credential"); - puts(" --password, -p Set password of the credential"); - puts(" --fingerprint, -F Use fingerprint for outgoing requests"); + puts(" --tcp, -T Use TCP to connect to TURN server"); + puts(" --realm, -r REALM Set realm of the credential to REALM"); + puts(" --username, -u UID Set username of the credential to UID"); + puts(" --password, -p PASSWD Set password of the credential to PASSWD"); + puts(" --fingerprint, -F Use fingerprint for outgoing requests"); puts(" --help, -h"); } @@ -464,14 +471,14 @@ int main(int argc, char *argv[]) { "username", 1, 0, 'u'}, { "password", 1, 0, 'p'}, { "fingerprint",0, 0, 'F'}, - { "data", 1, 0, 'D'}, + { "tcp", 0, 0, 'T'}, { "help", 0, 0, 'h'} }; int c, opt_id; char *pos; pj_status_t status; - while((c=pj_getopt_long(argc,argv, "r:u:p:N:hF", long_options, &opt_id))!=-1) { + while((c=pj_getopt_long(argc,argv, "r:u:p:N:hFT", long_options, &opt_id))!=-1) { switch (c) { case 'r': o.realm = pj_optarg; @@ -488,6 +495,9 @@ int main(int argc, char *argv[]) case 'F': o.use_fingerprint = PJ_TRUE; break; + case 'T': + o.use_tcp = PJ_TRUE; + break; default: printf("Argument \"%s\" is not valid. Use -h to see help", diff --git a/pjnath/src/pjturn-srv/allocation.c b/pjnath/src/pjturn-srv/allocation.c index 339b2924..b552bc45 100644 --- a/pjnath/src/pjturn-srv/allocation.c +++ b/pjnath/src/pjturn-srv/allocation.c @@ -65,6 +65,7 @@ static void on_rx_from_peer(pj_ioqueue_key_t *key, pj_ioqueue_op_key_t *op_key, pj_ssize_t bytes_read); static pj_status_t stun_on_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -73,12 +74,14 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_rx_data *rdata, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len); static pj_status_t stun_on_rx_indication(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_msg *msg, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len); @@ -123,7 +126,7 @@ static pj_status_t parse_allocate_req(alloc_request *cfg, if (cfg->bandwidth > MAX_CLIENT_BANDWIDTH) { pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ALLOCATION_QUOTA_REACHED, - "Invalid bandwidth", PJ_TRUE, + "Invalid bandwidth", NULL, PJ_TRUE, src_addr, src_addr_len); return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_ALLOCATION_QUOTA_REACHED); } @@ -134,7 +137,7 @@ static pj_status_t parse_allocate_req(alloc_request *cfg, if (attr_req_tp == NULL) { pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, "Missing REQUESTED-TRANSPORT attribute", - PJ_TRUE, src_addr, src_addr_len); + NULL, PJ_TRUE, src_addr, src_addr_len); return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST); } @@ -143,7 +146,7 @@ static pj_status_t parse_allocate_req(alloc_request *cfg, /* Can only support UDP for now */ if (cfg->tp_type != PJ_TURN_TP_UDP) { pj_stun_session_respond(sess, rdata, PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO, - NULL, PJ_TRUE, src_addr, src_addr_len); + NULL, NULL, PJ_TRUE, src_addr, src_addr_len); return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO); } @@ -155,8 +158,8 @@ static pj_status_t parse_allocate_req(alloc_request *cfg, /* We don't support RESERVATION-TOKEN for now */ pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, - "RESERVATION-TOKEN is not supported", PJ_TRUE, - src_addr, src_addr_len); + "RESERVATION-TOKEN is not supported", NULL, + PJ_TRUE, src_addr, src_addr_len); return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST); } @@ -167,8 +170,8 @@ static pj_status_t parse_allocate_req(alloc_request *cfg, /* We don't support REQUESTED-PROPS for now */ pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, - "REQUESTED-PROPS is not supported", PJ_TRUE, - src_addr, src_addr_len); + "REQUESTED-PROPS is not supported", + NULL, PJ_TRUE, src_addr, src_addr_len); return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST); } @@ -179,8 +182,8 @@ static pj_status_t parse_allocate_req(alloc_request *cfg, cfg->lifetime = attr_lifetime->value; if (cfg->lifetime < MIN_LIFETIME) { pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, - "LIFETIME too short", PJ_TRUE, - src_addr, src_addr_len); + "LIFETIME too short", NULL, + PJ_TRUE, src_addr, src_addr_len); return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST); } if (cfg->lifetime > MAX_LIFETIME) @@ -196,6 +199,7 @@ static pj_status_t parse_allocate_req(alloc_request *cfg, /* Respond to ALLOCATE request */ static pj_status_t send_allocate_response(pj_turn_allocation *alloc, pj_stun_session *srv_sess, + pj_turn_transport *transport, const pj_stun_rx_data *rdata) { pj_stun_tx_data *tdata; @@ -232,8 +236,8 @@ static pj_status_t send_allocate_response(pj_turn_allocation *alloc, pj_sockaddr_get_len(&alloc->hkey.clt_addr)); /* Send the response */ - return pj_stun_session_send_msg(srv_sess, PJ_TRUE, - &alloc->hkey.clt_addr, + return pj_stun_session_send_msg(srv_sess, transport, PJ_TRUE, + PJ_FALSE, &alloc->hkey.clt_addr, pj_sockaddr_get_len(&alloc->hkey.clt_addr), tdata); } @@ -283,14 +287,14 @@ static pj_status_t init_cred(pj_turn_allocation *alloc, const pj_stun_msg *req) /* * Create new allocation. */ -PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_listener *listener, +PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport, const pj_sockaddr_t *src_addr, unsigned src_addr_len, const pj_stun_rx_data *rdata, pj_stun_session *srv_sess, pj_turn_allocation **p_alloc) { - pj_turn_srv *srv = listener->server; + pj_turn_srv *srv = transport->listener->server; const pj_stun_msg *msg = rdata->msg; pj_pool_t *pool; alloc_request req; @@ -310,13 +314,16 @@ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_listener *listener, alloc = PJ_POOL_ZALLOC_T(pool, pj_turn_allocation); alloc->pool = pool; alloc->obj_name = pool->obj_name; - alloc->listener = listener; - alloc->clt_sock = PJ_INVALID_SOCKET; alloc->relay.tp.sock = PJ_INVALID_SOCKET; + alloc->server = transport->listener->server; alloc->bandwidth = req.bandwidth; - alloc->hkey.tp_type = listener->tp_type; + /* Set transport */ + alloc->transport = transport; + pj_turn_transport_add_ref(transport, alloc); + + alloc->hkey.tp_type = transport->listener->tp_type; pj_memcpy(&alloc->hkey.clt_addr, src_addr, src_addr_len); status = pj_lock_create_recursive_mutex(pool, alloc->obj_name, @@ -332,7 +339,8 @@ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_listener *listener, alloc->ch_table = pj_hash_create(pool, PEER_TABLE_SIZE); /* Print info */ - pj_ansi_strcpy(alloc->info, pj_turn_tp_type_name(listener->tp_type)); + pj_ansi_strcpy(alloc->info, + pj_turn_tp_type_name(transport->listener->tp_type)); alloc->info[3] = ':'; pj_sockaddr_print(src_addr, alloc->info+4, sizeof(alloc->info)-4, 3); @@ -370,7 +378,7 @@ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_listener *listener, pj_turn_srv_register_allocation(srv, alloc); /* Respond to ALLOCATE request */ - status = send_allocate_response(alloc, srv_sess, rdata); + status = send_allocate_response(alloc, srv_sess, transport, rdata); if (status != PJ_SUCCESS) goto on_error; @@ -388,7 +396,7 @@ on_error: /* Send reply to the ALLOCATE request */ pj_strerror(status, str_tmp, sizeof(str_tmp)); pj_stun_session_respond(srv_sess, rdata, PJ_STUN_SC_BAD_REQUEST, str_tmp, - PJ_TRUE, src_addr, src_addr_len); + transport, PJ_TRUE, src_addr, src_addr_len); /* Cleanup */ destroy_allocation(alloc); @@ -400,7 +408,7 @@ on_error: static void destroy_relay(pj_turn_relay_res *relay) { if (relay->timer.id) { - pj_timer_heap_cancel(relay->allocation->listener->server->core.timer_heap, + pj_timer_heap_cancel(relay->allocation->server->core.timer_heap, &relay->timer); relay->timer.id = PJ_FALSE; } @@ -427,7 +435,7 @@ static void destroy_allocation(pj_turn_allocation *alloc) pj_pool_t *pool; /* Unregister this allocation */ - pj_turn_srv_unregister_allocation(alloc->listener->server, alloc); + pj_turn_srv_unregister_allocation(alloc->server, alloc); /* Destroy relay */ destroy_relay(&alloc->relay); @@ -437,6 +445,12 @@ static void destroy_allocation(pj_turn_allocation *alloc) pj_lock_acquire(alloc->lock); } + /* Unreference transport */ + if (alloc->transport) { + pj_turn_transport_dec_ref(alloc->transport, alloc); + alloc->transport = NULL; + } + /* Destroy STUN session */ if (alloc->sess) { pj_stun_session_destroy(alloc->sess); @@ -465,6 +479,20 @@ PJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc) } +/* + * Handle transport closure. + */ +PJ_DEF(void) pj_turn_allocation_on_transport_closed( pj_turn_allocation *alloc, + pj_turn_transport *tp) +{ + PJ_LOG(5,(alloc->obj_name, "Transport %s unexpectedly closed, destroying " + "allocation %s", tp->info, alloc->info)); + pj_turn_transport_dec_ref(tp, alloc); + alloc->transport = NULL; + destroy_allocation(alloc); +} + + /* Initiate shutdown sequence for this allocation and start destroy timer. * Once allocation is marked as shutting down, any packets will be * rejected/discarded @@ -476,7 +504,7 @@ static void alloc_shutdown(pj_turn_allocation *alloc) /* Work with existing schedule */ if (alloc->relay.timer.id == TIMER_ID_TIMEOUT) { /* Cancel existing shutdown timer */ - pj_timer_heap_cancel(alloc->listener->server->core.timer_heap, + pj_timer_heap_cancel(alloc->server->core.timer_heap, &alloc->relay.timer); alloc->relay.timer.id = TIMER_ID_NONE; @@ -498,7 +526,7 @@ static void alloc_shutdown(pj_turn_allocation *alloc) /* Schedule destroy timer */ alloc->relay.timer.id = TIMER_ID_DESTROY; - pj_timer_heap_schedule(alloc->listener->server->core.timer_heap, + pj_timer_heap_schedule(alloc->server->core.timer_heap, &alloc->relay.timer, &destroy_delay); } @@ -514,7 +542,7 @@ static pj_status_t resched_timeout(pj_turn_allocation *alloc) pj_assert(alloc->relay.timer.id != TIMER_ID_DESTROY); if (alloc->relay.timer.id != 0) { - pj_timer_heap_cancel(alloc->listener->server->core.timer_heap, + pj_timer_heap_cancel(alloc->server->core.timer_heap, &alloc->relay.timer); alloc->relay.timer.id = TIMER_ID_NONE; } @@ -523,7 +551,7 @@ static pj_status_t resched_timeout(pj_turn_allocation *alloc) delay.msec = 0; alloc->relay.timer.id = TIMER_ID_TIMEOUT; - status = pj_timer_heap_schedule(alloc->listener->server->core.timer_heap, + status = pj_timer_heap_schedule(alloc->server->core.timer_heap, &alloc->relay.timer, &delay); if (status != PJ_SUCCESS) { alloc->relay.timer.id = TIMER_ID_NONE; @@ -589,7 +617,7 @@ static pj_status_t create_relay(pj_turn_srv *srv, relay->tp.sock = PJ_INVALID_SOCKET; /* TODO: get the requested address family from somewhere */ - af = alloc->listener->addr.addr.sa_family; + af = alloc->transport->listener->addr.addr.sa_family; /* Save realm */ sa = (pj_stun_string_attr*) @@ -686,7 +714,8 @@ static pj_status_t create_relay(pj_turn_srv *srv, return status; } if (!pj_sockaddr_has_addr(&relay->hkey.addr)) { - pj_sockaddr_copy_addr(&relay->hkey.addr, &alloc->listener->addr); + pj_sockaddr_copy_addr(&relay->hkey.addr, + &alloc->transport->listener->addr); } if (!pj_sockaddr_has_addr(&relay->hkey.addr)) { pj_sockaddr tmp_addr; @@ -724,8 +753,8 @@ static void send_reply_err(pj_turn_allocation *alloc, { pj_status_t status; - status = pj_stun_session_respond(alloc->sess, rdata, code, errmsg, cache, - &alloc->hkey.clt_addr, + status = pj_stun_session_respond(alloc->sess, rdata, code, errmsg, NULL, + cache, &alloc->hkey.clt_addr, pj_sockaddr_get_len(&alloc->hkey.clt_addr.addr)); if (status != PJ_SUCCESS) { alloc_err(alloc, "Error sending STUN error response", status); @@ -769,8 +798,8 @@ static void send_reply_ok(pj_turn_allocation *alloc, } } - status = pj_stun_session_send_msg(alloc->sess, PJ_TRUE, - &alloc->hkey.clt_addr, + status = pj_stun_session_send_msg(alloc->sess, NULL, PJ_TRUE, + PJ_FALSE, &alloc->hkey.clt_addr, pj_sockaddr_get_len(&alloc->hkey.clt_addr), tdata); if (status != PJ_SUCCESS) { @@ -790,13 +819,6 @@ static pj_turn_permission *create_permission(pj_turn_allocation *alloc, perm = PJ_POOL_ZALLOC_T(alloc->pool, pj_turn_permission); pj_memcpy(&perm->hkey.peer_addr, peer_addr, addr_len); - if (alloc->listener->tp_type == PJ_TURN_TP_UDP) { - perm->sock = alloc->listener->sock; - } else { - pj_assert(!"TCP is not supported yet"); - return NULL; - } - perm->allocation = alloc; perm->channel = PJ_TURN_INVALID_CHANNEL; @@ -900,13 +922,28 @@ PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc, * callbacks. */ unsigned options = PJ_STUN_CHECK_PACKET; - if (pkt->listener->tp_type == PJ_TURN_TP_UDP) + unsigned parsed_len = 0; + + if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) options |= PJ_STUN_IS_DATAGRAM; status = pj_stun_session_on_rx_pkt(alloc->sess, pkt->pkt, pkt->len, - options, NULL, + options, NULL, &parsed_len, &pkt->src.clt_addr, pkt->src_addr_len); + + if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) { + pkt->len = 0; + } else if (parsed_len > 0) { + if (parsed_len == pkt->len) { + pkt->len = 0; + } else { + pj_memmove(pkt->pkt, pkt->pkt+parsed_len, + pkt->len - parsed_len); + pkt->len -= parsed_len; + } + } + if (status != PJ_SUCCESS) { alloc_err(alloc, "Error handling STUN packet", status); goto on_return; @@ -923,7 +960,7 @@ PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc, pj_assert(sizeof(*cd)==4); /* For UDP check the packet length */ - if (alloc->listener->tp_type == PJ_TURN_TP_UDP) { + if (alloc->transport->listener->tp_type == PJ_TURN_TP_UDP) { if (pkt->len < pj_ntohs(cd->length)+sizeof(*cd)) { PJ_LOG(4,(alloc->obj_name, "ChannelData from %s discarded: UDP size error", @@ -1003,10 +1040,10 @@ static void handle_peer_pkt(pj_turn_allocation *alloc, pj_memcpy(rel->tp.tx_pkt+sizeof(pj_turn_channel_data), pkt, len); /* Send to client */ - pj_turn_listener_sendto(alloc->listener, rel->tp.tx_pkt, - len+sizeof(pj_turn_channel_data), 0, - &alloc->hkey.clt_addr, - pj_sockaddr_get_len(&alloc->hkey.clt_addr)); + alloc->transport->sendto(alloc->transport, rel->tp.tx_pkt, + len+sizeof(pj_turn_channel_data), 0, + &alloc->hkey.clt_addr, + pj_sockaddr_get_len(&alloc->hkey.clt_addr)); } else { /* Send Data Indication */ pj_stun_tx_data *tdata; @@ -1026,8 +1063,8 @@ static void handle_peer_pkt(pj_turn_allocation *alloc, PJ_STUN_ATTR_DATA, (const pj_uint8_t*)pkt, len); - pj_stun_session_send_msg(alloc->sess, PJ_FALSE, - &alloc->hkey.clt_addr, + pj_stun_session_send_msg(alloc->sess, NULL, PJ_FALSE, + PJ_FALSE, &alloc->hkey.clt_addr, pj_sockaddr_get_len(&alloc->hkey.clt_addr), tdata); } @@ -1076,6 +1113,7 @@ static void on_rx_from_peer(pj_ioqueue_key_t *key, * a STUN message towards the client. */ static pj_status_t stun_on_send_msg(pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -1083,10 +1121,12 @@ static pj_status_t stun_on_send_msg(pj_stun_session *sess, { pj_turn_allocation *alloc; + PJ_UNUSED_ARG(token); + alloc = (pj_turn_allocation*) pj_stun_session_get_user_data(sess); - return pj_turn_listener_sendto(alloc->listener, pkt, pkt_size, 0, - dst_addr, addr_len); + return alloc->transport->sendto(alloc->transport, pkt, pkt_size, 0, + dst_addr, addr_len); } /* @@ -1098,6 +1138,7 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_rx_data *rdata, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { @@ -1106,6 +1147,7 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess, PJ_UNUSED_ARG(pkt); PJ_UNUSED_ARG(pkt_len); + PJ_UNUSED_ARG(token); PJ_UNUSED_ARG(src_addr); PJ_UNUSED_ARG(src_addr_len); @@ -1274,6 +1316,7 @@ static pj_status_t stun_on_rx_indication(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_msg *msg, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { @@ -1281,9 +1324,11 @@ static pj_status_t stun_on_rx_indication(pj_stun_session *sess, pj_stun_data_attr *data_attr; pj_turn_allocation *alloc; pj_turn_permission *perm; + pj_ssize_t len; PJ_UNUSED_ARG(pkt); PJ_UNUSED_ARG(pkt_len); + PJ_UNUSED_ARG(token); PJ_UNUSED_ARG(src_addr); PJ_UNUSED_ARG(src_addr_len); @@ -1320,15 +1365,11 @@ static pj_status_t stun_on_rx_indication(pj_stun_session *sess, if (data_attr == NULL) return PJ_SUCCESS; - /* Relay the data to client */ - if (alloc->hkey.tp_type == PJ_TURN_TP_UDP) { - pj_ssize_t len = data_attr->length; - pj_sock_sendto(alloc->listener->sock, data_attr->data, - &len, 0, &peer_attr->sockaddr, - pj_sockaddr_get_len(&peer_attr->sockaddr)); - } else { - pj_assert(!"TCP is not supported"); - } + /* Relay the data to peer */ + len = data_attr->length; + pj_sock_sendto(alloc->relay.tp.sock, data_attr->data, + &len, 0, &peer_attr->sockaddr, + pj_sockaddr_get_len(&peer_attr->sockaddr)); return PJ_SUCCESS; } diff --git a/pjnath/src/pjturn-srv/listener_tcp.c b/pjnath/src/pjturn-srv/listener_tcp.c new file mode 100644 index 00000000..e5369e5a --- /dev/null +++ b/pjnath/src/pjturn-srv/listener_tcp.c @@ -0,0 +1,480 @@ +/* $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 "turn.h" +#include <pj/compat/socket.h> + +struct accept_op +{ + pj_ioqueue_op_key_t op_key; + pj_sock_t sock; + pj_sockaddr src_addr; + int src_addr_len; +}; + +struct tcp_listener +{ + pj_turn_listener base; + pj_ioqueue_key_t *key; + unsigned accept_cnt; + struct accept_op *accept_op; /* Array of accept_op's */ +}; + + +static void lis_on_accept_complete(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_sock_t sock, + pj_status_t status); +static pj_status_t lis_destroy(pj_turn_listener *listener); +static void transport_create(pj_sock_t sock, pj_turn_listener *lis, + pj_sockaddr_t *src_addr, int src_addr_len); + +static void show_err(const char *sender, const char *title, + pj_status_t status) +{ + char errmsg[PJ_ERR_MSG_SIZE]; + + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(4,(sender, "%s: %s", title, errmsg)); +} + + +/* + * Create a new listener on the specified port. + */ +PJ_DEF(pj_status_t) pj_turn_listener_create_tcp(pj_turn_srv *srv, + int af, + const pj_str_t *bound_addr, + unsigned port, + unsigned concurrency_cnt, + unsigned flags, + pj_turn_listener **p_listener) +{ + pj_pool_t *pool; + struct tcp_listener *tcp_lis; + pj_ioqueue_callback ioqueue_cb; + unsigned i; + pj_status_t status; + + /* Create structure */ + pool = pj_pool_create(srv->core.pf, "tcpl%p", 1000, 1000, NULL); + tcp_lis = PJ_POOL_ZALLOC_T(pool, struct tcp_listener); + tcp_lis->base.pool = pool; + tcp_lis->base.obj_name = pool->obj_name; + tcp_lis->base.server = srv; + tcp_lis->base.tp_type = PJ_TURN_TP_TCP; + tcp_lis->base.sock = PJ_INVALID_SOCKET; + //tcp_lis->base.sendto = &tcp_sendto; + tcp_lis->base.destroy = &lis_destroy; + tcp_lis->accept_cnt = concurrency_cnt; + tcp_lis->base.flags = flags; + + /* Create socket */ + status = pj_sock_socket(af, pj_SOCK_STREAM(), 0, &tcp_lis->base.sock); + if (status != PJ_SUCCESS) + goto on_error; + + /* Init bind address */ + status = pj_sockaddr_init(af, &tcp_lis->base.addr, bound_addr, + (pj_uint16_t)port); + if (status != PJ_SUCCESS) + goto on_error; + + /* Create info */ + pj_ansi_strcpy(tcp_lis->base.info, "TCP:"); + pj_sockaddr_print(&tcp_lis->base.addr, tcp_lis->base.info+4, + sizeof(tcp_lis->base.info)-4, 3); + + /* Bind socket */ + status = pj_sock_bind(tcp_lis->base.sock, &tcp_lis->base.addr, + pj_sockaddr_get_len(&tcp_lis->base.addr)); + if (status != PJ_SUCCESS) + goto on_error; + + /* Listen() */ + status = pj_sock_listen(tcp_lis->base.sock, 5); + if (status != PJ_SUCCESS) + goto on_error; + + /* Register to ioqueue */ + pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb)); + ioqueue_cb.on_accept_complete = &lis_on_accept_complete; + status = pj_ioqueue_register_sock(pool, srv->core.ioqueue, tcp_lis->base.sock, + tcp_lis, &ioqueue_cb, &tcp_lis->key); + + /* Create op keys */ + tcp_lis->accept_op = (struct accept_op*)pj_pool_calloc(pool, concurrency_cnt, + sizeof(struct accept_op)); + + /* Create each accept_op and kick off read operation */ + for (i=0; i<concurrency_cnt; ++i) { + lis_on_accept_complete(tcp_lis->key, &tcp_lis->accept_op[i].op_key, + PJ_INVALID_SOCKET, PJ_EPENDING); + } + + /* Done */ + PJ_LOG(4,(tcp_lis->base.obj_name, "Listener %s created", + tcp_lis->base.info)); + + *p_listener = &tcp_lis->base; + return PJ_SUCCESS; + + +on_error: + lis_destroy(&tcp_lis->base); + return status; +} + + +/* + * Destroy listener. + */ +static pj_status_t lis_destroy(pj_turn_listener *listener) +{ + struct tcp_listener *tcp_lis = (struct tcp_listener *)listener; + unsigned i; + + if (tcp_lis->key) { + pj_ioqueue_unregister(tcp_lis->key); + tcp_lis->key = NULL; + tcp_lis->base.sock = PJ_INVALID_SOCKET; + } else if (tcp_lis->base.sock != PJ_INVALID_SOCKET) { + pj_sock_close(tcp_lis->base.sock); + tcp_lis->base.sock = PJ_INVALID_SOCKET; + } + + for (i=0; i<tcp_lis->accept_cnt; ++i) { + /* Nothing to do */ + } + + if (tcp_lis->base.pool) { + pj_pool_t *pool = tcp_lis->base.pool; + + PJ_LOG(4,(tcp_lis->base.obj_name, "Listener %s destroyed", + tcp_lis->base.info)); + + tcp_lis->base.pool = NULL; + pj_pool_release(pool); + } + return PJ_SUCCESS; +} + + +/* + * Callback on new TCP connection. + */ +static void lis_on_accept_complete(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_sock_t sock, + pj_status_t status) +{ + struct tcp_listener *tcp_lis; + struct accept_op *accept_op = (struct accept_op*) op_key; + + tcp_lis = (struct tcp_listener*) pj_ioqueue_get_user_data(key); + + PJ_UNUSED_ARG(sock); + + do { + /* Report new connection. */ + if (status == PJ_SUCCESS) { + char addr[PJ_INET6_ADDRSTRLEN+8]; + PJ_LOG(5,(tcp_lis->base.obj_name, "Incoming TCP from %s", + pj_sockaddr_print(&accept_op->src_addr, addr, + sizeof(addr), 3))); + transport_create(accept_op->sock, &tcp_lis->base, + &accept_op->src_addr, accept_op->src_addr_len); + } else if (status != PJ_EPENDING) { + show_err(tcp_lis->base.obj_name, "accept()", status); + } + + /* Prepare next accept() */ + accept_op->src_addr_len = sizeof(accept_op->src_addr); + status = pj_ioqueue_accept(key, op_key, &accept_op->sock, + NULL, + &accept_op->src_addr, + &accept_op->src_addr_len); + + } while (status != PJ_EPENDING && status != PJ_ECANCELLED && + status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL)); +} + + +/****************************************************************************/ +/* + * Transport + */ +enum +{ + TIMER_NONE, + TIMER_DESTROY +}; + +/* The delay in seconds to be applied before TCP transport is destroyed when + * no allocation is referencing it. This also means the initial time to wait + * after the initial TCP connection establishment to receive a valid STUN + * message in the transport. + */ +#define SHUTDOWN_DELAY 10 + +struct recv_op +{ + pj_ioqueue_op_key_t op_key; + pj_turn_pkt pkt; +}; + +struct tcp_transport +{ + pj_turn_transport base; + pj_pool_t *pool; + pj_timer_entry timer; + + pj_turn_allocation *alloc; + int ref_cnt; + + pj_sock_t sock; + pj_ioqueue_key_t *key; + struct recv_op recv_op; + pj_ioqueue_op_key_t send_op; +}; + + +static void tcp_on_read_complete(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_read); + +static pj_status_t tcp_sendto(pj_turn_transport *tp, + const void *packet, + pj_size_t size, + unsigned flag, + const pj_sockaddr_t *addr, + int addr_len); +static void tcp_destroy(struct tcp_transport *tcp); +static void tcp_add_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc); +static void tcp_dec_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc); +static void timer_callback(pj_timer_heap_t *timer_heap, + pj_timer_entry *entry); + +static void transport_create(pj_sock_t sock, pj_turn_listener *lis, + pj_sockaddr_t *src_addr, int src_addr_len) +{ + pj_pool_t *pool; + struct tcp_transport *tcp; + pj_ioqueue_callback cb; + pj_status_t status; + + pool = pj_pool_create(lis->server->core.pf, "tcp%p", 1000, 1000, NULL); + + tcp = PJ_POOL_ZALLOC_T(pool, struct tcp_transport); + tcp->base.obj_name = pool->obj_name; + tcp->base.listener = lis; + tcp->base.info = lis->info; + tcp->base.sendto = &tcp_sendto; + tcp->base.add_ref = &tcp_add_ref; + tcp->base.dec_ref = &tcp_dec_ref; + tcp->pool = pool; + tcp->sock = sock; + + pj_timer_entry_init(&tcp->timer, TIMER_NONE, tcp, &timer_callback); + + /* Register to ioqueue */ + pj_bzero(&cb, sizeof(cb)); + cb.on_read_complete = &tcp_on_read_complete; + status = pj_ioqueue_register_sock(pool, lis->server->core.ioqueue, sock, + tcp, &cb, &tcp->key); + if (status != PJ_SUCCESS) { + tcp_destroy(tcp); + return; + } + + /* Init pkt */ + tcp->recv_op.pkt.pool = pj_pool_create(lis->server->core.pf, "tcpkt%p", + 1000, 1000, NULL); + tcp->recv_op.pkt.transport = &tcp->base; + tcp->recv_op.pkt.src.tp_type = PJ_TURN_TP_TCP; + tcp->recv_op.pkt.src_addr_len = src_addr_len; + pj_memcpy(&tcp->recv_op.pkt.src.clt_addr, src_addr, src_addr_len); + + tcp_on_read_complete(tcp->key, &tcp->recv_op.op_key, -PJ_EPENDING); + /* Should not access transport from now, it may have been destroyed */ +} + + +static void tcp_destroy(struct tcp_transport *tcp) +{ + if (tcp->key) { + pj_ioqueue_unregister(tcp->key); + tcp->key = NULL; + tcp->sock = 0; + } else if (tcp->sock) { + pj_sock_close(tcp->sock); + tcp->sock = 0; + } + + if (tcp->pool) { + pj_pool_release(tcp->pool); + } +} + + +static void timer_callback(pj_timer_heap_t *timer_heap, + pj_timer_entry *entry) +{ + struct tcp_transport *tcp = (struct tcp_transport*) entry->user_data; + + PJ_UNUSED_ARG(timer_heap); + + tcp_destroy(tcp); +} + + +static void tcp_on_read_complete(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_read) +{ + struct tcp_transport *tcp; + struct recv_op *recv_op = (struct recv_op*) op_key; + pj_status_t status; + + tcp = (struct tcp_transport*) pj_ioqueue_get_user_data(key); + + do { + /* Report to server or allocation, if we have allocation */ + if (bytes_read > 0) { + + recv_op->pkt.len = bytes_read; + pj_gettimeofday(&recv_op->pkt.rx_time); + + tcp_add_ref(&tcp->base, NULL); + + if (tcp->alloc) { + pj_turn_allocation_on_rx_client_pkt(tcp->alloc, &recv_op->pkt); + } else { + pj_turn_srv_on_rx_pkt(tcp->base.listener->server, &recv_op->pkt); + } + + pj_assert(tcp->ref_cnt > 0); + tcp_dec_ref(&tcp->base, NULL); + + } else if (bytes_read != -PJ_EPENDING) { + /* TCP connection closed/error. Notify client and then destroy + * ourselves. + * Note: the -PJ_EPENDING is the value passed during init. + */ + ++tcp->ref_cnt; + + if (tcp->alloc) { + if (bytes_read != 0) { + show_err(tcp->base.obj_name, "TCP socket error", + -bytes_read); + } else { + PJ_LOG(5,(tcp->base.obj_name, "TCP socket closed")); + } + pj_turn_allocation_on_transport_closed(tcp->alloc, &tcp->base); + tcp->alloc = NULL; + } + + pj_assert(tcp->ref_cnt > 0); + if (--tcp->ref_cnt == 0) { + tcp_destroy(tcp); + return; + } + } + + /* Reset pool */ + pj_pool_reset(recv_op->pkt.pool); + + /* If packet is full discard it */ + if (recv_op->pkt.len == sizeof(recv_op->pkt.pkt)) { + PJ_LOG(4,(tcp->base.obj_name, "Buffer discarded")); + recv_op->pkt.len = 0; + } + + /* Read next packet */ + bytes_read = sizeof(recv_op->pkt.pkt) - recv_op->pkt.len; + status = pj_ioqueue_recv(tcp->key, op_key, + recv_op->pkt.pkt + recv_op->pkt.len, + &bytes_read, 0); + + if (status != PJ_EPENDING && status != PJ_SUCCESS) + bytes_read = -status; + + } while (status != PJ_EPENDING && status != PJ_ECANCELLED && + status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL)); + +} + + +static pj_status_t tcp_sendto(pj_turn_transport *tp, + const void *packet, + pj_size_t size, + unsigned flag, + const pj_sockaddr_t *addr, + int addr_len) +{ + struct tcp_transport *tcp = (struct tcp_transport*) tp; + pj_ssize_t length = size; + + PJ_UNUSED_ARG(addr); + PJ_UNUSED_ARG(addr_len); + + return pj_ioqueue_send(tcp->key, &tcp->send_op, packet, &length, flag); +} + + +static void tcp_add_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc) +{ + struct tcp_transport *tcp = (struct tcp_transport*) tp; + + ++tcp->ref_cnt; + + if (tcp->alloc == NULL && alloc) { + tcp->alloc = alloc; + } + + /* Cancel shutdown timer if it's running */ + if (tcp->timer.id != TIMER_NONE) { + pj_timer_heap_cancel(tcp->base.listener->server->core.timer_heap, + &tcp->timer); + tcp->timer.id = TIMER_NONE; + } +} + + +static void tcp_dec_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc) +{ + struct tcp_transport *tcp = (struct tcp_transport*) tp; + + --tcp->ref_cnt; + + if (alloc && alloc == tcp->alloc) { + tcp->alloc = NULL; + } + + if (tcp->ref_cnt == 0 && tcp->timer.id == TIMER_NONE) { + pj_time_val delay = { SHUTDOWN_DELAY, 0 }; + tcp->timer.id = TIMER_DESTROY; + pj_timer_heap_schedule(tcp->base.listener->server->core.timer_heap, + &tcp->timer, &delay); + } +} + diff --git a/pjnath/src/pjturn-srv/listener_udp.c b/pjnath/src/pjturn-srv/listener_udp.c index b634d092..2c0eccdc 100644 --- a/pjnath/src/pjturn-srv/listener_udp.c +++ b/pjnath/src/pjturn-srv/listener_udp.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "turn.h" +#include <pj/compat/socket.h> struct read_op { @@ -27,22 +28,30 @@ struct read_op struct udp_listener { pj_turn_listener base; + pj_ioqueue_key_t *key; unsigned read_cnt; struct read_op **read_op; /* Array of read_op's */ + + pj_turn_transport tp; /* Transport instance */ }; -static pj_status_t udp_sendto(pj_turn_listener *listener, +static pj_status_t udp_destroy(pj_turn_listener *udp); +static void on_read_complete(pj_ioqueue_key_t *key, + pj_ioqueue_op_key_t *op_key, + pj_ssize_t bytes_read); + +static pj_status_t udp_sendto(pj_turn_transport *tp, const void *packet, pj_size_t size, unsigned flag, const pj_sockaddr_t *addr, int addr_len); -static pj_status_t udp_destroy(pj_turn_listener *udp); -static void on_read_complete(pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_ssize_t bytes_read); +static void udp_add_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc); +static void udp_dec_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc); /* @@ -70,11 +79,17 @@ PJ_DEF(pj_status_t) pj_turn_listener_create_udp( pj_turn_srv *srv, udp->base.server = srv; udp->base.tp_type = PJ_TURN_TP_UDP; udp->base.sock = PJ_INVALID_SOCKET; - udp->base.sendto = &udp_sendto; udp->base.destroy = &udp_destroy; udp->read_cnt = concurrency_cnt; udp->base.flags = flags; + udp->tp.obj_name = udp->base.obj_name; + udp->tp.info = udp->base.info; + udp->tp.listener = &udp->base; + udp->tp.sendto = &udp_sendto; + udp->tp.add_ref = &udp_add_ref; + udp->tp.dec_ref = &udp_dec_ref; + /* Create socket */ status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &udp->base.sock); if (status != PJ_SUCCESS) @@ -172,7 +187,7 @@ static pj_status_t udp_destroy(pj_turn_listener *listener) /* * Callback to send packet. */ -static pj_status_t udp_sendto(pj_turn_listener *listener, +static pj_status_t udp_sendto(pj_turn_transport *tp, const void *packet, pj_size_t size, unsigned flag, @@ -180,9 +195,27 @@ static pj_status_t udp_sendto(pj_turn_listener *listener, int addr_len) { pj_ssize_t len = size; - return pj_sock_sendto(listener->sock, packet, &len, flag, addr, addr_len); + return pj_sock_sendto(tp->listener->sock, packet, &len, flag, addr, addr_len); +} + + +static void udp_add_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc) +{ + /* Do nothing */ + PJ_UNUSED_ARG(tp); + PJ_UNUSED_ARG(alloc); } +static void udp_dec_ref(pj_turn_transport *tp, + pj_turn_allocation *alloc) +{ + /* Do nothing */ + PJ_UNUSED_ARG(tp); + PJ_UNUSED_ARG(alloc); +} + + /* * Callback on received packet. */ @@ -211,7 +244,7 @@ static void on_read_complete(pj_ioqueue_key_t *key, rpool = read_op->pkt.pool; pj_pool_reset(rpool); read_op->pkt.pool = rpool; - read_op->pkt.listener = &udp->base; + read_op->pkt.transport = &udp->tp; read_op->pkt.src.tp_type = udp->base.tp_type; /* Read next packet */ @@ -227,6 +260,7 @@ static void on_read_complete(pj_ioqueue_key_t *key, if (status != PJ_EPENDING && status != PJ_SUCCESS) bytes_read = -status; - } while (status != PJ_EPENDING && status != PJ_ECANCELLED); + } while (status != PJ_EPENDING && status != PJ_ECANCELLED && + status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL)); } diff --git a/pjnath/src/pjturn-srv/main.c b/pjnath/src/pjturn-srv/main.c index 348ad3db..4ebdcde8 100644 --- a/pjnath/src/pjturn-srv/main.c +++ b/pjnath/src/pjturn-srv/main.c @@ -140,6 +140,11 @@ int main() status = pj_turn_listener_create_udp(srv, pj_AF_INET(), NULL, PJ_STUN_PORT, 1, 0, &listener); if (status != PJ_SUCCESS) + return err("Error creating UDP listener", status); + + status = pj_turn_listener_create_tcp(srv, pj_AF_INET(), NULL, + PJ_STUN_PORT, 1, 0, &listener); + if (status != PJ_SUCCESS) return err("Error creating listener", status); status = pj_turn_srv_add_listener(srv, listener); diff --git a/pjnath/src/pjturn-srv/server.c b/pjnath/src/pjturn-srv/server.c index 66f1c6a7..17ded7b0 100644 --- a/pjnath/src/pjturn-srv/server.c +++ b/pjnath/src/pjturn-srv/server.c @@ -28,11 +28,12 @@ #define MAX_PORT 65535 #define MAX_LISTENERS 16 #define MAX_THREADS 2 -#define MAX_NET_EVENTS 10 +#define MAX_NET_EVENTS 1000 /* Prototypes */ static int server_thread_proc(void *arg); static pj_status_t on_tx_stun_msg( pj_stun_session *sess, + void *token, const void *pkt, pj_size_t pkt_size, const pj_sockaddr_t *dst_addr, @@ -41,6 +42,7 @@ static pj_status_t on_rx_stun_request(pj_stun_session *sess, const pj_uint8_t *pkt, unsigned pkt_len, const pj_stun_rx_data *rdata, + void *user_data, const pj_sockaddr_t *src_addr, unsigned src_addr_len); @@ -77,6 +79,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf, pj_turn_srv **p_srv) { pj_pool_t *pool; + pj_stun_session_cb sess_cb; pj_turn_srv *srv; unsigned i; pj_status_t status; @@ -124,11 +127,6 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf, pj_pool_calloc(pool, MAX_LISTENERS, sizeof(srv->core.listener[0])); - /* Array of STUN sessions, one for each listener */ - srv->core.stun_sess = (pj_stun_session**) - pj_pool_calloc(pool, MAX_LISTENERS, - (sizeof(srv->core.stun_sess[0]))); - /* Create hash tables */ srv->tables.alloc = pj_hash_create(pool, MAX_CLIENTS); srv->tables.res = pj_hash_create(pool, MAX_CLIENTS); @@ -150,6 +148,22 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf, srv->core.cred.data.dyn_cred.get_password = &pj_turn_get_password; srv->core.cred.data.dyn_cred.verify_nonce = &pj_turn_verify_nonce; + /* Create STUN session to handle new allocation */ + pj_bzero(&sess_cb, sizeof(sess_cb)); + sess_cb.on_rx_request = &on_rx_stun_request; + sess_cb.on_send_msg = &on_tx_stun_msg; + + status = pj_stun_session_create(&srv->core.stun_cfg, srv->obj_name, + &sess_cb, PJ_FALSE, &srv->core.stun_sess); + if (status != PJ_SUCCESS) { + goto on_error; + } + + pj_stun_session_set_user_data(srv->core.stun_sess, srv); + pj_stun_session_set_credential(srv->core.stun_sess, PJ_STUN_AUTH_LONG_TERM, + &srv->core.cred); + + /* Array of worker threads */ srv->core.thread_cnt = MAX_THREADS; srv->core.thread = (pj_thread_t**) @@ -240,7 +254,7 @@ static int server_thread_proc(void *arg) pj_turn_srv *srv = (pj_turn_srv*)arg; while (!srv->core.quit) { - pj_time_val timeout_max = {0, 500}; + pj_time_val timeout_max = {0, 100}; srv_handle_events(srv, &timeout_max); } @@ -277,16 +291,18 @@ PJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv) } } - /* Destroy all listeners and STUN sessions associated with them. */ + /* Destroy all listeners. */ for (i=0; i<srv->core.lis_cnt; ++i) { if (srv->core.listener[i]) { pj_turn_listener_destroy(srv->core.listener[i]); srv->core.listener[i] = NULL; } - if (srv->core.stun_sess[i]) { - pj_stun_session_destroy(srv->core.stun_sess[i]); - srv->core.stun_sess[i] = NULL; - } + } + + /* Destroy STUN session */ + if (srv->core.stun_sess) { + pj_stun_session_destroy(srv->core.stun_sess); + srv->core.stun_sess = NULL; } /* Destroy hash tables (well, sort of) */ @@ -341,10 +357,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv) PJ_DEF(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv, pj_turn_listener *lis) { - pj_stun_session_cb sess_cb; unsigned index; - pj_stun_session *sess; - pj_status_t status; PJ_ASSERT_RETURN(srv && lis, PJ_EINVAL); PJ_ASSERT_RETURN(srv->core.lis_cnt < MAX_LISTENERS, PJ_ETOOMANY); @@ -353,24 +366,6 @@ PJ_DEF(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv, index = srv->core.lis_cnt; srv->core.listener[index] = lis; lis->server = srv; - - /* Create STUN session to handle new allocation */ - pj_bzero(&sess_cb, sizeof(sess_cb)); - sess_cb.on_rx_request = &on_rx_stun_request; - sess_cb.on_send_msg = &on_tx_stun_msg; - - status = pj_stun_session_create(&srv->core.stun_cfg, lis->obj_name, - &sess_cb, PJ_FALSE, &sess); - if (status != PJ_SUCCESS) { - srv->core.listener[index] = NULL; - return status; - } - - pj_stun_session_set_user_data(sess, lis); - pj_stun_session_set_credential(sess, PJ_STUN_AUTH_LONG_TERM, - &srv->core.cred); - - srv->core.stun_sess[index] = sess; lis->id = index; srv->core.lis_cnt++; @@ -382,21 +377,6 @@ PJ_DEF(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv, /* - * Send packet with this listener. - */ -PJ_DEF(pj_status_t) pj_turn_listener_sendto(pj_turn_listener *listener, - const void *packet, - pj_size_t size, - unsigned flag, - const pj_sockaddr_t *addr, - int addr_len) -{ - pj_assert(listener->id != PJ_TURN_INVALID_LIS_ID); - return listener->sendto(listener, packet, size, flag, addr, addr_len); -} - - -/* * Destroy listener. */ PJ_DEF(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener) @@ -411,10 +391,6 @@ PJ_DEF(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener) srv->core.listener[i] = NULL; srv->core.lis_cnt--; listener->id = PJ_TURN_INVALID_LIS_ID; - if (srv->core.stun_sess[i]) { - pj_stun_session_destroy(srv->core.stun_sess[i]); - srv->core.stun_sess[i] = NULL; - } break; } } @@ -425,6 +401,26 @@ PJ_DEF(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener) } +/** + * Add a reference to a transport. + */ +PJ_DEF(void) pj_turn_transport_add_ref( pj_turn_transport *transport, + pj_turn_allocation *alloc) +{ + transport->add_ref(transport, alloc); +} + + +/** + * Decrement transport reference counter. + */ +PJ_DEF(void) pj_turn_transport_dec_ref( pj_turn_transport *transport, + pj_turn_allocation *alloc) +{ + transport->dec_ref(transport, alloc); +} + + /* * Register an allocation to the hash tables. */ @@ -466,24 +462,26 @@ PJ_DEF(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv, * outgoing STUN packet. */ static pj_status_t on_tx_stun_msg( pj_stun_session *sess, - const void *pkt, - pj_size_t pkt_size, + void *token, + const void *pdu, + pj_size_t pdu_size, const pj_sockaddr_t *dst_addr, unsigned addr_len) { - pj_turn_listener *listener; + pj_turn_transport *transport = (pj_turn_transport*) token; - listener = (pj_turn_listener*) pj_stun_session_get_user_data(sess); + PJ_ASSERT_RETURN(transport!=NULL, PJ_EINVALIDOP); - PJ_ASSERT_RETURN(listener!=NULL, PJ_EINVALIDOP); + PJ_UNUSED_ARG(sess); - return pj_turn_listener_sendto(listener, pkt, pkt_size, 0, - dst_addr, addr_len); + return transport->sendto(transport, pdu, pdu_size, 0, + dst_addr, addr_len); } /* Respond to STUN request */ static pj_status_t stun_respond(pj_stun_session *sess, + pj_turn_transport *transport, const pj_stun_rx_data *rdata, unsigned code, const char *errmsg, @@ -503,36 +501,38 @@ static pj_status_t stun_respond(pj_stun_session *sess, return status; /* Send the response */ - return pj_stun_session_send_msg(sess, cache, dst_addr, addr_len, tdata); + return pj_stun_session_send_msg(sess, transport, cache, PJ_FALSE, + dst_addr, addr_len, tdata); } /* Callback from our own STUN session when incoming request arrives. * This function is triggered by pj_stun_session_on_rx_pkt() call in - * pj_turn_srv_on_rx_pkt() function below. + * pj_turn_srv_on_rx_pkt() function below. */ static pj_status_t on_rx_stun_request(pj_stun_session *sess, - const pj_uint8_t *pkt, - unsigned pkt_len, + const pj_uint8_t *pdu, + unsigned pdu_len, const pj_stun_rx_data *rdata, + void *token, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { - pj_turn_listener *listener; + pj_turn_transport *transport; const pj_stun_msg *msg = rdata->msg; pj_turn_srv *srv; pj_turn_allocation *alloc; pj_status_t status; - PJ_UNUSED_ARG(pkt); - PJ_UNUSED_ARG(pkt_len); + PJ_UNUSED_ARG(pdu); + PJ_UNUSED_ARG(pdu_len); - listener = (pj_turn_listener*) pj_stun_session_get_user_data(sess); - srv = listener->server; + transport = (pj_turn_transport*) token; + srv = transport->listener->server; /* Respond any requests other than ALLOCATE with 437 response */ if (msg->hdr.type != PJ_STUN_ALLOCATE_REQUEST) { - stun_respond(sess, rdata, PJ_STUN_SC_ALLOCATION_MISMATCH, + stun_respond(sess, transport, rdata, PJ_STUN_SC_ALLOCATION_MISMATCH, NULL, PJ_FALSE, src_addr, src_addr_len); return PJ_SUCCESS; } @@ -540,7 +540,7 @@ static pj_status_t on_rx_stun_request(pj_stun_session *sess, /* Create new allocation. The relay resource will be allocated * in this function. */ - status = pj_turn_allocation_create(listener, src_addr, src_addr_len, + status = pj_turn_allocation_create(transport, src_addr, src_addr_len, rdata, sess, &alloc); if (status != PJ_SUCCESS) { /* STUN response has been sent, no need to reply here */ @@ -576,37 +576,53 @@ PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv, pj_turn_allocation_on_rx_client_pkt(alloc, pkt); } else { /* Otherwise this is a new client */ - unsigned options, lis_id; + unsigned options; + unsigned parsed_len; pj_status_t status; /* Check that this is a STUN message */ options = PJ_STUN_CHECK_PACKET; - if (pkt->listener->tp_type == PJ_TURN_TP_UDP) + if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) options |= PJ_STUN_IS_DATAGRAM; status = pj_stun_msg_check(pkt->pkt, pkt->len, options); if (status != PJ_SUCCESS) { - char errmsg[PJ_ERR_MSG_SIZE]; - char ip[PJ_INET6_ADDRSTRLEN+10]; - - pj_strerror(status, errmsg, sizeof(errmsg)); - PJ_LOG(5,(srv->obj_name, - "Non STUN packet from %s is dropped: %s", - pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3), - errmsg)); + /* If the first byte are not STUN, drop the packet. First byte + * of STUN message is always 0x00 or 0x01. Otherwise wait for + * more data as the data might have come from TCP. + * + * Also drop packet if it's unreasonably too big, as this might + * indicate invalid data that's building up in the buffer. + * + * Or if packet is a datagram. + */ + if ((*pkt->pkt != 0x00 && *pkt->pkt != 0x01) || + pkt->len > 1600 || + (options & PJ_STUN_IS_DATAGRAM)) + { + char errmsg[PJ_ERR_MSG_SIZE]; + char ip[PJ_INET6_ADDRSTRLEN+10]; + + pkt->len = 0; + + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(5,(srv->obj_name, + "Non-STUN packet from %s is dropped: %s", + pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3), + errmsg)); + } return; } - lis_id = pkt->listener->id; - /* Hand over processing to STUN session. This will trigger * on_rx_stun_request() callback to be called if the STUN * message is a request. */ options &= ~PJ_STUN_CHECK_PACKET; - status = pj_stun_session_on_rx_pkt(srv->core.stun_sess[lis_id], - pkt->pkt, pkt->len, options, NULL, - &pkt->src.clt_addr, + parsed_len = 0; + status = pj_stun_session_on_rx_pkt(srv->core.stun_sess, pkt->pkt, + pkt->len, options, pkt->transport, + &parsed_len, &pkt->src.clt_addr, pkt->src_addr_len); if (status != PJ_SUCCESS) { char errmsg[PJ_ERR_MSG_SIZE]; @@ -617,7 +633,18 @@ PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv, "Error processing STUN packet from %s: %s", pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3), errmsg)); - return; + } + + if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) { + pkt->len = 0; + } else if (parsed_len > 0) { + if (parsed_len == pkt->len) { + pkt->len = 0; + } else { + pj_memmove(pkt->pkt, pkt->pkt+parsed_len, + pkt->len - parsed_len); + pkt->len -= parsed_len; + } } } } diff --git a/pjnath/src/pjturn-srv/turn.h b/pjnath/src/pjturn-srv/turn.h index 337e8746..ae9cc590 100644 --- a/pjnath/src/pjturn-srv/turn.h +++ b/pjnath/src/pjturn-srv/turn.h @@ -22,10 +22,11 @@ #include <pjlib.h> #include <pjnath.h> -typedef struct pj_turn_relay_res pj_turn_relay_res; +typedef struct pj_turn_relay_res pj_turn_relay_res; typedef struct pj_turn_listener pj_turn_listener; -typedef struct pj_turn_permission pj_turn_permission; -typedef struct pj_turn_allocation pj_turn_allocation; +typedef struct pj_turn_transport pj_turn_transport; +typedef struct pj_turn_permission pj_turn_permission; +typedef struct pj_turn_allocation pj_turn_allocation; typedef struct pj_turn_srv pj_turn_srv; typedef struct pj_turn_pkt pj_turn_pkt; @@ -132,11 +133,11 @@ struct pj_turn_allocation /** Mutex */ pj_lock_t *lock; - /** TURN listener. */ - pj_turn_listener *listener; + /** Server instance. */ + pj_turn_srv *server; - /** Client socket, if connection to client is using TCP. */ - pj_sock_t clt_sock; + /** Transport to send/receive packets to/from client. */ + pj_turn_transport *transport; /** The relay resource for this allocation. */ pj_turn_relay_res relay; @@ -181,11 +182,6 @@ struct pj_turn_permission /** Hash table key */ pj_turn_permission_key hkey; - /** Transport socket. If TCP is used, the value will be the actual - * TCP socket. If UDP is used, the value will be the relay address - */ - pj_sock_t sock; - /** TURN allocation that owns this permission/channel */ pj_turn_allocation *allocation; @@ -201,12 +197,12 @@ struct pj_turn_permission /** * Create new allocation. */ -PJ_DECL(pj_status_t) pj_turn_allocation_create(pj_turn_listener *listener, - const pj_sockaddr_t *src_addr, - unsigned src_addr_len, - const pj_stun_rx_data *rdata, - pj_stun_session *srv_sess, - pj_turn_allocation **p_alloc); +PJ_DECL(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport, + const pj_sockaddr_t *src_addr, + unsigned src_addr_len, + const pj_stun_rx_data *rdata, + pj_stun_session *srv_sess, + pj_turn_allocation **p_alloc); /** * Destroy allocation. */ @@ -217,7 +213,13 @@ PJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc); * Handle incoming packet from client. */ PJ_DECL(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc, - pj_turn_pkt *pkt); + pj_turn_pkt *pkt); + +/** + * Handle transport closure. + */ +PJ_DECL(void) pj_turn_allocation_on_transport_closed(pj_turn_allocation *alloc, + pj_turn_transport *tp); /****************************************************************************/ /* @@ -257,16 +259,42 @@ struct pj_turn_listener /** Flags. */ unsigned flags; + /** Destroy handler */ + pj_status_t (*destroy)(pj_turn_listener*); +}; + + +/** + * This structure describes TURN transport socket which is used to send and + * receive packets towards client. + */ +struct pj_turn_transport +{ + /** Object name/identification */ + char *obj_name; + + /** Slightly longer info about this listener */ + char *info; + + /** Listener instance */ + pj_turn_listener *listener; + /** Sendto handler */ - pj_status_t (*sendto)(pj_turn_listener *listener, + pj_status_t (*sendto)(pj_turn_transport *tp, const void *packet, pj_size_t size, unsigned flag, const pj_sockaddr_t *addr, int addr_len); - /** Destroy handler */ - pj_status_t (*destroy)(pj_turn_listener*); + /** Addref handler */ + void (*add_ref)(pj_turn_transport *tp, + pj_turn_allocation *alloc); + + /** Decref handler */ + void (*dec_ref)(pj_turn_transport *tp, + pj_turn_allocation *alloc); + }; @@ -278,8 +306,8 @@ struct pj_turn_pkt /** Pool for this packet */ pj_pool_t *pool; - /** Listener that owns this. */ - pj_turn_listener *listener; + /** Transport where the packet was received. */ + pj_turn_transport *transport; /** Packet buffer (must be 32bit aligned). */ pj_uint8_t pkt[PJ_TURN_MAX_PKT_LEN]; @@ -299,25 +327,26 @@ struct pj_turn_pkt /** - * Create a new listener on the specified port. + * Create a UDP listener on the specified port. */ PJ_DECL(pj_status_t) pj_turn_listener_create_udp(pj_turn_srv *srv, - int af, - const pj_str_t *bound_addr, - unsigned port, - unsigned concurrency_cnt, - unsigned flags, - pj_turn_listener **p_listener); + int af, + const pj_str_t *bound_addr, + unsigned port, + unsigned concurrency_cnt, + unsigned flags, + pj_turn_listener **p_lis); /** - * Send packet with this listener. + * Create a TCP listener on the specified port. */ -PJ_DECL(pj_status_t) pj_turn_listener_sendto(pj_turn_listener *listener, - const void *packet, - pj_size_t size, - unsigned flag, - const pj_sockaddr_t *addr, - int addr_len); +PJ_DECL(pj_status_t) pj_turn_listener_create_tcp(pj_turn_srv *srv, + int af, + const pj_str_t *bound_addr, + unsigned port, + unsigned concurrency_cnt, + unsigned flags, + pj_turn_listener **p_lis); /** * Destroy listener. @@ -325,6 +354,21 @@ PJ_DECL(pj_status_t) pj_turn_listener_sendto(pj_turn_listener *listener, PJ_DECL(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener); +/** + * Add a reference to a transport. + */ +PJ_DECL(void) pj_turn_transport_add_ref(pj_turn_transport *transport, + pj_turn_allocation *alloc); + + +/** + * Decrement transport reference counter. + */ +PJ_DECL(void) pj_turn_transport_dec_ref(pj_turn_transport *transport, + pj_turn_allocation *alloc); + + + /****************************************************************************/ /* * TURN Server API @@ -360,8 +404,8 @@ struct pj_turn_srv /** Array of listeners. */ pj_turn_listener **listener; - /** Array of STUN sessions, one for each listeners. */ - pj_stun_session **stun_sess; + /** STUN session to handle initial Allocate request. */ + pj_stun_session *stun_sess; /** Number of worker threads. */ unsigned thread_cnt; @@ -456,7 +500,7 @@ PJ_DECL(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv, * This callback is called by UDP listener on incoming packet. */ PJ_DECL(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv, - pj_turn_pkt *pkt); + pj_turn_pkt *pkt); #endif /* __PJ_TURN_SRV_TURN_H__ */ |