Changeset 1988
- Timestamp:
- Jun 6, 2008 2:47:10 PM (16 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 6 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/build.symbian/pjnath.mmp
r1913 r1988 38 38 SOURCE stun_msg_dump.c 39 39 SOURCE stun_session.c 40 SOURCE stun_sock.c 40 41 SOURCE stun_transaction.c 41 42 SOURCE turn_session.c -
pjproject/trunk/pjnath/build/Makefile
r1916 r1988 32 32 export PJNATH_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 33 33 errno.o ice_session.o ice_strans.o nat_detect.o stun_auth.o \ 34 stun_msg.o stun_msg_dump.o stun_session.o stun_ transaction.o \35 turn_session.o turn_sock.o34 stun_msg.o stun_msg_dump.o stun_session.o stun_sock.o \ 35 stun_transaction.o turn_session.o turn_sock.o 36 36 export PJNATH_CFLAGS += $(_CFLAGS) 37 37 … … 40 40 # 41 41 export PJNATH_TEST_SRCDIR = ../src/pjnath-test 42 export PJNATH_TEST_OBJS += ice_test.o stun.o sess_auth.o test.o 42 export PJNATH_TEST_OBJS += ice_test.o stun.o sess_auth.o server.o \ 43 stun_sock_test.o turn_sock_test.o test.o 43 44 export PJNATH_TEST_CFLAGS += $(_CFLAGS) 44 45 export PJNATH_TEST_LDFLAGS += $(_LDFLAGS) -
pjproject/trunk/pjnath/build/pjnath.dsp
r1913 r1988 122 122 # Begin Source File 123 123 124 SOURCE=..\src\pjnath\stun_sock.c 125 # End Source File 126 # Begin Source File 127 124 128 SOURCE=..\src\pjnath\stun_transaction.c 125 129 # End Source File … … 175 179 176 180 SOURCE=..\include\pjnath\stun_session.h 181 # End Source File 182 # Begin Source File 183 184 SOURCE=..\include\pjnath\stun_sock.h 177 185 # End Source File 178 186 # Begin Source File -
pjproject/trunk/pjnath/build/pjnath.vcproj
r1913 r1988 299 299 </File> 300 300 <File 301 RelativePath="..\src\pjnath\stun_sock.c" 302 > 303 </File> 304 <File 301 305 RelativePath="..\src\pjnath\stun_transaction.c" 302 306 > -
pjproject/trunk/pjnath/build/pjnath_test.dsp
r1877 r1988 89 89 90 90 SOURCE="..\src\pjnath-test\ice_test.c" 91 92 !IF "$(CFG)" == "pjnath_test - Win32 Release" 93 94 !ELSEIF "$(CFG)" == "pjnath_test - Win32 Debug" 95 96 !ENDIF 97 91 98 # End Source File 92 99 # Begin Source File 93 100 94 101 SOURCE="..\src\pjnath-test\main.c" 102 # End Source File 103 # Begin Source File 104 105 SOURCE="..\src\pjnath-test\server.c" 95 106 # End Source File 96 107 # Begin Source File … … 104 115 # Begin Source File 105 116 117 SOURCE="..\src\pjnath-test\stun_sock_test.c" 118 # End Source File 119 # Begin Source File 120 106 121 SOURCE="..\src\pjnath-test\test.c" 122 # End Source File 123 # Begin Source File 124 125 SOURCE="..\src\pjnath-test\turn_sock_test.c" 107 126 # End Source File 108 127 # End Group … … 110 129 111 130 # PROP Default_Filter "h;hpp;hxx;hm;inl" 131 # Begin Source File 132 133 SOURCE="..\src\pjnath-test\server.h" 134 # End Source File 112 135 # Begin Source File 113 136 -
pjproject/trunk/pjnath/build/wince-evc4/pjnath_wince.vcp
r1913 r1988 582 582 583 583 DEP_CPP_ERRNO=\ 584 "..\..\..\pjlib\include\pj\activesock.h"\ 584 585 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 585 586 "..\..\..\pjlib\include\pj\array.h"\ … … 627 628 "..\..\..\pjlib\include\pj\lock.h"\ 628 629 "..\..\..\pjlib\include\pj\log.h"\ 630 "..\..\..\pjlib\include\pj\math.h"\ 629 631 "..\..\..\pjlib\include\pj\os.h"\ 630 632 "..\..\..\pjlib\include\pj\pool.h"\ … … 1257 1259 1258 1260 DEP_CPP_ICE_S=\ 1261 "..\..\..\pjlib\include\pj\activesock.h"\ 1259 1262 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 1260 1263 "..\..\..\pjlib\include\pj\array.h"\ … … 1302 1305 "..\..\..\pjlib\include\pj\lock.h"\ 1303 1306 "..\..\..\pjlib\include\pj\log.h"\ 1307 "..\..\..\pjlib\include\pj\math.h"\ 1304 1308 "..\..\..\pjlib\include\pj\os.h"\ 1305 1309 "..\..\..\pjlib\include\pj\pool.h"\ … … 1986 1990 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 1987 1991 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 1992 "..\..\..\pjlib\include\pj\activesock.h"\ 1988 1993 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 1989 1994 "..\..\..\pjlib\include\pj\array.h"\ … … 2032 2037 "..\..\..\pjlib\include\pj\lock.h"\ 2033 2038 "..\..\..\pjlib\include\pj\log.h"\ 2039 "..\..\..\pjlib\include\pj\math.h"\ 2034 2040 "..\..\..\pjlib\include\pj\os.h"\ 2035 2041 "..\..\..\pjlib\include\pj\pool.h"\ … … 2055 2061 "..\..\include\pjnath\stun_msg.h"\ 2056 2062 "..\..\include\pjnath\stun_session.h"\ 2063 "..\..\include\pjnath\stun_sock.h"\ 2057 2064 "..\..\include\pjnath\stun_transaction.h"\ 2065 "..\..\include\pjnath\turn_session.h"\ 2066 "..\..\include\pjnath\turn_sock.h"\ 2058 2067 "..\..\include\pjnath\types.h"\ 2059 2068 … … 2740 2749 2741 2750 DEP_CPP_NAT_D=\ 2751 "..\..\..\pjlib\include\pj\activesock.h"\ 2742 2752 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 2743 2753 "..\..\..\pjlib\include\pj\array.h"\ … … 2786 2796 "..\..\..\pjlib\include\pj\lock.h"\ 2787 2797 "..\..\..\pjlib\include\pj\log.h"\ 2798 "..\..\..\pjlib\include\pj\math.h"\ 2788 2799 "..\..\..\pjlib\include\pj\os.h"\ 2789 2800 "..\..\..\pjlib\include\pj\pool.h"\ … … 3470 3481 "..\..\..\pjlib-util\include\pjlib-util\md5.h"\ 3471 3482 "..\..\..\pjlib-util\include\pjlib-util\sha1.h"\ 3483 "..\..\..\pjlib\include\pj\activesock.h"\ 3472 3484 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 3473 3485 "..\..\..\pjlib\include\pj\array.h"\ … … 3515 3527 "..\..\..\pjlib\include\pj\lock.h"\ 3516 3528 "..\..\..\pjlib\include\pj\log.h"\ 3529 "..\..\..\pjlib\include\pj\math.h"\ 3517 3530 "..\..\..\pjlib\include\pj\os.h"\ 3518 3531 "..\..\..\pjlib\include\pj\pool.h"\ … … 4167 4180 "..\..\..\pjlib-util\include\pjlib-util\sha1.h"\ 4168 4181 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 4182 "..\..\..\pjlib\include\pj\activesock.h"\ 4169 4183 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 4170 4184 "..\..\..\pjlib\include\pj\array.h"\ … … 4212 4226 "..\..\..\pjlib\include\pj\lock.h"\ 4213 4227 "..\..\..\pjlib\include\pj\log.h"\ 4228 "..\..\..\pjlib\include\pj\math.h"\ 4214 4229 "..\..\..\pjlib\include\pj\os.h"\ 4215 4230 "..\..\..\pjlib\include\pj\pool.h"\ … … 4848 4863 4849 4864 DEP_CPP_STUN_MS=\ 4865 "..\..\..\pjlib\include\pj\activesock.h"\ 4850 4866 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 4851 4867 "..\..\..\pjlib\include\pj\array.h"\ … … 4893 4909 "..\..\..\pjlib\include\pj\lock.h"\ 4894 4910 "..\..\..\pjlib\include\pj\log.h"\ 4911 "..\..\..\pjlib\include\pj\math.h"\ 4895 4912 "..\..\..\pjlib\include\pj\os.h"\ 4896 4913 "..\..\..\pjlib\include\pj\pool.h"\ … … 5515 5532 5516 5533 DEP_CPP_STUN_S=\ 5534 "..\..\..\pjlib\include\pj\activesock.h"\ 5517 5535 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 5518 5536 "..\..\..\pjlib\include\pj\array.h"\ … … 5560 5578 "..\..\..\pjlib\include\pj\lock.h"\ 5561 5579 "..\..\..\pjlib\include\pj\log.h"\ 5580 "..\..\..\pjlib\include\pj\math.h"\ 5562 5581 "..\..\..\pjlib\include\pj\os.h"\ 5563 5582 "..\..\..\pjlib\include\pj\pool.h"\ … … 5926 5945 # Begin Source File 5927 5946 5928 SOURCE=..\..\src\pjnath\stun_ transaction.c5947 SOURCE=..\..\src\pjnath\stun_sock.c 5929 5948 5930 5949 !IF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Release" 5931 5950 5932 DEP_CPP_STUN_T=\ 5933 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 5934 "..\..\..\pjlib\include\pj\array.h"\ 5935 "..\..\..\pjlib\include\pj\assert.h"\ 5936 "..\..\..\pjlib\include\pj\compat\assert.h"\ 5937 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 5938 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 5939 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 5940 "..\..\..\pjlib\include\pj\compat\errno.h"\ 5941 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 5942 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 5943 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 5944 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 5945 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 5946 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 5947 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 5948 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 5949 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 5950 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 5951 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 5952 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 5953 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 5954 "..\..\..\pjlib\include\pj\compat\string.h"\ 5955 "..\..\..\pjlib\include\pj\config.h"\ 5956 "..\..\..\pjlib\include\pj\config_site.h"\ 5957 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 5958 "..\..\..\pjlib\include\pj\ctype.h"\ 5959 "..\..\..\pjlib\include\pj\errno.h"\ 5960 "..\..\..\pjlib\include\pj\except.h"\ 5961 "..\..\..\pjlib\include\pj\fifobuf.h"\ 5962 "..\..\..\pjlib\include\pj\file_access.h"\ 5963 "..\..\..\pjlib\include\pj\file_io.h"\ 5964 "..\..\..\pjlib\include\pj\guid.h"\ 5965 "..\..\..\pjlib\include\pj\hash.h"\ 5966 "..\..\..\pjlib\include\pj\ioqueue.h"\ 5967 "..\..\..\pjlib\include\pj\ip_helper.h"\ 5968 "..\..\..\pjlib\include\pj\list.h"\ 5969 "..\..\..\pjlib\include\pj\list_i.h"\ 5970 "..\..\..\pjlib\include\pj\lock.h"\ 5971 "..\..\..\pjlib\include\pj\log.h"\ 5972 "..\..\..\pjlib\include\pj\os.h"\ 5973 "..\..\..\pjlib\include\pj\pool.h"\ 5974 "..\..\..\pjlib\include\pj\pool_alt.h"\ 5975 "..\..\..\pjlib\include\pj\pool_buf.h"\ 5976 "..\..\..\pjlib\include\pj\pool_i.h"\ 5977 "..\..\..\pjlib\include\pj\rand.h"\ 5978 "..\..\..\pjlib\include\pj\rbtree.h"\ 5979 "..\..\..\pjlib\include\pj\sock.h"\ 5980 "..\..\..\pjlib\include\pj\sock_select.h"\ 5981 "..\..\..\pjlib\include\pj\string.h"\ 5982 "..\..\..\pjlib\include\pj\string_i.h"\ 5983 "..\..\..\pjlib\include\pj\timer.h"\ 5984 "..\..\..\pjlib\include\pj\types.h"\ 5985 "..\..\..\pjlib\include\pj\unicode.h"\ 5986 "..\..\..\pjlib\include\pjlib.h"\ 5987 "..\..\include\pjnath\config.h"\ 5988 "..\..\include\pjnath\errno.h"\ 5989 "..\..\include\pjnath\stun_config.h"\ 5990 "..\..\include\pjnath\stun_msg.h"\ 5991 "..\..\include\pjnath\stun_transaction.h"\ 5992 "..\..\include\pjnath\types.h"\ 5993 5994 5995 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Debug" 5996 5997 DEP_CPP_STUN_T=\ 5951 DEP_CPP_STUN_SO=\ 5952 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 5953 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 5954 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 5955 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 5956 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 5957 "..\..\..\pjlib\include\pj\activesock.h"\ 5998 5958 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 5999 5959 "..\..\..\pjlib\include\pj\array.h"\ … … 6041 6001 "..\..\..\pjlib\include\pj\lock.h"\ 6042 6002 "..\..\..\pjlib\include\pj\log.h"\ 6043 "..\..\..\pjlib\include\pj\os.h"\ 6044 "..\..\..\pjlib\include\pj\pool.h"\ 6045 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6046 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6047 "..\..\..\pjlib\include\pj\pool_i.h"\ 6048 "..\..\..\pjlib\include\pj\rand.h"\ 6049 "..\..\..\pjlib\include\pj\rbtree.h"\ 6050 "..\..\..\pjlib\include\pj\sock.h"\ 6051 "..\..\..\pjlib\include\pj\sock_select.h"\ 6052 "..\..\..\pjlib\include\pj\string.h"\ 6053 "..\..\..\pjlib\include\pj\string_i.h"\ 6054 "..\..\..\pjlib\include\pj\timer.h"\ 6055 "..\..\..\pjlib\include\pj\types.h"\ 6056 "..\..\..\pjlib\include\pj\unicode.h"\ 6057 "..\..\..\pjlib\include\pjlib.h"\ 6058 "..\..\include\pjnath\config.h"\ 6059 "..\..\include\pjnath\errno.h"\ 6003 "..\..\..\pjlib\include\pj\math.h"\ 6004 "..\..\..\pjlib\include\pj\os.h"\ 6005 "..\..\..\pjlib\include\pj\pool.h"\ 6006 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6007 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6008 "..\..\..\pjlib\include\pj\pool_i.h"\ 6009 "..\..\..\pjlib\include\pj\rand.h"\ 6010 "..\..\..\pjlib\include\pj\rbtree.h"\ 6011 "..\..\..\pjlib\include\pj\sock.h"\ 6012 "..\..\..\pjlib\include\pj\sock_select.h"\ 6013 "..\..\..\pjlib\include\pj\string.h"\ 6014 "..\..\..\pjlib\include\pj\string_i.h"\ 6015 "..\..\..\pjlib\include\pj\timer.h"\ 6016 "..\..\..\pjlib\include\pj\types.h"\ 6017 "..\..\..\pjlib\include\pj\unicode.h"\ 6018 "..\..\..\pjlib\include\pjlib.h"\ 6019 "..\..\include\pjnath\config.h"\ 6020 "..\..\include\pjnath\errno.h"\ 6021 "..\..\include\pjnath\stun_auth.h"\ 6060 6022 "..\..\include\pjnath\stun_config.h"\ 6061 6023 "..\..\include\pjnath\stun_msg.h"\ 6024 "..\..\include\pjnath\stun_session.h"\ 6025 "..\..\include\pjnath\stun_sock.h"\ 6062 6026 "..\..\include\pjnath\stun_transaction.h"\ 6063 6027 "..\..\include\pjnath\types.h"\ 6064 6028 6065 6029 6066 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Release" 6067 6068 DEP_CPP_STUN_T=\ 6069 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6070 "..\..\..\pjlib\include\pj\array.h"\ 6071 "..\..\..\pjlib\include\pj\assert.h"\ 6072 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6073 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6074 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6075 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6076 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6077 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6078 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6079 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6080 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6081 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6082 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6083 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6084 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6085 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6086 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6087 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6088 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6089 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6090 "..\..\..\pjlib\include\pj\compat\string.h"\ 6091 "..\..\..\pjlib\include\pj\config.h"\ 6092 "..\..\..\pjlib\include\pj\config_site.h"\ 6093 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6094 "..\..\..\pjlib\include\pj\ctype.h"\ 6095 "..\..\..\pjlib\include\pj\errno.h"\ 6096 "..\..\..\pjlib\include\pj\except.h"\ 6097 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6098 "..\..\..\pjlib\include\pj\file_access.h"\ 6099 "..\..\..\pjlib\include\pj\file_io.h"\ 6100 "..\..\..\pjlib\include\pj\guid.h"\ 6101 "..\..\..\pjlib\include\pj\hash.h"\ 6102 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6103 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6104 "..\..\..\pjlib\include\pj\list.h"\ 6105 "..\..\..\pjlib\include\pj\list_i.h"\ 6106 "..\..\..\pjlib\include\pj\lock.h"\ 6107 "..\..\..\pjlib\include\pj\log.h"\ 6108 "..\..\..\pjlib\include\pj\os.h"\ 6109 "..\..\..\pjlib\include\pj\pool.h"\ 6110 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6111 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6112 "..\..\..\pjlib\include\pj\pool_i.h"\ 6113 "..\..\..\pjlib\include\pj\rand.h"\ 6114 "..\..\..\pjlib\include\pj\rbtree.h"\ 6115 "..\..\..\pjlib\include\pj\sock.h"\ 6116 "..\..\..\pjlib\include\pj\sock_select.h"\ 6117 "..\..\..\pjlib\include\pj\string.h"\ 6118 "..\..\..\pjlib\include\pj\string_i.h"\ 6119 "..\..\..\pjlib\include\pj\timer.h"\ 6120 "..\..\..\pjlib\include\pj\types.h"\ 6121 "..\..\..\pjlib\include\pj\unicode.h"\ 6122 "..\..\..\pjlib\include\pjlib.h"\ 6123 "..\..\include\pjnath\config.h"\ 6124 "..\..\include\pjnath\errno.h"\ 6125 "..\..\include\pjnath\stun_config.h"\ 6126 "..\..\include\pjnath\stun_msg.h"\ 6127 "..\..\include\pjnath\stun_transaction.h"\ 6128 "..\..\include\pjnath\types.h"\ 6129 6130 6131 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Debug" 6132 6133 DEP_CPP_STUN_T=\ 6134 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6135 "..\..\..\pjlib\include\pj\array.h"\ 6136 "..\..\..\pjlib\include\pj\assert.h"\ 6137 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6138 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6139 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6140 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6141 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6142 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6143 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6144 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6145 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6146 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6147 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6148 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6149 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6150 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6151 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6152 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6153 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6154 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6155 "..\..\..\pjlib\include\pj\compat\string.h"\ 6156 "..\..\..\pjlib\include\pj\config.h"\ 6157 "..\..\..\pjlib\include\pj\config_site.h"\ 6158 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6159 "..\..\..\pjlib\include\pj\ctype.h"\ 6160 "..\..\..\pjlib\include\pj\errno.h"\ 6161 "..\..\..\pjlib\include\pj\except.h"\ 6162 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6163 "..\..\..\pjlib\include\pj\file_access.h"\ 6164 "..\..\..\pjlib\include\pj\file_io.h"\ 6165 "..\..\..\pjlib\include\pj\guid.h"\ 6166 "..\..\..\pjlib\include\pj\hash.h"\ 6167 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6168 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6169 "..\..\..\pjlib\include\pj\list.h"\ 6170 "..\..\..\pjlib\include\pj\list_i.h"\ 6171 "..\..\..\pjlib\include\pj\lock.h"\ 6172 "..\..\..\pjlib\include\pj\log.h"\ 6173 "..\..\..\pjlib\include\pj\os.h"\ 6174 "..\..\..\pjlib\include\pj\pool.h"\ 6175 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6176 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6177 "..\..\..\pjlib\include\pj\pool_i.h"\ 6178 "..\..\..\pjlib\include\pj\rand.h"\ 6179 "..\..\..\pjlib\include\pj\rbtree.h"\ 6180 "..\..\..\pjlib\include\pj\sock.h"\ 6181 "..\..\..\pjlib\include\pj\sock_select.h"\ 6182 "..\..\..\pjlib\include\pj\string.h"\ 6183 "..\..\..\pjlib\include\pj\string_i.h"\ 6184 "..\..\..\pjlib\include\pj\timer.h"\ 6185 "..\..\..\pjlib\include\pj\types.h"\ 6186 "..\..\..\pjlib\include\pj\unicode.h"\ 6187 "..\..\..\pjlib\include\pjlib.h"\ 6188 "..\..\include\pjnath\config.h"\ 6189 "..\..\include\pjnath\errno.h"\ 6190 "..\..\include\pjnath\stun_config.h"\ 6191 "..\..\include\pjnath\stun_msg.h"\ 6192 "..\..\include\pjnath\stun_transaction.h"\ 6193 "..\..\include\pjnath\types.h"\ 6194 6195 6196 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Release" 6197 6198 DEP_CPP_STUN_T=\ 6030 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Debug" 6031 6032 DEP_CPP_STUN_SO=\ 6033 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6034 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6035 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6036 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6037 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6038 "..\..\..\pjlib\include\pj\activesock.h"\ 6199 6039 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6200 6040 "..\..\..\pjlib\include\pj\array.h"\ … … 6242 6082 "..\..\..\pjlib\include\pj\lock.h"\ 6243 6083 "..\..\..\pjlib\include\pj\log.h"\ 6084 "..\..\..\pjlib\include\pj\math.h"\ 6085 "..\..\..\pjlib\include\pj\os.h"\ 6086 "..\..\..\pjlib\include\pj\pool.h"\ 6087 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6088 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6089 "..\..\..\pjlib\include\pj\pool_i.h"\ 6090 "..\..\..\pjlib\include\pj\rand.h"\ 6091 "..\..\..\pjlib\include\pj\rbtree.h"\ 6092 "..\..\..\pjlib\include\pj\sock.h"\ 6093 "..\..\..\pjlib\include\pj\sock_select.h"\ 6094 "..\..\..\pjlib\include\pj\string.h"\ 6095 "..\..\..\pjlib\include\pj\string_i.h"\ 6096 "..\..\..\pjlib\include\pj\timer.h"\ 6097 "..\..\..\pjlib\include\pj\types.h"\ 6098 "..\..\..\pjlib\include\pj\unicode.h"\ 6099 "..\..\..\pjlib\include\pjlib.h"\ 6100 "..\..\include\pjnath\config.h"\ 6101 "..\..\include\pjnath\errno.h"\ 6102 "..\..\include\pjnath\stun_auth.h"\ 6103 "..\..\include\pjnath\stun_config.h"\ 6104 "..\..\include\pjnath\stun_msg.h"\ 6105 "..\..\include\pjnath\stun_session.h"\ 6106 "..\..\include\pjnath\stun_sock.h"\ 6107 "..\..\include\pjnath\stun_transaction.h"\ 6108 "..\..\include\pjnath\types.h"\ 6109 6110 6111 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Release" 6112 6113 DEP_CPP_STUN_SO=\ 6114 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6115 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6116 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6117 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6118 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6119 "..\..\..\pjlib\include\pj\activesock.h"\ 6120 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6121 "..\..\..\pjlib\include\pj\array.h"\ 6122 "..\..\..\pjlib\include\pj\assert.h"\ 6123 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6124 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6125 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6126 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6127 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6128 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6129 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6130 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6131 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6132 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6133 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6134 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6135 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6136 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6137 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6138 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6139 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6140 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6141 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6142 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6143 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6144 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6145 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6146 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6147 "..\..\..\pjlib\include\pj\compat\string.h"\ 6148 "..\..\..\pjlib\include\pj\config.h"\ 6149 "..\..\..\pjlib\include\pj\config_site.h"\ 6150 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6151 "..\..\..\pjlib\include\pj\ctype.h"\ 6152 "..\..\..\pjlib\include\pj\errno.h"\ 6153 "..\..\..\pjlib\include\pj\except.h"\ 6154 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6155 "..\..\..\pjlib\include\pj\file_access.h"\ 6156 "..\..\..\pjlib\include\pj\file_io.h"\ 6157 "..\..\..\pjlib\include\pj\guid.h"\ 6158 "..\..\..\pjlib\include\pj\hash.h"\ 6159 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6160 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6161 "..\..\..\pjlib\include\pj\list.h"\ 6162 "..\..\..\pjlib\include\pj\list_i.h"\ 6163 "..\..\..\pjlib\include\pj\lock.h"\ 6164 "..\..\..\pjlib\include\pj\log.h"\ 6165 "..\..\..\pjlib\include\pj\math.h"\ 6166 "..\..\..\pjlib\include\pj\os.h"\ 6167 "..\..\..\pjlib\include\pj\pool.h"\ 6168 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6169 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6170 "..\..\..\pjlib\include\pj\pool_i.h"\ 6171 "..\..\..\pjlib\include\pj\rand.h"\ 6172 "..\..\..\pjlib\include\pj\rbtree.h"\ 6173 "..\..\..\pjlib\include\pj\sock.h"\ 6174 "..\..\..\pjlib\include\pj\sock_select.h"\ 6175 "..\..\..\pjlib\include\pj\string.h"\ 6176 "..\..\..\pjlib\include\pj\string_i.h"\ 6177 "..\..\..\pjlib\include\pj\timer.h"\ 6178 "..\..\..\pjlib\include\pj\types.h"\ 6179 "..\..\..\pjlib\include\pj\unicode.h"\ 6180 "..\..\..\pjlib\include\pjlib.h"\ 6181 "..\..\include\pjnath\config.h"\ 6182 "..\..\include\pjnath\errno.h"\ 6183 "..\..\include\pjnath\stun_auth.h"\ 6184 "..\..\include\pjnath\stun_config.h"\ 6185 "..\..\include\pjnath\stun_msg.h"\ 6186 "..\..\include\pjnath\stun_session.h"\ 6187 "..\..\include\pjnath\stun_sock.h"\ 6188 "..\..\include\pjnath\stun_transaction.h"\ 6189 "..\..\include\pjnath\types.h"\ 6190 6191 6192 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Debug" 6193 6194 DEP_CPP_STUN_SO=\ 6195 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6196 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6197 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6198 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6199 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6200 "..\..\..\pjlib\include\pj\activesock.h"\ 6201 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6202 "..\..\..\pjlib\include\pj\array.h"\ 6203 "..\..\..\pjlib\include\pj\assert.h"\ 6204 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6205 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6206 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6207 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6208 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6209 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6210 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6211 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6212 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6213 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6214 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6215 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6216 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6217 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6218 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6219 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6220 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6221 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6222 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6223 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6224 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6225 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6226 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6227 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6228 "..\..\..\pjlib\include\pj\compat\string.h"\ 6229 "..\..\..\pjlib\include\pj\config.h"\ 6230 "..\..\..\pjlib\include\pj\config_site.h"\ 6231 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6232 "..\..\..\pjlib\include\pj\ctype.h"\ 6233 "..\..\..\pjlib\include\pj\errno.h"\ 6234 "..\..\..\pjlib\include\pj\except.h"\ 6235 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6236 "..\..\..\pjlib\include\pj\file_access.h"\ 6237 "..\..\..\pjlib\include\pj\file_io.h"\ 6238 "..\..\..\pjlib\include\pj\guid.h"\ 6239 "..\..\..\pjlib\include\pj\hash.h"\ 6240 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6241 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6242 "..\..\..\pjlib\include\pj\list.h"\ 6243 "..\..\..\pjlib\include\pj\list_i.h"\ 6244 "..\..\..\pjlib\include\pj\lock.h"\ 6245 "..\..\..\pjlib\include\pj\log.h"\ 6246 "..\..\..\pjlib\include\pj\math.h"\ 6247 "..\..\..\pjlib\include\pj\os.h"\ 6248 "..\..\..\pjlib\include\pj\pool.h"\ 6249 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6250 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6251 "..\..\..\pjlib\include\pj\pool_i.h"\ 6252 "..\..\..\pjlib\include\pj\rand.h"\ 6253 "..\..\..\pjlib\include\pj\rbtree.h"\ 6254 "..\..\..\pjlib\include\pj\sock.h"\ 6255 "..\..\..\pjlib\include\pj\sock_select.h"\ 6256 "..\..\..\pjlib\include\pj\string.h"\ 6257 "..\..\..\pjlib\include\pj\string_i.h"\ 6258 "..\..\..\pjlib\include\pj\timer.h"\ 6259 "..\..\..\pjlib\include\pj\types.h"\ 6260 "..\..\..\pjlib\include\pj\unicode.h"\ 6261 "..\..\..\pjlib\include\pjlib.h"\ 6262 "..\..\include\pjnath\config.h"\ 6263 "..\..\include\pjnath\errno.h"\ 6264 "..\..\include\pjnath\stun_auth.h"\ 6265 "..\..\include\pjnath\stun_config.h"\ 6266 "..\..\include\pjnath\stun_msg.h"\ 6267 "..\..\include\pjnath\stun_session.h"\ 6268 "..\..\include\pjnath\stun_sock.h"\ 6269 "..\..\include\pjnath\stun_transaction.h"\ 6270 "..\..\include\pjnath\types.h"\ 6271 6272 6273 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Release" 6274 6275 DEP_CPP_STUN_SO=\ 6276 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6277 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6278 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6279 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6280 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6281 "..\..\..\pjlib\include\pj\activesock.h"\ 6282 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6283 "..\..\..\pjlib\include\pj\array.h"\ 6284 "..\..\..\pjlib\include\pj\assert.h"\ 6285 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6286 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6287 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6288 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6289 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6290 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6291 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6292 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6293 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6294 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6295 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6296 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6297 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6298 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6299 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6300 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6301 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6302 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6303 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6304 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6305 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6306 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6307 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6308 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6309 "..\..\..\pjlib\include\pj\compat\string.h"\ 6310 "..\..\..\pjlib\include\pj\config.h"\ 6311 "..\..\..\pjlib\include\pj\config_site.h"\ 6312 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6313 "..\..\..\pjlib\include\pj\ctype.h"\ 6314 "..\..\..\pjlib\include\pj\errno.h"\ 6315 "..\..\..\pjlib\include\pj\except.h"\ 6316 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6317 "..\..\..\pjlib\include\pj\file_access.h"\ 6318 "..\..\..\pjlib\include\pj\file_io.h"\ 6319 "..\..\..\pjlib\include\pj\guid.h"\ 6320 "..\..\..\pjlib\include\pj\hash.h"\ 6321 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6322 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6323 "..\..\..\pjlib\include\pj\list.h"\ 6324 "..\..\..\pjlib\include\pj\list_i.h"\ 6325 "..\..\..\pjlib\include\pj\lock.h"\ 6326 "..\..\..\pjlib\include\pj\log.h"\ 6327 "..\..\..\pjlib\include\pj\math.h"\ 6328 "..\..\..\pjlib\include\pj\os.h"\ 6329 "..\..\..\pjlib\include\pj\pool.h"\ 6330 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6331 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6332 "..\..\..\pjlib\include\pj\pool_i.h"\ 6333 "..\..\..\pjlib\include\pj\rand.h"\ 6334 "..\..\..\pjlib\include\pj\rbtree.h"\ 6335 "..\..\..\pjlib\include\pj\sock.h"\ 6336 "..\..\..\pjlib\include\pj\sock_select.h"\ 6337 "..\..\..\pjlib\include\pj\string.h"\ 6338 "..\..\..\pjlib\include\pj\string_i.h"\ 6339 "..\..\..\pjlib\include\pj\timer.h"\ 6340 "..\..\..\pjlib\include\pj\types.h"\ 6341 "..\..\..\pjlib\include\pj\unicode.h"\ 6342 "..\..\..\pjlib\include\pjlib.h"\ 6343 "..\..\include\pjnath\config.h"\ 6344 "..\..\include\pjnath\errno.h"\ 6345 "..\..\include\pjnath\stun_auth.h"\ 6346 "..\..\include\pjnath\stun_config.h"\ 6347 "..\..\include\pjnath\stun_msg.h"\ 6348 "..\..\include\pjnath\stun_session.h"\ 6349 "..\..\include\pjnath\stun_sock.h"\ 6350 "..\..\include\pjnath\stun_transaction.h"\ 6351 "..\..\include\pjnath\types.h"\ 6352 6353 6354 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Debug" 6355 6356 DEP_CPP_STUN_SO=\ 6357 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6358 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6359 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6360 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6361 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6362 "..\..\..\pjlib\include\pj\activesock.h"\ 6363 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6364 "..\..\..\pjlib\include\pj\array.h"\ 6365 "..\..\..\pjlib\include\pj\assert.h"\ 6366 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6367 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6368 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6369 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6370 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6371 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6372 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6373 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6374 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6375 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6376 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6377 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6378 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6379 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6380 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6381 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6382 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6383 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6384 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6385 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6386 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6387 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6388 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6389 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6390 "..\..\..\pjlib\include\pj\compat\string.h"\ 6391 "..\..\..\pjlib\include\pj\config.h"\ 6392 "..\..\..\pjlib\include\pj\config_site.h"\ 6393 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6394 "..\..\..\pjlib\include\pj\ctype.h"\ 6395 "..\..\..\pjlib\include\pj\errno.h"\ 6396 "..\..\..\pjlib\include\pj\except.h"\ 6397 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6398 "..\..\..\pjlib\include\pj\file_access.h"\ 6399 "..\..\..\pjlib\include\pj\file_io.h"\ 6400 "..\..\..\pjlib\include\pj\guid.h"\ 6401 "..\..\..\pjlib\include\pj\hash.h"\ 6402 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6403 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6404 "..\..\..\pjlib\include\pj\list.h"\ 6405 "..\..\..\pjlib\include\pj\list_i.h"\ 6406 "..\..\..\pjlib\include\pj\lock.h"\ 6407 "..\..\..\pjlib\include\pj\log.h"\ 6408 "..\..\..\pjlib\include\pj\math.h"\ 6409 "..\..\..\pjlib\include\pj\os.h"\ 6410 "..\..\..\pjlib\include\pj\pool.h"\ 6411 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6412 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6413 "..\..\..\pjlib\include\pj\pool_i.h"\ 6414 "..\..\..\pjlib\include\pj\rand.h"\ 6415 "..\..\..\pjlib\include\pj\rbtree.h"\ 6416 "..\..\..\pjlib\include\pj\sock.h"\ 6417 "..\..\..\pjlib\include\pj\sock_select.h"\ 6418 "..\..\..\pjlib\include\pj\string.h"\ 6419 "..\..\..\pjlib\include\pj\string_i.h"\ 6420 "..\..\..\pjlib\include\pj\timer.h"\ 6421 "..\..\..\pjlib\include\pj\types.h"\ 6422 "..\..\..\pjlib\include\pj\unicode.h"\ 6423 "..\..\..\pjlib\include\pjlib.h"\ 6424 "..\..\include\pjnath\config.h"\ 6425 "..\..\include\pjnath\errno.h"\ 6426 "..\..\include\pjnath\stun_auth.h"\ 6427 "..\..\include\pjnath\stun_config.h"\ 6428 "..\..\include\pjnath\stun_msg.h"\ 6429 "..\..\include\pjnath\stun_session.h"\ 6430 "..\..\include\pjnath\stun_sock.h"\ 6431 "..\..\include\pjnath\stun_transaction.h"\ 6432 "..\..\include\pjnath\types.h"\ 6433 6434 6435 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4T) Release" 6436 6437 DEP_CPP_STUN_SO=\ 6438 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6439 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6440 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6441 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6442 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6443 "..\..\..\pjlib\include\pj\activesock.h"\ 6444 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6445 "..\..\..\pjlib\include\pj\array.h"\ 6446 "..\..\..\pjlib\include\pj\assert.h"\ 6447 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6448 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6449 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6450 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6451 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6452 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6453 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6454 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6455 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6456 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6457 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6458 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6459 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6460 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6461 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6462 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6463 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6464 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6465 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6466 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6467 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6468 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6469 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6470 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6471 "..\..\..\pjlib\include\pj\compat\string.h"\ 6472 "..\..\..\pjlib\include\pj\config.h"\ 6473 "..\..\..\pjlib\include\pj\config_site.h"\ 6474 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6475 "..\..\..\pjlib\include\pj\ctype.h"\ 6476 "..\..\..\pjlib\include\pj\errno.h"\ 6477 "..\..\..\pjlib\include\pj\except.h"\ 6478 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6479 "..\..\..\pjlib\include\pj\file_access.h"\ 6480 "..\..\..\pjlib\include\pj\file_io.h"\ 6481 "..\..\..\pjlib\include\pj\guid.h"\ 6482 "..\..\..\pjlib\include\pj\hash.h"\ 6483 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6484 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6485 "..\..\..\pjlib\include\pj\list.h"\ 6486 "..\..\..\pjlib\include\pj\list_i.h"\ 6487 "..\..\..\pjlib\include\pj\lock.h"\ 6488 "..\..\..\pjlib\include\pj\log.h"\ 6489 "..\..\..\pjlib\include\pj\math.h"\ 6490 "..\..\..\pjlib\include\pj\os.h"\ 6491 "..\..\..\pjlib\include\pj\pool.h"\ 6492 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6493 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6494 "..\..\..\pjlib\include\pj\pool_i.h"\ 6495 "..\..\..\pjlib\include\pj\rand.h"\ 6496 "..\..\..\pjlib\include\pj\rbtree.h"\ 6497 "..\..\..\pjlib\include\pj\sock.h"\ 6498 "..\..\..\pjlib\include\pj\sock_select.h"\ 6499 "..\..\..\pjlib\include\pj\string.h"\ 6500 "..\..\..\pjlib\include\pj\string_i.h"\ 6501 "..\..\..\pjlib\include\pj\timer.h"\ 6502 "..\..\..\pjlib\include\pj\types.h"\ 6503 "..\..\..\pjlib\include\pj\unicode.h"\ 6504 "..\..\..\pjlib\include\pjlib.h"\ 6505 "..\..\include\pjnath\config.h"\ 6506 "..\..\include\pjnath\errno.h"\ 6507 "..\..\include\pjnath\stun_auth.h"\ 6508 "..\..\include\pjnath\stun_config.h"\ 6509 "..\..\include\pjnath\stun_msg.h"\ 6510 "..\..\include\pjnath\stun_session.h"\ 6511 "..\..\include\pjnath\stun_sock.h"\ 6512 "..\..\include\pjnath\stun_transaction.h"\ 6513 "..\..\include\pjnath\types.h"\ 6514 6515 6516 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4T) Debug" 6517 6518 DEP_CPP_STUN_SO=\ 6519 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6520 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6521 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6522 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6523 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6524 "..\..\..\pjlib\include\pj\activesock.h"\ 6525 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6526 "..\..\..\pjlib\include\pj\array.h"\ 6527 "..\..\..\pjlib\include\pj\assert.h"\ 6528 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6529 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6530 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6531 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6532 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6533 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6534 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6535 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6536 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6537 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6538 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6539 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6540 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6541 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6542 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6543 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6544 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6545 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6546 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6547 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6548 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6549 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6550 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6551 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6552 "..\..\..\pjlib\include\pj\compat\string.h"\ 6553 "..\..\..\pjlib\include\pj\config.h"\ 6554 "..\..\..\pjlib\include\pj\config_site.h"\ 6555 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6556 "..\..\..\pjlib\include\pj\ctype.h"\ 6557 "..\..\..\pjlib\include\pj\errno.h"\ 6558 "..\..\..\pjlib\include\pj\except.h"\ 6559 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6560 "..\..\..\pjlib\include\pj\file_access.h"\ 6561 "..\..\..\pjlib\include\pj\file_io.h"\ 6562 "..\..\..\pjlib\include\pj\guid.h"\ 6563 "..\..\..\pjlib\include\pj\hash.h"\ 6564 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6565 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6566 "..\..\..\pjlib\include\pj\list.h"\ 6567 "..\..\..\pjlib\include\pj\list_i.h"\ 6568 "..\..\..\pjlib\include\pj\lock.h"\ 6569 "..\..\..\pjlib\include\pj\log.h"\ 6570 "..\..\..\pjlib\include\pj\math.h"\ 6571 "..\..\..\pjlib\include\pj\os.h"\ 6572 "..\..\..\pjlib\include\pj\pool.h"\ 6573 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6574 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6575 "..\..\..\pjlib\include\pj\pool_i.h"\ 6576 "..\..\..\pjlib\include\pj\rand.h"\ 6577 "..\..\..\pjlib\include\pj\rbtree.h"\ 6578 "..\..\..\pjlib\include\pj\sock.h"\ 6579 "..\..\..\pjlib\include\pj\sock_select.h"\ 6580 "..\..\..\pjlib\include\pj\string.h"\ 6581 "..\..\..\pjlib\include\pj\string_i.h"\ 6582 "..\..\..\pjlib\include\pj\timer.h"\ 6583 "..\..\..\pjlib\include\pj\types.h"\ 6584 "..\..\..\pjlib\include\pj\unicode.h"\ 6585 "..\..\..\pjlib\include\pjlib.h"\ 6586 "..\..\include\pjnath\config.h"\ 6587 "..\..\include\pjnath\errno.h"\ 6588 "..\..\include\pjnath\stun_auth.h"\ 6589 "..\..\include\pjnath\stun_config.h"\ 6590 "..\..\include\pjnath\stun_msg.h"\ 6591 "..\..\include\pjnath\stun_session.h"\ 6592 "..\..\include\pjnath\stun_sock.h"\ 6593 "..\..\include\pjnath\stun_transaction.h"\ 6594 "..\..\include\pjnath\types.h"\ 6595 6596 6597 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE x86) Release" 6598 6599 DEP_CPP_STUN_SO=\ 6600 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6601 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6602 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6603 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6604 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6605 "..\..\..\pjlib\include\pj\activesock.h"\ 6606 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6607 "..\..\..\pjlib\include\pj\array.h"\ 6608 "..\..\..\pjlib\include\pj\assert.h"\ 6609 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6610 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6611 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6612 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6613 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6614 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6615 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6616 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6617 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6618 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6619 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6620 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6621 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6622 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6623 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6624 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6625 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6626 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6627 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6628 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6629 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6630 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6631 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6632 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6633 "..\..\..\pjlib\include\pj\compat\string.h"\ 6634 "..\..\..\pjlib\include\pj\config.h"\ 6635 "..\..\..\pjlib\include\pj\config_site.h"\ 6636 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6637 "..\..\..\pjlib\include\pj\ctype.h"\ 6638 "..\..\..\pjlib\include\pj\errno.h"\ 6639 "..\..\..\pjlib\include\pj\except.h"\ 6640 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6641 "..\..\..\pjlib\include\pj\file_access.h"\ 6642 "..\..\..\pjlib\include\pj\file_io.h"\ 6643 "..\..\..\pjlib\include\pj\guid.h"\ 6644 "..\..\..\pjlib\include\pj\hash.h"\ 6645 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6646 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6647 "..\..\..\pjlib\include\pj\list.h"\ 6648 "..\..\..\pjlib\include\pj\list_i.h"\ 6649 "..\..\..\pjlib\include\pj\lock.h"\ 6650 "..\..\..\pjlib\include\pj\log.h"\ 6651 "..\..\..\pjlib\include\pj\math.h"\ 6652 "..\..\..\pjlib\include\pj\os.h"\ 6653 "..\..\..\pjlib\include\pj\pool.h"\ 6654 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6655 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6656 "..\..\..\pjlib\include\pj\pool_i.h"\ 6657 "..\..\..\pjlib\include\pj\rand.h"\ 6658 "..\..\..\pjlib\include\pj\rbtree.h"\ 6659 "..\..\..\pjlib\include\pj\sock.h"\ 6660 "..\..\..\pjlib\include\pj\sock_select.h"\ 6661 "..\..\..\pjlib\include\pj\string.h"\ 6662 "..\..\..\pjlib\include\pj\string_i.h"\ 6663 "..\..\..\pjlib\include\pj\timer.h"\ 6664 "..\..\..\pjlib\include\pj\types.h"\ 6665 "..\..\..\pjlib\include\pj\unicode.h"\ 6666 "..\..\..\pjlib\include\pjlib.h"\ 6667 "..\..\include\pjnath\config.h"\ 6668 "..\..\include\pjnath\errno.h"\ 6669 "..\..\include\pjnath\stun_auth.h"\ 6670 "..\..\include\pjnath\stun_config.h"\ 6671 "..\..\include\pjnath\stun_msg.h"\ 6672 "..\..\include\pjnath\stun_session.h"\ 6673 "..\..\include\pjnath\stun_sock.h"\ 6674 "..\..\include\pjnath\stun_transaction.h"\ 6675 "..\..\include\pjnath\types.h"\ 6676 6677 6678 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE x86) Debug" 6679 6680 DEP_CPP_STUN_SO=\ 6681 "..\..\..\pjlib-util\include\pjlib-util\config.h"\ 6682 "..\..\..\pjlib-util\include\pjlib-util\dns.h"\ 6683 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 6684 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6685 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 6686 "..\..\..\pjlib\include\pj\activesock.h"\ 6687 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6688 "..\..\..\pjlib\include\pj\array.h"\ 6689 "..\..\..\pjlib\include\pj\assert.h"\ 6690 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6691 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6692 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6693 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6694 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6695 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6696 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6697 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6698 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6699 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6700 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6701 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6702 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6703 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6704 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6705 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6706 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6707 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6708 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6709 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6710 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6711 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6712 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6713 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6714 "..\..\..\pjlib\include\pj\compat\string.h"\ 6715 "..\..\..\pjlib\include\pj\config.h"\ 6716 "..\..\..\pjlib\include\pj\config_site.h"\ 6717 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6718 "..\..\..\pjlib\include\pj\ctype.h"\ 6719 "..\..\..\pjlib\include\pj\errno.h"\ 6720 "..\..\..\pjlib\include\pj\except.h"\ 6721 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6722 "..\..\..\pjlib\include\pj\file_access.h"\ 6723 "..\..\..\pjlib\include\pj\file_io.h"\ 6724 "..\..\..\pjlib\include\pj\guid.h"\ 6725 "..\..\..\pjlib\include\pj\hash.h"\ 6726 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6727 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6728 "..\..\..\pjlib\include\pj\list.h"\ 6729 "..\..\..\pjlib\include\pj\list_i.h"\ 6730 "..\..\..\pjlib\include\pj\lock.h"\ 6731 "..\..\..\pjlib\include\pj\log.h"\ 6732 "..\..\..\pjlib\include\pj\math.h"\ 6733 "..\..\..\pjlib\include\pj\os.h"\ 6734 "..\..\..\pjlib\include\pj\pool.h"\ 6735 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6736 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6737 "..\..\..\pjlib\include\pj\pool_i.h"\ 6738 "..\..\..\pjlib\include\pj\rand.h"\ 6739 "..\..\..\pjlib\include\pj\rbtree.h"\ 6740 "..\..\..\pjlib\include\pj\sock.h"\ 6741 "..\..\..\pjlib\include\pj\sock_select.h"\ 6742 "..\..\..\pjlib\include\pj\string.h"\ 6743 "..\..\..\pjlib\include\pj\string_i.h"\ 6744 "..\..\..\pjlib\include\pj\timer.h"\ 6745 "..\..\..\pjlib\include\pj\types.h"\ 6746 "..\..\..\pjlib\include\pj\unicode.h"\ 6747 "..\..\..\pjlib\include\pjlib.h"\ 6748 "..\..\include\pjnath\config.h"\ 6749 "..\..\include\pjnath\errno.h"\ 6750 "..\..\include\pjnath\stun_auth.h"\ 6751 "..\..\include\pjnath\stun_config.h"\ 6752 "..\..\include\pjnath\stun_msg.h"\ 6753 "..\..\include\pjnath\stun_session.h"\ 6754 "..\..\include\pjnath\stun_sock.h"\ 6755 "..\..\include\pjnath\stun_transaction.h"\ 6756 "..\..\include\pjnath\types.h"\ 6757 6758 6759 !ENDIF 6760 6761 # End Source File 6762 # Begin Source File 6763 6764 SOURCE=..\..\src\pjnath\stun_transaction.c 6765 6766 !IF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Release" 6767 6768 DEP_CPP_STUN_T=\ 6769 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6770 "..\..\..\pjlib\include\pj\array.h"\ 6771 "..\..\..\pjlib\include\pj\assert.h"\ 6772 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6773 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6774 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6775 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6776 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6777 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6778 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6779 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6780 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6781 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6782 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6783 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6784 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6785 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6786 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6787 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6788 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6789 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6790 "..\..\..\pjlib\include\pj\compat\string.h"\ 6791 "..\..\..\pjlib\include\pj\config.h"\ 6792 "..\..\..\pjlib\include\pj\config_site.h"\ 6793 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6794 "..\..\..\pjlib\include\pj\ctype.h"\ 6795 "..\..\..\pjlib\include\pj\errno.h"\ 6796 "..\..\..\pjlib\include\pj\except.h"\ 6797 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6798 "..\..\..\pjlib\include\pj\file_access.h"\ 6799 "..\..\..\pjlib\include\pj\file_io.h"\ 6800 "..\..\..\pjlib\include\pj\guid.h"\ 6801 "..\..\..\pjlib\include\pj\hash.h"\ 6802 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6803 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6804 "..\..\..\pjlib\include\pj\list.h"\ 6805 "..\..\..\pjlib\include\pj\list_i.h"\ 6806 "..\..\..\pjlib\include\pj\lock.h"\ 6807 "..\..\..\pjlib\include\pj\log.h"\ 6808 "..\..\..\pjlib\include\pj\os.h"\ 6809 "..\..\..\pjlib\include\pj\pool.h"\ 6810 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6811 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6812 "..\..\..\pjlib\include\pj\pool_i.h"\ 6813 "..\..\..\pjlib\include\pj\rand.h"\ 6814 "..\..\..\pjlib\include\pj\rbtree.h"\ 6815 "..\..\..\pjlib\include\pj\sock.h"\ 6816 "..\..\..\pjlib\include\pj\sock_select.h"\ 6817 "..\..\..\pjlib\include\pj\string.h"\ 6818 "..\..\..\pjlib\include\pj\string_i.h"\ 6819 "..\..\..\pjlib\include\pj\timer.h"\ 6820 "..\..\..\pjlib\include\pj\types.h"\ 6821 "..\..\..\pjlib\include\pj\unicode.h"\ 6822 "..\..\..\pjlib\include\pjlib.h"\ 6823 "..\..\include\pjnath\config.h"\ 6824 "..\..\include\pjnath\errno.h"\ 6825 "..\..\include\pjnath\stun_config.h"\ 6826 "..\..\include\pjnath\stun_msg.h"\ 6827 "..\..\include\pjnath\stun_transaction.h"\ 6828 "..\..\include\pjnath\types.h"\ 6829 6830 6831 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Debug" 6832 6833 DEP_CPP_STUN_T=\ 6834 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6835 "..\..\..\pjlib\include\pj\array.h"\ 6836 "..\..\..\pjlib\include\pj\assert.h"\ 6837 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6838 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 6839 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 6840 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6841 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 6842 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6843 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 6844 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6845 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6846 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6847 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6848 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6849 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6850 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6851 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6852 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6853 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6854 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6855 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 6856 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6857 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6858 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6859 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6860 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 6861 "..\..\..\pjlib\include\pj\compat\string.h"\ 6862 "..\..\..\pjlib\include\pj\config.h"\ 6863 "..\..\..\pjlib\include\pj\config_site.h"\ 6864 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6865 "..\..\..\pjlib\include\pj\ctype.h"\ 6866 "..\..\..\pjlib\include\pj\errno.h"\ 6867 "..\..\..\pjlib\include\pj\except.h"\ 6868 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6869 "..\..\..\pjlib\include\pj\file_access.h"\ 6870 "..\..\..\pjlib\include\pj\file_io.h"\ 6871 "..\..\..\pjlib\include\pj\guid.h"\ 6872 "..\..\..\pjlib\include\pj\hash.h"\ 6873 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6874 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6875 "..\..\..\pjlib\include\pj\list.h"\ 6876 "..\..\..\pjlib\include\pj\list_i.h"\ 6877 "..\..\..\pjlib\include\pj\lock.h"\ 6878 "..\..\..\pjlib\include\pj\log.h"\ 6879 "..\..\..\pjlib\include\pj\os.h"\ 6880 "..\..\..\pjlib\include\pj\pool.h"\ 6881 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6882 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6883 "..\..\..\pjlib\include\pj\pool_i.h"\ 6884 "..\..\..\pjlib\include\pj\rand.h"\ 6885 "..\..\..\pjlib\include\pj\rbtree.h"\ 6886 "..\..\..\pjlib\include\pj\sock.h"\ 6887 "..\..\..\pjlib\include\pj\sock_select.h"\ 6888 "..\..\..\pjlib\include\pj\string.h"\ 6889 "..\..\..\pjlib\include\pj\string_i.h"\ 6890 "..\..\..\pjlib\include\pj\timer.h"\ 6891 "..\..\..\pjlib\include\pj\types.h"\ 6892 "..\..\..\pjlib\include\pj\unicode.h"\ 6893 "..\..\..\pjlib\include\pjlib.h"\ 6894 "..\..\include\pjnath\config.h"\ 6895 "..\..\include\pjnath\errno.h"\ 6896 "..\..\include\pjnath\stun_config.h"\ 6897 "..\..\include\pjnath\stun_msg.h"\ 6898 "..\..\include\pjnath\stun_transaction.h"\ 6899 "..\..\include\pjnath\types.h"\ 6900 6901 6902 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Release" 6903 6904 DEP_CPP_STUN_T=\ 6905 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6906 "..\..\..\pjlib\include\pj\array.h"\ 6907 "..\..\..\pjlib\include\pj\assert.h"\ 6908 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6909 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6910 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6911 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6912 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6913 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6914 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6915 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6916 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6917 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6918 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6919 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6920 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6921 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6922 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6923 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6924 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6925 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6926 "..\..\..\pjlib\include\pj\compat\string.h"\ 6927 "..\..\..\pjlib\include\pj\config.h"\ 6928 "..\..\..\pjlib\include\pj\config_site.h"\ 6929 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6930 "..\..\..\pjlib\include\pj\ctype.h"\ 6931 "..\..\..\pjlib\include\pj\errno.h"\ 6932 "..\..\..\pjlib\include\pj\except.h"\ 6933 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6934 "..\..\..\pjlib\include\pj\file_access.h"\ 6935 "..\..\..\pjlib\include\pj\file_io.h"\ 6936 "..\..\..\pjlib\include\pj\guid.h"\ 6937 "..\..\..\pjlib\include\pj\hash.h"\ 6938 "..\..\..\pjlib\include\pj\ioqueue.h"\ 6939 "..\..\..\pjlib\include\pj\ip_helper.h"\ 6940 "..\..\..\pjlib\include\pj\list.h"\ 6941 "..\..\..\pjlib\include\pj\list_i.h"\ 6942 "..\..\..\pjlib\include\pj\lock.h"\ 6943 "..\..\..\pjlib\include\pj\log.h"\ 6944 "..\..\..\pjlib\include\pj\os.h"\ 6945 "..\..\..\pjlib\include\pj\pool.h"\ 6946 "..\..\..\pjlib\include\pj\pool_alt.h"\ 6947 "..\..\..\pjlib\include\pj\pool_buf.h"\ 6948 "..\..\..\pjlib\include\pj\pool_i.h"\ 6949 "..\..\..\pjlib\include\pj\rand.h"\ 6950 "..\..\..\pjlib\include\pj\rbtree.h"\ 6951 "..\..\..\pjlib\include\pj\sock.h"\ 6952 "..\..\..\pjlib\include\pj\sock_select.h"\ 6953 "..\..\..\pjlib\include\pj\string.h"\ 6954 "..\..\..\pjlib\include\pj\string_i.h"\ 6955 "..\..\..\pjlib\include\pj\timer.h"\ 6956 "..\..\..\pjlib\include\pj\types.h"\ 6957 "..\..\..\pjlib\include\pj\unicode.h"\ 6958 "..\..\..\pjlib\include\pjlib.h"\ 6959 "..\..\include\pjnath\config.h"\ 6960 "..\..\include\pjnath\errno.h"\ 6961 "..\..\include\pjnath\stun_config.h"\ 6962 "..\..\include\pjnath\stun_msg.h"\ 6963 "..\..\include\pjnath\stun_transaction.h"\ 6964 "..\..\include\pjnath\types.h"\ 6965 6966 6967 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4I) Debug" 6968 6969 DEP_CPP_STUN_T=\ 6970 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6971 "..\..\..\pjlib\include\pj\array.h"\ 6972 "..\..\..\pjlib\include\pj\assert.h"\ 6973 "..\..\..\pjlib\include\pj\compat\assert.h"\ 6974 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 6975 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 6976 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 6977 "..\..\..\pjlib\include\pj\compat\errno.h"\ 6978 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 6979 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 6980 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 6981 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 6982 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 6983 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 6984 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 6985 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 6986 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 6987 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 6988 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 6989 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 6990 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 6991 "..\..\..\pjlib\include\pj\compat\string.h"\ 6992 "..\..\..\pjlib\include\pj\config.h"\ 6993 "..\..\..\pjlib\include\pj\config_site.h"\ 6994 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 6995 "..\..\..\pjlib\include\pj\ctype.h"\ 6996 "..\..\..\pjlib\include\pj\errno.h"\ 6997 "..\..\..\pjlib\include\pj\except.h"\ 6998 "..\..\..\pjlib\include\pj\fifobuf.h"\ 6999 "..\..\..\pjlib\include\pj\file_access.h"\ 7000 "..\..\..\pjlib\include\pj\file_io.h"\ 7001 "..\..\..\pjlib\include\pj\guid.h"\ 7002 "..\..\..\pjlib\include\pj\hash.h"\ 7003 "..\..\..\pjlib\include\pj\ioqueue.h"\ 7004 "..\..\..\pjlib\include\pj\ip_helper.h"\ 7005 "..\..\..\pjlib\include\pj\list.h"\ 7006 "..\..\..\pjlib\include\pj\list_i.h"\ 7007 "..\..\..\pjlib\include\pj\lock.h"\ 7008 "..\..\..\pjlib\include\pj\log.h"\ 7009 "..\..\..\pjlib\include\pj\os.h"\ 7010 "..\..\..\pjlib\include\pj\pool.h"\ 7011 "..\..\..\pjlib\include\pj\pool_alt.h"\ 7012 "..\..\..\pjlib\include\pj\pool_buf.h"\ 7013 "..\..\..\pjlib\include\pj\pool_i.h"\ 7014 "..\..\..\pjlib\include\pj\rand.h"\ 7015 "..\..\..\pjlib\include\pj\rbtree.h"\ 7016 "..\..\..\pjlib\include\pj\sock.h"\ 7017 "..\..\..\pjlib\include\pj\sock_select.h"\ 7018 "..\..\..\pjlib\include\pj\string.h"\ 7019 "..\..\..\pjlib\include\pj\string_i.h"\ 7020 "..\..\..\pjlib\include\pj\timer.h"\ 7021 "..\..\..\pjlib\include\pj\types.h"\ 7022 "..\..\..\pjlib\include\pj\unicode.h"\ 7023 "..\..\..\pjlib\include\pjlib.h"\ 7024 "..\..\include\pjnath\config.h"\ 7025 "..\..\include\pjnath\errno.h"\ 7026 "..\..\include\pjnath\stun_config.h"\ 7027 "..\..\include\pjnath\stun_msg.h"\ 7028 "..\..\include\pjnath\stun_transaction.h"\ 7029 "..\..\include\pjnath\types.h"\ 7030 7031 7032 !ELSEIF "$(CFG)" == "pjnath_wince - Win32 (WCE ARMV4) Release" 7033 7034 DEP_CPP_STUN_T=\ 7035 "..\..\..\pjlib\include\pj\activesock.h"\ 7036 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 7037 "..\..\..\pjlib\include\pj\array.h"\ 7038 "..\..\..\pjlib\include\pj\assert.h"\ 7039 "..\..\..\pjlib\include\pj\compat\assert.h"\ 7040 "..\..\..\pjlib\include\pj\compat\cc_armcc.h"\ 7041 "..\..\..\pjlib\include\pj\compat\cc_codew.h"\ 7042 "..\..\..\pjlib\include\pj\compat\cc_gcc.h"\ 7043 "..\..\..\pjlib\include\pj\compat\cc_gcce.h"\ 7044 "..\..\..\pjlib\include\pj\compat\cc_msvc.h"\ 7045 "..\..\..\pjlib\include\pj\compat\cc_mwcc.h"\ 7046 "..\..\..\pjlib\include\pj\compat\ctype.h"\ 7047 "..\..\..\pjlib\include\pj\compat\errno.h"\ 7048 "..\..\..\pjlib\include\pj\compat\high_precision.h"\ 7049 "..\..\..\pjlib\include\pj\compat\m_auto.h"\ 7050 "..\..\..\pjlib\include\pj\compat\os_auto.h"\ 7051 "..\..\..\pjlib\include\pj\compat\os_darwinos.h"\ 7052 "..\..\..\pjlib\include\pj\compat\os_linux.h"\ 7053 "..\..\..\pjlib\include\pj\compat\os_linux_kernel.h"\ 7054 "..\..\..\pjlib\include\pj\compat\os_palmos.h"\ 7055 "..\..\..\pjlib\include\pj\compat\os_rtems.h"\ 7056 "..\..\..\pjlib\include\pj\compat\os_sunos.h"\ 7057 "..\..\..\pjlib\include\pj\compat\os_symbian.h"\ 7058 "..\..\..\pjlib\include\pj\compat\os_win32.h"\ 7059 "..\..\..\pjlib\include\pj\compat\os_win32_wince.h"\ 7060 "..\..\..\pjlib\include\pj\compat\setjmp.h"\ 7061 "..\..\..\pjlib\include\pj\compat\size_t.h"\ 7062 "..\..\..\pjlib\include\pj\compat\stdarg.h"\ 7063 "..\..\..\pjlib\include\pj\compat\string.h"\ 7064 "..\..\..\pjlib\include\pj\config.h"\ 7065 "..\..\..\pjlib\include\pj\config_site.h"\ 7066 "..\..\..\pjlib\include\pj\config_site_sample.h"\ 7067 "..\..\..\pjlib\include\pj\ctype.h"\ 7068 "..\..\..\pjlib\include\pj\errno.h"\ 7069 "..\..\..\pjlib\include\pj\except.h"\ 7070 "..\..\..\pjlib\include\pj\fifobuf.h"\ 7071 "..\..\..\pjlib\include\pj\file_access.h"\ 7072 "..\..\..\pjlib\include\pj\file_io.h"\ 7073 "..\..\..\pjlib\include\pj\guid.h"\ 7074 "..\..\..\pjlib\include\pj\hash.h"\ 7075 "..\..\..\pjlib\include\pj\ioqueue.h"\ 7076 "..\..\..\pjlib\include\pj\ip_helper.h"\ 7077 "..\..\..\pjlib\include\pj\list.h"\ 7078 "..\..\..\pjlib\include\pj\list_i.h"\ 7079 "..\..\..\pjlib\include\pj\lock.h"\ 7080 "..\..\..\pjlib\include\pj\log.h"\ 7081 "..\..\..\pjlib\include\pj\math.h"\ 6244 7082 "..\..\..\pjlib\include\pj\os.h"\ 6245 7083 "..\..\..\pjlib\include\pj\pool.h"\ … … 6927 7765 "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 6928 7766 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 7767 "..\..\..\pjlib\include\pj\activesock.h"\ 6929 7768 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 6930 7769 "..\..\..\pjlib\include\pj\array.h"\ … … 6972 7811 "..\..\..\pjlib\include\pj\lock.h"\ 6973 7812 "..\..\..\pjlib\include\pj\log.h"\ 7813 "..\..\..\pjlib\include\pj\math.h"\ 6974 7814 "..\..\..\pjlib\include\pj\os.h"\ 6975 7815 "..\..\..\pjlib\include\pj\pool.h"\ … … 7719 8559 "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 7720 8560 "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 8561 "..\..\..\pjlib\include\pj\activesock.h"\ 7721 8562 "..\..\..\pjlib\include\pj\addr_resolv.h"\ 7722 8563 "..\..\..\pjlib\include\pj\array.h"\ … … 7764 8605 "..\..\..\pjlib\include\pj\lock.h"\ 7765 8606 "..\..\..\pjlib\include\pj\log.h"\ 8607 "..\..\..\pjlib\include\pj\math.h"\ 7766 8608 "..\..\..\pjlib\include\pj\os.h"\ 7767 8609 "..\..\..\pjlib\include\pj\pool.h"\ -
pjproject/trunk/pjnath/include/pjnath.h
r1913 r1988 27 27 #include <pjnath/stun_msg.h> 28 28 #include <pjnath/stun_session.h> 29 #include <pjnath/stun_sock.h> 29 30 #include <pjnath/stun_transaction.h> 30 31 #include <pjnath/turn_session.h> -
pjproject/trunk/pjnath/include/pjnath/config.h
r1654 r1988 143 143 144 144 /* ************************************************************************** 145 * STUN TRANSPORT CONFIGURATION 146 */ 147 148 /** 149 * The packet buffer size for the STUN transport. 150 */ 151 #ifndef PJ_STUN_SOCK_PKT_LEN 152 # define PJ_STUN_SOCK_PKT_LEN 2000 153 #endif 154 155 156 /** 157 * The duration of the STUN keep-alive period, in seconds. 158 */ 159 #ifndef PJ_STUN_KEEP_ALIVE_SEC 160 # define PJ_STUN_KEEP_ALIVE_SEC 15 161 #endif 162 163 164 /* ************************************************************************** 165 * TURN CONFIGURATION 166 */ 167 168 /** 169 * Maximum DNS SRV entries to be processed in the DNS SRV response 170 */ 171 #ifndef PJ_TURN_MAX_DNS_SRV_CNT 172 # define PJ_TURN_MAX_DNS_SRV_CNT 4 173 #endif 174 175 176 /** 177 * Maximum TURN packet size to be supported. 178 */ 179 #ifndef PJ_TURN_MAX_PKT_LEN 180 # define PJ_TURN_MAX_PKT_LEN 3000 181 #endif 182 183 184 /** 185 * The TURN permission lifetime setting. This value should be taken from the 186 * TURN protocol specification. 187 */ 188 #ifndef PJ_TURN_PERM_TIMEOUT 189 # define PJ_TURN_PERM_TIMEOUT 300 190 #endif 191 192 193 /** 194 * The TURN channel binding lifetime. This value should be taken from the 195 * TURN protocol specification. 196 */ 197 #ifndef PJ_TURN_CHANNEL_TIMEOUT 198 # define PJ_TURN_CHANNEL_TIMEOUT 600 199 #endif 200 201 202 /** 203 * Number of seconds to refresh the permission/channel binding before the 204 * permission/channel binding expires. This value should be greater than 205 * PJ_TURN_PERM_TIMEOUT setting. 206 */ 207 #ifndef PJ_TURN_REFRESH_SEC_BEFORE 208 # define PJ_TURN_REFRESH_SEC_BEFORE 60 209 #endif 210 211 212 /** 213 * The TURN session timer heart beat interval. When this timer occurs, the 214 * TURN session will scan all the permissions/channel bindings to see which 215 * need to be refreshed. 216 */ 217 #ifndef PJ_TURN_KEEP_ALIVE_SEC 218 # define PJ_TURN_KEEP_ALIVE_SEC 15 219 #endif 220 221 222 /* ************************************************************************** 145 223 * ICE CONFIGURATION 146 224 */ -
pjproject/trunk/pjnath/include/pjnath/errno.h
r1862 r1988 122 122 123 123 124 /************************************************************ 125 * STUN SESSION/TRANSPORT ERROR CODES 126 ***********************************************************/ 127 /** 128 * @hideinitializer 129 * STUN object has been destoyed. 130 */ 131 #define PJNATH_ESTUNDESTROYED (PJNATH_ERRNO_START+60) /* 370060 */ 132 124 133 125 134 /************************************************************ -
pjproject/trunk/pjnath/include/pjnath/ice_session.h
r1654 r1988 130 130 131 131 /** 132 * Forward declaration for checklist. 133 */ 134 typedef struct pj_ice_sess_checklist pj_ice_sess_checklist; 135 136 /** 132 137 * This enumeration describes the type of an ICE candidate. 133 138 */ … … 192 197 193 198 } pj_ice_sess_comp; 199 200 201 /** 202 * Data structure to be attached to internal message processing. 203 */ 204 typedef struct pj_ice_msg_data 205 { 206 unsigned transport_id; 207 pj_bool_t has_req_data; 208 209 union data { 210 struct request_data { 211 pj_ice_sess *ice; 212 pj_ice_sess_checklist *clist; 213 unsigned ckid; 214 } req; 215 } data; 216 } pj_ice_msg_data; 194 217 195 218 … … 205 228 { 206 229 /** 230 * The candidate type, as described in #pj_ice_cand_type enumeration. 231 */ 232 pj_ice_cand_type type; 233 234 /** 235 * Status of this candidate. The value will be PJ_SUCCESS if candidate 236 * address has been resolved successfully, PJ_EPENDING when the address 237 * resolution process is in progress, or other value when the address 238 * resolution has completed with failure. 239 */ 240 pj_status_t status; 241 242 /** 207 243 * The component ID of this candidate. Note that component IDs starts 208 244 * with one for RTP and two for RTCP. In other words, it's not zero 209 245 * based. 210 246 */ 211 pj_uint32_t comp_id; 212 213 /** 214 * The candidate type, as described in #pj_ice_cand_type enumeration. 215 */ 216 pj_ice_cand_type type; 247 pj_uint8_t comp_id; 248 249 /** 250 * Transport ID to be used to send packets for this candidate. 251 */ 252 pj_uint8_t transport_id; 253 254 /** 255 * Local preference value, which typically is 65535. 256 */ 257 pj_uint16_t local_pref; 217 258 218 259 /** … … 384 425 * candidate pairs that an agent will use to generate checks. 385 426 */ 386 typedefstruct pj_ice_sess_checklist427 struct pj_ice_sess_checklist 387 428 { 388 429 /** … … 406 447 pj_timer_entry timer; 407 448 408 } pj_ice_sess_checklist;449 }; 409 450 410 451 … … 431 472 * @param ice The ICE session. 432 473 * @param comp_id ICE component ID. 474 * @param transport_id Transport ID. 433 475 * @param pkt The STUN packet. 434 476 * @param size The size of the packet. … … 437 479 */ 438 480 pj_status_t (*on_tx_pkt)(pj_ice_sess *ice, unsigned comp_id, 481 unsigned transport_id, 439 482 const void *pkt, pj_size_t size, 440 483 const pj_sockaddr_t *dst_addr, … … 447 490 * @param ice The ICE session. 448 491 * @param comp_id ICE component ID. 492 * @param transport_id Transport ID. 449 493 * @param pkt The whole packet. 450 494 * @param size Size of the packet. … … 454 498 */ 455 499 void (*on_rx_data)(pj_ice_sess *ice, unsigned comp_id, 500 unsigned transport_id, 456 501 void *pkt, pj_size_t size, 457 502 const pj_sockaddr_t *src_addr, … … 497 542 498 543 unsigned comp_id; /**< Component ID. */ 544 unsigned transport_id; /**< Transport ID. */ 499 545 500 546 pj_sockaddr src_addr; /**< Source address of request */ … … 553 599 unsigned rcand_cnt; /**< # of remote cand. */ 554 600 pj_ice_sess_cand rcand[PJ_ICE_MAX_CAND]; /**< Array of cand. */ 601 602 /* Array of transport datas */ 603 pj_ice_msg_data tp_data[4]; 555 604 556 605 /* List of eearly checks */ … … 580 629 */ 581 630 PJ_DECL(const char*) pj_ice_get_cand_type_name(pj_ice_cand_type type); 631 632 633 /** 634 * This is a utility function to retrieve the string name for the 635 * particular role type. 636 * 637 * @param role Role type. 638 * 639 * @return The string representation of the role. 640 */ 641 PJ_DECL(const char*) pj_ice_sess_role_name(pj_ice_sess_role role); 582 642 583 643 … … 686 746 * @param ice ICE session instance. 687 747 * @param comp_id Component ID of this candidate. 748 * @param transport_id Transport ID to be used to send packets for this 749 * candidate. 688 750 * @param type Candidate type. 689 751 * @param local_pref Local preference for this candidate, which … … 700 762 PJ_DECL(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, 701 763 unsigned comp_id, 764 unsigned transport_id, 702 765 pj_ice_cand_type type, 703 766 pj_uint16_t local_pref, … … 798 861 * @param ice The ICE session. 799 862 * @param comp_id Component ID. 863 * @param transport_id Number to identify where this packet was received 864 * from. This parameter will be returned back to 865 * application in \a on_tx_pkt() callback. 800 866 * @param pkt Incoming packet. 801 867 * @param pkt_size Size of incoming packet. … … 807 873 PJ_DECL(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 808 874 unsigned comp_id, 875 unsigned transport_id, 809 876 void *pkt, 810 877 pj_size_t pkt_size, -
pjproject/trunk/pjnath/include/pjnath/ice_strans.h
r1487 r1988 26 26 */ 27 27 #include <pjnath/ice_session.h> 28 #include <pjnath/stun_sock.h> 29 #include <pjnath/turn_sock.h> 28 30 #include <pjlib-util/resolver.h> 29 31 #include <pj/ioqueue.h> … … 45 47 * 46 48 * ICE stream transport, as represented by #pj_ice_strans structure, is an ICE 47 * capable c omponentfor transporting media streams within a media session.49 * capable class for transporting media streams within a media session. 48 50 * It consists of one or more transport sockets (typically two for RTP 49 51 * based communication - one for RTP and one for RTCP), and an … … 51 53 * various candidates of the transport addresses. 52 54 * 53 * \section PJNATH_ICE_STREAM_TRANSPORT_USING Using the ICE Stream Transport54 *55 * Application may use the ICE stream transport in two ways:56 * - it can create the ICE stream transports once during application57 * initialization and keep them alive throughout application lifetime, or58 * - it can create and destroy the ICE stream transport as needed everytime59 * a call is made and destroyed.60 *61 * Keeping the ICE stream transport alive throughout62 * application's lifetime is normally preferable, as initializing the63 * ICE stream transport may incur delay because the ICE stream transport64 * would need to communicate with the STUN/TURN server to get the65 * server reflexive and relayed candidates for the transports.66 *67 * Regardless of which usage scenario is being used, the ICE stream68 * transport is capable for restarting the ICE session being used and to69 * send STUN keep-alives for its STUN server reflexive and relayed70 * candidates. When ICE stream transport detects that the STUN mapped71 * address has changed in the keep-alive response, it will automatically72 * update its address to the new address, and notify the application via73 * \a on_addr_change() function of the #pj_ice_strans_cb callback.74 *75 * \subsection PJNATH_ICE_ST_TRA_INIT Initialization76 *77 * Application creates the ICE stream transport by calling78 * #pj_ice_strans_create() function. Among other things, application needs79 * to specify:80 * - STUN configuration (pj_stun_config), containing STUN settings81 * such as timeout values and the instances of timer heap and82 * ioqueue.83 * - Session name, useful for identifying this session in the log.84 * - Number of ICE components.85 * - Arbitrary user data, useful when associating the ICE session86 * with some application's data structure.87 * - A callback (#pj_ice_strans_cb) to receive events from the ICE88 * stream transport. Two of the most important fields in this89 * callback structure are \a on_rx_data() to notify application90 * about incoming data (perhaps RTP or RTCP packet), and91 * \a on_ice_complete() to notify application that ICE negotiation92 * has completed, either successfully or with failure.93 *94 * After the ICE stream transport is created, application may set up the95 * STUN servers to be used to obtain STUN server reflexive and relayed96 * candidate, by calling #pj_ice_strans_set_stun_domain() or97 * #pj_ice_strans_set_stun_srv().98 *99 * Application then creates each component by calling100 * #pj_ice_strans_create_comp(); this would create an actual socket101 * which listens to the specified local address, and it would also102 * perform lookup to find various transport address candidates for this103 * socket.104 *105 * Adding component may involve contacting STUN and TURN servers to get106 * STUN mapped address and allocate TURN relay channel, and this process107 * may take some time to complete. Once application has added all108 * components, it can check whether server reflexive and relayed109 * candidates have been acquired, by calling #pj_ice_strans_get_comps_status().110 *111 * \subsection PJNATH_ICE_ST_TRA_INIT_ICE Starting ICE Session112 *113 * When application is about to send an offer containing ICE capability,114 * or when it receives an offer containing ICE capability, it would115 * create the ICE session by calling #pj_ice_strans_init_ice(). This would116 * register all transport address aliases for each component to the ICE117 * session as candidates. After this application can enumerate all local118 * candidates by calling #pj_ice_strans_enum_cands(), and encode these119 * candidates in the SDP to be sent to remote agent.120 *121 * \subsection PJNATH_ICE_ST_TRA_START Starting Connectivity Checks122 *123 * Once application receives the SDP from remote, it pairs local candidates124 * with remote candidates, and can start ICE connectivity checks. This is125 * done by calling #pj_ice_strans_start_ice(), specifying126 * the remote candidate list, and remote username and password. If the127 * pairing process is successful, ICE connectivity checks will begin128 * immediately. The ICE session/transport will then notify the application129 * via the callback when ICE connectivity checks completes, either130 * successfully or with failure.131 *132 * \subsection PJNATH_ICE_ST_TRA_SEND_RECV Sending and Receiving Data133 *134 * Application can send data (normally RTP or RTCP packets) at any time135 * by calling #pj_ice_strans_sendto(). This function takes a destination136 * address as one of the arguments, and this destination address should137 * be taken from the default transport address of the component (that is138 * the address in SDP c= and m= lines, or in a=rtcp attribute).139 * If ICE negotiation is in progress, this function will send the data140 * to the destination address. Otherwise if ICE negotiation has completed141 * successfully, this function will send the data to the nominated remote142 * address, as negotiated by ICE.143 *144 * Upon receiving incoming data (that is a non-STUN message), the ICE145 * stream transport will notify the application by calling \a on_rx_data()146 * of the #pj_ice_strans_cb callback.147 *148 * \subsection PJNATH_ICE_ST_TRA_STOP Stopping ICE Session149 *150 * Once the call is terminated, application no longer needs to keep the151 * ICE session, so it should call #pj_ice_strans_stop_ice() to destroy the152 * ICE session within this ICE stream transport. Note that this WILL NOT153 * destroy the sockets/transports, it only destroys the ICE session154 * within this ICE stream transport. It is recommended that application155 * retains the ICE stream transport to speed up the process of setting up156 * the next call. The ICE stream transport will continue to send STUN157 * keep-alive packets to keep the NAT binding open and to detect change158 * in STUN mapped address.159 *160 * \subsection PJNATH_ICE_ST_TRA_RESTART Restarting ICE Session161 *162 * When a new call is made, application can repeat the above163 * #pj_ice_strans_init_ice() to #pj_ice_strans_stop_ice() cycle for164 * the new call, using this same ICE stream transport.165 *166 * \subsection PJNATH_ICE_ST_TRA_DESTROY Destroying ICE Stream Transport167 *168 * Finally, when the ICE stream transport itself is no longer needed,169 * for example when the application quits, application should call170 * #pj_ice_strans_destroy() to release back all resources allocated by this171 * ICE stream transport.172 *173 55 */ 174 56 175 57 /** Forward declaration for ICE stream transport. */ 176 58 typedef struct pj_ice_strans pj_ice_strans; 59 60 /** Transport operation types to be reported on \a on_status() callback */ 61 typedef enum pj_ice_strans_op 62 { 63 /** Initialization (candidate gathering) */ 64 PJ_ICE_STRANS_OP_INIT, 65 66 /** Negotiation */ 67 PJ_ICE_STRANS_OP_NEGOTIATION 68 69 } pj_ice_strans_op; 177 70 178 71 /** … … 201 94 202 95 /** 203 * This callback will be called when ICE checks have completed. 204 * This callback is optional. 96 * Callback to report status. 205 97 * 206 98 * @param ice_st The ICE stream transport. 207 * @param status The ICE connectivity check status. 99 * @param op The operation 100 * @param status Operation status. 208 101 */ 209 102 void (*on_ice_complete)(pj_ice_strans *ice_st, 103 pj_ice_strans_op op, 210 104 pj_status_t status); 211 105 212 /** 213 * This callback will be called when ICE transport has detected that 214 * the STUN mapped address of a candidate has changed. 106 } pj_ice_strans_cb; 107 108 109 /** 110 * This structure describes ICE stream transport configuration. Application 111 * should initialize the structure by calling #pj_ice_strans_cfg_default() 112 * before changing the settings. 113 */ 114 typedef struct pj_ice_strans_cfg 115 { 116 /** 117 * Address family, IPv4 or IPv6. Currently only pj_AF_INET() (IPv4) 118 * is supported, and this is the default value. 119 */ 120 int af; 121 122 /** 123 * STUN configuration which contains the timer heap and 124 * ioqueue instance to be used, and STUN retransmission 125 * settings. This setting is mandatory. 215 126 * 216 * @param ice_st The ICE stream transport. 217 * @param comp_id Component ID. 218 * @param cand_id Candidate ID. 219 */ 220 void (*on_addr_change)(pj_ice_strans *ice_st, 221 unsigned comp_id, 222 unsigned cand_id); 223 224 } pj_ice_strans_cb; 225 226 227 /** 228 * Various flags that can be specified when creating a component with 229 * #pj_ice_strans_create_comp(). These options may be combined together 230 * with bitmask operation. 231 */ 232 enum pj_ice_strans_option 233 { 234 /** 235 * If this option is specified, only a listening socket will be 236 * created for the component, and no candidate will be added to 237 * the component. Application must add the component manually 238 * by inspecting the socket and transport address of the component. 239 */ 240 PJ_ICE_ST_OPT_DONT_ADD_CAND = 1, 241 242 /** 243 * If this option is specified, then no STUN reflexive candidate 244 * will be added to the component. 245 */ 246 PJ_ICE_ST_OPT_DISABLE_STUN = 2, 247 248 /** 249 * If this option is specified, then no STUN relay candidate 250 * will be added to the component. 251 */ 252 PJ_ICE_ST_OPT_DISABLE_RELAY = 4, 253 254 /** 255 * If this option is specified, then when the function fails to 256 * bind the socket to the specified port, it WILL NOT try to 257 * bind the socket to the next available port. 127 * The default value is all zero. Application must initialize 128 * this setting with #pj_stun_config_init(). 129 */ 130 pj_stun_config stun_cfg; 131 132 /** 133 * DNS resolver to be used to resolve servers. If DNS SRV 134 * resolution is required, the resolver must be set. 258 135 * 259 * If this option is NOT specified, then the function will try to 260 * bind the socket to next port+2, repetitively until the socket 261 * is bound successfully. 262 */ 263 PJ_ICE_ST_OPT_NO_PORT_RETRY = 8, 264 }; 265 266 267 /** 268 * This structure describes ICE stream transport candidate. A "candidate" 269 * in ICE stream transport can be viewed as alias transport address 270 * for the socket. 271 */ 272 typedef struct pj_ice_strans_cand 273 { 274 /** 275 * Candidate type. 276 */ 277 pj_ice_cand_type type; 278 279 /** 280 * Status of this candidate. This status is useful for ICE reflexive 281 * and relay candidate, where the address needs to be resolved 282 * asynchronously by sending STUN request to STUN server. 283 * 284 * The value will be PJ_SUCCESS if candidate address has been resolved 285 * successfully, PJ_EPENDING when the address resolution process is 286 * in progress, or other value when the address resolution has 287 * completed with failure. 288 */ 289 pj_status_t status; 290 291 /** 292 * The candidate transport address. 293 */ 294 pj_sockaddr addr; 295 296 /** 297 * The ICE session candidate ID after this candidate has been registered 298 * to an ICE session. Before ICE session is created, or after ICE 299 * session has been destroyed, the value will be -1. 300 */ 301 int ice_cand_id; 302 303 /** 304 * Local preference value, which typically is 65535. 305 */ 306 pj_uint16_t local_pref; 307 308 /** 309 * Foundation associated with this candidate, which value normally will be 310 * calculated by the function. 311 */ 312 pj_str_t foundation; 313 314 } pj_ice_strans_cand; 315 316 317 /** 318 * This structure describes an ICE stream transport component. A component 319 * in ICE stream transport typically corresponds to a single socket created 320 * for this component, and bound to a specific transport address. This 321 * component may have multiple alias addresses, for example one alias 322 * address for each interfaces in multi-homed host, another for server 323 * reflexive alias, and another for relayed alias. For each transport 324 * address alias, an ICE stream transport candidate (#pj_ice_strans_cand) will 325 * be created, and these candidates will eventually registered to the ICE 326 * session. 327 */ 328 typedef struct pj_ice_strans_comp 329 { 330 pj_ice_strans *ice_st; /**< ICE stream transport. */ 331 unsigned comp_id; /**< Component ID. */ 332 pj_uint32_t options; /**< Option flags. */ 333 pj_sock_t sock; /**< Socket descriptor. */ 334 335 pj_stun_session *stun_sess; /**< STUN session. */ 336 pj_uint8_t ka_tsx_id[12]; /**< ID for keep STUN alives */ 337 338 pj_sockaddr local_addr; /**< Local/base address. */ 339 340 unsigned pending_cnt; /**< Pending resolution cnt. */ 341 pj_status_t last_status; /**< Last status. */ 342 343 unsigned cand_cnt; /**< # of candidates/aliaes. */ 344 pj_ice_strans_cand cand_list[PJ_ICE_ST_MAX_CAND]; /**< Cand array */ 345 int default_cand; /**< Default candidate selected */ 346 347 pj_ioqueue_key_t *key; /**< ioqueue key. */ 348 pj_uint8_t pkt[1500]; /**< Incoming packet buffer. */ 349 pj_ioqueue_op_key_t read_op; /**< ioqueue read operation key */ 350 pj_ioqueue_op_key_t write_op; /**< ioqueue write op. key */ 351 pj_sockaddr src_addr; /**< source packet address buf. */ 352 int src_addr_len; /**< length of src addr. buf. */ 353 354 } pj_ice_strans_comp; 355 356 357 /** 358 * This structure represents the ICE stream transport. 359 */ 360 struct pj_ice_strans 361 { 362 char obj_name[PJ_MAX_OBJ_NAME]; /**< Log ID. */ 363 364 pj_pool_t *pool; /**< Pool used by this object. */ 365 void *user_data; /**< Application data. */ 366 pj_stun_config stun_cfg; /**< STUN settings. */ 367 pj_ice_strans_cb cb; /**< Application callback. */ 368 369 pj_ice_sess *ice; /**< ICE session. */ 370 371 unsigned comp_cnt; /**< Number of components. */ 372 pj_ice_strans_comp **comp; /**< Components array. */ 373 374 pj_dns_resolver *resolver; /**< The resolver instance. */ 375 pj_bool_t has_rjob; /**< Has pending resolve? */ 376 pj_sockaddr_in stun_srv; /**< STUN server address. */ 377 pj_sockaddr_in turn_srv; /**< TURN server address. */ 378 379 pj_timer_entry ka_timer; /**< STUN keep-alive timer. */ 380 }; 381 382 383 /** 384 * Create the ICE stream transport containing the specified number of 385 * components. After the ICE stream transport is created, application 386 * may initialize the STUN server settings, and after that it has to 387 * initialize each components by calling #pj_ice_strans_create_comp() 388 * function. 389 * 390 * @param stun_cfg The STUN settings. 136 * The default value is NULL. 137 */ 138 pj_dns_resolver *resolver; 139 140 /** 141 * STUN and local transport settings. This specifies the 142 * settings for local UDP socket, which will be resolved 143 * to get the STUN mapped address. 144 */ 145 struct { 146 /** 147 * Optional configuration for STUN transport. The default 148 * value will be initialized with #pj_stun_sock_cfg_default(). 149 */ 150 pj_stun_sock_cfg cfg; 151 152 /** 153 * Disable host candidates. When this option is set, no 154 * host candidates will be added. 155 * 156 * Default: PJ_FALSE 157 */ 158 pj_bool_t no_host_cands; 159 160 /** 161 * Include loopback addresses in the host candidates. 162 * 163 * Default: PJ_FALSE 164 */ 165 pj_bool_t loop_addr; 166 167 /** 168 * Specify the STUN server domain or hostname or IP address. 169 * If DNS SRV resolution is required, application must fill 170 * in this setting with the domain name of the STUN server 171 * and set the resolver instance in the \a resolver field. 172 * Otherwise if the \a resolver setting is not set, this 173 * field will be resolved with hostname resolution and in 174 * this case the \a port field must be set. 175 * 176 * The \a port field should also be set even when DNS SRV 177 * resolution is used, in case the DNS SRV resolution fails. 178 * 179 * When this field is empty, STUN mapped address resolution 180 * will not be performed. In this case only ICE host candidates 181 * will be added to the ICE transport, unless if \a no_host_cands 182 * field is set. In this case, both host and srflx candidates 183 * are disabled. 184 * 185 * The default value is empty. 186 */ 187 pj_str_t server; 188 189 /** 190 * The port number of the STUN server, when \a server 191 * field specifies a hostname rather than domain name. This 192 * field should also be set even when the \a server 193 * specifies a domain name, to allow DNS SRV resolution 194 * to fallback to DNS A/AAAA resolution when the DNS SRV 195 * resolution fails. 196 * 197 * The default value is PJ_STUN_PORT. 198 */ 199 pj_uint16_t port; 200 201 } stun; 202 203 /** 204 * TURN specific settings. 205 */ 206 struct { 207 /** 208 * Specify the TURN server domain or hostname or IP address. 209 * If DNS SRV resolution is required, application must fill 210 * in this setting with the domain name of the TURN server 211 * and set the resolver instance in the \a resolver field. 212 * Otherwise if the \a resolver setting is not set, this 213 * field will be resolved with hostname resolution and in 214 * this case the \a port field must be set. 215 * 216 * The \a port field should also be set even when DNS SRV 217 * resolution is used, in case the DNS SRV resolution fails. 218 * 219 * When this field is empty, relay candidate will not be 220 * created. 221 * 222 * The default value is empty. 223 */ 224 pj_str_t server; 225 226 /** 227 * The port number of the TURN server, when \a server 228 * field specifies a hostname rather than domain name. This 229 * field should also be set even when the \a server 230 * specifies a domain name, to allow DNS SRV resolution 231 * to fallback to DNS A/AAAA resolution when the DNS SRV 232 * resolution fails. 233 * 234 * Default is zero. 235 */ 236 pj_uint16_t port; 237 238 /** 239 * Type of connection to the TURN server. 240 * 241 * Default is PJ_TURN_TP_UDP. 242 */ 243 pj_turn_tp_type conn_type; 244 245 /** 246 * Credential to be used for the TURN session. This setting 247 * is mandatory. 248 * 249 * Default is to have no credential. 250 */ 251 pj_stun_auth_cred auth_cred; 252 253 /** 254 * Optional TURN Allocate parameter. The default value will be 255 * initialized by #pj_turn_alloc_param_default(). 256 */ 257 pj_turn_alloc_param alloc_param; 258 259 } turn; 260 261 } pj_ice_strans_cfg; 262 263 264 /** 265 * Initialize ICE transport configuration with default values. 266 * 267 * @param cfg The configuration to be initialized. 268 */ 269 PJ_DECL(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg); 270 271 272 /** 273 * Copy configuration. 274 * 275 * @param pool Pool. 276 * @param dst Destination. 277 * @param src Source. 278 */ 279 PJ_DECL(void) pj_ice_strans_cfg_copy(pj_pool_t *pool, 280 pj_ice_strans_cfg *dst, 281 const pj_ice_strans_cfg *src); 282 283 284 /** 285 * Create and initialize the ICE stream transport with the specified 286 * parameters. 287 * 391 288 * @param name Optional name for logging identification. 289 * @param cfg Configuration. 392 290 * @param comp_cnt Number of components. 393 291 * @param user_data Arbitrary user data to be associated with this … … 400 298 * successfully. 401 299 */ 402 PJ_DECL(pj_status_t) pj_ice_strans_create( pj_stun_config *stun_cfg,403 const char *name,300 PJ_DECL(pj_status_t) pj_ice_strans_create(const char *name, 301 const pj_ice_strans_cfg *cfg, 404 302 unsigned comp_cnt, 405 303 void *user_data, … … 420 318 421 319 /** 422 * Set the domain to be used when resolving the STUN servers. If application 423 * wants to utillize STUN, then STUN server must be specified, either by 424 * calling this function or by calling #pj_ice_strans_set_stun_srv(). 425 * 426 * If application calls this function, then the STUN/TURN servers will 427 * be resolved by querying DNS SRV records for the specified domain. 428 * 429 * @param ice_st The ICE stream transport. 430 * @param resolver The resolver instance that will be used to 431 * resolve the STUN/TURN servers. 432 * @param domain The target domain. 433 * 434 * @return PJ_SUCCESS if DNS SRV resolution job can be 435 * started. The resolution process itself will 436 * complete asynchronously. 437 */ 438 PJ_DECL(pj_status_t) pj_ice_strans_set_stun_domain(pj_ice_strans *ice_st, 439 pj_dns_resolver *resolver, 440 const pj_str_t *domain); 441 442 /** 443 * Set the STUN and TURN server addresses. If application 444 * wants to utillize STUN, then STUN server must be specified, either by 445 * calling this function or by calling #pj_ice_strans_set_stun_domain(). 446 * 447 * With this function, the STUN and TURN server addresses will be 448 * assigned immediately, that is no DNS resolution will need to be 449 * performed. 450 * 451 * @param ice_st The ICE stream transport. 452 * @param stun_srv The STUN server address, or NULL if STUN 453 * reflexive candidate is not to be used. 454 * @param turn_srv The TURN server address, or NULL if STUN 455 * relay candidate is not to be used. 456 * 457 * @return PJ_SUCCESS, or the appropriate error code. 458 */ 459 PJ_DECL(pj_status_t) 460 pj_ice_strans_set_stun_srv( pj_ice_strans *ice_st, 461 const pj_sockaddr_in *stun_srv, 462 const pj_sockaddr_in *turn_srv); 463 464 /** 465 * Create and initialize the specified component. This function will 466 * instantiate the socket descriptor for this component, optionally 467 * bind the socket to the specified address (or bind to any address/port 468 * if the \a addr parameter is NULL), and start finding all alias 469 * addresses for this socket. For each alias addresses that if finds, 470 * it will add an ICE stream transport candidate for this component. 471 * 472 * After all components have been initialized, application should poll 473 * the #pj_ice_strans_get_comps_status() peridically to check if STUN 474 * server reflexive and relayed candidates have been obtained 475 * successfully. 476 * 477 * @param ice_st The ICE stream transport. 478 * @param comp_id The component ID, which value must be greater than 479 * zero and less than or equal to the number of 480 * components in this ICE stream transport. 481 * @param options Options, see #pj_ice_strans_option. 482 * @param addr Local address where socket will be bound to. This 483 * address will be used as follows: 484 * - if the value is NULL, then socket will be bound 485 * to any available port. 486 * - if the value is not NULL, then if the port number 487 * is not zero, it will used as the starting port 488 * where the socket will be bound to. If bind() to 489 * this port fails, this function will try to bind 490 * to port+2, repeatedly until it succeeded. 491 * If application doesn't want this function to 492 * retry binding the socket to other port, it can 493 * specify PJ_ICE_ST_OPT_NO_PORT_RETRY option. 494 * - if the value is not NULL, then if the address 495 * is not INADDR_ANY, this function will bind the 496 * socket to this particular interface only, and 497 * no other host candidates will be added for this 498 * socket. 499 * 500 * 501 * @return PJ_SUCCESS, or the appropriate error code. 502 */ 503 PJ_DECL(pj_status_t) pj_ice_strans_create_comp(pj_ice_strans *ice_st, 504 unsigned comp_id, 505 pj_uint32_t options, 506 const pj_sockaddr_in *addr); 507 508 /** 509 * Manually add a candidate (transport address alias) for the specified 510 * component. Normally application shouldn't need to use this function, 511 * as candidates will be added automatically when component is created 512 * with #pj_ice_strans_create_comp(). 513 * 514 * @param ice_st ICE stream transport. 515 * @param comp_id The component ID. 516 * @param type The candidate type. 517 * @param local_pref The local preference for this candidate 518 * (typically the value is 65535). 519 * @param addr The candidate address. 520 * @param set_default Set to non-zero to make this candidate the 521 * default candidate for this component. 522 * 523 * @return PJ_SUCCESS, or the appropriate error code. 524 */ 525 PJ_DECL(pj_status_t) pj_ice_strans_add_cand(pj_ice_strans *ice_st, 526 unsigned comp_id, 527 pj_ice_cand_type type, 528 pj_uint16_t local_pref, 529 const pj_sockaddr_in *addr, 530 pj_bool_t set_default); 531 532 /** 533 * Get the status of components in the ICE stream transports. Since 534 * some IP address candidates have to be obtained asynchronously (for 535 * example, the STUN reflexive or relay candidate), application can 536 * use this function to know whether the address resolution has 537 * completed. 538 * 539 * @param ice_st The ICE stream transport. 540 * 541 * @return PJ_SUCCESS if all candidates have been resolved 542 * successfully, PJ_EPENDING if transport resolution 543 * is still in progress, or other status on failure. 544 */ 545 PJ_DECL(pj_status_t) pj_ice_strans_get_comps_status(pj_ice_strans *ice_st); 320 * Get the user data associated with the ICE stream transport. 321 * 322 * @param ice_st The ICE stream transport. 323 * 324 * @return The user data. 325 */ 326 PJ_DECL(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st); 327 546 328 547 329 /** 548 330 * Initialize the ICE session in the ICE stream transport. 331 * When application is about to send an offer containing ICE capability, 332 * or when it receives an offer containing ICE capability, it must 333 * call this function to initialize the internal ICE session. This would 334 * register all transport address aliases for each component to the ICE 335 * session as candidates. Then application can enumerate all local 336 * candidates by calling #pj_ice_strans_enum_cands(), and encode these 337 * candidates in the SDP to be sent to remote agent. 549 338 * 550 339 * @param ice_st The ICE stream transport. … … 561 350 562 351 /** 563 * Enumerate the local candidates . This function can only be called564 * after the ICE session has been created in the ICE stream transport.565 * 566 * @param ice_st The ICE stream transport.352 * Enumerate the local candidates for the specified component. 353 * 354 * @param ice_st The ICE stream transport. 355 * @param comp_id Component ID. 567 356 * @param count On input, it specifies the maximum number of 568 357 * elements. On output, it will be filled with … … 574 363 */ 575 364 PJ_DECL(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st, 365 unsigned comp_id, 576 366 unsigned *count, 577 367 pj_ice_sess_cand cand[]); 578 368 579 369 /** 370 * Get the default candidate for the specified component. When this 371 * function is called before ICE negotiation completes, the default 372 * candidate is selected according to local preference criteria. When 373 * this function is called after ICE negotiation completes, the 374 * default candidate is the candidate that forms the valid pair. 375 * 376 * @param ice_st The ICE stream transport. 377 * @param comp_id Component ID. 378 * @param cand Pointer to receive the default candidate 379 * information. 380 */ 381 PJ_DECL(pj_status_t) pj_ice_strans_get_def_cand(pj_ice_strans *ice_st, 382 unsigned comp_id, 383 pj_ice_sess_cand *cand); 384 385 /** 386 * Get the current ICE role. ICE session must have been initialized 387 * before this function can be called. 388 * 389 * @param ice_st The ICE stream transport. 390 * 391 * @return Current ICE role. 392 */ 393 PJ_DECL(pj_ice_sess_role) pj_ice_strans_get_role(pj_ice_strans *ice_st); 394 395 396 /** 397 * Change session role. This happens for example when ICE session was 398 * created with controlled role when receiving an offer, but it turns out 399 * that the offer contains "a=ice-lite" attribute when the SDP gets 400 * inspected. ICE session must have been initialized before this function 401 * can be called. 402 * 403 * @param ice_st The ICE stream transport. 404 * @param new_role The new role to be set. 405 * 406 * @return PJ_SUCCESS on success, or the appropriate error. 407 */ 408 PJ_DECL(pj_status_t) pj_ice_strans_change_role(pj_ice_strans *ice_st, 409 pj_ice_sess_role new_role); 410 411 412 /** 580 413 * Start ICE connectivity checks. This function can only be called 581 * after the ICE session has been created in the ICE stream transport. 582 * 583 * This function will pair the local and remote candidates to create 584 * check list. Once the check list is created and sorted based on the 585 * priority, ICE periodic checks will be started. This function will 586 * return immediately, and application will be notified about the 587 * connectivity check status in the callback. 414 * after the ICE session has been created in the ICE stream transport 415 * with #pj_ice_strans_init_ice(). 416 * 417 * This function must be called once application has received remote 418 * candidate list (typically from the remote SDP). This function pairs 419 * local candidates with remote candidates, and starts ICE connectivity 420 * checks. The ICE session/transport will then notify the application 421 * via the callback when ICE connectivity checks completes, either 422 * successfully or with failure. 588 423 * 589 424 * @param ice_st The ICE stream transport. … … 592 427 * @param rem_passwd Remote password, as seen in the SDP received from 593 428 * the remote agent. 594 * @param r em_cand_cnt Number of remote candidates.595 * @param r em_cand Remote candidatearray.429 * @param rcand_cnt Number of remote candidates in the array. 430 * @param rcand Remote candidates array. 596 431 * 597 432 * @return PJ_SUCCESS, or the appropriate error code. 598 433 */ 599 PJ_DECL(pj_status_t) 600 pj_ice_strans_start_ice( pj_ice_strans *ice_st, 601 const pj_str_t *rem_ufrag, 602 const pj_str_t *rem_passwd, 603 unsigned rem_cand_cnt, 604 const pj_ice_sess_cand rem_cand[]); 605 606 /** 607 * Stop and destroy the ICE session inside this media transport. 434 PJ_DECL(pj_status_t) pj_ice_strans_start_ice(pj_ice_strans *ice_st, 435 const pj_str_t *rem_ufrag, 436 const pj_str_t *rem_passwd, 437 unsigned rcand_cnt, 438 const pj_ice_sess_cand rcand[]); 439 440 /** 441 * Retrieve the candidate pair that has been nominated and successfully 442 * checked for the specified component. If ICE negotiation is still in 443 * progress or it has failed, this function will return NULL. 444 * 445 * @param ice_st The ICE stream transport. 446 * @param comp_id Component ID. 447 * 448 * @return The valid pair as ICE checklist structure if the 449 * pair exist. 450 */ 451 PJ_DECL(const pj_ice_sess_check*) 452 pj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st, 453 unsigned comp_id); 454 455 /** 456 * Stop and destroy the ICE session inside this media transport. Application 457 * needs to call this function once the media session is over (the call has 458 * been disconnected). 459 * 460 * Application MAY reuse this ICE stream transport for subsequent calls. 461 * In this case, it must call #pj_ice_strans_stop_ice() when the call is 462 * disconnected, and reinitialize the ICE stream transport for subsequent 463 * call with #pj_ice_strans_init_ice()/#pj_ice_strans_start_ice(). In this 464 * case, the ICE stream transport will maintain the internal sockets and 465 * continue to send STUN keep-alive packets and TURN Refresh request to 466 * keep the NAT binding/TURN allocation open and to detect change in STUN 467 * mapped address. 468 * 469 * If application does not want to reuse the ICE stream transport for 470 * subsequent calls, it must call #pj_ice_strans_destroy() to destroy the 471 * ICE stream transport altogether. 608 472 * 609 473 * @param ice_st The ICE stream transport. … … 615 479 616 480 /** 617 * Send outgoing packet using this transport. If ICE checks have not 618 * produced a valid check for the specified component ID, this function 619 * send to the destination address. Otherwise it will send the packet to 620 * remote destination using the nominated local candidate as have been checked 621 * previously. 481 * Send outgoing packet using this transport. 482 * Application can send data (normally RTP or RTCP packets) at any time 483 * by calling this function. This function takes a destination 484 * address as one of the arguments, and this destination address should 485 * be taken from the default transport address of the component (that is 486 * the address in SDP c= and m= lines, or in a=rtcp attribute). 487 * If ICE negotiation is in progress, this function will send the data 488 * to the destination address. Otherwise if ICE negotiation has completed 489 * successfully, this function will send the data to the nominated remote 490 * address, as negotiated by ICE. 622 491 * 623 492 * @param ice_st The ICE stream transport. -
pjproject/trunk/pjnath/include/pjnath/nat_detect.h
r1501 r1988 33 33 * @defgroup PJNATH_NAT_DETECT NAT Classification/Detection Tool 34 34 * @brief NAT Classification/Detection Tool 35 * @ingroup PJNATH_ICE36 35 * @{ 37 36 * -
pjproject/trunk/pjnath/include/pjnath/stun_config.h
r1374 r1988 26 26 27 27 #include <pjnath/stun_msg.h> 28 #include <pj/assert.h> 29 #include <pj/errno.h> 28 30 #include <pj/string.h> 29 31 … … 104 106 105 107 /** 108 * Check that STUN config is valid. 109 */ 110 PJ_INLINE(pj_status_t) pj_stun_config_check_valid(const pj_stun_config *cfg) 111 { 112 PJ_ASSERT_RETURN(cfg->ioqueue && cfg->pf && cfg->timer_heap && 113 cfg->rto_msec && cfg->res_cache_msec, PJ_EINVAL); 114 return PJ_SUCCESS; 115 } 116 117 118 /** 106 119 * @} 107 120 */ -
pjproject/trunk/pjnath/include/pjnath/stun_msg.h
r1924 r1988 35 35 /** 36 36 * @defgroup PJNATH_STUN_MSG STUN Message Representation and Parsing 37 * @ingroup PJNATH_STUN 37 38 * @brief Low-level representation and parsing of STUN messages. 38 * @ingroup PJNATH_STUN39 39 * @{ 40 40 */ … … 956 956 * This describes the TURN REQUESTED-PROPS attribute, encoded as 957 957 * STUN 32bit integer attribute. Few macros are provided to manipulate 958 * the values in this attribute: #PJ_STUN_GET_RPP_BITS(), 959 * #PJ_STUN_SET_RPP_BITS(), #PJ_STUN_GET_RPP_PORT(), and 960 * #PJ_STUN_SET_RPP_PORT(). 958 * the values in this attribute: #PJ_STUN_GET_PROP_TYPE(), and 959 * #PJ_STUN_SET_PROP_TYPE(). 961 960 * 962 961 * This attribute allows the client to request certain properties for … … 1165 1164 * #pj_stun_msg_check() and #pj_stun_msg_decode() to disable the 1166 1165 * verification of FINGERPRINT, for example when the STUN usage says when 1167 * FINGERPRINT mechanism shall not *be used.1166 * FINGERPRINT mechanism shall not be used. 1168 1167 */ 1169 1168 PJ_STUN_NO_FINGERPRINT_CHECK = 8 … … 1293 1292 * 1294 1293 * If application wants to apply credential to the message, it MUST 1295 * include a blank MESSAGE-INTEGRITY attribute in the message ,as the1294 * include a blank MESSAGE-INTEGRITY attribute in the message as the 1296 1295 * last attribute or the attribute before FINGERPRINT. This function will 1297 1296 * calculate the HMAC digest from the message using the supplied key in … … 1321 1320 PJ_DECL(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg, 1322 1321 pj_uint8_t *pkt_buf, 1323 unsignedbuf_size,1322 pj_size_t buf_size, 1324 1323 unsigned options, 1325 1324 const pj_str_t *key, 1326 unsigned*p_msg_len);1325 pj_size_t *p_msg_len); 1327 1326 1328 1327 /** … … 1346 1345 */ 1347 1346 PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, 1348 unsignedpdu_len, unsigned options);1347 pj_size_t pdu_len, unsigned options); 1349 1348 1350 1349 … … 1372 1371 PJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, 1373 1372 const pj_uint8_t *pdu, 1374 unsignedpdu_len,1373 pj_size_t pdu_len, 1375 1374 unsigned options, 1376 1375 pj_stun_msg **p_msg, 1377 unsigned*p_parsed_len,1376 pj_size_t *p_parsed_len, 1378 1377 pj_stun_msg **p_response); 1379 1378 -
pjproject/trunk/pjnath/include/pjnath/stun_session.h
r1913 r1988 214 214 struct pj_stun_tx_data 215 215 { 216 /** PJLIB list interface */ 216 217 PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data); 217 218 … … 238 239 pj_timer_entry res_timer; /**< Response cache timer. */ 239 240 }; 241 242 243 /** 244 * These are the flags to control the message logging in the STUN session. 245 */ 246 typedef enum pj_stun_sess_msg_log_flag 247 { 248 PJ_STUN_SESS_LOG_TX_REQ=1, /**< Log outgoing STUN requests. */ 249 PJ_STUN_SESS_LOG_TX_RES=2, /**< Log outgoing STUN responses. */ 250 PJ_STUN_SESS_LOG_TX_IND=4, /**< Log outgoing STUN indications. */ 251 252 PJ_STUN_SESS_LOG_RX_REQ=8, /**< Log incoming STUN requests. */ 253 PJ_STUN_SESS_LOG_RX_RES=16, /**< Log incoming STUN responses */ 254 PJ_STUN_SESS_LOG_RX_IND=32 /**< Log incoming STUN indications */ 255 } pj_stun_sess_msg_log_flag; 240 256 241 257 … … 259 275 260 276 /** 261 * Destroy the STUN session. 262 * 263 * @param sess The STUN session instance. 264 * 265 * @return PJ_SUCCESS on success, or the appropriate error code. 277 * Destroy the STUN session and all objects created in the context of 278 * this session. 279 * 280 * @param sess The STUN session instance. 281 * 282 * @return PJ_SUCCESS on success, or the appropriate error code. 283 * This function will return PJ_EPENDING if the operation 284 * cannot be performed immediately because callbacks are 285 * being called; in this case the session will be destroyed 286 * as soon as the last callback returns. 266 287 */ 267 288 PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess); … … 334 355 pj_stun_auth_type auth_type, 335 356 const pj_stun_auth_cred *cred); 357 /** 358 * Configure message logging. By default all flags are enabled. 359 * 360 * @param sess The STUN session instance. 361 * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag 362 */ 363 PJ_DECL(void) pj_stun_session_set_log(pj_stun_session *sess, 364 unsigned flags); 336 365 337 366 /** … … 382 411 * 383 412 * @param sess The STUN session instance. 384 * @param r eqThe STUN request where the response is to be created.413 * @param rdata The STUN request where the response is to be created. 385 414 * @param err_code Error code to be set in the response, if error response 386 415 * is to be created, according to pj_stun_status enumeration. … … 433 462 * 434 463 * @return PJ_SUCCESS on success, or the appropriate error code. 464 * This function will return PJNATH_ESTUNDESTROYED if 465 * application has destroyed the session in 466 * \a on_send_msg() callback. 435 467 */ 436 468 PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess, … … 450 482 * @param sess The STUN session instance. 451 483 * @param rdata The STUN request message to be responded. 452 * @param err_codeError code to be set in the response, if error response484 * @param code Error code to be set in the response, if error response 453 485 * is to be created, according to pj_stun_status enumeration. 454 486 * This argument MUST be zero if successful response is … … 473 505 * 474 506 * @return PJ_SUCCESS on success, or the appropriate error code. 507 * This function will return PJNATH_ESTUNDESTROYED if 508 * application has destroyed the session in 509 * \a on_send_msg() callback. 475 510 */ 476 511 PJ_DECL(pj_status_t) pj_stun_session_respond(pj_stun_session *sess, … … 497 532 * 498 533 * @return PJ_SUCCESS if transaction is successfully cancelled. 534 * This function will return PJNATH_ESTUNDESTROYED if 535 * application has destroyed the session in 536 * \a on_request_complete() callback. 499 537 */ 500 538 PJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess, … … 512 550 * 513 551 * @return PJ_SUCCESS on success, or the appropriate error. 552 * This function will return PJNATH_ESTUNDESTROYED if 553 * application has destroyed the session in \a on_send_msg() 554 * callback. 514 555 */ 515 556 PJ_DECL(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess, … … 549 590 * 550 591 * @return PJ_SUCCESS on success, or the appropriate error code. 592 * This function will return PJNATH_ESTUNDESTROYED if 593 * application has destroyed the session in one of the 594 * callback. 551 595 */ 552 596 PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, -
pjproject/trunk/pjnath/include/pjnath/stun_transaction.h
r1374 r1988 90 90 * 91 91 * @return If return value of the callback is not PJ_SUCCESS, 92 * the transaction will fail. 92 * the transaction will fail. Application MUST return 93 * PJNATH_ESTUNDESTROYED if it has destroyed the 94 * transaction in this callback. 93 95 */ 94 96 pj_status_t (*on_send_msg)(pj_stun_client_tsx *tsx, … … 162 164 * @param tsx The STUN transaction. 163 165 * 164 * @return PJ_SUCCESS on success, or the appropriate error code. 166 * @return PJ_SUCCESS on success or PJ_EINVAL if the parameter 167 * is NULL. 165 168 */ 166 169 PJ_DECL(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx); … … 215 218 * @param pkt_len Length of STUN packet. 216 219 * 217 * @return PJ_SUCCESS on success or the appropriate error code. 220 * @return PJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED 221 * when the user has destroyed the transaction in 222 * \a on_send_msg() callback, or any other error code 223 * as returned by \a on_send_msg() callback. 218 224 */ 219 225 PJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx, … … 229 235 * @param tsx The STUN client transaction instance. 230 236 * 231 * @return PJ_SUCCESS on success or the appropriate error code. 237 * @return PJ_SUCCESS on success, or PJNATH_ESTUNDESTROYED 238 * when the user has destroyed the transaction in 239 * \a on_send_msg() callback, or any other error code 240 * as returned by \a on_send_msg() callback. 232 241 */ 233 242 PJ_DECL(pj_status_t) pj_stun_client_tsx_retransmit(pj_stun_client_tsx *tsx); -
pjproject/trunk/pjnath/include/pjnath/turn_session.h
r1914 r1988 30 30 PJ_BEGIN_DECL 31 31 32 /** 33 * @defgroup PJNATH_TURN TURN Client Library 34 */ 35 36 32 37 /* **************************************************************************/ 33 38 /** 34 * @defgroup PJNATH_TURN_SESSION T URN client session39 * @defgroup PJNATH_TURN_SESSION Transport independent TURN client session 35 40 * @brief Transport independent TURN client session 36 * @ingroup PJNATH_ STUN41 * @ingroup PJNATH_TURN 37 42 * @{ 43 * 44 * This module describes the transport independent TURN client session. This 45 * interface is provided for implementors of a TURN client transport, and 46 * application usually will want to use \ref PJNATH_TURN_SOCK instead. 47 * 48 * The transport independent TURN client session is created to facilitate 49 * the creation of different types of transports between the client and the 50 * TURN server. 38 51 */ 39 52 … … 42 55 */ 43 56 typedef struct pj_turn_session pj_turn_session; 44 45 46 #define PJ_TURN_INVALID_CHANNEL 0xFFFF47 #define PJ_TURN_CHANNEL_MIN 0x400048 #define PJ_TURN_CHANNEL_MAX 0xFFFE /* inclusive */49 #define PJ_TURN_NO_TIMEOUT ((long)0x7FFFFFFF)50 #define PJ_TURN_MAX_PKT_LEN 300051 #define PJ_TURN_PERM_TIMEOUT 300 /* Must be greater than REFRESH_SEC_BEFORE */52 #define PJ_TURN_CHANNEL_TIMEOUT 600 /* Must be greater than REFRESH_SEC_BEFORE */53 #define PJ_TURN_REFRESH_SEC_BEFORE 6054 #define PJ_TURN_KEEP_ALIVE_SEC 1555 #define PJ_TURN_PEER_HTABLE_SIZE 856 57 57 58 … … 134 135 135 136 136 /* ChannelData header */ 137 #pragma pack(1) 138 139 /** 140 * This structure ChannelData header. All the fields are in network byte 141 * order when it's on the wire. 142 */ 137 143 typedef struct pj_turn_channel_data 138 144 { 139 pj_uint16_t ch_number; 140 pj_uint16_t length; 145 pj_uint16_t ch_number; /**< Channel number. */ 146 pj_uint16_t length; /**< Payload length. */ 141 147 } pj_turn_channel_data; 142 148 149 150 #pragma pack() 143 151 144 152 … … 152 160 * needs to send outgoing message. Since the TURN session doesn't 153 161 * have a socket on its own, this callback must be implemented. 162 * 163 * @param sess The TURN session. 164 * @param pkt The packet/data to be sent. 165 * @param pkt_len Length of the packet/data. 166 * @param dst_addr Destination address of the packet. 167 * @param addr_len Length of the destination address. 168 * 169 * @return The callback should return the status of the 170 * send operation. 154 171 */ 155 172 pj_status_t (*on_send_pkt)(pj_turn_session *sess, … … 157 174 unsigned pkt_len, 158 175 const pj_sockaddr_t *dst_addr, 159 unsigned dst_addr_len);176 unsigned addr_len); 160 177 161 178 /** … … 163 180 * a channel number. 164 181 * 165 * This callback is optional. 182 * This callback is optional since the nature of this callback is 183 * for information only. 184 * 185 * @param sess The TURN session. 186 * @param peer_addr The peer address. 187 * @param addr_len Length of the peer address. 188 * @param ch_num The channel number associated with this peer address. 166 189 */ 167 190 void (*on_channel_bound)(pj_turn_session *sess, … … 174 197 * Data indication or ChannelData message from the TURN server. 175 198 * 176 * This callback is optional. 199 * @param sess The TURN session. 200 * @param pkt The data/payload of the Data Indication or ChannelData 201 * packet. 202 * @param pkt_len Length of the data/payload. 203 * @param peer_addr Peer address where this payload was received by 204 * the TURN server. 205 * @param addr_len Length of the peer address. 177 206 */ 178 207 void (*on_rx_data)(pj_turn_session *sess, 179 const pj_uint8_t*pkt,208 void *pkt, 180 209 unsigned pkt_len, 181 210 const pj_sockaddr_t *peer_addr, … … 186 215 * implement this callback at least to know that the TURN session is 187 216 * going to be destroyed. 188 */ 189 void (*on_state)(pj_turn_session *sess, pj_turn_state_t old_state, 217 * 218 * @param sess The TURN session. 219 * @param old_state The previous state of the session. 220 * @param new_state The current state of the session. 221 */ 222 void (*on_state)(pj_turn_session *sess, 223 pj_turn_state_t old_state, 190 224 pj_turn_state_t new_state); 191 225 … … 194 228 195 229 /** 196 * Allocate parameter. 230 * Allocation parameter, which can be given when application calls 231 * pj_turn_session_alloc() to allocate relay address in the TURN server. 232 * Application should call pj_turn_alloc_param_default() to initialize 233 * this structure with the default values. 197 234 */ 198 235 typedef struct pj_turn_alloc_param 199 236 { 237 /** 238 * The requested BANDWIDTH. Default is zero to not request any 239 * specific bandwidth. 240 */ 200 241 int bandwidth; 242 243 /** 244 * The requested LIFETIME. Default is zero to not request any 245 * explicit allocation lifetime. 246 */ 201 247 int lifetime; 248 249 /** 250 * If set to non-zero, the TURN session will periodically send blank 251 * Send Indication every PJ_TURN_KEEP_ALIVE_SEC to refresh local 252 * NAT bindings. Default is zero. 253 */ 202 254 int ka_interval; 255 203 256 } pj_turn_alloc_param; 204 257 205 258 206 259 /** 207 * T URN session info.260 * This structure describes TURN session info. 208 261 */ 209 262 typedef struct pj_turn_session_info … … 215 268 216 269 /** 270 * Last error (if session was terminated because of error) 271 */ 272 pj_status_t last_status; 273 274 /** 217 275 * Type of connection to the TURN server. 218 276 */ 219 pj_turn_tp_type tp_type; 277 pj_turn_tp_type conn_type; 278 279 /** 280 * The selected TURN server address. 281 */ 282 pj_sockaddr server; 283 284 /** 285 * Mapped address, as reported by the TURN server. 286 */ 287 pj_sockaddr mapped_addr; 220 288 221 289 /** … … 225 293 226 294 /** 227 * The selected TURN server address.228 */229 pj_sockaddr server;230 231 /**232 295 * Current seconds before allocation expires. 233 296 */ … … 238 301 239 302 /** 240 * Create default pj_turn_alloc_param. 303 * Initialize pj_turn_alloc_param with the default values. 304 * 305 * @param prm The TURN allocation parameter to be initialized. 241 306 */ 242 307 PJ_DECL(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm); 243 308 309 244 310 /** 245 311 * Duplicate pj_turn_alloc_param. 312 * 313 * @param pool Pool to allocate memory (currently not used) 314 * @param dst Destination parameter. 315 * @param src Source parameter. 246 316 */ 247 317 PJ_DECL(void) pj_turn_alloc_param_copy(pj_pool_t *pool, … … 250 320 251 321 /** 252 * Get TURN state name. 322 * Get string representation for the given TURN state. 323 * 324 * @param state The TURN session state. 325 * 326 * @return The state name as NULL terminated string. 253 327 */ 254 328 PJ_DECL(const char*) pj_turn_state_name(pj_turn_state_t state); … … 256 330 257 331 /** 258 * Create TURN client session. 259 */ 260 PJ_DECL(pj_status_t) pj_turn_session_create(pj_stun_config *cfg, 332 * Create a TURN session instance with the specified address family and 333 * connection type. Once TURN session instance is created, application 334 * must call pj_turn_session_alloc() to allocate a relay address in the TURN 335 * server. 336 * 337 * @param cfg The STUN configuration which contains among other 338 * things the ioqueue and timer heap instance for 339 * the operation of this session. 340 * @param name Optional name to identify this session in the log. 341 * @param af Address family of the client connection. Currently 342 * pj_AF_INET() and pj_AF_INET6() are supported. 343 * @param conn_type Connection type to the TURN server. 344 * @param cb Callback to receive events from the TURN session. 345 * @param options Option flags, currently this value must be zero. 346 * @param user_data Arbitrary application data to be associated with 347 * this transport. 348 * @param p_sess Pointer to receive the created instance of the 349 * TURN session. 350 * 351 * @return PJ_SUCCESS if the operation has been successful, 352 * or the appropriate error code on failure. 353 */ 354 PJ_DECL(pj_status_t) pj_turn_session_create(const pj_stun_config *cfg, 261 355 const char *name, 262 356 int af, 263 357 pj_turn_tp_type conn_type, 264 358 const pj_turn_session_cb *cb, 359 unsigned options, 265 360 void *user_data, 266 unsigned options,267 361 pj_turn_session **p_sess); 268 362 269 270 /** 271 * Shutdown TURN client session. 363 /** 364 * Shutdown TURN client session. This will gracefully deallocate and 365 * destroy the client session. 366 * 367 * @param sess The TURN client session. 368 * 369 * @return PJ_SUCCESS if the operation has been successful, 370 * or the appropriate error code on failure. 272 371 */ 273 372 PJ_DECL(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess); … … 275 374 276 375 /** 277 * Forcefully destroy the TURN session. 376 * Forcefully destroy the TURN session. This will destroy the session 377 * immediately. If there is an active allocation, the server will not 378 * be notified about the client destruction. 379 * 380 * @param sess The TURN client session. 381 * 382 * @return PJ_SUCCESS if the operation has been successful, 383 * or the appropriate error code on failure. 278 384 */ 279 385 PJ_DECL(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess); … … 281 387 282 388 /** 283 * Get TURN session info. 389 * Get the information about this TURN session and the allocation, if 390 * any. 391 * 392 * @param sess The TURN client session. 393 * @param info The structure to be initialized with the TURN 394 * session info. 395 * 396 * @return PJ_SUCCESS if the operation has been successful, 397 * or the appropriate error code on failure. 284 398 */ 285 399 PJ_DECL(pj_status_t) pj_turn_session_get_info(pj_turn_session *sess, … … 287 401 288 402 /** 289 * Re-assign user data. 403 * Associate a user data with this TURN session. The user data may then 404 * be retrieved later with pj_turn_session_get_user_data(). 405 * 406 * @param sess The TURN client session. 407 * @param user_data Arbitrary data. 408 * 409 * @return PJ_SUCCESS if the operation has been successful, 410 * or the appropriate error code on failure. 290 411 */ 291 412 PJ_DECL(pj_status_t) pj_turn_session_set_user_data(pj_turn_session *sess, … … 293 414 294 415 /** 295 * Retrieve user data. 416 * Retrieve the previously assigned user data associated with this TURN 417 * session. 418 * 419 * @param sess The TURN client session. 420 * 421 * @return The user/application data. 296 422 */ 297 423 PJ_DECL(void*) pj_turn_session_get_user_data(pj_turn_session *sess); 298 424 299 /** 300 * Set the server or domain name of the server. 425 426 /** 427 * Configure message logging. By default all flags are enabled. 428 * 429 * @param sess The TURN client session. 430 * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag 431 */ 432 PJ_DECL(void) pj_turn_session_set_log(pj_turn_session *sess, 433 unsigned flags); 434 435 436 /** 437 * Set the server or domain name of the server. Before the application 438 * can send Allocate request (with pj_turn_session_alloc()), it must first 439 * resolve the server address(es) using this function. This function will 440 * resolve the TURN server using DNS SRV resolution if the \a resolver 441 * is set. The server resolution process will complete asynchronously, 442 * and application will be notified in \a on_state() callback with the 443 * session state set to PJ_TURN_STATE_RESOLVED. 444 * 445 * Application may call with pj_turn_session_alloc() before the server 446 * resolution completes. In this case, the operation will be queued by 447 * the session, and it will be sent once the server resolution completes. 448 * 449 * @param sess The TURN client session. 450 * @param domain The domain, hostname, or IP address of the TURN 451 * server. When this parameter contains domain name, 452 * the \a resolver parameter must be set to activate 453 * DNS SRV resolution. 454 * @param default_port The default TURN port number to use when DNS SRV 455 * resolution is not used. If DNS SRV resolution is 456 * used, the server port number will be set from the 457 * DNS SRV records. 458 * @param resolver If this parameter is not NULL, then the \a domain 459 * parameter will be first resolved with DNS SRV and 460 * then fallback to using DNS A/AAAA resolution when 461 * DNS SRV resolution fails. If this parameter is 462 * NULL, the \a domain parameter will be resolved as 463 * hostname. 464 * 465 * @return PJ_SUCCESS if the operation has been successfully 466 * queued, or the appropriate error code on failure. 467 * When this function returns PJ_SUCCESS, the final 468 * result of the resolution process will be notified 469 * to application in \a on_state() callback. 301 470 */ 302 471 PJ_DECL(pj_status_t) pj_turn_session_set_server(pj_turn_session *sess, … … 307 476 308 477 /** 309 * Set credential to be used by the session. 478 * Set credential to be used to authenticate against TURN server. 479 * Application must call this function before sending Allocate request 480 * with pj_turn_session_alloc(). 481 * 482 * @param sess The TURN client session 483 * @param cred STUN credential to be used. 484 * 485 * @return PJ_SUCCESS if the operation has been successful, 486 * or the appropriate error code on failure. 310 487 */ 311 488 PJ_DECL(pj_status_t) pj_turn_session_set_credential(pj_turn_session *sess, … … 314 491 315 492 /** 316 * Create TURN allocation. 493 * Allocate a relay address/resource in the TURN server by sending TURN 494 * Allocate request. Application must first initiate the server resolution 495 * process with pj_turn_session_set_server() and set the credential to be 496 * used with pj_turn_session_set_credential() before calling this function. 497 * 498 * This function will complete asynchronously, and the application will be 499 * notified about the allocation result in \a on_state() callback. The 500 * TURN session state will move to PJ_TURN_STATE_READY if allocation is 501 * successful, and PJ_TURN_STATE_DEALLOCATING or greater state if allocation 502 * has failed. 503 * 504 * Once allocation has been successful, the TURN session will keep this 505 * allocation alive until the session is destroyed, by sending periodic 506 * allocation refresh to the TURN server. 507 * 508 * @param sess The TURN client session. 509 * @param param Optional TURN allocation parameter. 510 * 511 * @return PJ_SUCCESS if the operation has been successfully 512 * initiated or the appropriate error code on failure. 317 513 */ 318 514 PJ_DECL(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess, … … 321 517 322 518 /** 323 * Relay data to the specified peer through the session. 519 * Send a data to the specified peer address via the TURN relay. This 520 * function will encapsulate the data as STUN Send Indication or TURN 521 * ChannelData packet and send the message to the TURN server. The TURN 522 * server then will send the data to the peer. 523 * 524 * The allocation (pj_turn_session_alloc()) must have been successfully 525 * created before application can relay any data. 526 * 527 * Since TURN session is transport independent, this function will 528 * ultimately call \a on_send_pkt() callback to request the application 529 * to actually send the packet containing the data to the TURN server. 530 * 531 * @param sess The TURN client session. 532 * @param pkt The data/packet to be sent to peer. 533 * @param pkt_len Length of the data. 534 * @param peer_addr The remote peer address (the ultimate destination 535 * of the data, and not the TURN server address). 536 * @param addr_len Length of the address. 537 * 538 * @return PJ_SUCCESS if the operation has been successful, 539 * or the appropriate error code on failure. 324 540 */ 325 541 PJ_DECL(pj_status_t) pj_turn_session_sendto(pj_turn_session *sess, 326 542 const pj_uint8_t *pkt, 327 543 unsigned pkt_len, 328 const pj_sockaddr_t * addr,544 const pj_sockaddr_t *peer_addr, 329 545 unsigned addr_len); 330 546 331 547 /** 332 * Bind a peer address to a channel number. 548 * Optionally establish channel binding for the specified a peer address. 549 * This function will assign a unique channel number for the peer address 550 * and request channel binding to the TURN server for this address. When 551 * a channel has been bound to a peer, the TURN client and TURN server 552 * will exchange data using ChannelData encapsulation format, which has 553 * lower bandwidth overhead than Send Indication (the default format used 554 * when peer address is not bound to a channel). 555 * 556 * This function will complete asynchronously, and application will be 557 * notified about the result in \a on_channel_bound() callback. 558 * 559 * @param sess The TURN client session. 560 * @param peer The remote peer address. 561 * @param addr_len Length of the address. 562 * 563 * @return PJ_SUCCESS if the operation has been successfully 564 * initiated, or the appropriate error code on failure. 333 565 */ 334 566 PJ_DECL(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess, … … 337 569 338 570 /** 339 * Notify TURN client session upon receiving a packet from server. 340 * The packet maybe a STUN packet or ChannelData packet. 571 * Notify TURN client session upon receiving a packet from server. Since 572 * the TURN session is transport independent, it does not read packet from 573 * any sockets, and rather relies on application giving it packets that 574 * are received from the TURN server. The session then processes this packet 575 * and decides whether it is part of TURN protocol exchange or if it is a 576 * data to be reported back to user, which in this case it will call the 577 * \a on_rx_data() callback. 578 * 579 * @param sess The TURN client session. 580 * @param pkt The packet as received from the TURN server. This 581 * should contain either STUN encapsulated message or 582 * a ChannelData packet. 583 * @param pkt_len The length of the packet. 584 * 585 * @return The function may return non-PJ_SUCCESS if it receives 586 * non-STUN and non-ChannelData packet, or if the 587 * \a on_rx_data() returns non-PJ_SUCCESS; 341 588 */ 342 589 PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, 343 const pj_uint8_t *pkt, 344 unsigned pkt_len, 345 pj_bool_t is_datagram); 590 void *pkt, 591 unsigned pkt_len); 346 592 347 593 -
pjproject/trunk/pjnath/include/pjnath/turn_sock.h
r1913 r1988 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 #ifndef __PJNATH_ turn_sock_H__20 #define __PJNATH_ turn_sock_H__19 #ifndef __PJNATH_TURN_SOCK_H__ 20 #define __PJNATH_TURN_SOCK_H__ 21 21 22 22 /** … … 32 32 /* **************************************************************************/ 33 33 /** 34 * @defgroup PJNATH_TURN_ UDP TURN TCP client35 * @brief TURN relay using TCP client as transport protocol36 * @ingroup PJNATH_ STUN34 * @defgroup PJNATH_TURN_SOCK TURN client transport 35 * @brief Client transport utilizing TURN relay 36 * @ingroup PJNATH_TURN 37 37 * @{ 38 * 39 * The TURN relay client transport can be used to relay data from the client 40 * to peer via a TURN relay. The application establishes TURN connection to 41 * the TURN server using UDP or TCP as the transport, then creates a relay 42 * address in the TURN server to be advertised to remote peer(s) as the 43 * transport address. When application sends data to a remote address via 44 * this transport, the data will be sent via the TURN relay, and vice versa. 38 45 */ 39 46 40 47 41 48 /** 42 * Opaque declaration for TURN TCPclient.49 * Opaque declaration for TURN client. 43 50 */ 44 51 typedef struct pj_turn_sock pj_turn_sock; 45 52 46 53 /** 54 * This structure contains callbacks that will be called by the TURN 55 * transport. 56 */ 47 57 typedef struct pj_turn_sock_cb 48 58 { 49 59 /** 50 * Notification when incoming data has been received, either through 51 * Data indication or ChannelData message from the TURN server. 60 * Notification when incoming data has been received from the remote 61 * peer via the TURN server. The data reported in this callback will 62 * be the exact data as sent by the peer (e.g. the TURN encapsulation 63 * such as Data Indication or ChannelData will be removed before this 64 * function is called). 52 65 * 53 * This callback is mandatory. 66 * @param turn_sock The TURN client transport. 67 * @param data The data as received from the peer. 68 * @param data_len Length of the data. 69 * @param peer_addr The peer address. 70 * @param addr_len The length of the peer address. 54 71 */ 55 72 void (*on_rx_data)(pj_turn_sock *turn_sock, 56 const pj_uint8_t*pkt,73 void *pkt, 57 74 unsigned pkt_len, 58 75 const pj_sockaddr_t *peer_addr, … … 61 78 /** 62 79 * Notification when TURN session state has changed. Application should 63 * implement this callback to know that the TURN session is no longer 64 * available. 80 * implement this callback to monitor the progress of the TURN session. 81 * 82 * @param turn_sock The TURN client transport. 83 * @param old_state Previous state. 84 * @param new_state Current state. 65 85 */ 66 void (*on_state)(pj_turn_sock *turn_sock, pj_turn_state_t old_state, 86 void (*on_state)(pj_turn_sock *turn_sock, 87 pj_turn_state_t old_state, 67 88 pj_turn_state_t new_state); 68 89 … … 71 92 72 93 /** 73 * Create. 94 * Create a TURN transport instance with the specified address family and 95 * connection type. Once TURN transport instance is created, application 96 * must call pj_turn_sock_alloc() to allocate a relay address in the TURN 97 * server. 98 * 99 * @param cfg The STUN configuration which contains among other 100 * things the ioqueue and timer heap instance for 101 * the operation of this transport. 102 * @param af Address family of the client connection. Currently 103 * pj_AF_INET() and pj_AF_INET6() are supported. 104 * @param conn_type Connection type to the TURN server. Both TCP and 105 * UDP are supported. 106 * @param cb Callback to receive events from the TURN transport. 107 * @param options Option flags, currently this value must be zero. 108 * @param user_data Arbitrary application data to be associated with 109 * this transport. 110 * @param p_turn_sock Pointer to receive the created instance of the 111 * TURN transport. 112 * 113 * @return PJ_SUCCESS if the operation has been successful, 114 * or the appropriate error code on failure. 74 115 */ 75 116 PJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg, … … 82 123 83 124 /** 84 * Destroy. 125 * Destroy the TURN transport instance. This will gracefully close the 126 * connection between the client and the TURN server. Although this 127 * function will return immediately, the TURN socket deletion may continue 128 * in the background and the application may still get state changes 129 * notifications from this transport. 130 * 131 * @param turn_sock The TURN transport instance. 85 132 */ 86 133 PJ_DECL(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock); 87 134 88 /** 89 * Set user data. 135 136 /** 137 * Associate a user data with this TURN transport. The user data may then 138 * be retrieved later with #pj_turn_sock_get_user_data(). 139 * 140 * @param turn_sock The TURN transport instance. 141 * @param user_data Arbitrary data. 142 * 143 * @return PJ_SUCCESS if the operation has been successful, 144 * or the appropriate error code on failure. 90 145 */ 91 146 PJ_DECL(pj_status_t) pj_turn_sock_set_user_data(pj_turn_sock *turn_sock, 92 void *user_data); 93 94 /** 95 * Get user data. 147 void *user_data); 148 149 /** 150 * Retrieve the previously assigned user data associated with this TURN 151 * transport. 152 * 153 * @param turn_sock The TURN transport instance. 154 * 155 * @return The user/application data. 96 156 */ 97 157 PJ_DECL(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock); … … 99 159 100 160 /** 101 * Get info. 161 * Get the TURN transport info. The transport info contains, among other 162 * things, the allocated relay address. 163 * 164 * @param turn_sock The TURN transport instance. 165 * @param info Pointer to be filled with TURN transport info. 166 * 167 * @return PJ_SUCCESS if the operation has been successful, 168 * or the appropriate error code on failure. 102 169 */ 103 170 PJ_DECL(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock, 104 pj_turn_session_info *info); 105 106 /** 107 * Initialize. 108 */ 109 PJ_DECL(pj_status_t) pj_turn_sock_init(pj_turn_sock *turn_sock, 110 const pj_str_t *domain, 111 int default_port, 112 pj_dns_resolver *resolver, 113 const pj_stun_auth_cred *cred, 114 const pj_turn_alloc_param *param); 115 116 /** 117 * Send packet. 171 pj_turn_session_info *info); 172 173 /** 174 * Acquire the internal mutex of the TURN transport. Application may need 175 * to call this function to synchronize access to other objects alongside 176 * the TURN transport, to avoid deadlock. 177 * 178 * @param turn_sock The TURN transport instance. 179 * 180 * @return PJ_SUCCESS if the operation has been successful, 181 * or the appropriate error code on failure. 182 */ 183 PJ_DECL(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock); 184 185 186 /** 187 * Release the internal mutex previously held with pj_turn_sock_lock(). 188 * 189 * @param turn_sock The TURN transport instance. 190 * 191 * @return PJ_SUCCESS if the operation has been successful, 192 * or the appropriate error code on failure. 193 */ 194 PJ_DECL(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock); 195 196 197 /** 198 * Set STUN message logging for this TURN session. 199 * See #pj_stun_session_set_log(). 200 * 201 * @param turn_sock The TURN transport instance. 202 * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag 203 */ 204 PJ_DECL(void) pj_turn_sock_set_log(pj_turn_sock *turn_sock, 205 unsigned flags); 206 207 /** 208 * Allocate a relay address/resource in the TURN server. This function 209 * will resolve the TURN server using DNS SRV (if desired) and send TURN 210 * \a Allocate request using the specified credential to allocate a relay 211 * address in the server. This function completes asynchronously, and 212 * application will be notified when the allocation process has been 213 * successful in the \a on_state() callback when the state is set to 214 * PJ_TURN_STATE_READY. If the allocation fails, the state will be set 215 * to PJ_TURN_STATE_DEALLOCATING or greater. 216 * 217 * @param turn_sock The TURN transport instance. 218 * @param domain The domain, hostname, or IP address of the TURN 219 * server. When this parameter contains domain name, 220 * the \a resolver parameter must be set to activate 221 * DNS SRV resolution. 222 * @param default_port The default TURN port number to use when DNS SRV 223 * resolution is not used. If DNS SRV resolution is 224 * used, the server port number will be set from the 225 * DNS SRV records. 226 * @param resolver If this parameter is not NULL, then the \a domain 227 * parameter will be first resolved with DNS SRV and 228 * then fallback to using DNS A/AAAA resolution when 229 * DNS SRV resolution fails. If this parameter is 230 * NULL, the \a domain parameter will be resolved as 231 * hostname. 232 * @param cred The STUN credential to be used for the TURN server. 233 * @param param Optional TURN allocation parameter. 234 * 235 * @return PJ_SUCCESS if the operation has been successfully 236 * queued, or the appropriate error code on failure. 237 * When this function returns PJ_SUCCESS, the final 238 * result of the allocation process will be notified 239 * to application in \a on_state() callback. 240 * 241 */ 242 PJ_DECL(pj_status_t) pj_turn_sock_alloc(pj_turn_sock *turn_sock, 243 const pj_str_t *domain, 244 int default_port, 245 pj_dns_resolver *resolver, 246 const pj_stun_auth_cred *cred, 247 const pj_turn_alloc_param *param); 248 249 /** 250 * Send a data to the specified peer address via the TURN relay. This 251 * function will encapsulate the data as STUN Send Indication or TURN 252 * ChannelData packet and send the message to the TURN server. The TURN 253 * server then will send the data to the peer. 254 * 255 * The allocation (pj_turn_sock_alloc()) must have been successfully 256 * created before application can relay any data. 257 * 258 * @param turn_sock The TURN transport instance. 259 * @param pkt The data/packet to be sent to peer. 260 * @param pkt_len Length of the data. 261 * @param peer_addr The remote peer address (the ultimate destination 262 * of the data, and not the TURN server address). 263 * @param addr_len Length of the address. 264 * 265 * @return PJ_SUCCESS if the operation has been successful, 266 * or the appropriate error code on failure. 118 267 */ 119 268 PJ_DECL(pj_status_t) pj_turn_sock_sendto(pj_turn_sock *turn_sock, 120 269 const pj_uint8_t *pkt, 121 270 unsigned pkt_len, 122 const pj_sockaddr_t * addr,271 const pj_sockaddr_t *peer_addr, 123 272 unsigned addr_len); 124 273 125 274 /** 126 * Bind a peer address to a channel number. 275 * Optionally establish channel binding for the specified a peer address. 276 * This function will assign a unique channel number for the peer address 277 * and request channel binding to the TURN server for this address. When 278 * a channel has been bound to a peer, the TURN transport and TURN server 279 * will exchange data using ChannelData encapsulation format, which has 280 * lower bandwidth overhead than Send Indication (the default format used 281 * when peer address is not bound to a channel). 282 * 283 * @param turn_sock The TURN transport instance. 284 * @param peer The remote peer address. 285 * @param addr_len Length of the address. 286 * 287 * @return PJ_SUCCESS if the operation has been successful, 288 * or the appropriate error code on failure. 127 289 */ 128 290 PJ_DECL(pj_status_t) pj_turn_sock_bind_channel(pj_turn_sock *turn_sock, 129 const pj_sockaddr_t *peer,130 unsigned addr_len);291 const pj_sockaddr_t *peer, 292 unsigned addr_len); 131 293 132 294 … … 139 301 140 302 141 #endif /* __PJNATH_ turn_sock_H__ */142 303 #endif /* __PJNATH_TURN_SOCK_H__ */ 304 -
pjproject/trunk/pjnath/include/pjnath/types.h
r1914 r1988 36 36 37 37 /** 38 * This constant describes a number to be used to identify an invalid TURN 39 * channel number. 40 */ 41 #define PJ_TURN_INVALID_CHANNEL 0xFFFF 42 43 44 /** 38 45 * Initialize pjnath library. 39 46 * … … 44 51 45 52 /** 46 * Display error to the log. 53 * Display error to the log. 47 54 * 48 55 * @param sender The sender name. … … 68 75 69 76 /** 70 * @mainpage PJNATH - Open Source ICE, STUN, and TURN Library 71 * 72 * \n 73 * This is the documentation of PJNATH, an Open Source library providing 74 * NAT traversal helper functionalities by using standard based protocols. 75 * 76 * \n 77 78 * \section PJNATH_STUN STUN Protocol Library 79 * 80 * Session Traversal Utilities (STUN, or previously known as Simple 81 * Traversal of User Datagram Protocol (UDP) Through Network Address 82 * Translators (NAT)s), is a lightweight protocol that serves as a tool for 83 * application protocols in dealing with NAT traversal. It allows a client 84 * to determine the IP address and port allocated to them by a NAT and to 85 * keep NAT bindings open. 86 * 87 * The PJNATH library provides facilities to support both the core 88 * <B>STUN-bis</B> specification and the <B>TURN</B> usage of STUN, 89 * as well as other STUN usages. Please see #pj_stun_attr_type for 90 * list of STUN attributes supported by this library. 91 * 92 * 93 * The following are some design principles that have been utilized 94 * when implementing the STUN library in PJNATH: 95 * 96 * - layered architecture, with \ref PJNATH_STUN_MSG as the lowest 97 * layer and \ref PJNATH_STUN_SESSION as the highest abstraction 98 * layer, to accommodate various usage scenario of the library. 99 * 100 * - no transport -- the STUN library is pretty much transport 101 * independent and all sending and receiving functionalities will 102 * have to be implemented by application or higher level 103 * abstraction (such as ICE). This helps facilitating an even 104 * more usage scenarios of the library. 105 * 106 * - common functionalities for both STUN client and server 107 * development. All STUN components can be used to develop both 108 * STUN client and STUN server application, and in fact, in ICE, 109 * both STUN client and server functionality exist in a single 110 * ICE session. 111 * 112 * \n 113 * 114 * \subsection PJNATH_STUN_ARCH STUN Library Organization 115 * 116 * \image html stun-arch.jpg "STUN Library Architecture" 117 * 118 * The STUN library is organized as follows: 119 * 120 * - for both client and server, the highest abstraction is 121 * \ref PJNATH_STUN_SESSION, which provides management of incoming 122 * and outgoing messages and association of STUN credential to 123 * a STUN session. 124 * 125 * - for client, the next layer below is \ref PJNATH_STUN_TRANSACTION, 126 * which manages retransmissions of STUN request. Server side STUN 127 * transaction is handled in \ref PJNATH_STUN_SESSION layer above. 128 * 129 * - \ref PJNATH_STUN_AUTH provides mechanism to verify STUN 130 * credential in incoming STUN messages. 131 * 132 * - the lowest layer of the library is \ref PJNATH_STUN_MSG. This layer 133 * provides STUN message representation, validation, parsing, 134 * encoding MESSAGE-INTEGRITY for outgoing messages, and 135 * debugging (dump to log) of STUN messages. 136 * 137 * All STUN library components are independent of any transports. 138 * Application gives incoming packet to the STUN components for processing, 139 * and it must supply the STUN components with callback to send outgoing 140 * messages. 141 * 142 * 143 * \n 144 * 145 * \subsection PJNATH_STUN_CLASSES PJNATH Class Diagram 146 * 147 * 148 * \image html UML-class-diagram.png "Class Diagram" 149 * 150 * TBD: write descriptions. 151 * 152 * \subsection PJNATH_STUN_USING Using STUN Library 153 * 154 * [The developers guide documentation can certainly be improved here] 155 * 156 * For a sample STUN and TURN client, please see <tt>pjstun-client</tt> 157 * project under <tt>pjnath/src</tt> directory. 158 * 159 * For a sample STUN and TURN server, please see <tt>pjstun-srv-test</tt> 160 * project under <tt>pjnath/src</tt> directory. 161 * 162 * 163 * \subsection PJNATH_STUN_REF STUN Reference 164 * 165 * References for STUN: 166 * 167 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-15.txt"> 168 * <B>draft-ietf-behave-rfc3489bis-15</b></A>: Session Traversal 169 * Utilities for (NAT) (STUN), 170 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-07.txt"> 171 * <B>draft-ietf-behave-turn-07</B></A>: Obtaining Relay Addresses 172 * from Simple Traversal Underneath NAT (STUN) 173 * - Obsoleted: <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>. 174 * 175 * \n 176 * 177 * \section PJNATH_ICE ICE Implementation 178 * 179 * Interactive Connectivity Establishment (ICE) is a standard based 180 * methodology for traversing Network Address Translator (NAT), and 181 * is described in 182 * <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-19.txt"> 183 * <B>draft-ietf-mmusic-ice-19.txt</B></A> draft. The PJNATH ICE 184 * implementation is aimed to provide a usable and generic ICE transports 185 * for different types of application, including but not limited to 186 * the usage of ICE in SIP/SDP offer/answer. 187 * 188 * 189 * \subsection PJNATH_ICE_ARCH ICE Library Organization 190 * 191 * \image html ice-arch.jpg "ICE Architecture" 192 * 193 * The ICE library is organized as follows: 194 * 195 * - the highest abstraction is ICE media transport, which maintains 196 * ICE stream transport and provides SDP translations to be used 197 * for SIP offer/answer exchanges. ICE media transport is part 198 * of PJMEDIA library. 199 * 200 * - higher in the hierarchy is \ref PJNATH_ICE_STREAM_TRANSPORT, 201 * which binds ICE with UDP sockets, and provides STUN binding 202 * and relay/TURN allocation for the sockets. This component can 203 * be directly used by application, although normally application 204 * should use the next higher abstraction since it provides 205 * SDP translations and better integration with other PJ libraries 206 * such as PJSIP and PJMEDIA. 207 * 208 * - the lowest layer is \ref PJNATH_ICE_SESSION, which provides 209 * ICE management and negotiation in a transport-independent way. 210 * This layer contains the state machines to perform ICE 211 * negotiation, and provides the most flexibility to control all 212 * aspects of ICE session. This layer normally is only usable for 213 * ICE implementors. 214 * 215 * \subsection PJNATH_ICE_USING Using the ICE Library 216 * 217 * For ICE implementation that has been integrated with socket transport, 218 * please see \ref PJNATH_ICE_STREAM_TRANSPORT_USING. 219 * 220 * For ICE implementation that has not been integrated with socket 221 * transport, please see \ref pj_ice_sess_using_sec. 222 * 223 * \subsection PJNATH_ICE_REF Reference 224 * 225 * References for ICE: 226 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-19.txt"> 227 * <B>draft-ietf-mmusic-ice-19.txt</B></A>: Interactive Connectivity 228 * Establishment (ICE): A Methodology for Network Address Translator 229 * (NAT) Traversal for Offer/Answer Protocols 230 */ 77 78 @mainpage PJNATH - Open Source ICE, STUN, and TURN Library 79 80 \n 81 This is the documentation of PJNATH, an Open Source library providing 82 NAT traversal helper functionalities by using standard based protocols 83 such as STUN, TURN, and ICE. 84 85 \n 86 \n 87 88 \section lib_comps Library Components 89 90 \subsection comp_stun STUN 91 92 Session Traversal Utilities (STUN, or previously known as Simple 93 Traversal of User Datagram Protocol (UDP) Through Network Address 94 Translators (NAT)s), is a lightweight protocol that serves as a tool for 95 application protocols in dealing with NAT traversal. It allows a client 96 to determine the IP address and port allocated to them by a NAT and to 97 keep NAT bindings open. 98 99 This version of PJNATH implements the following STUN-bis draft: 100 - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-15.txt"> 101 <B>draft-ietf-behave-rfc3489bis-15</b></A>: Session Traversal 102 Utilities for (NAT) (STUN), 103 104 105 \subsection comp_turn TURN 106 107 Traversal Using Relays around NAT (TURN) allows the host to control the 108 operation of the relay and to exchange packets with its peers using the relay. 109 110 This version of PJNATH implements both TCP and UDP client transport and it 111 complies with the following TURN draft: 112 - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-07.txt"> 113 <B>draft-ietf-behave-turn-07</B></A>: Obtaining Relay Addresses 114 from Simple Traversal Underneath NAT (STUN) 115 116 117 \subsection comp_ice ICE 118 119 Interactive Connectivity Establishment (ICE) is a standard based 120 methodology for traversing Network Address Translator (NAT). This 121 implementation is aimed to provide a usable and generic ICE transports 122 for different types of application, including but not limited to 123 the usage of ICE in SIP/SDP offer/answer. 124 125 126 This version of PJNATH implements the following ICE draft: 127 - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-19.txt"> 128 <B>draft-ietf-mmusic-ice-19.txt</B></A> draft. The PJNATH ICE 129 130 131 \subsection comp_natck NAT Classification Utility 132 133 The PJNATH library also provides NAT classification utility as 134 described in <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>. 135 While the practice to detect the NAT type to assist NAT traversal 136 has been deprecated in favor of ICE, the information may still be 137 useful for troubleshooting purposes, hence the utility is provided. 138 139 140 \n 141 \n 142 143 \section lib_org Library Organization 144 145 The PJNATH library consists of many components with each providing 146 specific functionality that may or may not be of the interests of 147 applications (or application developers). This section attempts to 148 give brief overview on the components provided by PJNATH. 149 150 The PJNATH components from the highest layer to the lower layer are 151 as follows. 152 153 154 \n 155 156 \subsection user_comp High-level Transport Objects 157 158 PJNATH library provides some high-level objects that may be used 159 by applications: 160 161 162 \subsubsection stun_sock STUN Transport 163 164 The \ref PJNATH_STUN_SOCK provides asynchronous UDP like socket transport 165 with the additional capability to query the publicly mapped transport 166 address (using STUN resolution), to refresh the NAT binding, and to 167 demultiplex internal STUN messages from application data (the 168 application data may be a STUN message as well). 169 170 171 \subsubsection turn_sock TURN Client Transport 172 173 The \ref PJNATH_TURN_SOCK may be used by the application to send and 174 receive data via TURN server. For more information please see the 175 documentation of \ref PJNATH_TURN_SOCK. 176 177 178 \subsubsection ice_strans ICE Stream Transport 179 180 The \ref PJNATH_ICE_STREAM_TRANSPORT provides transport interface to 181 send and receive data through connection that is negotiated 182 with ICE protocol. The \ref PJNATH_ICE_STREAM_TRANSPORT naturally 183 contains both STUN Transport and \ref PJNATH_TURN_SOCK. 184 185 The \ref PJNATH_ICE_STREAM_TRANSPORT interface is suitable for both 186 SIP or non-SIP use. For SIP use, application may prefer to use the 187 ICE media transport in PJMEDIA instead where it has been integrated 188 with the SDP offer and answer mechanism. 189 190 191 \subsubsection natck NAT Classification Utility 192 193 PJNATH also provides \a PJNATH_NAT_DETECT to assist troubleshooting 194 of problems related to NAT traversal. 195 196 197 198 \n 199 200 201 \subsection sessions Transport Independent Sessions Layer 202 203 Right below the high level transports objects are the transport 204 independent sessions. These sessions don't have access to sockets, 205 so higher level objects (such as transports) must give incoming 206 packets to the sessions and provide callback to be called by 207 sessions to send outgoing packets. 208 209 210 \subsubsection ice_sess ICE Session 211 212 The \ref PJNATH_ICE_SESSION is used by the \ref PJNATH_ICE_STREAM_TRANSPORT 213 and contains the actual logic of the ICE negotiation. 214 215 216 \subsubsection turn_sess TURN Session 217 218 The \ref PJNATH_TURN_SESSION is used by the \ref PJNATH_TURN_SOCK 219 and it contains TURN protocol logic. Implementors may implement 220 other types of TURN client connection (such as TURN TLS client) 221 by utilizing this session. 222 223 224 \subsubsection stun_sess STUN Session 225 226 The \ref PJNATH_STUN_SESSION manages STUN message exchange between 227 a client and server (or vice versa). It manages \ref PJNATH_STUN_TRANSACTION 228 for sending or receiving requests and \ref PJNATH_STUN_AUTH for both 229 both incoming and outgoing STUN messages. 230 231 The \ref PJNATH_STUN_SESSION is naturally used by the \ref PJNATH_TURN_SESSION 232 and \ref PJNATH_ICE_SESSION 233 234 235 \n 236 237 \subsection stun_tsx STUN Transaction Layer 238 239 The \ref PJNATH_STUN_TRANSACTION is a thin layer to manage retransmission 240 of STUN requests. 241 242 243 \n 244 245 246 \subsection stun_msg STUN Messaging Layer 247 248 At the very bottom of the PJNATH components is the \ref PJNATH_STUN_MSG 249 layer. The API contains various representation of STUN messaging components 250 and it provides API to encode and decode STUN messages. 251 252 253 254 \n 255 \n 256 257 \section class_dia Class Diagram 258 259 260 The following class diagram shows the interactions between objects in 261 PJNATH: 262 263 \image html UML-class-diagram.png "Class Diagram" 264 \image latex UML-class-diagram.png "Class Diagram" 265 266 267 268 \n 269 \n 270 271 \section samples Sample Applications 272 273 274 Some sample applications have been provided with PJNATH, and it's available 275 under <tt>pjnath/src</tt> directory: 276 277 - <b>pjturn-client</b>: this is a stand-alone, console based TURN client 278 application to be used as a demonstration for PJNATH TURN client 279 transport API and for simple testing against TURN server implementations. 280 The client supports both UDP and TCP connection to the TURN server. 281 282 - <b>pjturn-srv</b>: this is a simple TURN server to be used for testing 283 purposes. It supports both UDP and TCP connections to the clients. 284 285 286 */ 231 287 232 288 /** -
pjproject/trunk/pjnath/src/pjnath-test/ice_test.c
r1288 r1988 18 18 */ 19 19 #include "test.h" 20 21 #define THIS_FILE "ice_test.c" 22 23 24 struct ice_data 25 { 26 const char *obj_name; 27 pj_bool_t complete; 28 pj_status_t err_code; 29 unsigned rx_rtp_cnt; 30 unsigned rx_rtcp_cnt; 31 32 unsigned rx_rtp_count; 33 char last_rx_rtp_data[32]; 34 unsigned rx_rtcp_count; 35 char last_rx_rtcp_data[32]; 20 #include "server.h" 21 22 enum 23 { 24 NO = 0, 25 YES = 1, 26 SRV = 3, 36 27 }; 37 28 38 static pj_stun_config stun_cfg; 39 40 static void on_ice_complete(pj_ice_strans *icest, 41 pj_status_t status) 42 { 43 struct ice_data *id = (struct ice_data*) icest->user_data; 44 id->complete = PJ_TRUE; 45 id->err_code = status; 46 PJ_LOG(3,(THIS_FILE, " ICE %s complete %s", id->obj_name, 47 (status==PJ_SUCCESS ? "successfully" : "with failure"))); 29 #define NODELAY 0xFFFFFFFF 30 #define SRV_DOMAIN "pjsip.lab.domain" 31 32 #define INDENT " " 33 34 /* Client flags */ 35 enum 36 { 37 WRONG_TURN = 1, 38 DEL_ON_ERR = 2, 39 }; 40 41 42 /* Test results */ 43 struct test_result 44 { 45 pj_status_t init_status; /* init successful? */ 46 pj_status_t nego_status; /* negotiation successful? */ 47 unsigned rx_cnt[4]; /* Number of data received */ 48 }; 49 50 51 /* Test session configuration */ 52 struct test_cfg 53 { 54 pj_ice_sess_role role; /* Role. */ 55 unsigned comp_cnt; /* Component count */ 56 unsigned enable_host; /* Enable host candidates */ 57 unsigned enable_stun; /* Enable srflx candidates */ 58 unsigned enable_turn; /* Enable turn candidates */ 59 unsigned client_flag; /* Client flags */ 60 61 unsigned answer_delay; /* Delay before sending SDP */ 62 unsigned send_delay; /* Delay before sending data */ 63 unsigned destroy_delay; /* Delay before destroy() */ 64 65 struct test_result expected;/* Expected result */ 66 }; 67 68 /* ICE endpoint state */ 69 struct ice_ept 70 { 71 struct test_cfg cfg; /* Configuratino. */ 72 pj_ice_strans *ice; /* ICE stream transport */ 73 struct test_result result;/* Test result. */ 74 75 pj_str_t ufrag; /* username fragment. */ 76 pj_str_t pass; /* password */ 77 }; 78 79 /* The test session */ 80 struct test_sess 81 { 82 pj_pool_t *pool; 83 pj_stun_config *stun_cfg; 84 pj_dns_resolver *resolver; 85 86 test_server *server; 87 88 unsigned server_flag; 89 struct ice_ept caller; 90 struct ice_ept callee; 91 }; 92 93 94 static void ice_on_rx_data(pj_ice_strans *ice_st, 95 unsigned comp_id, 96 void *pkt, pj_size_t size, 97 const pj_sockaddr_t *src_addr, 98 unsigned src_addr_len); 99 static void ice_on_ice_complete(pj_ice_strans *ice_st, 100 pj_ice_strans_op op, 101 pj_status_t status); 102 static void destroy_sess(struct test_sess *sess, unsigned wait_msec); 103 104 /* Create ICE stream transport */ 105 static int create_ice_strans(struct test_sess *test_sess, 106 struct ice_ept *ept, 107 pj_ice_strans **p_ice) 108 { 109 pj_ice_strans *ice; 110 pj_ice_strans_cb ice_cb; 111 pj_ice_strans_cfg ice_cfg; 112 pj_sockaddr hostip; 113 char serverip[PJ_INET6_ADDRSTRLEN]; 114 pj_status_t status; 115 116 status = pj_gethostip(pj_AF_INET(), &hostip); 117 if (status != PJ_SUCCESS) 118 return -1030; 119 120 pj_sockaddr_print(&hostip, serverip, sizeof(serverip), 0); 121 122 /* Init callback structure */ 123 pj_bzero(&ice_cb, sizeof(ice_cb)); 124 ice_cb.on_rx_data = &ice_on_rx_data; 125 ice_cb.on_ice_complete = &ice_on_ice_complete; 126 127 /* Init ICE stream transport configuration structure */ 128 pj_ice_strans_cfg_default(&ice_cfg); 129 pj_memcpy(&ice_cfg.stun_cfg, test_sess->stun_cfg, sizeof(pj_stun_config)); 130 if ((ept->cfg.enable_stun & SRV)==SRV || (ept->cfg.enable_turn & SRV)==SRV) 131 ice_cfg.resolver = test_sess->resolver; 132 133 if (ept->cfg.enable_stun & YES) { 134 if ((ept->cfg.enable_stun & SRV) == SRV) { 135 ice_cfg.stun.server = pj_str(SRV_DOMAIN); 136 } else { 137 ice_cfg.stun.server = pj_str(serverip); 138 } 139 ice_cfg.stun.port = STUN_SERVER_PORT; 140 } 141 142 if (ept->cfg.enable_host == 0) { 143 ice_cfg.stun.no_host_cands = PJ_TRUE; 144 } else { 145 ice_cfg.stun.no_host_cands = PJ_FALSE; 146 ice_cfg.stun.loop_addr = PJ_TRUE; 147 } 148 149 150 if (ept->cfg.enable_turn & YES) { 151 if ((ept->cfg.enable_turn & SRV) == SRV) { 152 ice_cfg.turn.server = pj_str(SRV_DOMAIN); 153 } else { 154 ice_cfg.turn.server = pj_str(serverip); 155 } 156 ice_cfg.turn.port = TURN_SERVER_PORT; 157 ice_cfg.turn.conn_type = PJ_TURN_TP_UDP; 158 ice_cfg.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC; 159 ice_cfg.turn.auth_cred.data.static_cred.realm = pj_str(SRV_DOMAIN); 160 if (ept->cfg.client_flag & WRONG_TURN) 161 ice_cfg.turn.auth_cred.data.static_cred.username = pj_str("xxx"); 162 else 163 ice_cfg.turn.auth_cred.data.static_cred.username = pj_str(TURN_USERNAME); 164 ice_cfg.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; 165 ice_cfg.turn.auth_cred.data.static_cred.data = pj_str(TURN_PASSWD); 166 } 167 168 /* Create ICE stream transport */ 169 status = pj_ice_strans_create(NULL, &ice_cfg, ept->cfg.comp_cnt, 170 (void*)ept, &ice_cb, 171 &ice); 172 if (status != PJ_SUCCESS) { 173 app_perror(INDENT "err: pj_ice_strans_create()", status); 174 return status; 175 } 176 177 pj_create_unique_string(test_sess->pool, &ept->ufrag); 178 pj_create_unique_string(test_sess->pool, &ept->pass); 179 180 /* Looks alright */ 181 *p_ice = ice; 182 return PJ_SUCCESS; 48 183 } 49 50 51 static void on_rx_data(pj_ice_strans *icest, unsigned comp_id, 52 void *pkt, pj_size_t size, 53 const pj_sockaddr_t *src_addr, 54 unsigned src_addr_len) 55 { 56 struct ice_data *id = (struct ice_data*) icest->user_data; 57 58 if (comp_id == 1) { 59 id->rx_rtp_cnt++; 60 pj_memcpy(id->last_rx_rtp_data, pkt, size); 61 id->last_rx_rtp_data[size] = '\0'; 62 } else if (comp_id == 2) { 63 id->rx_rtcp_cnt++; 64 pj_memcpy(id->last_rx_rtcp_data, pkt, size); 65 id->last_rx_rtcp_data[size] = '\0'; 66 } else { 67 pj_assert(!"Invalid component ID"); 68 } 69 184 185 /* Create test session */ 186 static int create_sess(pj_stun_config *stun_cfg, 187 unsigned server_flag, 188 struct test_cfg *caller_cfg, 189 struct test_cfg *callee_cfg, 190 struct test_sess **p_sess) 191 { 192 pj_pool_t *pool; 193 struct test_sess *sess; 194 pj_str_t ns_ip; 195 pj_uint16_t ns_port; 196 unsigned flags; 197 pj_status_t status; 198 199 /* Create session structure */ 200 pool = pj_pool_create(mem, "testsess", 512, 512, NULL); 201 sess = PJ_POOL_ZALLOC_T(pool, struct test_sess); 202 sess->pool = pool; 203 sess->stun_cfg = stun_cfg; 204 205 pj_memcpy(&sess->caller.cfg, caller_cfg, sizeof(*caller_cfg)); 206 sess->caller.result.init_status = sess->caller.result.nego_status = PJ_EPENDING; 207 208 pj_memcpy(&sess->callee.cfg, callee_cfg, sizeof(*callee_cfg)); 209 sess->callee.result.init_status = sess->callee.result.nego_status = PJ_EPENDING; 210 211 /* Create server */ 212 flags = server_flag; 213 status = create_test_server(stun_cfg, flags, SRV_DOMAIN, &sess->server); 214 if (status != PJ_SUCCESS) { 215 app_perror(INDENT "error: create_test_server()", status); 216 destroy_sess(sess, 500); 217 return -10; 218 } 219 sess->server->turn_respond_allocate = 220 sess->server->turn_respond_refresh = PJ_TRUE; 221 222 /* Create resolver */ 223 status = pj_dns_resolver_create(mem, NULL, 0, stun_cfg->timer_heap, 224 stun_cfg->ioqueue, &sess->resolver); 225 if (status != PJ_SUCCESS) { 226 app_perror(INDENT "error: pj_dns_resolver_create()", status); 227 destroy_sess(sess, 500); 228 return -20; 229 } 230 231 ns_ip = pj_str("127.0.0.1"); 232 ns_port = (pj_uint16_t)DNS_SERVER_PORT; 233 status = pj_dns_resolver_set_ns(sess->resolver, 1, &ns_ip, &ns_port); 234 if (status != PJ_SUCCESS) { 235 app_perror( INDENT "error: pj_dns_resolver_set_ns()", status); 236 destroy_sess(sess, 500); 237 return -21; 238 } 239 240 /* Create caller ICE stream transport */ 241 status = create_ice_strans(sess, &sess->caller, &sess->caller.ice); 242 if (status != PJ_SUCCESS) { 243 destroy_sess(sess, 500); 244 return -30; 245 } 246 247 /* Create callee ICE stream transport */ 248 status = create_ice_strans(sess, &sess->callee, &sess->callee.ice); 249 if (status != PJ_SUCCESS) { 250 destroy_sess(sess, 500); 251 return -40; 252 } 253 254 *p_sess = sess; 255 return 0; 256 } 257 258 /* Destroy test session */ 259 static void destroy_sess(struct test_sess *sess, unsigned wait_msec) 260 { 261 if (sess->caller.ice) { 262 pj_ice_strans_destroy(sess->caller.ice); 263 sess->caller.ice = NULL; 264 } 265 266 if (sess->callee.ice) { 267 pj_ice_strans_destroy(sess->callee.ice); 268 sess->callee.ice = NULL; 269 } 270 271 poll_events(sess->stun_cfg, wait_msec, PJ_FALSE); 272 273 if (sess->resolver) { 274 pj_dns_resolver_destroy(sess->resolver, PJ_FALSE); 275 sess->resolver = NULL; 276 } 277 278 if (sess->server) { 279 destroy_test_server(sess->server); 280 sess->server = NULL; 281 } 282 283 if (sess->pool) { 284 pj_pool_t *pool = sess->pool; 285 sess->pool = NULL; 286 pj_pool_release(pool); 287 } 288 } 289 290 static void ice_on_rx_data(pj_ice_strans *ice_st, 291 unsigned comp_id, 292 void *pkt, pj_size_t size, 293 const pj_sockaddr_t *src_addr, 294 unsigned src_addr_len) 295 { 296 struct ice_ept *ept; 297 298 PJ_UNUSED_ARG(pkt); 299 PJ_UNUSED_ARG(size); 70 300 PJ_UNUSED_ARG(src_addr); 71 301 PJ_UNUSED_ARG(src_addr_len); 302 303 ept = (struct ice_ept*) pj_ice_strans_get_user_data(ice_st); 304 ept->result.rx_cnt[comp_id]++; 72 305 } 73 306 74 307 75 static void handle_events(unsigned msec_timeout) 76 { 77 pj_time_val delay; 78 79 pj_timer_heap_poll(stun_cfg.timer_heap, NULL); 80 81 delay.sec = 0; 82 delay.msec = msec_timeout; 83 pj_time_val_normalize(&delay); 84 85 pj_ioqueue_poll(stun_cfg.ioqueue, &delay); 308 static void ice_on_ice_complete(pj_ice_strans *ice_st, 309 pj_ice_strans_op op, 310 pj_status_t status) 311 { 312 struct ice_ept *ept; 313 314 ept = (struct ice_ept*) pj_ice_strans_get_user_data(ice_st); 315 switch (op) { 316 case PJ_ICE_STRANS_OP_INIT: 317 ept->result.init_status = status; 318 if (status != PJ_SUCCESS && (ept->cfg.client_flag & DEL_ON_ERR)) { 319 pj_ice_strans_destroy(ice_st); 320 ept->ice = NULL; 321 } 322 break; 323 case PJ_ICE_STRANS_OP_NEGOTIATION: 324 ept->result.nego_status = status; 325 break; 326 default: 327 pj_assert(!"Unknown op"); 328 } 86 329 } 87 330 88 331 89 /* Basic create and destroy test */ 90 static int ice_basic_create_destroy_test() 91 { 92 pj_ice_strans *im; 93 pj_ice_strans_cb icest_cb; 332 /* Start ICE negotiation on the endpoint, based on parameter from 333 * the other endpoint. 334 */ 335 static pj_status_t start_ice(struct ice_ept *ept, const struct ice_ept *remote) 336 { 337 pj_ice_sess_cand rcand[32]; 338 unsigned i, rcand_cnt = 0; 94 339 pj_status_t status; 95 340 96 PJ_LOG(3,(THIS_FILE, "...basic create/destroy")); 97 98 pj_bzero(&icest_cb, sizeof(icest_cb)); 99 icest_cb.on_ice_complete = &on_ice_complete; 100 icest_cb.on_rx_data = &on_rx_data; 101 102 status = pj_ice_strans_create(&stun_cfg, "icetest", 2, NULL, &icest_cb, &im); 103 if (status != PJ_SUCCESS) 104 return -10; 105 106 pj_ice_strans_destroy(im); 341 /* Enum remote candidates */ 342 for (i=0; i<remote->cfg.comp_cnt; ++i) { 343 unsigned cnt = PJ_ARRAY_SIZE(rcand) - rcand_cnt; 344 status = pj_ice_strans_enum_cands(remote->ice, i+1, &cnt, rcand+rcand_cnt); 345 if (status != PJ_SUCCESS) { 346 app_perror(INDENT "err: pj_ice_strans_enum_cands()", status); 347 return status; 348 } 349 rcand_cnt += cnt; 350 } 351 352 status = pj_ice_strans_start_ice(ept->ice, &remote->ufrag, &remote->pass, 353 rcand_cnt, rcand); 354 if (status != PJ_SUCCESS) { 355 app_perror(INDENT "err: pj_ice_strans_start_ice()", status); 356 return status; 357 } 358 359 return PJ_SUCCESS; 360 } 361 362 363 /* Check that the pair in both agents are matched */ 364 static int check_pair(const struct ice_ept *ept1, const struct ice_ept *ept2, 365 int start_err) 366 { 367 unsigned i, min_cnt, max_cnt; 368 369 if (ept1->cfg.comp_cnt < ept2->cfg.comp_cnt) { 370 min_cnt = ept1->cfg.comp_cnt; 371 max_cnt = ept2->cfg.comp_cnt; 372 } else { 373 min_cnt = ept2->cfg.comp_cnt; 374 max_cnt = ept1->cfg.comp_cnt; 375 } 376 377 /* Must have valid pair for common components */ 378 for (i=0; i<min_cnt; ++i) { 379 const pj_ice_sess_check *c1; 380 const pj_ice_sess_check *c2; 381 382 c1 = pj_ice_strans_get_valid_pair(ept1->ice, i+1); 383 if (c1 == NULL) { 384 PJ_LOG(3,("", INDENT "err: unable to get valid pair for ice1 " 385 "component %d", i+1)); 386 return start_err - 2; 387 } 388 389 c2 = pj_ice_strans_get_valid_pair(ept2->ice, i+1); 390 if (c2 == NULL) { 391 PJ_LOG(3,("", INDENT "err: unable to get valid pair for ice2 " 392 "component %d", i+1)); 393 return start_err - 4; 394 } 395 396 if (pj_sockaddr_cmp(&c1->rcand->addr, &c2->lcand->addr) != 0) { 397 PJ_LOG(3,("", INDENT "err: candidate pair does not match " 398 "for component %d", i+1)); 399 return start_err - 6; 400 } 401 } 402 403 /* Extra components must not have valid pair */ 404 for (; i<max_cnt; ++i) { 405 if (ept1->cfg.comp_cnt>i && 406 pj_ice_strans_get_valid_pair(ept1->ice, i+1) != NULL) 407 { 408 PJ_LOG(3,("", INDENT "err: ice1 shouldn't have valid pair " 409 "for component %d", i+1)); 410 return start_err - 8; 411 } 412 if (ept2->cfg.comp_cnt>i && 413 pj_ice_strans_get_valid_pair(ept2->ice, i+1) != NULL) 414 { 415 PJ_LOG(3,("", INDENT "err: ice2 shouldn't have valid pair " 416 "for component %d", i+1)); 417 return start_err - 9; 418 } 419 } 107 420 108 421 return 0; … … 110 423 111 424 112 static pj_status_t start_ice(pj_ice_strans *ist, pj_ice_strans *remote) 113 { 114 unsigned count; 115 pj_ice_sess_cand cand[PJ_ICE_MAX_CAND]; 116 pj_status_t status; 117 118 count = PJ_ARRAY_SIZE(cand); 119 status = pj_ice_strans_enum_cands(remote, &count, cand); 120 if (status != PJ_SUCCESS) 121 return status; 122 123 return pj_ice_strans_start_ice(ist, &remote->ice->rx_ufrag, &remote->ice->rx_pass, 124 count, cand); 125 } 126 127 128 struct dummy_cand 129 { 130 unsigned comp_id; 131 pj_ice_cand_type type; 132 const char *addr; 133 unsigned port; 134 }; 135 136 static int init_ice_st(pj_ice_strans *ice_st, 137 pj_bool_t add_valid_comp, 138 unsigned dummy_cnt, 139 struct dummy_cand cand[]) 140 { 141 pj_str_t a; 142 pj_status_t status; 143 unsigned i; 144 145 /* Create components */ 146 for (i=0; i<ice_st->comp_cnt; ++i) { 147 status = pj_ice_strans_create_comp(ice_st, i+1, PJ_ICE_ST_OPT_DONT_ADD_CAND, NULL); 148 if (status != PJ_SUCCESS) 149 return -21; 150 } 151 152 /* Add dummy candidates */ 153 for (i=0; i<dummy_cnt; ++i) { 154 pj_sockaddr_in addr; 155 156 pj_sockaddr_in_init(&addr, pj_cstr(&a, cand[i].addr), (pj_uint16_t)cand[i].port); 157 status = pj_ice_strans_add_cand(ice_st, cand[i].comp_id, cand[i].type, 158 65535, &addr, PJ_FALSE); 159 if (status != PJ_SUCCESS) 160 return -22; 161 } 162 163 /* Add the real candidate */ 164 if (add_valid_comp) { 165 for (i=0; i<ice_st->comp_cnt; ++i) { 166 status = pj_ice_strans_add_cand(ice_st, i+1, PJ_ICE_CAND_TYPE_HOST, 65535, 167 &ice_st->comp[i]->local_addr.ipv4, PJ_TRUE); 168 if (status != PJ_SUCCESS) 169 return -23; 170 } 425 #define WAIT_UNTIL(timeout,expr, RC) { \ 426 pj_time_val t0, t; \ 427 pj_gettimeofday(&t0); \ 428 RC = -1; \ 429 for (;;) { \ 430 poll_events(stun_cfg, 10, PJ_FALSE); \ 431 pj_gettimeofday(&t); \ 432 if (expr) { \ 433 rc = PJ_SUCCESS; \ 434 break; \ 435 } \ 436 if (t.sec - t0.sec > (timeout)) break; \ 437 } \ 438 } 439 440 441 static int perform_test(const char *title, 442 pj_stun_config *stun_cfg, 443 unsigned server_flag, 444 struct test_cfg *caller_cfg, 445 struct test_cfg *callee_cfg) 446 { 447 pjlib_state pjlib_state; 448 struct test_sess *sess; 449 int rc; 450 451 PJ_LOG(3,("", INDENT "%s", title)); 452 453 capture_pjlib_state(stun_cfg, &pjlib_state); 454 455 rc = create_sess(stun_cfg, server_flag, caller_cfg, callee_cfg, &sess); 456 if (rc != 0) 457 return rc; 458 459 #define ALL_READY (sess->caller.result.init_status!=PJ_EPENDING && \ 460 sess->callee.result.init_status!=PJ_EPENDING) 461 462 /* Wait until both ICE transports are initialized */ 463 WAIT_UNTIL(30, ALL_READY, rc); 464 465 if (!ALL_READY) { 466 PJ_LOG(3,("", INDENT "err: init timed-out")); 467 destroy_sess(sess, 500); 468 return -100; 469 } 470 471 if (sess->caller.result.init_status != sess->caller.cfg.expected.init_status) { 472 app_perror(INDENT "err: caller init", sess->caller.result.init_status); 473 destroy_sess(sess, 500); 474 return -102; 475 } 476 if (sess->callee.result.init_status != sess->callee.cfg.expected.init_status) { 477 app_perror(INDENT "err: callee init", sess->callee.result.init_status); 478 destroy_sess(sess, 500); 479 return -104; 480 } 481 482 /* Failure condition */ 483 if (sess->caller.result.init_status != PJ_SUCCESS || 484 sess->callee.result.init_status != PJ_SUCCESS) 485 { 486 rc = 0; 487 goto on_return; 488 } 489 490 /* Init ICE on caller */ 491 rc = pj_ice_strans_init_ice(sess->caller.ice, sess->caller.cfg.role, 492 &sess->caller.ufrag, &sess->caller.pass); 493 if (rc != PJ_SUCCESS) { 494 app_perror(INDENT "err: caller pj_ice_strans_init_ice()", rc); 495 destroy_sess(sess, 500); 496 return -100; 497 } 498 499 /* Init ICE on callee */ 500 rc = pj_ice_strans_init_ice(sess->callee.ice, sess->callee.cfg.role, 501 &sess->callee.ufrag, &sess->callee.pass); 502 if (rc != PJ_SUCCESS) { 503 app_perror(INDENT "err: callee pj_ice_strans_init_ice()", rc); 504 destroy_sess(sess, 500); 505 return -110; 506 } 507 508 /* Start ICE on callee */ 509 rc = start_ice(&sess->callee, &sess->caller); 510 if (rc != PJ_SUCCESS) { 511 destroy_sess(sess, 500); 512 return -120; 513 } 514 515 /* Wait for callee's answer_delay */ 516 poll_events(stun_cfg, sess->callee.cfg.answer_delay, PJ_FALSE); 517 518 /* Start ICE on caller */ 519 rc = start_ice(&sess->caller, &sess->callee); 520 if (rc != PJ_SUCCESS) { 521 destroy_sess(sess, 500); 522 return -130; 523 } 524 525 /* Wait until negotiation is complete on both endpoints */ 526 #define ALL_DONE (sess->caller.result.nego_status!=PJ_EPENDING && \ 527 sess->callee.result.nego_status!=PJ_EPENDING) 528 WAIT_UNTIL(30, ALL_DONE, rc); 529 530 if (!ALL_DONE) { 531 PJ_LOG(3,("", INDENT "err: negotiation timed-out")); 532 destroy_sess(sess, 500); 533 return -140; 534 } 535 536 if (sess->caller.result.nego_status != sess->caller.cfg.expected.nego_status) { 537 app_perror(INDENT "err: caller negotiation failed", sess->caller.result.nego_status); 538 destroy_sess(sess, 500); 539 return -150; 540 } 541 542 if (sess->callee.result.nego_status != sess->callee.cfg.expected.nego_status) { 543 app_perror(INDENT "err: callee negotiation failed", sess->callee.result.nego_status); 544 destroy_sess(sess, 500); 545 return -160; 546 } 547 548 /* Verify that both agents have agreed on the same pair */ 549 rc = check_pair(&sess->caller, &sess->callee, -170); 550 if (rc != 0) { 551 destroy_sess(sess, 500); 552 return rc; 553 } 554 rc = check_pair(&sess->callee, &sess->caller, -180); 555 if (rc != 0) { 556 destroy_sess(sess, 500); 557 return rc; 558 } 559 560 /* Looks like everything is okay */ 561 562 /* Destroy ICE stream transports first to let it de-allocate 563 * TURN relay (otherwise there'll be timer/memory leak, unless 564 * we wait for long time in the last poll_events() below). 565 */ 566 if (sess->caller.ice) { 567 pj_ice_strans_destroy(sess->caller.ice); 568 sess->caller.ice = NULL; 569 } 570 571 if (sess->callee.ice) { 572 pj_ice_strans_destroy(sess->callee.ice); 573 sess->callee.ice = NULL; 574 } 575 576 on_return: 577 /* Wait.. */ 578 poll_events(stun_cfg, 500, PJ_FALSE); 579 580 /* Now destroy everything */ 581 destroy_sess(sess, 500); 582 583 /* Flush events */ 584 poll_events(stun_cfg, 100, PJ_FALSE); 585 586 rc = check_pjlib_state(stun_cfg, &pjlib_state); 587 if (rc != 0) { 588 return rc; 171 589 } 172 590 … … 174 592 } 175 593 176 177 /* When ICE completes, both agents should agree on the same candidate pair. 178 * Check that the remote address selected by agent1 is equal to the 179 * local address of selected by agent 2. 180 */ 181 static int verify_address(pj_ice_strans *agent1, pj_ice_strans *agent2, 182 unsigned comp_id) 183 { 184 pj_ice_sess_cand *rcand, *lcand; 185 int lcand_id; 186 187 if (agent1->ice->comp[comp_id-1].valid_check == NULL) { 188 PJ_LOG(3,(THIS_FILE, "....error: valid_check not set for comp_id %d", comp_id)); 189 return -60; 190 } 191 192 /* Get default remote candidate of agent 1 */ 193 rcand = agent1->ice->comp[comp_id-1].valid_check->rcand; 194 195 /* Get default local candidate of agent 2 */ 196 pj_ice_sess_find_default_cand(agent2->ice, comp_id, &lcand_id); 197 if (lcand_id < 0) 198 return -62; 199 200 lcand = &agent2->ice->lcand[lcand_id]; 201 202 if (pj_memcmp(&rcand->addr, &lcand->addr, sizeof(pj_sockaddr_in))!=0) { 203 PJ_LOG(3,(THIS_FILE, "....error: the selected addresses are incorrect for comp_id %d", comp_id)); 204 return -64; 205 } 206 207 return 0; 208 } 209 210 211 /* Perform ICE test with the following parameters: 212 * 213 * - title: The title of the test 214 * - ocand_cnt, 215 * ocand Additional candidates to be added to offerer 216 * - acand_cnt, 217 * acand Additional candidates to be added to answerer 218 * 219 * The additional candidates are normally invalid candidates, meaning 220 * they won't be reachable by the agents. They are used to "confuse" 221 * ICE processing. 222 */ 223 static int perform_ice_test(const char *title, 224 pj_bool_t expected_success, 225 unsigned comp_cnt, 226 pj_bool_t add_valid_comp, 227 unsigned wait_before_send, 228 unsigned max_total_time, 229 unsigned ocand_cnt, 230 struct dummy_cand ocand[], 231 unsigned acand_cnt, 232 struct dummy_cand acand[]) 233 { 234 pj_ice_strans *im1, *im2; 235 pj_ice_strans_cb icest_cb; 236 struct ice_data *id1, *id2; 237 pj_timestamp t_start, t_end; 594 #define ROLE1 PJ_ICE_SESS_ROLE_CONTROLLED 595 #define ROLE2 PJ_ICE_SESS_ROLE_CONTROLLING 596 597 int ice_test(void) 598 { 599 pj_pool_t *pool; 600 pj_stun_config stun_cfg; 238 601 unsigned i; 239 pj_str_t data_from_offerer, data_from_answerer; 240 pj_status_t status; 241 242 #define CHECK_COMPLETE() if (id1->complete && id2->complete) { \ 243 if (t_end.u32.lo==0) pj_get_timestamp(&t_end); \ 244 } else {} 245 246 PJ_LOG(3,(THIS_FILE, "...%s", title)); 247 248 pj_bzero(&t_end, sizeof(t_end)); 249 250 pj_bzero(&icest_cb, sizeof(icest_cb)); 251 icest_cb.on_ice_complete = &on_ice_complete; 252 icest_cb.on_rx_data = &on_rx_data; 253 254 /* Create first ICE */ 255 status = pj_ice_strans_create(&stun_cfg, "offerer", comp_cnt, NULL, &icest_cb, &im1); 256 if (status != PJ_SUCCESS) 257 return -20; 258 259 id1 = PJ_POOL_ZALLOC_T(im1->pool, struct ice_data); 260 id1->obj_name = "offerer"; 261 im1->user_data = id1; 262 263 /* Init components */ 264 status = init_ice_st(im1, add_valid_comp, ocand_cnt, ocand); 265 if (status != 0) 266 return status; 267 268 /* Create second ICE */ 269 status = pj_ice_strans_create(&stun_cfg, "answerer", comp_cnt, NULL, &icest_cb, &im2); 270 if (status != PJ_SUCCESS) 271 return -25; 272 273 id2 = PJ_POOL_ZALLOC_T(im2->pool, struct ice_data); 274 id2->obj_name = "answerer"; 275 im2->user_data = id2; 276 277 /* Init components */ 278 status = init_ice_st(im2, add_valid_comp, acand_cnt, acand); 279 if (status != 0) 280 return status; 281 282 283 /* Init ICE on im1 */ 284 status = pj_ice_strans_init_ice(im1, PJ_ICE_SESS_ROLE_CONTROLLING, NULL, NULL); 285 if (status != PJ_SUCCESS) 286 return -29; 287 288 /* Init ICE on im2 */ 289 status = pj_ice_strans_init_ice(im2, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL); 290 if (status != PJ_SUCCESS) 291 return -29; 292 293 /* Start ICE on im2 */ 294 status = start_ice(im2, im1); 295 if (status != PJ_SUCCESS) { 296 app_perror(" error starting ICE", status); 297 return -30; 298 } 299 300 /* Start ICE on im1 */ 301 status = start_ice(im1, im2); 302 if (status != PJ_SUCCESS) 303 return -35; 304 305 /* Apply delay to let other checks commence */ 306 pj_thread_sleep(40); 307 308 /* Mark start time */ 309 pj_get_timestamp(&t_start); 310 311 /* Poll for wait_before_send msecs before we send the first data */ 312 if (expected_success) { 313 for (;;) { 314 pj_timestamp t_now; 315 316 handle_events(1); 317 318 CHECK_COMPLETE(); 319 320 pj_get_timestamp(&t_now); 321 if (pj_elapsed_msec(&t_start, &t_now) >= wait_before_send) 322 break; 323 } 324 325 /* Send data. It must be successful! */ 326 data_from_offerer = pj_str("from offerer"); 327 status = pj_ice_sess_send_data(im1->ice, 1, data_from_offerer.ptr, data_from_offerer.slen); 328 if (status != PJ_SUCCESS) 329 return -47; 330 331 data_from_answerer = pj_str("from answerer"); 332 status = pj_ice_sess_send_data(im2->ice, 1, data_from_answerer.ptr, data_from_answerer.slen); 333 if (status != PJ_SUCCESS) { 334 app_perror(" error sending packet", status); 335 return -48; 336 } 337 338 /* Poll to allow data to be received */ 339 for (;;) { 340 pj_timestamp t_now; 341 handle_events(1); 342 CHECK_COMPLETE(); 343 pj_get_timestamp(&t_now); 344 if (pj_elapsed_msec(&t_start, &t_now) >= (wait_before_send + 200)) 345 break; 346 } 347 } 348 349 /* Just wait until both completes, or timed out */ 350 while (!id1->complete || !id2->complete) { 351 pj_timestamp t_now; 352 353 handle_events(1); 354 355 CHECK_COMPLETE(); 356 pj_get_timestamp(&t_now); 357 if (pj_elapsed_msec(&t_start, &t_now) >= max_total_time) { 358 PJ_LOG(3,(THIS_FILE, "....error: timed-out")); 359 return -50; 360 } 361 } 362 363 /* Mark end-time */ 364 CHECK_COMPLETE(); 365 366 /* If expected to fail, then just check that both fail */ 367 if (!expected_success) { 368 /* Check status */ 369 if (id1->err_code == PJ_SUCCESS) 370 return -51; 371 if (id2->err_code == PJ_SUCCESS) 372 return -52; 373 goto on_return; 374 } 375 376 /* Check status */ 377 if (id1->err_code != PJ_SUCCESS) 378 return -53; 379 if (id2->err_code != PJ_SUCCESS) 380 return -56; 381 382 /* Verify that offerer gets answerer's transport address */ 383 for (i=0; i<comp_cnt; ++i) { 384 status = verify_address(im1, im2, i+1); 385 if (status != 0) 386 return status; 387 } 388 389 /* And the other way around */ 390 for (i=0; i<comp_cnt; ++i) { 391 status = verify_address(im2, im1, i+1); 392 if (status != 0) 393 return status; 394 } 395 396 /* Check that data is received in offerer */ 397 if (id1->rx_rtp_cnt != 1) { 398 PJ_LOG(3,(THIS_FILE, "....error: data not received in offerer")); 399 return -80; 400 } 401 if (pj_strcmp2(&data_from_answerer, id1->last_rx_rtp_data) != 0) { 402 PJ_LOG(3,(THIS_FILE, "....error: data mismatch in offerer")); 403 return -82; 404 } 405 406 /* And the same in answerer */ 407 if (id2->rx_rtp_cnt != 1) { 408 PJ_LOG(3,(THIS_FILE, "....error: data not received in answerer")); 409 return -84; 410 } 411 if (pj_strcmp2(&data_from_offerer, id2->last_rx_rtp_data) != 0) { 412 PJ_LOG(3,(THIS_FILE, "....error: data mismatch in answerer")); 413 return -82; 414 } 415 602 int rc; 603 struct sess_cfg_t { 604 const char *title; 605 unsigned server_flag; 606 struct test_cfg ua1; 607 struct test_cfg ua2; 608 } sess_cfg[] = 609 { 610 /* Role comp# host? stun? turn? flag? ans_del snd_del des_del */ 611 { 612 "hosts candidates only", 613 0xFFFF, 614 {ROLE1, 1, YES, NO, NO, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 615 {ROLE2, 1, YES, NO, NO, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 616 }, 617 { 618 "host and srflxes", 619 0xFFFF, 620 {ROLE1, 1, YES, YES, NO, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 621 {ROLE2, 1, YES, YES, NO, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 622 }, 623 { 624 "host vs relay", 625 0xFFFF, 626 {ROLE1, 1, YES, NO, NO, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 627 {ROLE2, 1, NO, NO, YES, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 628 }, 629 { 630 "relay vs host", 631 0xFFFF, 632 {ROLE1, 1, NO, NO, YES, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 633 {ROLE2, 1, YES, NO, NO, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 634 }, 635 { 636 "relay vs relay", 637 0xFFFF, 638 {ROLE1, 1, NO, NO, YES, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 639 {ROLE2, 1, NO, NO, YES, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 640 }, 641 { 642 "all candidates", 643 0xFFFF, 644 {ROLE1, 1, YES, YES, YES, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 645 {ROLE2, 1, YES, YES, YES, NO, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 646 }, 647 }; 648 649 pool = pj_pool_create(mem, NULL, 512, 512, NULL); 650 rc = create_stun_config(pool, &stun_cfg); 651 if (rc != PJ_SUCCESS) { 652 pj_pool_release(pool); 653 return -7; 654 } 655 656 /* Simple test first with host candidate */ 657 if (1) { 658 struct sess_cfg_t cfg = 659 { 660 "Basic with host candidates", 661 0x0, 662 /* Role comp# host? stun? turn? flag? ans_del snd_del des_del */ 663 {ROLE1, 1, YES, NO, NO, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 664 {ROLE2, 1, YES, NO, NO, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 665 }; 666 667 rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag, 668 &cfg.ua1, &cfg.ua2); 669 if (rc != 0) 670 goto on_return; 671 672 cfg.ua1.comp_cnt = 4; 673 cfg.ua2.comp_cnt = 4; 674 rc = perform_test("Basic with host candidates, 4 components", 675 &stun_cfg, cfg.server_flag, 676 &cfg.ua1, &cfg.ua2); 677 if (rc != 0) 678 goto on_return; 679 } 680 681 /* Simple test first with srflx candidate */ 682 if (1) { 683 struct sess_cfg_t cfg = 684 { 685 "Basic with srflx candidates", 686 0xFFFF, 687 /* Role comp# host? stun? turn? flag? ans_del snd_del des_del */ 688 {ROLE1, 1, YES, YES, NO, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 689 {ROLE2, 1, YES, YES, NO, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 690 }; 691 692 rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag, 693 &cfg.ua1, &cfg.ua2); 694 if (rc != 0) 695 goto on_return; 696 697 cfg.ua1.comp_cnt = 4; 698 cfg.ua2.comp_cnt = 4; 699 700 rc = perform_test("Basic with srflx candidates, 4 components", 701 &stun_cfg, cfg.server_flag, 702 &cfg.ua1, &cfg.ua2); 703 if (rc != 0) 704 goto on_return; 705 } 706 707 /* Simple test with relay candidate */ 708 if (1) { 709 struct sess_cfg_t cfg = 710 { 711 "Basic with relay candidates", 712 0xFFFF, 713 /* Role comp# host? stun? turn? flag? ans_del snd_del des_del */ 714 {ROLE1, 1, NO, NO, YES, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}, 715 {ROLE2, 1, NO, NO, YES, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}} 716 }; 717 718 rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag, 719 &cfg.ua1, &cfg.ua2); 720 if (rc != 0) 721 goto on_return; 722 723 cfg.ua1.comp_cnt = 4; 724 cfg.ua2.comp_cnt = 4; 725 726 rc = perform_test("Basic with relay candidates, 4 components", 727 &stun_cfg, cfg.server_flag, 728 &cfg.ua1, &cfg.ua2); 729 if (rc != 0) 730 goto on_return; 731 } 732 733 /* Failure test with STUN resolution */ 734 if (1) { 735 struct sess_cfg_t cfg = 736 { 737 "STUN resolution failure", 738 0x0, 739 /* Role comp# host? stun? turn? flag? ans_del snd_del des_del */ 740 {ROLE1, 2, NO, YES, NO, 0, 0, 0, 0, {PJNATH_ESTUNTIMEDOUT, -1}}, 741 {ROLE2, 2, NO, YES, NO, 0, 0, 0, 0, {PJNATH_ESTUNTIMEDOUT, -1}} 742 }; 743 744 rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag, 745 &cfg.ua1, &cfg.ua2); 746 if (rc != 0) 747 goto on_return; 748 749 cfg.ua1.client_flag |= DEL_ON_ERR; 750 cfg.ua2.client_flag |= DEL_ON_ERR; 751 752 rc = perform_test("STUN resolution failure with destroy on callback", 753 &stun_cfg, cfg.server_flag, 754 &cfg.ua1, &cfg.ua2); 755 if (rc != 0) 756 goto on_return; 757 } 758 759 /* Failure test with TURN resolution */ 760 if (1) { 761 struct sess_cfg_t cfg = 762 { 763 "TURN allocation failure", 764 0xFFFF, 765 /* Role comp# host? stun? turn? flag? ans_del snd_del des_del */ 766 {ROLE1, 4, NO, NO, YES, WRONG_TURN, 0, 0, 0, {PJ_STATUS_FROM_STUN_CODE(401), -1}}, 767 {ROLE2, 4, NO, NO, YES, WRONG_TURN, 0, 0, 0, {PJ_STATUS_FROM_STUN_CODE(401), -1}} 768 }; 769 770 rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag, 771 &cfg.ua1, &cfg.ua2); 772 if (rc != 0) 773 goto on_return; 774 775 cfg.ua1.client_flag |= DEL_ON_ERR; 776 cfg.ua2.client_flag |= DEL_ON_ERR; 777 778 rc = perform_test("TURN allocation failure with destroy on callback", 779 &stun_cfg, cfg.server_flag, 780 &cfg.ua1, &cfg.ua2); 781 if (rc != 0) 782 goto on_return; 783 } 784 785 /* STUN failure, testing TURN deallocation */ 786 if (1) { 787 struct sess_cfg_t cfg = 788 { 789 "STUN failure, testing TURN deallocation", 790 0xFFFF & (~(CREATE_STUN_SERVER)), 791 /* Role comp# host? stun? turn? flag? ans_del snd_del des_del */ 792 {ROLE1, 2, YES, YES, YES, 0, 0, 0, 0, {PJNATH_ESTUNTIMEDOUT, -1}}, 793 {ROLE2, 2, YES, YES, YES, 0, 0, 0, 0, {PJNATH_ESTUNTIMEDOUT, -1}} 794 }; 795 796 rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag, 797 &cfg.ua1, &cfg.ua2); 798 if (rc != 0) 799 goto on_return; 800 801 cfg.ua1.client_flag |= DEL_ON_ERR; 802 cfg.ua2.client_flag |= DEL_ON_ERR; 803 804 rc = perform_test("STUN failure, testing TURN deallocation (cb)", 805 &stun_cfg, cfg.server_flag, 806 &cfg.ua1, &cfg.ua2); 807 if (rc != 0) 808 goto on_return; 809 } 810 811 rc = 0; 812 /* Iterate each test item */ 813 for (i=0; i<PJ_ARRAY_SIZE(sess_cfg); ++i) { 814 struct sess_cfg_t *cfg = &sess_cfg[i]; 815 unsigned delay[] = { 50, 2000 }; 816 unsigned d; 817 818 PJ_LOG(3,("", " %s", cfg->title)); 819 820 /* For each test item, test with various answer delay */ 821 for (d=0; d<PJ_ARRAY_SIZE(delay); ++d) { 822 struct role_t { 823 pj_ice_sess_role ua1; 824 pj_ice_sess_role ua2; 825 } role[] = 826 { 827 { ROLE1, ROLE2}, 828 { ROLE2, ROLE1}, 829 { ROLE1, ROLE1}, 830 { ROLE2, ROLE2} 831 }; 832 unsigned j; 833 834 cfg->ua1.answer_delay = delay[d]; 835 cfg->ua2.answer_delay = delay[d]; 836 837 /* For each test item, test with role conflict scenarios */ 838 for (j=0; j<PJ_ARRAY_SIZE(role); ++j) { 839 unsigned k1; 840 841 cfg->ua1.role = role[j].ua1; 842 cfg->ua2.role = role[j].ua2; 843 844 /* For each test item, test with different number of components */ 845 for (k1=1; k1<=2; ++k1) { 846 unsigned k2; 847 848 cfg->ua1.comp_cnt = k1; 849 850 for (k2=1; k2<=2; ++k2) { 851 char title[120]; 852 853 sprintf(title, 854 "%s/%s, %dms answer delay, %d vs %d components", 855 pj_ice_sess_role_name(role[j].ua1), 856 pj_ice_sess_role_name(role[j].ua2), 857 delay[d], k1, k2); 858 859 cfg->ua2.comp_cnt = k2; 860 rc = perform_test(title, &stun_cfg, cfg->server_flag, 861 &cfg->ua1, &cfg->ua2); 862 if (rc != 0) 863 goto on_return; 864 } 865 } 866 } 867 } 868 } 416 869 417 870 on_return: 418 419 /* Done */ 420 PJ_LOG(3,(THIS_FILE, "....success: ICE completed in %d msec, waiting..", 421 pj_elapsed_msec(&t_start, &t_end))); 422 423 /* Wait for some more time */ 424 for (;;) { 425 pj_timestamp t_now; 426 427 pj_get_timestamp(&t_now); 428 if (pj_elapsed_msec(&t_start, &t_now) > max_total_time) 429 break; 430 431 handle_events(1); 432 } 433 434 435 pj_ice_strans_destroy(im1); 436 pj_ice_strans_destroy(im2); 437 handle_events(100); 438 return 0; 439 } 440 441 442 int ice_test(void) 443 { 444 int rc = 0; 445 pj_pool_t *pool; 446 pj_ioqueue_t *ioqueue; 447 pj_timer_heap_t *timer_heap; 448 enum { D1=500, D2=5000, D3=15000 }; 449 struct dummy_cand ocand[] = 450 { 451 {1, PJ_ICE_CAND_TYPE_SRFLX, "127.1.1.1", 65534 }, 452 {2, PJ_ICE_CAND_TYPE_SRFLX, "127.1.1.1", 65535 }, 453 }; 454 struct dummy_cand acand[] = 455 { 456 {1, PJ_ICE_CAND_TYPE_SRFLX, "127.2.2.2", 65534 }, 457 {2, PJ_ICE_CAND_TYPE_SRFLX, "127.2.2.2", 65535 }, 458 }; 459 460 pool = pj_pool_create(mem, NULL, 4000, 4000, NULL); 461 pj_ioqueue_create(pool, 12, &ioqueue); 462 pj_timer_heap_create(pool, 100, &timer_heap); 463 464 pj_stun_config_init(&stun_cfg, mem, 0, ioqueue, timer_heap); 465 466 #if 0 467 pj_log_set_level(5); 468 #endif 469 470 //goto test; 471 472 /* Basic create/destroy */ 473 rc = ice_basic_create_destroy_test(); 474 if (rc != 0) 475 goto on_return; 476 477 /* Direct communication */ 478 rc = perform_ice_test("Simple test (1 component)", PJ_TRUE, 1, PJ_TRUE, D1, D2, 0, NULL, 0, NULL); 479 if (rc != 0) 480 goto on_return; 481 482 /* Failure case (all checks fail) */ 483 #if 0 484 /* Cannot just add an SRFLX candidate; it needs a base */ 485 rc = perform_ice_test("Failure case (all checks fail)", PJ_FALSE, 1, PJ_FALSE, D3, D3, 1, ocand, 1, acand); 486 if (rc != 0) 487 goto on_return; 488 #endif 489 490 /* Direct communication with invalid address */ 491 rc = perform_ice_test("With 1 unreachable address", PJ_TRUE, 1, PJ_TRUE, D1, D2, 1, ocand, 0, NULL); 492 if (rc != 0) 493 goto on_return; 494 495 /* Direct communication with invalid address */ 496 rc = perform_ice_test("With 2 unreachable addresses (one each)", PJ_TRUE, 1, PJ_TRUE, D1, D2, 1, ocand, 1, acand); 497 if (rc != 0) 498 goto on_return; 499 500 /* Direct communication with two components */ 501 //test: 502 rc = perform_ice_test("With two components (RTP and RTCP)", PJ_TRUE, 2, PJ_TRUE, D1, D2, 0, NULL, 0, NULL); 503 if (rc != 0) 504 goto on_return; 505 506 goto on_return; 507 508 /* Direct communication with mismatch number of components */ 509 510 /* Direct communication with 2 components and 2 invalid address */ 511 rc = perform_ice_test("With 2 two components and 2 unreachable address", PJ_TRUE, 2, PJ_TRUE, D1, D2, 1, ocand, 1, acand); 512 if (rc != 0) 513 goto on_return; 514 515 516 517 on_return: 518 pj_log_set_level(3); 519 pj_ioqueue_destroy(stun_cfg.ioqueue); 871 destroy_stun_config(&stun_cfg); 520 872 pj_pool_release(pool); 521 873 return rc; -
pjproject/trunk/pjnath/src/pjnath-test/sess_auth.c
r1929 r1988 1099 1099 /* If REALM doesn't match, server must respond with 401 1100 1100 */ 1101 #if 0 1102 // STUN session now will just use the realm sent in the 1103 // response, so this test will fail because it will 1104 // authenticate successfully. 1105 1101 1106 rc = run_client_test("Invalid REALM (long term)", // title 1102 1107 PJ_TRUE, // server responding … … 1117 1122 goto done; 1118 1123 } 1124 #endif 1119 1125 1120 1126 /* Invalid HMAC */ -
pjproject/trunk/pjnath/src/pjnath-test/test.c
r1877 r1988 30 30 } 31 31 32 pj_status_t create_stun_config(pj_pool_t *pool, pj_stun_config *stun_cfg) 33 { 34 pj_ioqueue_t *ioqueue; 35 pj_timer_heap_t *timer_heap; 36 pj_status_t status; 37 38 status = pj_ioqueue_create(pool, 64, &ioqueue); 39 if (status != PJ_SUCCESS) { 40 app_perror(" pj_ioqueue_create()", status); 41 return status; 42 } 43 44 status = pj_timer_heap_create(pool, 256, &timer_heap); 45 if (status != PJ_SUCCESS) { 46 app_perror(" pj_timer_heap_create()", status); 47 pj_ioqueue_destroy(ioqueue); 48 return status; 49 } 50 51 pj_stun_config_init(stun_cfg, mem, 0, ioqueue, timer_heap); 52 53 return PJ_SUCCESS; 54 } 55 56 void destroy_stun_config(pj_stun_config *stun_cfg) 57 { 58 if (stun_cfg->timer_heap) { 59 pj_timer_heap_destroy(stun_cfg->timer_heap); 60 stun_cfg->timer_heap = NULL; 61 } 62 if (stun_cfg->ioqueue) { 63 pj_ioqueue_destroy(stun_cfg->ioqueue); 64 stun_cfg->ioqueue = NULL; 65 } 66 } 67 68 void poll_events(pj_stun_config *stun_cfg, unsigned msec, 69 pj_bool_t first_event_only) 70 { 71 pj_time_val stop_time; 72 int count = 0; 73 74 pj_gettimeofday(&stop_time); 75 stop_time.msec += msec; 76 pj_time_val_normalize(&stop_time); 77 78 /* Process all events for the specified duration. */ 79 for (;;) { 80 pj_time_val timeout = {0, 1}, now; 81 int c; 82 83 c = pj_timer_heap_poll( stun_cfg->timer_heap, NULL ); 84 if (c > 0) 85 count += c; 86 87 //timeout.sec = timeout.msec = 0; 88 c = pj_ioqueue_poll( stun_cfg->ioqueue, &timeout); 89 if (c > 0) 90 count += c; 91 92 pj_gettimeofday(&now); 93 if (PJ_TIME_VAL_GTE(now, stop_time)) 94 break; 95 96 if (first_event_only && count >= 0) 97 break; 98 } 99 } 100 101 void capture_pjlib_state(pj_stun_config *cfg, struct pjlib_state *st) 102 { 103 pj_caching_pool *cp; 104 105 st->timer_cnt = pj_timer_heap_count(cfg->timer_heap); 106 107 cp = (pj_caching_pool*)mem; 108 st->pool_used_cnt = cp->used_count; 109 } 110 111 int check_pjlib_state(pj_stun_config *cfg, 112 const struct pjlib_state *initial_st) 113 { 114 struct pjlib_state current_state; 115 int rc = 0; 116 117 capture_pjlib_state(cfg, ¤t_state); 118 119 if (current_state.timer_cnt > initial_st->timer_cnt) { 120 PJ_LOG(3,("", " error: possibly leaking timer")); 121 rc |= ERR_TIMER_LEAK; 122 } 123 124 if (current_state.pool_used_cnt > initial_st->pool_used_cnt) { 125 PJ_LOG(3,("", " error: possibly leaking memory")); 126 PJ_LOG(3,("", " dumping memory pool:")); 127 pj_pool_factory_dump(mem, PJ_TRUE); 128 rc |= ERR_MEMORY_LEAK; 129 } 130 131 return rc; 132 } 133 134 32 135 #define DO_TEST(test) do { \ 33 136 PJ_LOG(3, ("test", "Running %s...", #test)); \ … … 65 168 pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 ); 66 169 170 pjlib_util_init(); 67 171 pjnath_init(); 68 172 … … 74 178 #if INCLUDE_ICE_TEST 75 179 DO_TEST(ice_test()); 180 #endif 181 182 #if INCLUDE_STUN_SOCK_TEST 183 DO_TEST(stun_sock_test()); 184 #endif 185 186 #if INCLUDE_TURN_SOCK_TEST 187 DO_TEST(turn_sock_test()); 76 188 #endif 77 189 -
pjproject/trunk/pjnath/src/pjnath-test/test.h
r1877 r1988 23 23 #define INCLUDE_STUN_TEST 1 24 24 #define INCLUDE_ICE_TEST 1 25 #define INCLUDE_STUN_SOCK_TEST 1 26 #define INCLUDE_TURN_SOCK_TEST 1 25 27 26 28 int stun_test(void); 27 29 int sess_auth_test(void); 30 int stun_sock_test(void); 31 int turn_sock_test(void); 28 32 int ice_test(void); 29 33 int test_main(void); … … 32 36 extern pj_pool_factory *mem; 33 37 38 //////////////////////////////////// 39 /* 40 * Utilities 41 */ 42 pj_status_t create_stun_config(pj_pool_t *pool, pj_stun_config *stun_cfg); 43 void destroy_stun_config(pj_stun_config *stun_cfg); 44 45 void poll_events(pj_stun_config *stun_cfg, unsigned msec, 46 pj_bool_t first_event_only); 47 48 typedef struct pjlib_state 49 { 50 unsigned timer_cnt; /* Number of timer entries */ 51 unsigned pool_used_cnt; /* Number of app pools */ 52 } pjlib_state; 53 54 55 void capture_pjlib_state(pj_stun_config *cfg, struct pjlib_state *st); 56 int check_pjlib_state(pj_stun_config *cfg, 57 const struct pjlib_state *initial_st); 58 59 60 #define ERR_MEMORY_LEAK 1 61 #define ERR_TIMER_LEAK 2 62 -
pjproject/trunk/pjnath/src/pjnath/errno.c
r1862 r1988 53 53 PJ_BUILD_ERR( PJNATH_ESTUNINSERVER, "Invalid STUN server or server not configured"), 54 54 55 PJ_BUILD_ERR( PJNATH_ESTUNDESTROYED, "STUN object has been destoyed"), 56 55 57 /* ICE related errors */ 56 58 PJ_BUILD_ERR( PJNATH_ENOICE, "ICE session not available"), -
pjproject/trunk/pjnath/src/pjnath/ice_session.c
r1913 r1988 22 22 #include <pj/assert.h> 23 23 #include <pj/guid.h> 24 #include <pj/hash.h> 24 25 #include <pj/log.h> 25 26 #include <pj/os.h> … … 100 101 pj_ice_sess_checklist *clist; 101 102 } timer_data; 103 104 105 /* This is the data that will be attached as token to outgoing 106 * STUN messages. 107 */ 102 108 103 109 … … 170 176 171 177 178 PJ_DEF(const char*) pj_ice_sess_role_name(pj_ice_sess_role role) 179 { 180 switch (role) { 181 case PJ_ICE_SESS_ROLE_UNKNOWN: 182 return "Unknown"; 183 case PJ_ICE_SESS_ROLE_CONTROLLED: 184 return "Controlled"; 185 case PJ_ICE_SESS_ROLE_CONTROLLING: 186 return "Controlling"; 187 default: 188 return "??"; 189 } 190 } 191 192 172 193 /* Get the prefix for the foundation */ 173 194 static int get_type_prefix(pj_ice_cand_type type) … … 184 205 } 185 206 186 /* Calculate foundation */ 207 /* Calculate foundation: 208 * Two candidates have the same foundation when they are "similar" - of 209 * the same type and obtained from the same host candidate and STUN 210 * server using the same protocol. Otherwise, their foundation is 211 * different. 212 */ 187 213 PJ_DEF(void) pj_ice_calc_foundation(pj_pool_t *pool, 188 214 pj_str_t *foundation, … … 191 217 { 192 218 char buf[64]; 193 219 pj_uint32_t val; 220 221 if (base_addr->addr.sa_family == pj_AF_INET()) { 222 val = pj_ntohl(base_addr->ipv4.sin_addr.s_addr); 223 } else { 224 val = pj_hash_calc(0, pj_sockaddr_get_addr(base_addr), 225 pj_sockaddr_get_addr_len(base_addr)); 226 } 194 227 pj_ansi_snprintf(buf, sizeof(buf), "%c%x", 195 get_type_prefix(type), 196 (int)pj_ntohl(base_addr->ipv4.sin_addr.s_addr)); 228 get_type_prefix(type), val); 197 229 pj_strdup2(pool, foundation, buf); 198 230 } … … 264 296 265 297 if (name == NULL) 266 name = "ice %p";298 name = "icess%p"; 267 299 268 300 pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_SESS, … … 299 331 return status; 300 332 } 333 } 334 335 /* Initialize transport datas */ 336 for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) { 337 ice->tp_data[i].transport_id = i; 338 ice->tp_data[i].has_req_data = PJ_FALSE; 301 339 } 302 340 … … 552 590 PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, 553 591 unsigned comp_id, 592 unsigned transport_id, 554 593 pj_ice_cand_type type, 555 594 pj_uint16_t local_pref, … … 577 616 578 617 lcand = &ice->lcand[ice->lcand_cnt]; 579 lcand->comp_id = comp_id; 618 lcand->comp_id = (pj_uint8_t)comp_id; 619 lcand->transport_id = (pj_uint8_t)transport_id; 580 620 lcand->type = type; 581 621 pj_strdup(ice->pool, &lcand->foundation, foundation); … … 583 623 pj_memcpy(&lcand->addr, addr, addr_len); 584 624 pj_memcpy(&lcand->base_addr, base_addr, addr_len); 585 if (rel_addr) 586 pj_memcpy(&lcand->rel_addr, rel_addr, addr_len); 587 else 588 pj_bzero(&lcand->rel_addr, sizeof(lcand->rel_addr)); 589 625 pj_memcpy(&lcand->rel_addr, rel_addr, addr_len); 590 626 591 627 pj_ansi_strcpy(ice->tmp.txt, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); … … 1323 1359 1324 1360 /* Disable our components which don't have matching component */ 1325 if (ice->comp_cnt==2 && highest_comp==1) { 1326 ice->comp_cnt = 1; 1327 } 1361 for (i=highest_comp; i<ice->comp_cnt; ++i) { 1362 if (ice->comp[i].stun_sess) { 1363 pj_stun_session_destroy(ice->comp[i].stun_sess); 1364 pj_bzero(&ice->comp[i], sizeof(ice->comp[i])); 1365 } 1366 } 1367 ice->comp_cnt = highest_comp; 1328 1368 1329 1369 /* Init timer entry in the checklist. Initially the timer ID is FALSE … … 1346 1386 } 1347 1387 1348 1349 /* This is the data that will be attached as user data to outgoing1350 * STUN requests, and it will be given back when we receive completion1351 * status of the request.1352 */1353 struct req_data1354 {1355 pj_ice_sess *ice;1356 pj_ice_sess_checklist *clist;1357 unsigned ckid;1358 };1359 1360 1361 1388 /* Perform check on the specified candidate pair */ 1362 1389 static pj_status_t perform_check(pj_ice_sess *ice, … … 1365 1392 { 1366 1393 pj_ice_sess_comp *comp; 1367 struct req_data *rd;1394 pj_ice_msg_data *msg_data; 1368 1395 pj_ice_sess_check *check; 1369 1396 const pj_ice_sess_cand *lcand; … … 1393 1420 * completes and on_stun_request_complete() callback is called. 1394 1421 */ 1395 rd = PJ_POOL_ZALLOC_T(check->tdata->pool, struct req_data); 1396 rd->ice = ice; 1397 rd->clist = clist; 1398 rd->ckid = check_id; 1422 msg_data = PJ_POOL_ZALLOC_T(check->tdata->pool, pj_ice_msg_data); 1423 msg_data->transport_id = lcand->transport_id; 1424 msg_data->has_req_data = PJ_TRUE; 1425 msg_data->data.req.ice = ice; 1426 msg_data->data.req.clist = clist; 1427 msg_data->data.req.ckid = check_id; 1399 1428 1400 1429 /* Add PRIORITY */ … … 1428 1457 1429 1458 /* Initiate STUN transaction to send the request */ 1430 status = pj_stun_session_send_msg(comp->stun_sess, (void*)rd, PJ_FALSE,1459 status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE, 1431 1460 PJ_TRUE, &rcand->addr, 1432 1461 sizeof(pj_sockaddr_in), check->tdata); … … 1656 1685 stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 1657 1686 pj_ice_sess *ice = sd->ice; 1658 1659 PJ_UNUSED_ARG(token); 1660 1661 return (*ice->cb.on_tx_pkt)(ice, sd->comp_id, 1662 pkt, pkt_size, 1663 dst_addr, addr_len); 1687 pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token; 1688 1689 return (*ice->cb.on_tx_pkt)(ice, sd->comp_id, msg_data->transport_id, 1690 pkt, pkt_size, dst_addr, addr_len); 1664 1691 } 1665 1692 … … 1674 1701 unsigned src_addr_len) 1675 1702 { 1676 struct req_data *rd = (struct req_data*) token;1703 pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token; 1677 1704 pj_ice_sess *ice; 1678 1705 pj_ice_sess_check *check, *new_check; … … 1685 1712 PJ_UNUSED_ARG(src_addr_len); 1686 1713 1687 ice = rd->ice; 1688 check = &rd->clist->checks[rd->ckid]; 1689 clist = rd->clist; 1714 pj_assert(msg_data->has_req_data); 1715 1716 ice = msg_data->data.req.ice; 1717 clist = msg_data->data.req.clist; 1718 check = &clist->checks[msg_data->data.req.ckid]; 1719 1690 1720 1691 1721 /* Mark STUN transaction as complete */ … … 1740 1770 LOG4((ice->obj_name, "Resending check because of role conflict")); 1741 1771 check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0); 1742 perform_check(ice, clist, rd->ckid);1772 perform_check(ice, clist, msg_data->data.req.ckid); 1743 1773 pj_mutex_unlock(ice->mutex); 1744 1774 return; … … 1847 1877 /* Add new peer reflexive candidate */ 1848 1878 status = pj_ice_sess_add_cand(ice, check->lcand->comp_id, 1879 msg_data->transport_id, 1849 1880 PJ_ICE_CAND_TYPE_PRFLX, 1850 1881 65535, &foundation, … … 1920 1951 stun_data *sd; 1921 1952 const pj_stun_msg *msg = rdata->msg; 1953 pj_ice_msg_data *msg_data; 1922 1954 pj_ice_sess *ice; 1923 1955 pj_stun_priority_attr *prio_attr; … … 1930 1962 PJ_UNUSED_ARG(pkt); 1931 1963 PJ_UNUSED_ARG(pkt_len); 1932 PJ_UNUSED_ARG(token); 1933 1964 1934 1965 /* Reject any requests except Binding request */ 1935 1966 if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) { 1936 1967 pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST, 1937 NULL, NULL, PJ_TRUE,1968 NULL, token, PJ_TRUE, 1938 1969 src_addr, src_addr_len); 1939 1970 return PJ_SUCCESS; … … 2002 2033 /* Generate 487 response */ 2003 2034 pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, 2004 NULL, NULL, PJ_TRUE,2035 NULL, token, PJ_TRUE, 2005 2036 src_addr, src_addr_len); 2006 2037 pj_mutex_unlock(ice->mutex); … … 2014 2045 /* Generate 487 response */ 2015 2046 pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT, 2016 NULL, NULL, PJ_TRUE,2047 NULL, token, PJ_TRUE, 2017 2048 src_addr, src_addr_len); 2018 2049 pj_mutex_unlock(ice->mutex); … … 2035 2066 } 2036 2067 2068 /* Add XOR-MAPPED-ADDRESS attribute */ 2037 2069 status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 2038 2070 PJ_STUN_ATTR_XOR_MAPPED_ADDR, 2039 2071 PJ_TRUE, src_addr, src_addr_len); 2040 2072 2041 status = pj_stun_session_send_msg(sess, NULL, PJ_TRUE, PJ_TRUE, 2073 /* Create a msg_data to be associated with this response */ 2074 msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data); 2075 msg_data->transport_id = ((pj_ice_msg_data*)token)->transport_id; 2076 msg_data->has_req_data = PJ_FALSE; 2077 2078 /* Send the response */ 2079 status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE, PJ_TRUE, 2042 2080 src_addr, src_addr_len, tdata); 2043 2081 … … 2059 2097 /* Init rcheck */ 2060 2098 rcheck->comp_id = sd->comp_id; 2099 rcheck->transport_id = ((pj_ice_msg_data*)token)->transport_id; 2061 2100 rcheck->src_addr_len = src_addr_len; 2062 2101 pj_memcpy(&rcheck->src_addr, src_addr, src_addr_len); … … 2091 2130 pj_ice_sess_cand *rcand; 2092 2131 unsigned i; 2093 pj_bool_t is_relayed;2094 2132 2095 2133 comp = find_comp(ice, rcheck->comp_id); … … 2110 2148 if (i == ice->rcand_cnt) { 2111 2149 rcand = &ice->rcand[ice->rcand_cnt++]; 2112 rcand->comp_id = rcheck->comp_id;2150 rcand->comp_id = (pj_uint8_t)rcheck->comp_id; 2113 2151 rcand->type = PJ_ICE_CAND_TYPE_PRFLX; 2114 2152 rcand->prio = rcheck->priority; … … 2148 2186 } 2149 2187 #else 2150 /* Just get candidate with the highest priority for the specified2151 * component ID in the checklist.2188 /* Just get candidate with the highest priority and same transport ID 2189 * for the specified component ID in the checklist. 2152 2190 */ 2153 2191 for (i=0; i<ice->clist.count; ++i) { 2154 2192 pj_ice_sess_check *c = &ice->clist.checks[i]; 2155 if (c->lcand->comp_id == rcheck->comp_id) { 2193 if (c->lcand->comp_id == rcheck->comp_id && 2194 c->lcand->transport_id == rcheck->transport_id) 2195 { 2156 2196 lcand = c->lcand; 2157 2197 break; … … 2171 2211 * Create candidate pair for this request. 2172 2212 */ 2173 /* First check if the source address is the source address of the2174 * STUN relay, to determine if local candidate is relayed candidate.2175 */2176 PJ_TODO(DETERMINE_IF_REQUEST_COMES_FROM_RELAYED_CANDIDATE);2177 is_relayed = PJ_FALSE;2178 2213 2179 2214 /* … … 2310 2345 pj_status_t status = PJ_SUCCESS; 2311 2346 pj_ice_sess_comp *comp; 2347 pj_ice_sess_cand *cand; 2312 2348 2313 2349 PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL); … … 2333 2369 } 2334 2370 2335 status = (*ice->cb.on_tx_pkt)(ice, comp_id, data, data_len, 2371 cand = comp->valid_check->lcand; 2372 status = (*ice->cb.on_tx_pkt)(ice, comp_id, cand->transport_id, 2373 data, data_len, 2336 2374 &comp->valid_check->rcand->addr, 2337 2375 sizeof(pj_sockaddr_in)); … … 2345 2383 PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 2346 2384 unsigned comp_id, 2385 unsigned transport_id, 2347 2386 void *pkt, 2348 2387 pj_size_t pkt_size, … … 2352 2391 pj_status_t status = PJ_SUCCESS; 2353 2392 pj_ice_sess_comp *comp; 2393 pj_ice_msg_data *msg_data = NULL; 2394 unsigned i; 2354 2395 pj_status_t stun_status; 2355 2396 … … 2364 2405 } 2365 2406 2407 /* Find transport */ 2408 for (i=0; i<PJ_ARRAY_SIZE(ice->tp_data); ++i) { 2409 if (ice->tp_data[i].transport_id == transport_id) { 2410 msg_data = &ice->tp_data[i]; 2411 break; 2412 } 2413 } 2414 if (msg_data == NULL) { 2415 pj_assert(!"Invalid transport ID"); 2416 status = PJ_EINVAL; 2417 goto on_return; 2418 } 2419 2366 2420 stun_status = pj_stun_msg_check((const pj_uint8_t*)pkt, pkt_size, 2367 2421 PJ_STUN_IS_DATAGRAM); 2368 2422 if (stun_status == PJ_SUCCESS) { 2369 2423 status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size, 2370 PJ_STUN_IS_DATAGRAM, NULL,2424 PJ_STUN_IS_DATAGRAM, msg_data, 2371 2425 NULL, src_addr, src_addr_len); 2372 2426 if (status != PJ_SUCCESS) { … … 2376 2430 } 2377 2431 } else { 2378 (*ice->cb.on_rx_data)(ice, comp_id, pkt, pkt_size,2432 (*ice->cb.on_rx_data)(ice, comp_id, transport_id, pkt, pkt_size, 2379 2433 src_addr, src_addr_len); 2380 2434 } -
pjproject/trunk/pjnath/src/pjnath/ice_strans.c
r1913 r1988 20 20 #include <pjnath/errno.h> 21 21 #include <pj/addr_resolv.h> 22 #include <pj/array.h> 22 23 #include <pj/assert.h> 23 24 #include <pj/ip_helper.h> 24 25 #include <pj/log.h> 26 #include <pj/os.h> 25 27 #include <pj/pool.h> 26 28 #include <pj/rand.h> … … 36 38 37 39 40 /* Transport IDs */ 41 enum tp_type 42 { 43 TP_NONE, 44 TP_STUN, 45 TP_TURN 46 }; 47 48 /* Candidate preference default values */ 49 #define SRFLX_PREF 65535 50 #define HOST_PREF 65530 51 #define RELAY_PREF 65525 52 38 53 39 54 /* ICE callbacks */ … … 41 56 static pj_status_t ice_tx_pkt(pj_ice_sess *ice, 42 57 unsigned comp_id, 58 unsigned transport_id, 43 59 const void *pkt, pj_size_t size, 44 60 const pj_sockaddr_t *dst_addr, 45 61 unsigned dst_addr_len); 46 62 static void ice_rx_data(pj_ice_sess *ice, 47 unsigned comp_id, 48 void *pkt, pj_size_t size, 49 const pj_sockaddr_t *src_addr, 50 unsigned src_addr_len); 51 52 /* Ioqueue callback */ 53 static void on_read_complete(pj_ioqueue_key_t *key, 54 pj_ioqueue_op_key_t *op_key, 55 pj_ssize_t bytes_read); 56 57 static void destroy_component(pj_ice_strans_comp *comp); 58 static void destroy_ice_st(pj_ice_strans *ice_st, pj_status_t reason); 59 60 61 /* STUN session callback */ 62 static pj_status_t stun_on_send_msg(pj_stun_session *sess, 63 void *token, 64 const void *pkt, 65 pj_size_t pkt_size, 66 const pj_sockaddr_t *dst_addr, 67 unsigned addr_len); 68 static void stun_on_request_complete(pj_stun_session *sess, 69 pj_status_t status, 70 void *token, 71 pj_stun_tx_data *tdata, 72 const pj_stun_msg *response, 73 const pj_sockaddr_t *src_addr, 74 unsigned src_addr_len); 75 76 /* Keep-alive timer */ 77 static void start_ka_timer(pj_ice_strans *ice_st); 78 static void stop_ka_timer(pj_ice_strans *ice_st); 79 80 /* Utility: print error */ 63 unsigned comp_id, 64 unsigned transport_id, 65 void *pkt, pj_size_t size, 66 const pj_sockaddr_t *src_addr, 67 unsigned src_addr_len); 68 69 70 /* STUN socket callbacks */ 71 /* Notification when incoming packet has been received. */ 72 static pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock, 73 void *pkt, 74 unsigned pkt_len, 75 const pj_sockaddr_t *src_addr, 76 unsigned addr_len); 77 /* Notifification when asynchronous send operation has completed. */ 78 static pj_bool_t stun_on_data_sent(pj_stun_sock *stun_sock, 79 pj_ioqueue_op_key_t *send_key, 80 pj_ssize_t sent); 81 /* Notification when the status of the STUN transport has changed. */ 82 static pj_bool_t stun_on_status(pj_stun_sock *stun_sock, 83 pj_stun_sock_op op, 84 pj_status_t status); 85 86 87 /* TURN callbacks */ 88 static void turn_on_rx_data(pj_turn_sock *turn_sock, 89 void *pkt, 90 unsigned pkt_len, 91 const pj_sockaddr_t *peer_addr, 92 unsigned addr_len); 93 static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state, 94 pj_turn_state_t new_state); 95 96 97 98 /* Forward decls */ 99 static void destroy_ice_st(pj_ice_strans *ice_st); 81 100 #define ice_st_perror(ice_st,msg,rc) pjnath_perror(ice_st->obj_name,msg,rc) 101 static void sess_init_update(pj_ice_strans *ice_st); 102 103 static void sess_add_ref(pj_ice_strans *ice_st); 104 static pj_bool_t sess_dec_ref(pj_ice_strans *ice_st); 105 106 /** 107 * This structure describes an ICE stream transport component. A component 108 * in ICE stream transport typically corresponds to a single socket created 109 * for this component, and bound to a specific transport address. This 110 * component may have multiple alias addresses, for example one alias 111 * address for each interfaces in multi-homed host, another for server 112 * reflexive alias, and another for relayed alias. For each transport 113 * address alias, an ICE stream transport candidate (#pj_ice_sess_cand) will 114 * be created, and these candidates will eventually registered to the ICE 115 * session. 116 */ 117 typedef struct pj_ice_strans_comp 118 { 119 pj_ice_strans *ice_st; /**< ICE stream transport. */ 120 unsigned comp_id; /**< Component ID. */ 121 122 pj_stun_sock *stun_sock; /**< STUN transport. */ 123 pj_turn_sock *turn_sock; /**< TURN relay transport. */ 124 125 unsigned cand_cnt; /**< # of candidates/aliaes. */ 126 pj_ice_sess_cand cand_list[PJ_ICE_ST_MAX_CAND]; /**< Cand array */ 127 128 unsigned default_cand; /**< Default candidate. */ 129 130 } pj_ice_strans_comp; 131 132 133 /** 134 * This structure represents the ICE stream transport. 135 */ 136 struct pj_ice_strans 137 { 138 char *obj_name; /**< Log ID. */ 139 pj_pool_t *pool; /**< Pool used by this object. */ 140 void *user_data; /**< Application data. */ 141 pj_ice_strans_cfg cfg; /**< Configuration. */ 142 pj_ice_strans_cb cb; /**< Application callback. */ 143 144 pj_ice_sess *ice; /**< ICE session. */ 145 pj_time_val start_time;/**< Time when ICE was started */ 146 147 unsigned comp_cnt; /**< Number of components. */ 148 pj_ice_strans_comp **comp; /**< Components array. */ 149 150 pj_timer_entry ka_timer; /**< STUN keep-alive timer. */ 151 152 pj_atomic_t *busy_cnt; /**< To prevent destroy */ 153 pj_bool_t destroy_req;/**< Destroy has been called? */ 154 pj_bool_t cb_called; /**< Init error callback called?*/ 155 }; 156 157 158 /* Validate configuration */ 159 static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg) 160 { 161 pj_status_t status; 162 163 status = pj_stun_config_check_valid(&cfg->stun_cfg); 164 if (!status) 165 return status; 166 167 return PJ_SUCCESS; 168 } 169 170 171 /* 172 * Initialize ICE transport configuration with default values. 173 */ 174 PJ_DEF(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg) 175 { 176 pj_bzero(cfg, sizeof(*cfg)); 177 178 pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL); 179 pj_stun_sock_cfg_default(&cfg->stun.cfg); 180 pj_turn_alloc_param_default(&cfg->turn.alloc_param); 181 182 cfg->af = pj_AF_INET(); 183 cfg->stun.port = PJ_STUN_PORT; 184 cfg->turn.conn_type = PJ_TURN_TP_UDP; 185 } 186 187 188 /* 189 * Copy configuration. 190 */ 191 PJ_DEF(void) pj_ice_strans_cfg_copy( pj_pool_t *pool, 192 pj_ice_strans_cfg *dst, 193 const pj_ice_strans_cfg *src) 194 { 195 pj_memcpy(dst, src, sizeof(*src)); 196 197 if (src->stun.server.slen) 198 pj_strdup(pool, &dst->stun.server, &src->stun.server); 199 if (src->turn.server.slen) 200 pj_strdup(pool, &dst->turn.server, &src->turn.server); 201 pj_stun_auth_cred_dup(pool, &dst->turn.auth_cred, 202 &src->turn.auth_cred); 203 } 204 205 /* 206 * Create the component. 207 */ 208 static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id) 209 { 210 pj_ice_strans_comp *comp = NULL; 211 pj_status_t status; 212 213 /* Verify arguments */ 214 PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL); 215 216 /* Check that component ID present */ 217 PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID); 218 219 /* Create component */ 220 comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_strans_comp); 221 comp->ice_st = ice_st; 222 comp->comp_id = comp_id; 223 224 ice_st->comp[comp_id-1] = comp; 225 226 /* Initialize default candidate */ 227 comp->default_cand = 0; 228 229 /* Create STUN transport if configured */ 230 if (ice_st->cfg.stun.server.slen || !ice_st->cfg.stun.no_host_cands) { 231 pj_stun_sock_cb stun_sock_cb; 232 pj_ice_sess_cand *cand; 233 234 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 235 stun_sock_cb.on_rx_data = &stun_on_rx_data; 236 stun_sock_cb.on_status = &stun_on_status; 237 stun_sock_cb.on_data_sent = &stun_on_data_sent; 238 239 /* Create the STUN transport */ 240 status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL, 241 ice_st->cfg.af, &stun_sock_cb, 242 &ice_st->cfg.stun.cfg, 243 comp, &comp->stun_sock); 244 if (status != PJ_SUCCESS) 245 return status; 246 247 /* Start STUN Binding resolution and add srflx candidate 248 * only if server is set 249 */ 250 if (ice_st->cfg.stun.server.slen) { 251 pj_stun_sock_info stun_sock_info; 252 253 /* Add pending job */ 254 ///sess_add_ref(ice_st); 255 256 /* Start Binding resolution */ 257 status = pj_stun_sock_start(comp->stun_sock, 258 &ice_st->cfg.stun.server, 259 ice_st->cfg.stun.port, 260 ice_st->cfg.resolver); 261 if (status != PJ_SUCCESS) { 262 ///sess_dec_ref(ice_st); 263 return status; 264 } 265 266 /* Enumerate addresses */ 267 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info); 268 if (status != PJ_SUCCESS) { 269 ///sess_dec_ref(ice_st); 270 return status; 271 } 272 273 /* Add srflx candidate with pending status */ 274 cand = &comp->cand_list[comp->cand_cnt++]; 275 cand->type = PJ_ICE_CAND_TYPE_SRFLX; 276 cand->status = PJ_EPENDING; 277 cand->local_pref = SRFLX_PREF; 278 cand->transport_id = TP_STUN; 279 cand->comp_id = (pj_uint8_t) comp_id; 280 pj_sockaddr_cp(&cand->base_addr, &stun_sock_info.aliases[0]); 281 pj_sockaddr_cp(&cand->rel_addr, &cand->base_addr); 282 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 283 cand->type, &cand->base_addr); 284 PJ_LOG(4,(ice_st->obj_name, 285 "Comp %d: srflx candidate starts Binding discovery", 286 comp_id)); 287 288 /* Set default candidate to srflx */ 289 comp->default_cand = cand - comp->cand_list; 290 } 291 292 /* Add local addresses to host candidates, unless no_host_cands 293 * flag is set. 294 */ 295 if (ice_st->cfg.stun.no_host_cands == PJ_FALSE) { 296 pj_stun_sock_info stun_sock_info; 297 unsigned i; 298 299 /* Enumerate addresses */ 300 status = pj_stun_sock_get_info(comp->stun_sock, &stun_sock_info); 301 if (status != PJ_SUCCESS) 302 return status; 303 304 for (i=0; i<stun_sock_info.alias_cnt; ++i) { 305 char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 306 const pj_sockaddr *addr = &stun_sock_info.aliases[i]; 307 308 /* Leave one candidate for relay */ 309 if (comp->cand_cnt >= PJ_ICE_ST_MAX_CAND-1) { 310 PJ_LOG(4,(ice_st->obj_name, "Too many host candidates")); 311 break; 312 } 313 314 /* Ignore loopback addresses unless cfg->stun.loop_addr 315 * is set 316 */ 317 if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) { 318 if (ice_st->cfg.stun.loop_addr==PJ_FALSE) 319 continue; 320 } 321 322 cand = &comp->cand_list[comp->cand_cnt++]; 323 324 cand->type = PJ_ICE_CAND_TYPE_HOST; 325 cand->status = PJ_SUCCESS; 326 cand->local_pref = HOST_PREF; 327 cand->transport_id = TP_STUN; 328 cand->comp_id = (pj_uint8_t) comp_id; 329 pj_sockaddr_cp(&cand->addr, addr); 330 pj_sockaddr_cp(&cand->base_addr, addr); 331 pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr)); 332 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 333 cand->type, &cand->base_addr); 334 335 PJ_LOG(4,(ice_st->obj_name, 336 "Comp %d: host candidate %s added", 337 comp_id, pj_sockaddr_print(&cand->addr, addrinfo, 338 sizeof(addrinfo), 3))); 339 } 340 } 341 } 342 343 /* Create TURN relay if configured. */ 344 if (ice_st->cfg.turn.server.slen) { 345 pj_turn_sock_cb turn_sock_cb; 346 pj_ice_sess_cand *cand; 347 348 /* Init TURN socket */ 349 pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb)); 350 turn_sock_cb.on_rx_data = &turn_on_rx_data; 351 turn_sock_cb.on_state = &turn_on_state; 352 353 status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, ice_st->cfg.af, 354 ice_st->cfg.turn.conn_type, 355 &turn_sock_cb, 0, comp, 356 &comp->turn_sock); 357 if (status != PJ_SUCCESS) { 358 return status; 359 } 360 361 /* Add pending job */ 362 ///sess_add_ref(ice_st); 363 364 /* Start allocation */ 365 status=pj_turn_sock_alloc(comp->turn_sock, 366 &ice_st->cfg.turn.server, 367 ice_st->cfg.turn.port, 368 ice_st->cfg.resolver, 369 &ice_st->cfg.turn.auth_cred, 370 &ice_st->cfg.turn.alloc_param); 371 if (status != PJ_SUCCESS) { 372 ///sess_dec_ref(ice_st); 373 return status; 374 } 375 376 /* Add relayed candidate with pending status */ 377 cand = &comp->cand_list[comp->cand_cnt++]; 378 cand->type = PJ_ICE_CAND_TYPE_RELAYED; 379 cand->status = PJ_EPENDING; 380 cand->local_pref = RELAY_PREF; 381 cand->transport_id = TP_TURN; 382 cand->comp_id = (pj_uint8_t) comp_id; 383 384 PJ_LOG(4,(ice_st->obj_name, 385 "Comp %d: TURN relay candidate waiting for allocation", 386 comp_id)); 387 388 /* Set default candidate to relay */ 389 comp->default_cand = cand - comp->cand_list; 390 } 391 392 return PJ_SUCCESS; 393 } 394 82 395 83 396 /* 84 397 * Create ICE stream transport 85 398 */ 86 PJ_DEF(pj_status_t) pj_ice_strans_create( pj_stun_config *stun_cfg,87 const char *name,399 PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name, 400 const pj_ice_strans_cfg *cfg, 88 401 unsigned comp_cnt, 89 402 void *user_data, … … 93 406 pj_pool_t *pool; 94 407 pj_ice_strans *ice_st; 95 96 PJ_ASSERT_RETURN(stun_cfg && comp_cnt && cb && p_ice_st, PJ_EINVAL); 97 PJ_ASSERT_RETURN(stun_cfg->ioqueue && stun_cfg->timer_heap, PJ_EINVAL); 408 unsigned i; 409 pj_status_t status; 410 411 status = pj_ice_strans_cfg_check_valid(cfg); 412 if (status != PJ_SUCCESS) 413 return status; 414 415 PJ_ASSERT_RETURN(comp_cnt && cb && p_ice_st, PJ_EINVAL); 98 416 99 417 if (name == NULL) 100 name = "ic str%p";101 102 pool = pj_pool_create( stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_STRANS,418 name = "ice%p"; 419 420 pool = pj_pool_create(cfg->stun_cfg.pf, name, PJNATH_POOL_LEN_ICE_STRANS, 103 421 PJNATH_POOL_INC_ICE_STRANS, NULL); 104 422 ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans); 105 423 ice_st->pool = pool; 106 pj_memcpy(ice_st->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME);424 ice_st->obj_name = pool->obj_name; 107 425 ice_st->user_data = user_data; 426 427 PJ_LOG(4,(ice_st->obj_name, 428 "Creating ICE stream transport with %d component(s)", 429 comp_cnt)); 430 431 pj_ice_strans_cfg_copy(pool, &ice_st->cfg, cfg); 432 pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 108 433 434 status = pj_atomic_create(pool, 0, &ice_st->busy_cnt); 435 if (status != PJ_SUCCESS) { 436 destroy_ice_st(ice_st); 437 return status; 438 } 439 109 440 ice_st->comp_cnt = comp_cnt; 110 ice_st->comp = (pj_ice_strans_comp**) pj_pool_calloc(pool, comp_cnt, 111 sizeof(void*)); 112 113 pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 114 pj_memcpy(&ice_st->stun_cfg, stun_cfg, sizeof(*stun_cfg)); 115 441 ice_st->comp = (pj_ice_strans_comp**) 442 pj_pool_calloc(pool, comp_cnt, sizeof(pj_ice_strans_comp*)); 443 444 for (i=0; i<comp_cnt; ++i) { 445 status = create_comp(ice_st, i+1); 446 if (status != PJ_SUCCESS) { 447 destroy_ice_st(ice_st); 448 return status; 449 } 450 } 451 452 /* Check if all candidates are ready (this may call callback) */ 453 sess_init_update(ice_st); 116 454 117 455 PJ_LOG(4,(ice_st->obj_name, "ICE stream transport created")); … … 122 460 123 461 /* Destroy ICE */ 124 static void destroy_ice_st(pj_ice_strans *ice_st , pj_status_t reason)462 static void destroy_ice_st(pj_ice_strans *ice_st) 125 463 { 126 464 unsigned i; 127 char obj_name[PJ_MAX_OBJ_NAME];128 129 if (reason == PJ_SUCCESS) {130 pj_memcpy(obj_name, ice_st->obj_name, PJ_MAX_OBJ_NAME);131 PJ_LOG(4,(obj_name, "ICE stream transport shutting down"));132 }133 134 /* Kill keep-alive timer, if any */135 stop_ka_timer(ice_st);136 465 137 466 /* Destroy ICE if we have ICE */ … … 144 473 for (i=0; i<ice_st->comp_cnt; ++i) { 145 474 if (ice_st->comp[i]) { 146 destroy_component(ice_st->comp[i]); 147 ice_st->comp[i] = NULL; 475 if (ice_st->comp[i]->stun_sock) { 476 pj_stun_sock_set_user_data(ice_st->comp[i]->stun_sock, NULL); 477 pj_stun_sock_destroy(ice_st->comp[i]->stun_sock); 478 ice_st->comp[i]->stun_sock = NULL; 479 } 480 if (ice_st->comp[i]->turn_sock) { 481 pj_turn_sock_set_user_data(ice_st->comp[i]->turn_sock, NULL); 482 pj_turn_sock_destroy(ice_st->comp[i]->turn_sock); 483 ice_st->comp[i]->turn_sock = NULL; 484 } 148 485 } 149 486 } 150 487 ice_st->comp_cnt = 0; 488 489 /* Destroy reference counter */ 490 if (ice_st->busy_cnt) { 491 pj_assert(pj_atomic_get(ice_st->busy_cnt)==0); 492 pj_atomic_destroy(ice_st->busy_cnt); 493 ice_st->busy_cnt = NULL; 494 } 151 495 152 496 /* Done */ 153 497 pj_pool_release(ice_st->pool); 154 155 if (reason == PJ_SUCCESS) { 156 PJ_LOG(4,(obj_name, "ICE stream transport destroyed")); 157 } 498 } 499 500 /* Notification about failure */ 501 static void sess_fail(pj_ice_strans *ice_st, pj_ice_strans_op op, 502 const char *title, pj_status_t status) 503 { 504 char errmsg[PJ_ERR_MSG_SIZE]; 505 506 pj_strerror(status, errmsg, sizeof(errmsg)); 507 PJ_LOG(4,(ice_st->obj_name, "%s: %s", title, errmsg)); 508 509 if (op==PJ_ICE_STRANS_OP_INIT && ice_st->cb_called) 510 return; 511 512 ice_st->cb_called = PJ_TRUE; 513 514 if (ice_st->cb.on_ice_complete) 515 (*ice_st->cb.on_ice_complete)(ice_st, op, status); 516 } 517 518 /* Update initialization status */ 519 static void sess_init_update(pj_ice_strans *ice_st) 520 { 521 unsigned i; 522 523 /* Ignore if init callback has been called */ 524 if (ice_st->cb_called) 525 return; 526 527 /* Notify application when all candidates have been gathered */ 528 for (i=0; i<ice_st->comp_cnt; ++i) { 529 unsigned j; 530 pj_ice_strans_comp *comp = ice_st->comp[i]; 531 532 for (j=0; j<comp->cand_cnt; ++j) { 533 pj_ice_sess_cand *cand = &comp->cand_list[j]; 534 535 if (cand->status == PJ_EPENDING) 536 return; 537 } 538 } 539 540 /* All candidates have been gathered */ 541 ice_st->cb_called = PJ_TRUE; 542 if (ice_st->cb.on_ice_complete) 543 (*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_INIT, 544 PJ_SUCCESS); 158 545 } 159 546 … … 163 550 PJ_DEF(pj_status_t) pj_ice_strans_destroy(pj_ice_strans *ice_st) 164 551 { 165 destroy_ice_st(ice_st, PJ_SUCCESS); 552 char obj_name[PJ_MAX_OBJ_NAME]; 553 554 PJ_ASSERT_RETURN(ice_st, PJ_EINVAL); 555 556 ice_st->destroy_req = PJ_TRUE; 557 if (pj_atomic_get(ice_st->busy_cnt) > 0) { 558 PJ_LOG(5,(ice_st->obj_name, 559 "ICE strans object is busy, will destroy later")); 560 return PJ_EPENDING; 561 } 562 563 pj_memcpy(obj_name, ice_st->obj_name, PJ_MAX_OBJ_NAME); 564 destroy_ice_st(ice_st); 565 566 PJ_LOG(4,(obj_name, "ICE stream transport destroyed")); 166 567 return PJ_SUCCESS; 167 568 } 168 569 169 /* 170 * Resolve STUN server 171 */ 172 PJ_DEF(pj_status_t) pj_ice_strans_set_stun_domain(pj_ice_strans *ice_st, 173 pj_dns_resolver *resolver, 174 const pj_str_t *domain) 175 { 176 /* Yeah, TODO */ 177 PJ_UNUSED_ARG(ice_st); 178 PJ_UNUSED_ARG(resolver); 179 PJ_UNUSED_ARG(domain); 180 return -1; 181 } 182 183 /* 184 * Set STUN server address. 185 */ 186 PJ_DEF(pj_status_t) pj_ice_strans_set_stun_srv( pj_ice_strans *ice_st, 187 const pj_sockaddr_in *stun_srv, 188 const pj_sockaddr_in *turn_srv) 189 { 190 PJ_ASSERT_RETURN(ice_st, PJ_EINVAL); 191 /* Must not have pending resolver job */ 192 PJ_ASSERT_RETURN(ice_st->has_rjob==PJ_FALSE, PJ_EINVALIDOP); 193 194 if (stun_srv) { 195 pj_memcpy(&ice_st->stun_srv, stun_srv, sizeof(pj_sockaddr_in)); 570 571 /* 572 * Increment busy counter. 573 */ 574 static void sess_add_ref(pj_ice_strans *ice_st) 575 { 576 pj_atomic_inc(ice_st->busy_cnt); 577 } 578 579 /* 580 * Decrement busy counter. If the counter has reached zero and destroy 581 * has been requested, destroy the object and return FALSE. 582 */ 583 static pj_bool_t sess_dec_ref(pj_ice_strans *ice_st) 584 { 585 int count = pj_atomic_dec_and_get(ice_st->busy_cnt); 586 pj_assert(count >= 0); 587 if (count==0 && ice_st->destroy_req) { 588 pj_ice_strans_destroy(ice_st); 589 return PJ_FALSE; 196 590 } else { 197 pj_bzero(&ice_st->stun_srv, sizeof(pj_sockaddr_in)); 198 } 199 200 if (turn_srv) { 201 pj_memcpy(&ice_st->turn_srv, turn_srv, sizeof(pj_sockaddr_in)); 202 } else { 203 pj_bzero(&ice_st->turn_srv, sizeof(pj_sockaddr_in)); 204 } 205 206 return PJ_SUCCESS; 207 } 208 209 /* Add new candidate */ 210 static pj_status_t add_cand( pj_ice_strans *ice_st, 211 pj_ice_strans_comp *comp, 212 unsigned comp_id, 213 pj_ice_cand_type type, 214 pj_uint16_t local_pref, 215 const pj_sockaddr_in *addr, 216 pj_bool_t set_default) 217 { 218 pj_ice_strans_cand *cand; 219 unsigned i; 220 221 PJ_ASSERT_RETURN(ice_st && comp && addr, PJ_EINVAL); 222 PJ_ASSERT_RETURN(comp->cand_cnt < PJ_ICE_ST_MAX_CAND, PJ_ETOOMANY); 223 224 /* Check that we don't have candidate with the same 225 * address. 226 */ 227 for (i=0; i<comp->cand_cnt; ++i) { 228 if (pj_memcmp(addr, &comp->cand_list[i].addr, 229 sizeof(pj_sockaddr_in))==0) 230 { 231 /* Duplicate */ 232 PJ_LOG(5,(ice_st->obj_name, "Duplicate candidate not added")); 233 return PJ_SUCCESS; 234 } 235 } 236 237 cand = &comp->cand_list[comp->cand_cnt]; 238 239 pj_bzero(cand, sizeof(*cand)); 240 cand->type = type; 241 cand->status = PJ_SUCCESS; 242 pj_memcpy(&cand->addr, addr, sizeof(pj_sockaddr_in)); 243 cand->ice_cand_id = -1; 244 cand->local_pref = local_pref; 245 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, type, 246 &comp->local_addr); 247 248 if (set_default) 249 comp->default_cand = comp->cand_cnt; 250 251 PJ_LOG(5,(ice_st->obj_name, 252 "Candidate %s:%d (type=%s) added to component %d", 253 pj_inet_ntoa(addr->sin_addr), 254 (int)pj_ntohs(addr->sin_port), 255 pj_ice_get_cand_type_name(type), 256 comp_id)); 257 258 comp->cand_cnt++; 259 return PJ_SUCCESS; 260 } 261 262 /* Create new component (i.e. socket) */ 263 static pj_status_t create_component(pj_ice_strans *ice_st, 264 unsigned comp_id, 265 pj_uint32_t options, 266 const pj_sockaddr_in *addr, 267 pj_ice_strans_comp **p_comp) 268 { 269 enum { MAX_RETRY=100, PORT_INC=2 }; 270 pj_ioqueue_callback ioqueue_cb; 271 pj_ice_strans_comp *comp; 272 int retry, addr_len; 273 struct { 274 pj_uint32_t a1, a2, a3; 275 } tsx_id; 276 pj_status_t status; 277 278 comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_strans_comp); 279 comp->ice_st = ice_st; 280 comp->comp_id = comp_id; 281 comp->options = options; 282 comp->sock = PJ_INVALID_SOCKET; 283 comp->last_status = PJ_SUCCESS; 284 285 /* Create transaction ID for STUN keep alives */ 286 tsx_id.a1 = 0; 287 tsx_id.a2 = comp_id; 288 tsx_id.a3 = (pj_uint32_t) (unsigned long) ice_st; 289 pj_memcpy(comp->ka_tsx_id, &tsx_id, sizeof(comp->ka_tsx_id)); 290 291 /* Create socket */ 292 status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &comp->sock); 293 if (status != PJ_SUCCESS) 294 return status; 295 296 /* Init address */ 297 if (addr) 298 pj_memcpy(&comp->local_addr, addr, sizeof(pj_sockaddr_in)); 299 else 300 pj_sockaddr_in_init(&comp->local_addr.ipv4, NULL, 0); 301 302 /* Retry binding socket */ 303 for (retry=0; retry<MAX_RETRY; ++retry) { 304 pj_uint16_t port; 305 306 status = pj_sock_bind(comp->sock, &comp->local_addr, 307 sizeof(pj_sockaddr_in)); 308 if (status == PJ_SUCCESS) 309 break; 310 311 if (options & PJ_ICE_ST_OPT_NO_PORT_RETRY) 312 goto on_error; 313 314 port = pj_ntohs(comp->local_addr.ipv4.sin_port); 315 port += PORT_INC; 316 comp->local_addr.ipv4.sin_port = pj_htons(port); 317 } 318 319 /* Get the actual port where the socket is bound to. 320 * (don't care about the address, it will be retrieved later) 321 */ 322 addr_len = sizeof(comp->local_addr); 323 status = pj_sock_getsockname(comp->sock, &comp->local_addr, &addr_len); 324 if (status != PJ_SUCCESS) 325 goto on_error; 326 327 /* Register to ioqueue */ 328 pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb)); 329 ioqueue_cb.on_read_complete = &on_read_complete; 330 status = pj_ioqueue_register_sock(ice_st->pool, ice_st->stun_cfg.ioqueue, 331 comp->sock, comp, &ioqueue_cb, 332 &comp->key); 333 if (status != PJ_SUCCESS) 334 goto on_error; 335 336 /* Disable concurrency */ 337 status = pj_ioqueue_set_concurrency(comp->key, PJ_FALSE); 338 if (status != PJ_SUCCESS) 339 goto on_error; 340 341 pj_ioqueue_op_key_init(&comp->read_op, sizeof(comp->read_op)); 342 pj_ioqueue_op_key_init(&comp->write_op, sizeof(comp->write_op)); 343 344 /* Kick start reading the socket */ 345 on_read_complete(comp->key, &comp->read_op, 0); 346 347 /* If the socket is bound to INADDR_ANY, then lookup all interfaces in 348 * the host and add them into cand_list. Otherwise if the socket is bound 349 * to a specific interface, then only add that specific interface to 350 * cand_list. 351 */ 352 if (((options & PJ_ICE_ST_OPT_DONT_ADD_CAND)==0) && 353 comp->local_addr.ipv4.sin_addr.s_addr == 0) 354 { 355 /* Socket is bound to INADDR_ANY */ 356 unsigned i, ifs_cnt; 357 pj_sockaddr ifs[PJ_ICE_ST_MAX_CAND-2]; 358 359 /* Reset default candidate */ 360 comp->default_cand = -1; 361 362 /* Enum all IP interfaces in the host */ 363 ifs_cnt = PJ_ARRAY_SIZE(ifs); 364 status = pj_enum_ip_interface(pj_AF_INET(), &ifs_cnt, ifs); 365 if (status != PJ_SUCCESS) 366 goto on_error; 367 368 /* Set default IP interface as the base address */ 369 status = pj_gethostip(pj_AF_INET(), &comp->local_addr); 370 if (status != PJ_SUCCESS) 371 goto on_error; 372 373 /* Add candidate entry for each interface */ 374 for (i=0; i<ifs_cnt; ++i) { 375 pj_sockaddr_in cand_addr; 376 pj_bool_t set_default; 377 pj_uint16_t local_pref; 378 379 /* Ignore 127.0.0.0/24 address */ 380 if ((pj_ntohl(ifs[i].ipv4.sin_addr.s_addr) >> 24)==127) 381 continue; 382 383 pj_memcpy(&cand_addr, &comp->local_addr, sizeof(pj_sockaddr_in)); 384 cand_addr.sin_addr.s_addr = ifs[i].ipv4.sin_addr.s_addr; 385 386 387 /* If the IP address is equal to local address, assign it 388 * as default candidate. 389 */ 390 if (ifs[i].ipv4.sin_addr.s_addr == comp->local_addr.ipv4.sin_addr.s_addr) { 391 set_default = PJ_TRUE; 392 local_pref = 65535; 393 } else { 394 set_default = PJ_FALSE; 395 local_pref = 0; 396 } 397 398 status = add_cand(ice_st, comp, comp_id, 399 PJ_ICE_CAND_TYPE_HOST, 400 local_pref, &cand_addr, set_default); 401 if (status != PJ_SUCCESS) 402 goto on_error; 403 } 404 405 406 } else if ((options & PJ_ICE_ST_OPT_DONT_ADD_CAND)==0) { 407 /* Socket is bound to specific address. 408 * In this case only add that address as a single entry in the 409 * cand_list table. 410 */ 411 status = add_cand(ice_st, comp, comp_id, 412 PJ_ICE_CAND_TYPE_HOST, 413 65535, &comp->local_addr.ipv4, 414 PJ_TRUE); 415 if (status != PJ_SUCCESS) 416 goto on_error; 417 418 } else if (options & PJ_ICE_ST_OPT_DONT_ADD_CAND) { 419 /* If application doesn't want to add candidate, just fix local_addr 420 * in case its value is zero. 421 */ 422 if (comp->local_addr.ipv4.sin_addr.s_addr == 0) { 423 status = pj_gethostip(pj_AF_INET(), &comp->local_addr); 424 if (status != PJ_SUCCESS) 425 return status; 426 } 427 } 428 429 430 /* Done */ 431 if (p_comp) 432 *p_comp = comp; 433 434 return PJ_SUCCESS; 435 436 on_error: 437 destroy_component(comp); 438 return status; 439 } 440 441 /* 442 * This is callback called by ioqueue on incoming packet 443 */ 444 static void on_read_complete(pj_ioqueue_key_t *key, 445 pj_ioqueue_op_key_t *op_key, 446 pj_ssize_t bytes_read) 447 { 448 pj_ice_strans_comp *comp = (pj_ice_strans_comp*) 449 pj_ioqueue_get_user_data(key); 450 pj_ice_strans *ice_st = comp->ice_st; 451 pj_ssize_t pkt_size; 452 enum { RETRY = 10 }; 453 unsigned retry; 454 pj_status_t status; 455 456 if (bytes_read > 0) { 457 /* 458 * Okay, we got a packet from the socket for the component. There is 459 * a bit of situation here, since this packet could be one of these: 460 * 461 * 1) this could be the response of STUN binding request sent by 462 * this component to a) an initial request to get the STUN mapped 463 * address of this component, or b) subsequent request to keep 464 * the binding alive. 465 * 466 * 2) this could be a packet (STUN or not STUN) sent from the STUN 467 * relay server. In this case, still there are few options to do 468 * for this packet: a) process this locally if this packet is 469 * related to TURN session management (e.g. Allocate response), 470 * b) forward this packet to ICE if this is related to ICE 471 * discovery process. 472 * 473 * 3) this could be a STUN request or response sent as part of ICE 474 * discovery process. 475 * 476 * 4) this could be application's packet, e.g. when ICE processing 477 * is done and agents start sending RTP/RTCP packets to each 478 * other, or when ICE processing is not done and this ICE stream 479 * transport decides to allow sending data. 480 * 481 * So far we don't have good solution for this. 482 * The process below is just a workaround. 483 */ 484 status = pj_stun_msg_check(comp->pkt, bytes_read, 485 PJ_STUN_IS_DATAGRAM); 486 487 if (status == PJ_SUCCESS) { 488 if (comp->stun_sess && 489 PJ_STUN_IS_RESPONSE(((pj_stun_msg_hdr*)comp->pkt)->type) && 490 pj_memcmp(comp->pkt+8, comp->ka_tsx_id, 12) == 0) 491 { 492 status = pj_stun_session_on_rx_pkt(comp->stun_sess, comp->pkt, 493 bytes_read, 494 PJ_STUN_IS_DATAGRAM, NULL, 495 NULL, &comp->src_addr, 496 comp->src_addr_len); 497 } else if (ice_st->ice) { 498 PJ_TODO(DISTINGUISH_BETWEEN_LOCAL_AND_RELAY); 499 500 TRACE_PKT((comp->ice_st->obj_name, 501 "Component %d RX packet from %s:%d", 502 comp->comp_id, 503 pj_inet_ntoa(comp->src_addr.ipv4.sin_addr), 504 (int)pj_ntohs(comp->src_addr.ipv4.sin_port))); 505 506 status = pj_ice_sess_on_rx_pkt(ice_st->ice, comp->comp_id, 507 comp->pkt, bytes_read, 508 &comp->src_addr, 509 comp->src_addr_len); 510 } else { 511 /* This must have been a very late STUN reponse, 512 * or an early STUN Binding Request when our local 513 * ICE has not been created yet. */ 514 } 515 } else { 516 (*ice_st->cb.on_rx_data)(ice_st, comp->comp_id, 517 comp->pkt, bytes_read, 518 &comp->src_addr, comp->src_addr_len); 519 } 520 521 } else if (bytes_read < 0) { 522 ice_st_perror(comp->ice_st, "ioqueue read callback error", 523 -bytes_read); 524 } 525 526 /* Read next packet */ 527 for (retry=0; retry<RETRY;) { 528 pkt_size = sizeof(comp->pkt); 529 comp->src_addr_len = sizeof(comp->src_addr); 530 status = pj_ioqueue_recvfrom(key, op_key, comp->pkt, &pkt_size, 531 PJ_IOQUEUE_ALWAYS_ASYNC, 532 &comp->src_addr, &comp->src_addr_len); 533 if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) || 534 status == PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) || 535 status == PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) 536 { 537 ice_st_perror(comp->ice_st, "ioqueue recvfrom() error", status); 538 ++retry; 539 continue; 540 } else if (status != PJ_SUCCESS && status != PJ_EPENDING) { 541 retry += 2; 542 ice_st_perror(comp->ice_st, "ioqueue recvfrom() error", status); 543 } else { 544 break; 545 } 546 } 547 } 548 549 /* 550 * Destroy a component 551 */ 552 static void destroy_component(pj_ice_strans_comp *comp) 553 { 554 if (comp->stun_sess) { 555 pj_stun_session_destroy(comp->stun_sess); 556 comp->stun_sess = NULL; 557 } 558 559 if (comp->key) { 560 pj_ioqueue_unregister(comp->key); 561 comp->key = NULL; 562 comp->sock = PJ_INVALID_SOCKET; 563 } else if (comp->sock != PJ_INVALID_SOCKET && comp->sock != 0) { 564 pj_sock_close(comp->sock); 565 comp->sock = PJ_INVALID_SOCKET; 566 } 567 } 568 569 570 /* STUN keep-alive timer callback */ 571 static void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te) 572 { 573 pj_ice_strans *ice_st = (pj_ice_strans*)te->user_data; 574 unsigned i; 575 pj_status_t status; 576 577 PJ_UNUSED_ARG(th); 578 579 ice_st->ka_timer.id = PJ_FALSE; 580 581 for (i=0; i<ice_st->comp_cnt; ++i) { 582 pj_ice_strans_comp *comp = ice_st->comp[i]; 583 pj_stun_tx_data *tdata; 584 unsigned j; 585 586 /* Does this component have STUN server reflexive candidate? */ 587 for (j=0; j<comp->cand_cnt; ++j) { 588 if (comp->cand_list[j].type == PJ_ICE_CAND_TYPE_SRFLX) 589 break; 590 } 591 if (j == comp->cand_cnt) 592 continue; 593 594 /* Create STUN binding request */ 595 status = pj_stun_session_create_req(comp->stun_sess, 596 PJ_STUN_BINDING_REQUEST, 597 PJ_STUN_MAGIC, 598 comp->ka_tsx_id, &tdata); 599 if (status != PJ_SUCCESS) 600 continue; 601 602 /* tdata->user_data is NULL for keep-alive */ 603 //tdata->user_data = NULL; 604 605 ++comp->pending_cnt; 606 607 608 /* Send STUN binding request */ 609 PJ_LOG(5,(ice_st->obj_name, "Sending STUN keep-alive from %s;%d", 610 pj_inet_ntoa(comp->local_addr.ipv4.sin_addr), 611 pj_ntohs(comp->local_addr.ipv4.sin_port))); 612 status = pj_stun_session_send_msg(comp->stun_sess, &comp->cand_list[j], 613 PJ_FALSE, PJ_TRUE, &ice_st->stun_srv, 614 sizeof(pj_sockaddr_in), tdata); 615 if (status != PJ_SUCCESS) { 616 --comp->pending_cnt; 617 } 618 } 619 620 /* Start next timer */ 621 start_ka_timer(ice_st); 622 } 623 624 /* Start STUN keep-alive timer */ 625 static void start_ka_timer(pj_ice_strans *ice_st) 626 { 627 pj_time_val delay; 628 629 /* Skip if timer is already running */ 630 if (ice_st->ka_timer.id != PJ_FALSE) 631 return; 632 633 delay.sec = PJ_ICE_ST_KEEP_ALIVE_MIN; 634 delay.msec = pj_rand() % (PJ_ICE_ST_KEEP_ALIVE_MAX_RAND * 1000); 635 pj_time_val_normalize(&delay); 636 637 ice_st->ka_timer.cb = &ka_timer_cb; 638 ice_st->ka_timer.user_data = ice_st; 639 640 if (pj_timer_heap_schedule(ice_st->stun_cfg.timer_heap, 641 &ice_st->ka_timer, &delay)==PJ_SUCCESS) 642 { 643 ice_st->ka_timer.id = PJ_TRUE; 644 } 645 } 646 647 648 /* Stop STUN keep-alive timer */ 649 static void stop_ka_timer(pj_ice_strans *ice_st) 650 { 651 /* Skip if timer is already stop */ 652 if (ice_st->ka_timer.id == PJ_FALSE) 653 return; 654 655 pj_timer_heap_cancel(ice_st->stun_cfg.timer_heap, &ice_st->ka_timer); 656 ice_st->ka_timer.id = PJ_FALSE; 657 } 658 659 660 /* 661 * Add STUN mapping to a component. 662 */ 663 static pj_status_t get_stun_mapped_addr(pj_ice_strans *ice_st, 664 pj_ice_strans_comp *comp) 665 { 666 pj_ice_strans_cand *cand; 667 pj_stun_session_cb sess_cb; 668 pj_stun_tx_data *tdata; 669 pj_status_t status; 670 671 PJ_ASSERT_RETURN(ice_st && comp, PJ_EINVAL); 672 673 /* Bail out if STUN server is still being resolved */ 674 if (ice_st->has_rjob) 675 return PJ_EBUSY; 676 677 /* Just return (successfully) if STUN server is not configured */ 678 if (ice_st->stun_srv.sin_family == 0) 679 return PJ_SUCCESS; 680 681 682 /* Create STUN session for this component */ 683 pj_bzero(&sess_cb, sizeof(sess_cb)); 684 sess_cb.on_request_complete = &stun_on_request_complete; 685 sess_cb.on_send_msg = &stun_on_send_msg; 686 status = pj_stun_session_create(&ice_st->stun_cfg, ice_st->obj_name, 687 &sess_cb, PJ_FALSE, &comp->stun_sess); 688 if (status != PJ_SUCCESS) 689 return status; 690 691 /* Associate component with STUN session */ 692 pj_stun_session_set_user_data(comp->stun_sess, (void*)comp); 693 694 /* Create STUN binding request */ 695 status = pj_stun_session_create_req(comp->stun_sess, 696 PJ_STUN_BINDING_REQUEST, 697 PJ_STUN_MAGIC, 698 comp->ka_tsx_id, 699 &tdata); 700 if (status != PJ_SUCCESS) 701 return status; 702 703 /* Will be attached to tdata in send_msg() */ 704 cand = &comp->cand_list[comp->cand_cnt]; 705 706 /* Add pending count first, since stun_on_request_complete() 707 * may be called before this function completes 708 */ 709 comp->pending_cnt++; 710 711 /* Add new alias to this component */ 712 cand->type = PJ_ICE_CAND_TYPE_SRFLX; 713 cand->status = PJ_EPENDING; 714 cand->ice_cand_id = -1; 715 cand->local_pref = 65535; 716 pj_ice_calc_foundation(ice_st->pool, &cand->foundation, 717 PJ_ICE_CAND_TYPE_SRFLX, &comp->local_addr); 718 719 ++comp->cand_cnt; 720 721 /* Send STUN binding request */ 722 status = pj_stun_session_send_msg(comp->stun_sess, (void*)cand, PJ_FALSE, 723 PJ_TRUE, &ice_st->stun_srv, 724 sizeof(pj_sockaddr_in), tdata); 725 if (status != PJ_SUCCESS) { 726 --comp->pending_cnt; 727 --comp->cand_cnt; 728 return status; 729 } 730 731 return PJ_SUCCESS; 732 } 733 734 735 /* 736 * Create the component. 737 */ 738 PJ_DEF(pj_status_t) pj_ice_strans_create_comp(pj_ice_strans *ice_st, 739 unsigned comp_id, 740 pj_uint32_t options, 741 const pj_sockaddr_in *addr) 742 { 743 pj_ice_strans_comp *comp = NULL; 744 pj_status_t status; 745 746 /* Verify arguments */ 747 PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL); 748 749 /* Check that component ID present */ 750 PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID); 751 752 /* Can't add new component while ICE is running */ 753 PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EBUSY); 754 755 /* Can't add new component while resolver is running */ 756 PJ_ASSERT_RETURN(ice_st->has_rjob == PJ_FALSE, PJ_EBUSY); 757 758 759 /* Create component */ 760 status = create_component(ice_st, comp_id, options, addr, &comp); 761 if (status != PJ_SUCCESS) 762 return status; 763 764 if ((options & PJ_ICE_ST_OPT_DISABLE_STUN) == 0) { 765 status = get_stun_mapped_addr(ice_st, comp); 766 if (status != PJ_SUCCESS) { 767 destroy_component(comp); 768 return status; 769 } 770 } 771 772 /* Store this component */ 773 ice_st->comp[comp_id-1] = comp; 774 775 return PJ_SUCCESS; 776 } 777 778 779 PJ_DEF(pj_status_t) pj_ice_strans_add_cand( pj_ice_strans *ice_st, 780 unsigned comp_id, 781 pj_ice_cand_type type, 782 pj_uint16_t local_pref, 783 const pj_sockaddr_in *addr, 784 pj_bool_t set_default) 785 { 786 pj_ice_strans_comp *comp; 787 788 789 PJ_ASSERT_RETURN(ice_st && comp_id && addr, PJ_EINVAL); 790 PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJ_EINVAL); 791 PJ_ASSERT_RETURN(ice_st->comp[comp_id-1] != NULL, PJ_EINVALIDOP); 792 793 comp = ice_st->comp[comp_id-1]; 794 return add_cand(ice_st, comp, comp_id, type, local_pref, addr, 795 set_default); 796 } 797 798 799 PJ_DEF(pj_status_t) pj_ice_strans_get_comps_status(pj_ice_strans *ice_st) 800 { 801 unsigned i; 802 pj_status_t worst = PJ_SUCCESS; 803 804 for (i=0; i<ice_st->comp_cnt; ++i) { 805 pj_ice_strans_comp *comp = ice_st->comp[i]; 806 807 if (comp->last_status == PJ_SUCCESS) { 808 /* okay */ 809 } else if (comp->pending_cnt && worst==PJ_SUCCESS) { 810 worst = PJ_EPENDING; 811 break; 812 } else if (comp->last_status != PJ_SUCCESS) { 813 worst = comp->last_status; 814 break; 815 } 816 817 if (worst != PJ_SUCCESS) 818 break; 819 } 820 821 return worst; 822 } 591 return PJ_TRUE; 592 } 593 } 594 595 /* 596 * Get user data 597 */ 598 PJ_DEF(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st) 599 { 600 PJ_ASSERT_RETURN(ice_st, NULL); 601 return ice_st->user_data; 602 } 603 823 604 824 605 /* … … 833 614 unsigned i; 834 615 pj_ice_sess_cb ice_cb; 835 const pj_uint8_t srflx_prio[4] = { 100, 126, 110, 0 };616 //const pj_uint8_t srflx_prio[4] = { 100, 126, 110, 0 }; 836 617 837 618 /* Check arguments */ … … 849 630 850 631 /* Create! */ 851 status = pj_ice_sess_create(&ice_st-> stun_cfg, ice_st->obj_name, role,632 status = pj_ice_sess_create(&ice_st->cfg.stun_cfg, ice_st->obj_name, role, 852 633 ice_st->comp_cnt, &ice_cb, 853 634 local_ufrag, local_passwd, &ice_st->ice); … … 858 639 ice_st->ice->user_data = (void*)ice_st; 859 640 641 #if 0 860 642 /* If default candidate for components are SRFLX one, upload a custom 861 643 * type priority to ICE session so that SRFLX candidates will get … … 868 650 pj_ice_sess_set_prefs(ice_st->ice, srflx_prio); 869 651 } 870 871 872 /* Add c andidates */652 #endif 653 654 /* Add components/candidates */ 873 655 for (i=0; i<ice_st->comp_cnt; ++i) { 874 656 unsigned j; 875 pj_ice_strans_comp *comp= ice_st->comp[i]; 657 pj_ice_strans_comp *comp = ice_st->comp[i]; 658 659 /* Re-enable logging for Send/Data indications */ 660 if (comp->turn_sock) { 661 PJ_LOG(5,(ice_st->obj_name, 662 "Disabling STUN Indication logging for " 663 "component %d", i+1)); 664 pj_turn_sock_set_log(comp->turn_sock, 0xFFFF); 665 } 876 666 877 667 for (j=0; j<comp->cand_cnt; ++j) { 878 pj_ice_strans_cand *cand = &comp->cand_list[j]; 668 pj_ice_sess_cand *cand = &comp->cand_list[j]; 669 unsigned ice_cand_id; 879 670 880 671 /* Skip if candidate is not ready */ 881 672 if (cand->status != PJ_SUCCESS) { 882 673 PJ_LOG(5,(ice_st->obj_name, 883 "Candidate %d in component %d is not added",674 "Candidate %d of comp %d is not added (pending)", 884 675 j, i)); 885 676 continue; 886 677 } 887 678 679 /* Must have address */ 680 pj_assert(pj_sockaddr_has_addr(&cand->addr)); 681 682 /* Add the candidate */ 888 683 status = pj_ice_sess_add_cand(ice_st->ice, comp->comp_id, 889 cand->type, cand->local_pref, 684 cand->transport_id, cand->type, 685 cand->local_pref, 890 686 &cand->foundation, &cand->addr, 891 &c omp->local_addr, NULL,892 sizeof(pj_sockaddr_in),893 (unsigned*)& cand->ice_cand_id);687 &cand->base_addr, &cand->rel_addr, 688 pj_sockaddr_get_len(&cand->addr), 689 (unsigned*)&ice_cand_id); 894 690 if (status != PJ_SUCCESS) 895 691 goto on_error; … … 908 704 */ 909 705 PJ_DEF(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st, 910 unsigned *count, 911 pj_ice_sess_cand cand[]) 706 unsigned comp_id, 707 unsigned *count, 708 pj_ice_sess_cand cand[]) 912 709 { 913 710 unsigned i, cnt; 914 pj_ice_sess_cand *pcand; 915 916 PJ_ASSERT_RETURN(ice_st && count && cand, PJ_EINVAL); 917 PJ_ASSERT_RETURN(ice_st->ice, PJ_EINVALIDOP); 918 919 cnt = ice_st->ice->lcand_cnt; 711 pj_ice_strans_comp *comp; 712 713 PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt && 714 count && cand, PJ_EINVAL); 715 716 comp = ice_st->comp[comp_id - 1]; 717 cnt = comp->cand_cnt; 920 718 cnt = (cnt > *count) ? *count : cnt; 921 *count = 0;922 719 923 720 for (i=0; i<cnt; ++i) { 924 pcand = &ice_st->ice->lcand[i]; 925 pj_memcpy(&cand[i], pcand, sizeof(pj_ice_sess_cand)); 721 pj_memcpy(&cand[i], &comp->cand_list[i], sizeof(pj_ice_sess_cand)); 926 722 } 927 723 928 724 *count = cnt; 929 725 return PJ_SUCCESS; 726 } 727 728 /* 729 * Get default candidate. 730 */ 731 PJ_DEF(pj_status_t) pj_ice_strans_get_def_cand( pj_ice_strans *ice_st, 732 unsigned comp_id, 733 pj_ice_sess_cand *cand) 734 { 735 const pj_ice_sess_check *valid_pair; 736 737 PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt && 738 cand, PJ_EINVAL); 739 740 valid_pair = pj_ice_strans_get_valid_pair(ice_st, comp_id); 741 if (valid_pair) { 742 pj_memcpy(cand, valid_pair->lcand, sizeof(pj_ice_sess_cand)); 743 } else { 744 pj_ice_strans_comp *comp = ice_st->comp[comp_id - 1]; 745 pj_assert(comp->default_cand>=0 && comp->default_cand<comp->cand_cnt); 746 pj_memcpy(cand, &comp->cand_list[comp->default_cand], 747 sizeof(pj_ice_sess_cand)); 748 } 749 return PJ_SUCCESS; 750 } 751 752 /* 753 * Get the current ICE role. 754 */ 755 PJ_DEF(pj_ice_sess_role) pj_ice_strans_get_role(pj_ice_strans *ice_st) 756 { 757 PJ_ASSERT_RETURN(ice_st && ice_st->ice, PJ_ICE_SESS_ROLE_UNKNOWN); 758 return ice_st->ice->role; 759 } 760 761 /* 762 * Change session role. 763 */ 764 PJ_DEF(pj_status_t) pj_ice_strans_change_role( pj_ice_strans *ice_st, 765 pj_ice_sess_role new_role) 766 { 767 PJ_ASSERT_RETURN(ice_st && ice_st->ice, PJ_EINVALIDOP); 768 return pj_ice_sess_change_role(ice_st->ice, new_role); 930 769 } 931 770 … … 941 780 pj_status_t status; 942 781 782 PJ_ASSERT_RETURN(ice_st && rem_ufrag && rem_passwd && 783 rem_cand_cnt && rem_cand, PJ_EINVAL); 784 785 /* Mark start time */ 786 pj_gettimeofday(&ice_st->start_time); 787 788 /* Build check list */ 943 789 status = pj_ice_sess_create_check_list(ice_st->ice, rem_ufrag, rem_passwd, 944 790 rem_cand_cnt, rem_cand); … … 946 792 return status; 947 793 794 /* Start ICE negotiation! */ 948 795 status = pj_ice_sess_start_check(ice_st->ice); 949 796 if (status != PJ_SUCCESS) { … … 955 802 956 803 /* 804 * Get valid pair. 805 */ 806 PJ_DEF(const pj_ice_sess_check*) 807 pj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st, 808 unsigned comp_id) 809 { 810 PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt, 811 NULL); 812 813 if (ice_st->ice == NULL) 814 return NULL; 815 816 return ice_st->ice->comp[comp_id-1].valid_check; 817 } 818 819 /* 957 820 * Stop ICE! 958 821 */ 959 822 PJ_DEF(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st) 960 823 { 961 unsigned i;962 963 824 if (ice_st->ice) { 964 825 pj_ice_sess_destroy(ice_st->ice); … … 966 827 } 967 828 968 /* Invalidate all candidate Ids */969 for (i=0; i<ice_st->comp_cnt; ++i) {970 unsigned j;971 for (j=0; j<ice_st->comp[i]->cand_cnt; ++j) {972 ice_st->comp[i]->cand_list[j].ice_cand_id = -1;973 }974 }975 976 829 return PJ_SUCCESS; 977 830 } 978 831 979 832 /* 980 * Send packet using non-ICE means (e.g. when ICE was not negotiated).833 * Application wants to send outgoing packet. 981 834 */ 982 835 PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st, … … 998 851 /* If ICE is available, send data with ICE */ 999 852 if (ice_st->ice) { 1000 return pj_ice_sess_send_data(ice_st->ice, comp_id, data, data_len); 1001 } 1002 1003 /* Otherwise send direcly with the socket. This is for compatibility 1004 * with remote that doesn't support ICE. 1005 */ 1006 pkt_size = data_len; 1007 status = pj_ioqueue_sendto(comp->key, &comp->write_op, 1008 data, &pkt_size, 0, 1009 dst_addr, dst_addr_len); 1010 1011 return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 853 if (comp->turn_sock) { 854 pj_turn_sock_lock(comp->turn_sock); 855 } 856 status = pj_ice_sess_send_data(ice_st->ice, comp_id, data, data_len); 857 if (comp->turn_sock) { 858 pj_turn_sock_unlock(comp->turn_sock); 859 } 860 return status; 861 862 } else if (comp->stun_sock) { 863 864 pkt_size = data_len; 865 status = pj_stun_sock_sendto(comp->stun_sock, NULL, data, data_len, 866 0, dst_addr, dst_addr_len); 867 return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 868 869 } else 870 return PJ_EINVALIDOP; 1012 871 } 1013 872 … … 1019 878 { 1020 879 pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data; 880 pj_time_val t; 881 unsigned msec; 882 883 sess_add_ref(ice_st); 884 885 pj_gettimeofday(&t); 886 PJ_TIME_VAL_SUB(t, ice_st->start_time); 887 msec = PJ_TIME_VAL_MSEC(t); 888 1021 889 if (ice_st->cb.on_ice_complete) { 1022 (*ice_st->cb.on_ice_complete)(ice_st, status); 1023 } 890 if (status != PJ_SUCCESS) { 891 char errmsg[PJ_ERR_MSG_SIZE]; 892 pj_strerror(status, errmsg, sizeof(errmsg)); 893 PJ_LOG(4,(ice_st->obj_name, 894 "ICE negotiation failed after %ds:%03d: %s", 895 msec/1000, msec%1000, errmsg)); 896 } else { 897 unsigned i; 898 enum { 899 msg_disable_ind = 0xFFFF & 900 ~(PJ_STUN_SESS_LOG_TX_IND| 901 PJ_STUN_SESS_LOG_RX_IND) 902 }; 903 904 PJ_LOG(4,(ice_st->obj_name, 905 "ICE negotiation success after %ds:%03d", 906 msec/1000, msec%1000)); 907 908 for (i=0; i<ice_st->comp_cnt; ++i) { 909 const pj_ice_sess_check *check; 910 911 check = pj_ice_strans_get_valid_pair(ice_st, i+1); 912 if (check) { 913 char lip[PJ_INET6_ADDRSTRLEN+10]; 914 char rip[PJ_INET6_ADDRSTRLEN+10]; 915 916 pj_sockaddr_print(&check->lcand->addr, lip, 917 sizeof(lip), 3); 918 pj_sockaddr_print(&check->rcand->addr, rip, 919 sizeof(rip), 3); 920 921 if (check->lcand->transport_id == TP_TURN) { 922 /* Disable logging for Send/Data indications */ 923 PJ_LOG(5,(ice_st->obj_name, 924 "Disabling STUN Indication logging for " 925 "component %d", i+1)); 926 pj_turn_sock_set_log(ice_st->comp[i]->turn_sock, 927 msg_disable_ind); 928 } 929 930 PJ_LOG(4,(ice_st->obj_name, " Comp %d: " 931 "sending from %s candidate %s to " 932 "%s candidate %s", 933 i+1, 934 pj_ice_get_cand_type_name(check->lcand->type), 935 lip, 936 pj_ice_get_cand_type_name(check->rcand->type), 937 rip)); 938 939 } else { 940 PJ_LOG(4,(ice_st->obj_name, 941 "Comp %d: disabled", i+1)); 942 } 943 } 944 } 945 946 (*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_NEGOTIATION, 947 status); 948 949 950 } 951 952 sess_dec_ref(ice_st); 1024 953 } 1025 954 … … 1029 958 static pj_status_t ice_tx_pkt(pj_ice_sess *ice, 1030 959 unsigned comp_id, 960 unsigned transport_id, 1031 961 const void *pkt, pj_size_t size, 1032 962 const pj_sockaddr_t *dst_addr, … … 1034 964 { 1035 965 pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data; 1036 pj_ice_strans_comp *comp = NULL; 1037 pj_ssize_t pkt_size; 966 pj_ice_strans_comp *comp; 1038 967 pj_status_t status; 1039 968 1040 PJ_TODO(TX_TO_RELAY);1041 1042 969 PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); 970 1043 971 comp = ice_st->comp[comp_id-1]; 1044 972 1045 973 TRACE_PKT((comp->ice_st->obj_name, 1046 "Component %d TX packet to %s:%d ",1047 comp_id, 974 "Component %d TX packet to %s:%d with transport %d", 975 comp_id, 1048 976 pj_inet_ntoa(((pj_sockaddr_in*)dst_addr)->sin_addr), 1049 (int)pj_ntohs(((pj_sockaddr_in*)dst_addr)->sin_port))); 1050 1051 pkt_size = size; 1052 status = pj_ioqueue_sendto(comp->key, &comp->write_op, 1053 pkt, &pkt_size, 0, 1054 dst_addr, dst_addr_len); 977 (int)pj_ntohs(((pj_sockaddr_in*)dst_addr)->sin_port), 978 transport_id)); 979 980 if (transport_id == TP_TURN) { 981 if (comp->turn_sock) { 982 status = pj_turn_sock_sendto(comp->turn_sock, 983 (const pj_uint8_t*)pkt, size, 984 dst_addr, dst_addr_len); 985 } else { 986 status = PJ_EINVALIDOP; 987 } 988 } else if (transport_id == TP_STUN) { 989 status = pj_stun_sock_sendto(comp->stun_sock, NULL, 990 pkt, size, 0, 991 dst_addr, dst_addr_len); 992 } else { 993 pj_assert(!"Invalid transport ID"); 994 status = PJ_EINVALIDOP; 995 } 1055 996 1056 997 return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; … … 1062 1003 static void ice_rx_data(pj_ice_sess *ice, 1063 1004 unsigned comp_id, 1005 unsigned transport_id, 1064 1006 void *pkt, pj_size_t size, 1065 1007 const pj_sockaddr_t *src_addr, … … 1068 1010 pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data; 1069 1011 1012 PJ_UNUSED_ARG(transport_id); 1013 1070 1014 if (ice_st->cb.on_rx_data) { 1071 1015 (*ice_st->cb.on_rx_data)(ice_st, comp_id, pkt, size, … … 1074 1018 } 1075 1019 1076 /* 1077 * Callback called by STUN session to send outgoing packet. 1078 */ 1079 static pj_status_t stun_on_send_msg(pj_stun_session *sess, 1080 void *token, 1081 const void *pkt, 1082 pj_size_t size, 1083 const pj_sockaddr_t *dst_addr, 1084 unsigned dst_addr_len) 1020 /* Notification when incoming packet has been received from 1021 * the STUN socket. 1022 */ 1023 static pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock, 1024 void *pkt, 1025 unsigned pkt_len, 1026 const pj_sockaddr_t *src_addr, 1027 unsigned addr_len) 1085 1028 { 1086 1029 pj_ice_strans_comp *comp; 1087 pj_ ssize_t pkt_size;1030 pj_ice_strans *ice_st; 1088 1031 pj_status_t status; 1089 1032 1090 PJ_UNUSED_ARG(token); 1091 1092 comp = (pj_ice_strans_comp*) pj_stun_session_get_user_data(sess); 1093 pkt_size = size; 1094 status = pj_ioqueue_sendto(comp->key, &comp->write_op, 1095 pkt, &pkt_size, 0, 1096 dst_addr, dst_addr_len); 1097 1098 return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 1099 } 1100 1101 /* 1102 * Callback sent by STUN session when outgoing STUN request has 1103 * completed. 1104 */ 1105 static void stun_on_request_complete(pj_stun_session *sess, 1106 pj_status_t status, 1107 void *token, 1108 pj_stun_tx_data *tdata, 1109 const pj_stun_msg *response, 1110 const pj_sockaddr_t *src_addr, 1111 unsigned src_addr_len) 1033 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 1034 ice_st = comp->ice_st; 1035 1036 sess_add_ref(ice_st); 1037 1038 if (ice_st->ice == NULL) { 1039 /* The ICE session is gone, but we're still receiving packets. 1040 * This could also happen if remote doesn't do ICE. So just 1041 * report this to application. 1042 */ 1043 if (ice_st->cb.on_rx_data) { 1044 (*ice_st->cb.on_rx_data)(ice_st, comp->comp_id, pkt, pkt_len, 1045 src_addr, addr_len); 1046 } 1047 1048 } else { 1049 1050 /* Hand over the packet to ICE session */ 1051 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1052 TP_STUN, pkt, pkt_len, 1053 src_addr, addr_len); 1054 1055 if (status != PJ_SUCCESS) { 1056 ice_st_perror(comp->ice_st, "Error processing packet", 1057 status); 1058 } 1059 } 1060 1061 return sess_dec_ref(ice_st); 1062 } 1063 1064 /* Notifification when asynchronous send operation to the STUN socket 1065 * has completed. 1066 */ 1067 static pj_bool_t stun_on_data_sent(pj_stun_sock *stun_sock, 1068 pj_ioqueue_op_key_t *send_key, 1069 pj_ssize_t sent) 1070 { 1071 PJ_UNUSED_ARG(stun_sock); 1072 PJ_UNUSED_ARG(send_key); 1073 PJ_UNUSED_ARG(sent); 1074 return PJ_TRUE; 1075 } 1076 1077 /* Notification when the status of the STUN transport has changed. */ 1078 static pj_bool_t stun_on_status(pj_stun_sock *stun_sock, 1079 pj_stun_sock_op op, 1080 pj_status_t status) 1112 1081 { 1113 1082 pj_ice_strans_comp *comp; 1114 pj_ice_strans_cand *cand = NULL; 1115 pj_stun_xor_mapped_addr_attr *xa; 1116 pj_stun_mapped_addr_attr *ma; 1117 pj_sockaddr *mapped_addr; 1118 char ip[20]; 1119 1120 comp = (pj_ice_strans_comp*) pj_stun_session_get_user_data(sess); 1121 cand = (pj_ice_strans_cand*) token; 1122 1123 PJ_UNUSED_ARG(token); 1124 PJ_UNUSED_ARG(tdata); 1125 PJ_UNUSED_ARG(src_addr); 1126 PJ_UNUSED_ARG(src_addr_len); 1127 1128 if (cand == NULL) { 1129 /* This is keep-alive */ 1083 pj_ice_strans *ice_st; 1084 pj_ice_sess_cand *cand = NULL; 1085 unsigned i; 1086 1087 comp = (pj_ice_strans_comp*) pj_stun_sock_get_user_data(stun_sock); 1088 ice_st = comp->ice_st; 1089 1090 sess_add_ref(ice_st); 1091 1092 /* Find the srflx cancidate */ 1093 for (i=0; i<comp->cand_cnt; ++i) { 1094 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_SRFLX) { 1095 cand = &comp->cand_list[i]; 1096 break; 1097 } 1098 } 1099 1100 pj_assert(status != PJ_EPENDING); 1101 1102 switch (op) { 1103 case PJ_STUN_SOCK_DNS_OP: 1130 1104 if (status != PJ_SUCCESS) { 1131 ice_st_perror(comp->ice_st, "STUN keep-alive request failed", 1105 /* May not have cand, e.g. when error during init */ 1106 if (cand) 1107 cand->status = status; 1108 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, "DNS resolution failed", 1109 status); 1110 } 1111 break; 1112 case PJ_STUN_SOCK_BINDING_OP: 1113 if (status == PJ_SUCCESS) { 1114 pj_stun_sock_info info; 1115 1116 status = pj_stun_sock_get_info(stun_sock, &info); 1117 if (status == PJ_SUCCESS) { 1118 char ipaddr[PJ_INET6_ADDRSTRLEN+10]; 1119 pj_bool_t dup = PJ_FALSE; 1120 1121 /* Eliminate the srflx candidate if the address is 1122 * equal to other (host) candidates. 1123 */ 1124 for (i=0; i<comp->cand_cnt; ++i) { 1125 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_HOST && 1126 pj_sockaddr_cmp(&comp->cand_list[i].addr, 1127 &info.mapped_addr) == 0) 1128 { 1129 dup = PJ_TRUE; 1130 break; 1131 } 1132 } 1133 1134 if (dup) { 1135 /* Duplicate found, remove the srflx candidate */ 1136 pj_array_erase(comp->cand_list, sizeof(comp->cand_list[0]), 1137 comp->cand_cnt, cand - comp->cand_list); 1138 --comp->cand_cnt; 1139 } else { 1140 /* Otherwise update the address */ 1141 pj_sockaddr_cp(&cand->addr, &info.mapped_addr); 1142 cand->status = PJ_SUCCESS; 1143 } 1144 1145 PJ_LOG(4,(comp->ice_st->obj_name, 1146 "Comp %d: Binding discovery complete, " 1147 "srflx address is %s", 1148 comp->comp_id, 1149 pj_sockaddr_print(&info.mapped_addr, ipaddr, 1150 sizeof(ipaddr), 3))); 1151 1152 sess_init_update(ice_st); 1153 } 1154 } 1155 1156 if (status != PJ_SUCCESS) { 1157 /* May not have cand, e.g. when error during init */ 1158 if (cand) 1159 cand->status = status; 1160 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1161 "STUN binding request failed", status); 1162 } 1163 break; 1164 case PJ_STUN_SOCK_KEEP_ALIVE_OP: 1165 if (status != PJ_SUCCESS) { 1166 pj_assert(cand != NULL); 1167 cand->status = status; 1168 sess_fail(ice_st, PJ_ICE_STRANS_OP_INIT, 1169 "STUN keep-alive failed", status); 1170 } 1171 break; 1172 } 1173 1174 return sess_dec_ref(ice_st); 1175 } 1176 1177 /* Callback when TURN socket has received a packet */ 1178 static void turn_on_rx_data(pj_turn_sock *turn_sock, 1179 void *pkt, 1180 unsigned pkt_len, 1181 const pj_sockaddr_t *peer_addr, 1182 unsigned addr_len) 1183 { 1184 pj_ice_strans_comp *comp; 1185 pj_status_t status; 1186 1187 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 1188 if (comp == NULL) { 1189 /* We have disassociated ourselves from the TURN socket */ 1190 return; 1191 } 1192 1193 sess_add_ref(comp->ice_st); 1194 1195 if (comp->ice_st->ice == NULL) { 1196 /* The ICE session is gone, but we're still receiving packets. 1197 * This could also happen if remote doesn't do ICE and application 1198 * specifies TURN as the default address in SDP. 1199 * So in this case just give the packet to application. 1200 */ 1201 if (comp->ice_st->cb.on_rx_data) { 1202 (*comp->ice_st->cb.on_rx_data)(comp->ice_st, comp->comp_id, pkt, 1203 pkt_len, peer_addr, addr_len); 1204 } 1205 1206 } else { 1207 1208 /* Hand over the packet to ICE */ 1209 status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id, 1210 TP_TURN, pkt, pkt_len, 1211 peer_addr, addr_len); 1212 1213 if (status != PJ_SUCCESS) { 1214 ice_st_perror(comp->ice_st, 1215 "Error processing packet from TURN relay", 1132 1216 status); 1133 1217 } 1218 } 1219 1220 sess_dec_ref(comp->ice_st); 1221 } 1222 1223 1224 /* Callback when TURN client state has changed */ 1225 static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state, 1226 pj_turn_state_t new_state) 1227 { 1228 pj_ice_strans_comp *comp; 1229 1230 comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 1231 if (comp == NULL) { 1232 /* Not interested in further state notification once the relay is 1233 * disconnecting. 1234 */ 1134 1235 return; 1135 1236 } 1136 1237 1137 /* Decrement pending count for this component */ 1138 pj_assert(comp->pending_cnt > 0); 1139 comp->pending_cnt--; 1140 1141 if (status == PJNATH_ESTUNTIMEDOUT) { 1238 PJ_LOG(5,(comp->ice_st->obj_name, "TURN client state changed %s --> %s", 1239 pj_turn_state_name(old_state), pj_turn_state_name(new_state))); 1240 1241 sess_add_ref(comp->ice_st); 1242 1243 if (new_state == PJ_TURN_STATE_READY) { 1244 pj_turn_session_info rel_info; 1245 char ipaddr[PJ_INET6_ADDRSTRLEN+8]; 1246 pj_ice_sess_cand *cand = NULL; 1247 unsigned i; 1248 1249 /* Get allocation info */ 1250 pj_turn_sock_get_info(turn_sock, &rel_info); 1251 1252 /* Find relayed candidate in the component */ 1253 for (i=0; i<comp->cand_cnt; ++i) { 1254 if (comp->cand_list[i].type == PJ_ICE_CAND_TYPE_RELAYED) { 1255 cand = &comp->cand_list[i]; 1256 break; 1257 } 1258 } 1259 pj_assert(cand != NULL); 1260 1261 /* Update candidate */ 1262 pj_sockaddr_cp(&cand->addr, &rel_info.relay_addr); 1263 pj_sockaddr_cp(&cand->base_addr, &rel_info.relay_addr); 1264 pj_sockaddr_cp(&cand->rel_addr, &rel_info.mapped_addr); 1265 pj_ice_calc_foundation(comp->ice_st->pool, &cand->foundation, 1266 PJ_ICE_CAND_TYPE_RELAYED, 1267 &rel_info.relay_addr); 1268 cand->status = PJ_SUCCESS; 1142 1269 1143 1270 PJ_LOG(4,(comp->ice_st->obj_name, 1144 "STUN Binding request has timed-out, will retry " 1145 "again alter")); 1146 1147 /* Restart keep-alive timer */ 1148 start_ka_timer(comp->ice_st); 1149 return; 1150 1151 } else if (status != PJ_SUCCESS) { 1152 comp->last_status = cand->status = status; 1153 ice_st_perror(comp->ice_st, "STUN Binding request failed", 1154 cand->status); 1155 return; 1156 } 1157 1158 xa = (pj_stun_xor_mapped_addr_attr*) 1159 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0); 1160 ma = (pj_stun_mapped_addr_attr*) 1161 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_MAPPED_ADDR, 0); 1162 1163 if (xa) 1164 mapped_addr = &xa->sockaddr; 1165 else if (ma) 1166 mapped_addr = &ma->sockaddr; 1167 else { 1168 cand->status = PJNATH_ESTUNNOMAPPEDADDR; 1169 ice_st_perror(comp->ice_st, "STUN Binding request failed", 1170 cand->status); 1171 return; 1172 } 1173 1174 /* Save IP address for logging */ 1175 pj_ansi_strcpy(ip, pj_inet_ntoa(comp->local_addr.ipv4.sin_addr)); 1176 1177 /* Ignore response if it reports the same address */ 1178 if (comp->local_addr.ipv4.sin_addr.s_addr == mapped_addr->ipv4.sin_addr.s_addr && 1179 comp->local_addr.ipv4.sin_port == mapped_addr->ipv4.sin_port) 1180 { 1181 PJ_LOG(4,(comp->ice_st->obj_name, 1182 "Candidate %s:%d is directly connected to Internet, " 1183 "STUN mapped address is ignored", 1184 ip, pj_ntohs(comp->local_addr.ipv4.sin_port))); 1185 return; 1186 } 1187 1188 PJ_LOG(5,(comp->ice_st->obj_name, 1189 "STUN mapped address for %s:%d is %s:%d", 1190 ip, (int)pj_ntohs(comp->local_addr.ipv4.sin_port), 1191 pj_inet_ntoa(mapped_addr->ipv4.sin_addr), 1192 (int)pj_ntohs(mapped_addr->ipv4.sin_port))); 1193 pj_memcpy(&cand->addr, mapped_addr, sizeof(pj_sockaddr_in)); 1194 cand->status = PJ_SUCCESS; 1195 1196 /* Set this candidate as the default candidate */ 1197 comp->default_cand = (cand - comp->cand_list); 1198 comp->last_status = PJ_SUCCESS; 1199 1200 /* We have STUN, so we must start the keep-alive timer */ 1201 start_ka_timer(comp->ice_st); 1202 1203 /* Notify app that STUN address has changed. */ 1204 if (comp->ice_st->cb.on_addr_change) 1205 (*comp->ice_st->cb.on_addr_change)(comp->ice_st, comp->comp_id, 1206 (cand - comp->cand_list)); 1207 } 1208 1271 "Comp %d: TURN allocation complete, relay address is %s", 1272 comp->comp_id, 1273 pj_sockaddr_print(&rel_info.relay_addr, ipaddr, 1274 sizeof(ipaddr), 3))); 1275 1276 sess_init_update(comp->ice_st); 1277 1278 } else if (new_state >= PJ_TURN_STATE_DEALLOCATING) { 1279 pj_turn_session_info info; 1280 1281 pj_turn_sock_get_info(turn_sock, &info); 1282 1283 /* Unregister ourself from the TURN relay */ 1284 pj_turn_sock_set_user_data(turn_sock, NULL); 1285 comp->turn_sock = NULL; 1286 1287 /* Set session to fail if we're still initializing */ 1288 if (old_state < PJ_TURN_STATE_READY) { 1289 sess_fail(comp->ice_st, PJ_ICE_STRANS_OP_INIT, 1290 "TURN relay failed", info.last_status); 1291 } 1292 } 1293 1294 sess_dec_ref(comp->ice_st); 1295 } 1296 -
pjproject/trunk/pjnath/src/pjnath/stun_msg.c
r1924 r1988 1558 1558 PJ_DEF(pj_status_t) pj_stun_msg_add_unknown_attr(pj_pool_t *pool, 1559 1559 pj_stun_msg *msg, 1560 unsignedattr_cnt,1560 pj_size_t attr_cnt, 1561 1561 const pj_uint16_t attr_types[]) 1562 1562 { … … 1647 1647 int attr_type, 1648 1648 const pj_uint8_t *data, 1649 unsignedlength,1649 pj_size_t length, 1650 1650 pj_stun_binary_attr **p_attr) 1651 1651 { … … 1674 1674 int attr_type, 1675 1675 const pj_uint8_t *data, 1676 unsignedlength)1676 pj_size_t length) 1677 1677 { 1678 1678 pj_stun_binary_attr *attr = NULL; … … 1834 1834 * Check that the PDU is potentially a valid STUN message. 1835 1835 */ 1836 PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsignedpdu_len,1836 PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, pj_size_t pdu_len, 1837 1837 unsigned options) 1838 1838 { 1839 unsignedmsg_len;1839 pj_size_t msg_len; 1840 1840 1841 1841 PJ_ASSERT_RETURN(pdu, PJ_EINVAL); … … 1939 1939 PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, 1940 1940 const pj_uint8_t *pdu, 1941 unsignedpdu_len,1941 pj_size_t pdu_len, 1942 1942 unsigned options, 1943 1943 pj_stun_msg **p_msg, 1944 unsigned*p_parsed_len,1944 pj_size_t *p_parsed_len, 1945 1945 pj_stun_msg **p_response) 1946 1946 { … … 2191 2191 PJ_DEF(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg, 2192 2192 pj_uint8_t *buf, unsigned buf_size, 2193 unsignedoptions,2193 pj_size_t options, 2194 2194 const pj_str_t *key, 2195 unsigned*p_msg_len)2195 pj_size_t *p_msg_len) 2196 2196 { 2197 2197 pj_uint8_t *start = buf; -
pjproject/trunk/pjnath/src/pjnath/stun_session.c
r1913 r1988 30 30 void *user_data; 31 31 32 pj_atomic_t *busy; 33 pj_bool_t destroy_request; 34 32 35 pj_bool_t use_fingerprint; 33 36 37 pj_pool_t *rx_pool; 38 39 #if PJ_LOG_MAX_LEVEL >= 5 34 40 char dump_buf[1000]; 41 #endif 42 unsigned log_flag; 35 43 36 44 pj_stun_auth_type auth_type; … … 38 46 int auth_retry; 39 47 pj_str_t next_nonce; 48 pj_str_t server_realm; 40 49 41 50 pj_str_t srv_name; … … 80 89 pj_stun_tx_data *tdata) 81 90 { 82 pj_list_push_ back(&sess->pending_request_list, tdata);91 pj_list_push_front(&sess->pending_request_list, tdata); 83 92 return PJ_SUCCESS; 84 93 } … … 139 148 140 149 tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 150 tsx_erase(tdata->sess, tdata); 151 141 152 pj_stun_client_tsx_destroy(tsx); 142 153 pj_pool_release(tdata->pool); 143 154 } 144 155 145 static void destroy_tdata(pj_stun_tx_data *tdata )156 static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force) 146 157 { 147 158 if (tdata->res_timer.id != PJ_FALSE) { … … 152 163 } 153 164 154 if (tdata->client_tsx) { 155 pj_time_val delay = {2, 0}; 156 tsx_erase(tdata->sess, tdata); 157 pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay); 158 tdata->client_tsx = NULL; 165 if (force) { 166 if (tdata->client_tsx) { 167 tsx_erase(tdata->sess, tdata); 168 pj_stun_client_tsx_destroy(tdata->client_tsx); 169 } 170 pj_pool_release(tdata->pool); 159 171 160 172 } else { 161 pj_pool_release(tdata->pool); 173 if (tdata->client_tsx) { 174 pj_time_val delay = {2, 0}; 175 pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay); 176 177 } else { 178 pj_pool_release(tdata->pool); 179 } 162 180 } 163 181 } … … 170 188 { 171 189 PJ_UNUSED_ARG(sess); 172 destroy_tdata(tdata );190 destroy_tdata(tdata, PJ_FALSE); 173 191 } 174 192 … … 290 308 { 291 309 const pj_stun_nonce_attr *anonce; 310 const pj_stun_realm_attr *arealm; 292 311 pj_stun_tx_data *tdata; 293 312 unsigned i; … … 317 336 pj_strdup(sess->pool, &sess->next_nonce, &anonce->value); 318 337 338 /* Copy the realm from the response */ 339 arealm = (pj_stun_realm_attr*) 340 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_REALM, 0); 341 if (arealm) { 342 pj_strdup(sess->pool, &sess->server_realm, &arealm->value); 343 } 344 319 345 /* Create new request */ 320 346 status = pj_stun_session_create_req(sess, request->msg->hdr.type, … … 325 351 326 352 /* Duplicate all the attributes in the old request, except 327 * USERNAME, REALM, M-I, and NONCE 353 * USERNAME, REALM, M-I, and NONCE, which will be filled in 354 * later. 328 355 */ 329 356 for (i=0; i<request->msg->attr_count; ++i) { … … 374 401 sess = tdata->sess; 375 402 403 /* Lock the session and prevent user from destroying us in the callback */ 404 pj_atomic_inc(sess->busy); 405 pj_lock_acquire(sess->lock); 406 376 407 /* Handle authentication challenge */ 377 408 handle_auth_challenge(sess, tdata, response, src_addr, … … 388 419 pj_stun_msg_destroy_tdata(sess, tdata); 389 420 tdata = NULL; 421 422 pj_lock_release(sess->lock); 423 424 if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 425 pj_stun_session_destroy(sess); 426 return; 427 } 390 428 } 391 429 … … 395 433 { 396 434 pj_stun_tx_data *tdata; 435 pj_stun_session *sess; 436 pj_status_t status; 397 437 398 438 tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 399 400 return tdata->sess->cb.on_send_msg(tdata->sess, tdata->token, stun_pkt, 401 pkt_size, tdata->dst_addr, 402 tdata->addr_len); 439 sess = tdata->sess; 440 441 /* Lock the session and prevent user from destroying us in the callback */ 442 pj_atomic_inc(sess->busy); 443 pj_lock_acquire(sess->lock); 444 445 status = sess->cb.on_send_msg(tdata->sess, tdata->token, stun_pkt, 446 pkt_size, tdata->dst_addr, 447 tdata->addr_len); 448 pj_lock_release(sess->lock); 449 450 if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 451 pj_stun_session_destroy(sess); 452 return PJNATH_ESTUNDESTROYED; 453 } else { 454 return status; 455 } 403 456 } 404 457 … … 429 482 pj_memcpy(&sess->cb, cb, sizeof(*cb)); 430 483 sess->use_fingerprint = fingerprint; 484 sess->log_flag = 0xFFFF; 431 485 432 486 sess->srv_name.ptr = (char*) pj_pool_alloc(pool, 32); … … 434 488 "pj_stun-%s", pj_get_version()); 435 489 490 sess->rx_pool = pj_pool_create(sess->cfg->pf, "name", 491 PJNATH_POOL_LEN_STUN_TDATA, 492 PJNATH_POOL_INC_STUN_TDATA, NULL); 493 436 494 pj_list_init(&sess->pending_request_list); 437 495 pj_list_init(&sess->cached_response_list); … … 444 502 sess->delete_lock = PJ_TRUE; 445 503 504 status = pj_atomic_create(pool, 0, &sess->busy); 505 if (status != PJ_SUCCESS) { 506 pj_lock_destroy(sess->lock); 507 pj_pool_release(pool); 508 return status; 509 } 510 446 511 *p_sess = sess; 447 512 … … 454 519 455 520 pj_lock_acquire(sess->lock); 521 522 /* Can't destroy if we're in a callback */ 523 sess->destroy_request = PJ_TRUE; 524 if (pj_atomic_get(sess->busy)) { 525 pj_lock_release(sess->lock); 526 return PJ_EPENDING; 527 } 528 456 529 while (!pj_list_empty(&sess->pending_request_list)) { 457 530 pj_stun_tx_data *tdata = sess->pending_request_list.next; 458 destroy_tdata(tdata); 459 } 531 destroy_tdata(tdata, PJ_TRUE); 532 } 533 460 534 while (!pj_list_empty(&sess->cached_response_list)) { 461 535 pj_stun_tx_data *tdata = sess->cached_response_list.next; 462 destroy_tdata(tdata );536 destroy_tdata(tdata, PJ_TRUE); 463 537 } 464 538 pj_lock_release(sess->lock); … … 466 540 if (sess->delete_lock) { 467 541 pj_lock_destroy(sess->lock); 542 } 543 544 if (sess->rx_pool) { 545 pj_pool_release(sess->rx_pool); 546 sess->rx_pool = NULL; 468 547 } 469 548 … … 539 618 } 540 619 620 PJ_DEF(void) pj_stun_session_set_log( pj_stun_session *sess, 621 unsigned flags) 622 { 623 PJ_ASSERT_ON_FAIL(sess, return); 624 sess->log_flag = flags; 625 } 541 626 542 627 static pj_status_t get_auth(pj_stun_session *sess, … … 544 629 { 545 630 if (sess->cred.type == PJ_STUN_AUTH_CRED_STATIC) { 546 tdata->auth_info.realm = sess->cred.data.static_cred.realm; 631 //tdata->auth_info.realm = sess->cred.data.static_cred.realm; 632 tdata->auth_info.realm = sess->server_realm; 547 633 tdata->auth_info.username = sess->cred.data.static_cred.username; 548 634 tdata->auth_info.nonce = sess->cred.data.static_cred.nonce; … … 634 720 } 635 721 tdata->auth_info.nonce = sess->next_nonce; 722 tdata->auth_info.realm = sess->server_realm; 636 723 } 637 724 … … 715 802 unsigned pkt_size, const pj_sockaddr_t *addr) 716 803 { 717 char dst_name[ 80];804 char dst_name[PJ_INET6_ADDRSTRLEN+10]; 718 805 806 if ((PJ_STUN_IS_REQUEST(msg->hdr.type) && 807 (sess->log_flag & PJ_STUN_SESS_LOG_TX_REQ)==0) || 808 (PJ_STUN_IS_RESPONSE(msg->hdr.type) && 809 (sess->log_flag & PJ_STUN_SESS_LOG_TX_RES)==0) || 810 (PJ_STUN_IS_INDICATION(msg->hdr.type) && 811 (sess->log_flag & PJ_STUN_SESS_LOG_TX_IND)==0)) 812 { 813 return; 814 } 815 719 816 pj_sockaddr_print(addr, dst_name, sizeof(dst_name), 3); 720 817 … … 750 847 tdata->retransmit = retransmit; 751 848 752 /* Start locking the session now */ 849 /* Lock the session and prevent user from destroying us in the callback */ 850 pj_atomic_inc(sess->busy); 753 851 pj_lock_acquire(sess->lock); 754 852 … … 758 856 if (status != PJ_SUCCESS) { 759 857 pj_stun_msg_destroy_tdata(sess, tdata); 760 pj_lock_release(sess->lock);761 858 LOG_ERR_(sess, "Error applying options", status); 762 return status;859 goto on_return; 763 860 } 764 861 … … 770 867 if (status != PJ_SUCCESS) { 771 868 pj_stun_msg_destroy_tdata(sess, tdata); 772 pj_lock_release(sess->lock);773 869 LOG_ERR_(sess, "STUN encode() error", status); 774 return status;870 goto on_return; 775 871 } 776 872 … … 798 894 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 799 895 pj_stun_msg_destroy_tdata(sess, tdata); 800 pj_lock_release(sess->lock);801 896 LOG_ERR_(sess, "Error sending STUN request", status); 802 return status;897 goto on_return; 803 898 } 804 899 … … 825 920 &timeout); 826 921 if (status != PJ_SUCCESS) { 922 tdata->res_timer.id = PJ_FALSE; 827 923 pj_stun_msg_destroy_tdata(sess, tdata); 828 pj_lock_release(sess->lock);829 924 LOG_ERR_(sess, "Error scheduling response timer", status); 830 return status;925 goto on_return; 831 926 } 832 927 … … 839 934 840 935 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 936 pj_stun_msg_destroy_tdata(sess, tdata); 841 937 LOG_ERR_(sess, "Error sending STUN request", status); 938 goto on_return; 842 939 } 843 940 … … 848 945 } 849 946 850 947 on_return: 851 948 pj_lock_release(sess->lock); 949 950 /* Check if application has called destroy() in the callback */ 951 if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 952 pj_stun_session_destroy(sess); 953 return PJNATH_ESTUNDESTROYED; 954 } 955 852 956 return status; 853 957 } … … 893 997 PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL); 894 998 999 /* Lock the session and prevent user from destroying us in the callback */ 1000 pj_atomic_inc(sess->busy); 895 1001 pj_lock_acquire(sess->lock); 896 1002 … … 904 1010 905 1011 pj_lock_release(sess->lock); 1012 1013 if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 1014 pj_stun_session_destroy(sess); 1015 return PJNATH_ESTUNDESTROYED; 1016 } 1017 906 1018 return PJ_SUCCESS; 907 1019 } … … 918 1030 PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL); 919 1031 1032 /* Lock the session and prevent user from destroying us in the callback */ 1033 pj_atomic_inc(sess->busy); 920 1034 pj_lock_acquire(sess->lock); 921 1035 … … 923 1037 924 1038 pj_lock_release(sess->lock); 1039 1040 if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 1041 pj_stun_session_destroy(sess); 1042 return PJNATH_ESTUNDESTROYED; 1043 } 925 1044 926 1045 return status; … … 1166 1285 1167 1286 1287 /* Print outgoing message to log */ 1288 static void dump_rx_msg(pj_stun_session *sess, const pj_stun_msg *msg, 1289 unsigned pkt_size, const pj_sockaddr_t *addr) 1290 { 1291 char src_info[PJ_INET6_ADDRSTRLEN+10]; 1292 1293 if ((PJ_STUN_IS_REQUEST(msg->hdr.type) && 1294 (sess->log_flag & PJ_STUN_SESS_LOG_RX_REQ)==0) || 1295 (PJ_STUN_IS_RESPONSE(msg->hdr.type) && 1296 (sess->log_flag & PJ_STUN_SESS_LOG_RX_RES)==0) || 1297 (PJ_STUN_IS_INDICATION(msg->hdr.type) && 1298 (sess->log_flag & PJ_STUN_SESS_LOG_RX_IND)==0)) 1299 { 1300 return; 1301 } 1302 1303 pj_sockaddr_print(addr, src_info, sizeof(src_info), 3); 1304 1305 PJ_LOG(5,(SNAME(sess), 1306 "RX %d bytes STUN message from %s:\n" 1307 "--- begin STUN message ---\n" 1308 "%s" 1309 "--- end of STUN message ---\n", 1310 pkt_size, src_info, 1311 pj_stun_msg_dump(msg, sess->dump_buf, sizeof(sess->dump_buf), 1312 NULL))); 1313 1314 } 1315 1316 /* Incoming packet */ 1168 1317 PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, 1169 1318 const void *packet, … … 1176 1325 { 1177 1326 pj_stun_msg *msg, *response; 1178 pj_pool_t *tmp_pool;1179 char *dump;1180 1327 pj_status_t status; 1181 1328 1182 1329 PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL); 1183 1330 1184 tmp_pool = pj_pool_create(sess->cfg->pf, "tmpstun", 1185 PJNATH_POOL_LEN_STUN_TDATA, 1186 PJNATH_POOL_INC_STUN_TDATA, NULL); 1187 if (!tmp_pool) 1188 return PJ_ENOMEM; 1331 /* Lock the session and prevent user from destroying us in the callback */ 1332 pj_atomic_inc(sess->busy); 1333 pj_lock_acquire(sess->lock); 1334 1335 /* Reset pool */ 1336 pj_pool_reset(sess->rx_pool); 1189 1337 1190 1338 /* Try to parse the message */ 1191 status = pj_stun_msg_decode( tmp_pool, (const pj_uint8_t*)packet,1339 status = pj_stun_msg_decode(sess->rx_pool, (const pj_uint8_t*)packet, 1192 1340 pkt_size, options, 1193 1341 &msg, parsed_len, &response); … … 1195 1343 LOG_ERR_(sess, "STUN msg_decode() error", status); 1196 1344 if (response) { 1197 send_response(sess, token, tmp_pool, response, NULL,1345 send_response(sess, token, sess->rx_pool, response, NULL, 1198 1346 PJ_FALSE, src_addr, src_addr_len); 1199 1347 } 1200 pj_pool_release(tmp_pool); 1201 return status; 1202 } 1203 1204 dump = (char*) pj_pool_alloc(tmp_pool, PJ_STUN_MAX_PKT_LEN); 1205 1206 PJ_LOG(5,(SNAME(sess), 1207 "RX STUN message from %s:%d:\n" 1208 "--- begin STUN message ---\n" 1209 "%s" 1210 "--- end of STUN message ---\n", 1211 pj_inet_ntoa(((pj_sockaddr_in*)src_addr)->sin_addr), 1212 pj_ntohs(((pj_sockaddr_in*)src_addr)->sin_port), 1213 pj_stun_msg_dump(msg, dump, PJ_STUN_MAX_PKT_LEN, NULL))); 1214 1215 pj_lock_acquire(sess->lock); 1348 goto on_return; 1349 } 1350 1351 dump_rx_msg(sess, msg, pkt_size, src_addr); 1216 1352 1217 1353 /* For requests, check if we have cached response */ 1218 status = check_cached_response(sess, tmp_pool, msg,1354 status = check_cached_response(sess, sess->rx_pool, msg, 1219 1355 src_addr, src_addr_len); 1220 1356 if (status == PJ_SUCCESS) { … … 1232 1368 } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 1233 1369 1234 status = on_incoming_request(sess, options, token, tmp_pool,1370 status = on_incoming_request(sess, options, token, sess->rx_pool, 1235 1371 (const pj_uint8_t*) packet, pkt_size, 1236 1372 msg, src_addr, src_addr_len); … … 1238 1374 } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) { 1239 1375 1240 status = on_incoming_indication(sess, token, tmp_pool,1376 status = on_incoming_indication(sess, token, sess->rx_pool, 1241 1377 (const pj_uint8_t*) packet, pkt_size, 1242 1378 msg, src_addr, src_addr_len); … … 1250 1386 pj_lock_release(sess->lock); 1251 1387 1252 pj_pool_release(tmp_pool); 1388 /* If we've received destroy request while we're on the callback, 1389 * destroy the session now. 1390 */ 1391 if (pj_atomic_dec_and_get(sess->busy)==0 && sess->destroy_request) { 1392 pj_stun_session_destroy(sess); 1393 return PJNATH_ESTUNDESTROYED; 1394 } 1395 1253 1396 return status; 1254 1397 } 1255 1398 1256 1257 -
pjproject/trunk/pjnath/src/pjnath/stun_transaction.c
r1410 r1988 32 32 { 33 33 char obj_name[PJ_MAX_OBJ_NAME]; 34 pj_stun_config *cfg;35 34 pj_stun_tsx_cb cb; 36 35 void *user_data; … … 39 38 40 39 pj_bool_t require_retransmit; 40 unsigned rto_msec; 41 41 pj_timer_entry retransmit_timer; 42 42 unsigned transmit_count; 43 43 pj_time_val retransmit_time; 44 pj_timer_heap_t *timer_heap; 44 45 45 46 pj_timer_entry destroy_timer; … … 71 72 72 73 tsx = PJ_POOL_ZALLOC_T(pool, pj_stun_client_tsx); 73 tsx->cfg = cfg; 74 tsx->rto_msec = cfg->rto_msec; 75 tsx->timer_heap = cfg->timer_heap; 74 76 pj_memcpy(&tsx->cb, cb, sizeof(*cb)); 75 77 … … 100 102 /* Cancel previously registered timer */ 101 103 if (tsx->destroy_timer.id != 0) { 102 pj_timer_heap_cancel(tsx-> cfg->timer_heap, &tsx->destroy_timer);104 pj_timer_heap_cancel(tsx->timer_heap, &tsx->destroy_timer); 103 105 tsx->destroy_timer.id = 0; 104 106 } … … 106 108 /* Stop retransmission, just in case */ 107 109 if (tsx->retransmit_timer.id != 0) { 108 pj_timer_heap_cancel(tsx-> cfg->timer_heap, &tsx->retransmit_timer);109 tsx->retransmit_timer.id = 0; 110 } 111 112 status = pj_timer_heap_schedule(tsx-> cfg->timer_heap,110 pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer); 111 tsx->retransmit_timer.id = 0; 112 } 113 114 status = pj_timer_heap_schedule(tsx->timer_heap, 113 115 &tsx->destroy_timer, delay); 114 116 if (status != PJ_SUCCESS) … … 116 118 117 119 tsx->destroy_timer.id = TIMER_ACTIVE; 120 tsx->cb.on_complete = NULL; 118 121 119 122 return PJ_SUCCESS; … … 129 132 130 133 if (tsx->retransmit_timer.id != 0) { 131 pj_timer_heap_cancel(tsx-> cfg->timer_heap, &tsx->retransmit_timer);134 pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer); 132 135 tsx->retransmit_timer.id = 0; 133 136 } 134 137 if (tsx->destroy_timer.id != 0) { 135 pj_timer_heap_cancel(tsx-> cfg->timer_heap, &tsx->destroy_timer);138 pj_timer_heap_cancel(tsx->timer_heap, &tsx->destroy_timer); 136 139 tsx->destroy_timer.id = 0; 137 140 } … … 187 190 if (tsx->transmit_count == 0) { 188 191 tsx->retransmit_time.sec = 0; 189 tsx->retransmit_time.msec = tsx-> cfg->rto_msec;192 tsx->retransmit_time.msec = tsx->rto_msec; 190 193 191 194 } else if (tsx->transmit_count < PJ_STUN_MAX_TRANSMIT_COUNT-1) { … … 206 209 * cancel transmission). 207 210 */; 208 status = pj_timer_heap_schedule(tsx-> cfg->timer_heap,211 status = pj_timer_heap_schedule(tsx->timer_heap, 209 212 &tsx->retransmit_timer, 210 213 &tsx->retransmit_time); … … 224 227 /* Send message */ 225 228 status = tsx->cb.on_send_msg(tsx, tsx->last_pkt, tsx->last_pkt_size); 226 if (status != PJ_SUCCESS) { 229 230 if (status == PJNATH_ESTUNDESTROYED) { 231 /* We've been destroyed, don't access the object. */ 232 } else if (status != PJ_SUCCESS) { 227 233 if (tsx->retransmit_timer.id != 0) { 228 pj_timer_heap_cancel(tsx-> cfg->timer_heap,234 pj_timer_heap_cancel(tsx->timer_heap, 229 235 &tsx->retransmit_timer); 230 236 tsx->retransmit_timer.id = 0; … … 280 286 } 281 287 } 288 /* We might have been destroyed, don't try to access the object */ 282 289 return; 283 290 } … … 285 292 tsx->retransmit_timer.id = 0; 286 293 status = tsx_transmit_msg(tsx); 287 if (status != PJ_SUCCESS) { 294 if (status == PJNATH_ESTUNDESTROYED) { 295 /* We've been destroyed, don't try to access the object */ 296 } else if (status != PJ_SUCCESS) { 288 297 tsx->retransmit_timer.id = 0; 289 298 if (!tsx->complete) { … … 293 302 } 294 303 } 304 /* We might have been destroyed, don't try to access the object */ 295 305 } 296 306 } … … 306 316 307 317 if (tsx->retransmit_timer.id != 0) { 308 pj_timer_heap_cancel(tsx-> cfg->timer_heap, &tsx->retransmit_timer);318 pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer); 309 319 tsx->retransmit_timer.id = 0; 310 320 } … … 352 362 */ 353 363 if (tsx->retransmit_timer.id) { 354 pj_timer_heap_cancel(tsx-> cfg->timer_heap, &tsx->retransmit_timer);364 pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer); 355 365 tsx->retransmit_timer.id = 0; 356 366 } … … 385 395 tsx->cb.on_complete(tsx, status, msg, src_addr, src_addr_len); 386 396 } 397 /* We might have been destroyed, don't try to access the object */ 387 398 } 388 399 -
pjproject/trunk/pjnath/src/pjnath/turn_session.c
r1929 r1988 30 30 #include <pj/sock.h> 31 31 32 #define MAX_SRV_CNT 4 33 #define REFRESH_SEC_BEFORE 60 32 #define PJ_TURN_CHANNEL_MIN 0x4000 33 #define PJ_TURN_CHANNEL_MAX 0xFFFE /* inclusive */ 34 #define PJ_TURN_PEER_HTABLE_SIZE 8 34 35 35 36 static const char *state_names[] = … … 67 68 pj_turn_session_cb cb; 68 69 void *user_data; 70 pj_stun_config stun_cfg; 69 71 70 72 pj_lock_t *lock; … … 72 74 73 75 pj_turn_state_t state; 76 pj_status_t last_status; 74 77 pj_bool_t pending_destroy; 75 78 pj_bool_t destroy_notified; … … 88 91 89 92 pj_uint16_t af; 90 pj_turn_tp_type tp_type;93 pj_turn_tp_type conn_type; 91 94 pj_uint16_t srv_addr_cnt; 92 95 pj_sockaddr *srv_addr_list; … … 96 99 pj_turn_alloc_param alloc_param; 97 100 101 pj_sockaddr mapped_addr; 98 102 pj_sockaddr relay_addr; 99 103 … … 177 181 * Create TURN client session. 178 182 */ 179 PJ_DEF(pj_status_t) pj_turn_session_create( pj_stun_config *cfg,183 PJ_DEF(pj_status_t) pj_turn_session_create( const pj_stun_config *cfg, 180 184 const char *name, 181 185 int af, 182 pj_turn_tp_type tp_type,186 pj_turn_tp_type conn_type, 183 187 const pj_turn_session_cb *cb, 188 unsigned options, 184 189 void *user_data, 185 unsigned options,186 190 pj_turn_session **p_sess) 187 191 { … … 207 211 sess->timer_heap = cfg->timer_heap; 208 212 sess->af = (pj_uint16_t)af; 209 sess-> tp_type = tp_type;213 sess->conn_type = conn_type; 210 214 sess->ka_interval = PJ_TURN_KEEP_ALIVE_SEC; 211 215 sess->user_data = user_data; 212 216 sess->next_ch = PJ_TURN_CHANNEL_MIN; 217 218 /* Copy STUN session */ 219 pj_memcpy(&sess->stun_cfg, cfg, sizeof(pj_stun_config)); 213 220 214 221 /* Copy callback */ … … 234 241 stun_cb.on_request_complete = &stun_on_request_complete; 235 242 stun_cb.on_rx_indication = &stun_on_rx_indication; 236 status = pj_stun_session_create( cfg, sess->obj_name, &stun_cb, PJ_FALSE,237 &sess->stun);243 status = pj_stun_session_create(&sess->stun_cfg, sess->obj_name, &stun_cb, 244 PJ_FALSE, &sess->stun); 238 245 if (status != PJ_SUCCESS) { 239 246 do_destroy(sess); … … 334 341 break; 335 342 case PJ_TURN_STATE_RESOLVING: 336 pj_assert(sess->dns_async != NULL); 337 pj_dns_resolver_cancel_query(sess->dns_async, PJ_FALSE); 338 sess->dns_async = NULL; 343 if (sess->dns_async != NULL) { 344 pj_dns_resolver_cancel_query(sess->dns_async, PJ_FALSE); 345 sess->dns_async = NULL; 346 } 339 347 break; 340 348 case PJ_TURN_STATE_RESOLVED: … … 366 374 pj_time_val delay = {0, 0}; 367 375 376 set_state(sess, PJ_TURN_STATE_DESTROYING); 377 368 378 if (sess->timer.id != TIMER_NONE) { 369 379 pj_timer_heap_cancel(sess->timer_heap, &sess->timer); … … 371 381 } 372 382 373 set_state(sess, PJ_TURN_STATE_DESTROYING);374 375 383 sess->timer.id = TIMER_DESTROY; 376 384 pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay); … … 401 409 PJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess) 402 410 { 411 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 412 403 413 set_state(sess, PJ_TURN_STATE_DEALLOCATED); 404 414 sess_shutdown(sess, PJ_SUCCESS); … … 420 430 421 431 info->state = sess->state; 422 info-> tp_type = sess->tp_type;432 info->conn_type = sess->conn_type; 423 433 info->lifetime = sess->expiry.sec - now.sec; 434 info->last_status = sess->last_status; 424 435 425 436 if (sess->srv_addr) … … 428 439 pj_bzero(&info->server, sizeof(info->server)); 429 440 430 pj_memcpy(&info->relay_addr, &sess->relay_addr, sizeof(sess->relay_addr)); 441 pj_memcpy(&info->mapped_addr, &sess->mapped_addr, 442 sizeof(sess->mapped_addr)); 443 pj_memcpy(&info->relay_addr, &sess->relay_addr, 444 sizeof(sess->relay_addr)); 431 445 432 446 return PJ_SUCCESS; … … 451 465 { 452 466 return sess->user_data; 467 } 468 469 470 /* 471 * Configure message logging. By default all flags are enabled. 472 * 473 * @param sess The TURN client session. 474 * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag 475 */ 476 PJ_DEF(void) pj_turn_session_set_log( pj_turn_session *sess, 477 unsigned flags) 478 { 479 pj_stun_session_set_log(sess->stun, flags); 453 480 } 454 481 … … 462 489 pj_dns_resolver *resolver) 463 490 { 491 pj_sockaddr tmp_addr; 492 pj_bool_t is_ip_addr; 464 493 pj_status_t status; 465 494 … … 469 498 pj_lock_acquire(sess->lock); 470 499 471 if (resolver) { 500 /* See if "domain" contains just IP address */ 501 tmp_addr.addr.sa_family = sess->af; 502 status = pj_inet_pton(sess->af, domain, 503 pj_sockaddr_get_addr(&tmp_addr)); 504 is_ip_addr = (status == PJ_SUCCESS); 505 506 if (!is_ip_addr && resolver) { 472 507 /* Resolve with DNS SRV resolution, and fallback to DNS A resolution 473 508 * if default_port is specified. … … 476 511 pj_str_t res_name; 477 512 478 switch (sess-> tp_type) {513 switch (sess->conn_type) { 479 514 case PJ_TURN_TP_UDP: 480 515 res_name = pj_str("_turn._udp."); … … 502 537 set_state(sess, PJ_TURN_STATE_RESOLVING); 503 538 539 /* User may have destroyed us in the callback */ 540 if (sess->state != PJ_TURN_STATE_RESOLVING) { 541 status = PJ_ECANCELLED; 542 goto on_return; 543 } 544 504 545 status = pj_dns_srv_resolve(domain, &res_name, default_port, 505 546 sess->pool, resolver, opt, sess, … … 521 562 sess->default_port = (pj_uint16_t)default_port; 522 563 523 cnt = MAX_SRV_CNT;564 cnt = PJ_TURN_MAX_DNS_SRV_CNT; 524 565 ai = (pj_addrinfo*) 525 566 pj_pool_calloc(sess->pool, cnt, sizeof(pj_addrinfo)); … … 527 568 PJ_LOG(5,(sess->obj_name, "Resolving %.*s with DNS A", 528 569 (int)domain->slen, domain->ptr)); 570 set_state(sess, PJ_TURN_STATE_RESOLVING); 571 572 /* User may have destroyed us in the callback */ 573 if (sess->state != PJ_TURN_STATE_RESOLVING) { 574 status = PJ_ECANCELLED; 575 goto on_return; 576 } 529 577 530 578 status = pj_getaddrinfo(sess->af, domain, &cnt, ai); … … 637 685 /* Send request */ 638 686 set_state(sess, PJ_TURN_STATE_ALLOCATING); 639 retransmit = (sess-> tp_type == PJ_TURN_TP_UDP);687 retransmit = (sess->conn_type == PJ_TURN_TP_UDP); 640 688 status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, 641 689 retransmit, sess->srv_addr, … … 682 730 683 731 status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, 684 (sess-> tp_type==PJ_TURN_TP_UDP),732 (sess->conn_type==PJ_TURN_TP_UDP), 685 733 sess->srv_addr, 686 734 pj_sockaddr_get_len(sess->srv_addr), … … 834 882 */ 835 883 status = pj_stun_session_send_msg(sess->stun, peer, PJ_FALSE, 836 (sess-> tp_type==PJ_TURN_TP_UDP),884 (sess->conn_type==PJ_TURN_TP_UDP), 837 885 sess->srv_addr, 838 886 pj_sockaddr_get_len(sess->srv_addr), … … 850 898 */ 851 899 PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, 852 const pj_uint8_t *pkt, 853 unsigned pkt_len, 854 pj_bool_t is_datagram) 900 void *pkt, 901 unsigned pkt_len) 855 902 { 856 903 pj_bool_t is_stun; 857 904 pj_status_t status; 905 pj_bool_t is_datagram; 858 906 859 907 /* Packet could be ChannelData or STUN message (response or … … 864 912 pj_lock_acquire(sess->lock); 865 913 914 is_datagram = (sess->conn_type==PJ_TURN_TP_UDP); 915 866 916 /* Quickly check if this is STUN message */ 867 is_stun = (( pkt[0] & 0xC0) == 0);917 is_stun = ((((pj_uint8_t*)pkt)[0] & 0xC0) == 0); 868 918 869 919 if (is_stun) { … … 871 921 unsigned options; 872 922 873 options = PJ_STUN_CHECK_PACKET ;923 options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK; 874 924 if (is_datagram) 875 925 options |= PJ_STUN_IS_DATAGRAM; … … 906 956 907 957 /* Notify application */ 908 (*sess->cb.on_rx_data)(sess, pkt+sizeof(cd), cd.length,909 &peer->addr,958 (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd), 959 cd.length, &peer->addr, 910 960 pj_sockaddr_get_len(&peer->addr)); 911 961 … … 954 1004 const pj_str_t *reason) 955 1005 { 1006 sess->last_status = status; 1007 956 1008 do { 957 1009 pj_str_t reason1; … … 1011 1063 const pj_stun_lifetime_attr *lf_attr; 1012 1064 const pj_stun_relay_addr_attr *raddr_attr; 1065 const pj_stun_sockaddr_attr *mapped_attr; 1013 1066 pj_str_t s; 1014 1067 pj_time_val timeout; … … 1070 1123 " address family is not supported " 1071 1124 "for now")); 1125 return; 1126 } 1127 if (raddr_attr && !pj_sockaddr_has_addr(&raddr_attr->sockaddr)) { 1128 on_session_fail(sess, method, PJNATH_EINSTUNMSG, 1129 pj_cstr(&s, "Error: Invalid IP address in " 1130 "RELAY-ADDRESS attribute")); 1072 1131 return; 1073 1132 } … … 1092 1151 } 1093 1152 1153 /* Get mapped address */ 1154 mapped_attr = (const pj_stun_sockaddr_attr*) 1155 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0); 1156 if (mapped_attr) { 1157 pj_memcpy(&sess->mapped_addr, &mapped_attr->sockaddr, 1158 sizeof(mapped_attr->sockaddr)); 1159 } 1160 1094 1161 /* Success */ 1095 1162 … … 1133 1200 1134 1201 if (method == PJ_STUN_ALLOCATE_METHOD) { 1202 1203 /* Destroy if we have pending destroy request */ 1204 if (sess->pending_destroy) { 1205 if (status == PJ_SUCCESS) 1206 sess->state = PJ_TURN_STATE_READY; 1207 else 1208 sess->state = PJ_TURN_STATE_DEALLOCATED; 1209 sess_shutdown(sess, PJ_SUCCESS); 1210 return; 1211 } 1212 1135 1213 /* Handle ALLOCATE response */ 1136 1214 if (status==PJ_SUCCESS && … … 1299 1377 { 1300 1378 pj_turn_session *sess = (pj_turn_session*) user_data; 1301 unsigned i, cnt ;1379 unsigned i, cnt, tot_cnt; 1302 1380 1303 1381 /* Clear async resolver */ … … 1310 1388 } 1311 1389 1390 /* Calculate total number of server entries in the response */ 1391 tot_cnt = 0; 1392 for (i=0; i<rec->count; ++i) { 1393 tot_cnt += rec->entry[i].server.addr_count; 1394 } 1395 1396 if (tot_cnt > PJ_TURN_MAX_DNS_SRV_CNT) 1397 tot_cnt = PJ_TURN_MAX_DNS_SRV_CNT; 1398 1399 /* Allocate server entries */ 1400 sess->srv_addr_list = (pj_sockaddr*) 1401 pj_pool_calloc(sess->pool, tot_cnt, 1402 sizeof(pj_sockaddr)); 1403 1312 1404 /* Copy results to server entries */ 1313 for (i=0, cnt=0; i<rec->count && cnt< MAX_SRV_CNT; ++i) {1405 for (i=0, cnt=0; i<rec->count && cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++i) { 1314 1406 unsigned j; 1315 1407 1316 for (j=0; j<rec->entry[i].server.addr_count && cnt<MAX_SRV_CNT; ++j) { 1408 for (j=0; j<rec->entry[i].server.addr_count && 1409 cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++j) 1410 { 1317 1411 pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4; 1318 1412 -
pjproject/trunk/pjnath/src/pjnath/turn_sock.c
r1914 r1988 18 18 */ 19 19 #include <pjnath/turn_sock.h> 20 #include <pj/activesock.h> 20 21 #include <pj/assert.h> 21 22 #include <pj/errno.h> … … 51 52 int af; 52 53 pj_turn_tp_type conn_type; 53 pj_sock_t sock; 54 pj_ioqueue_key_t *key; 55 pj_ioqueue_op_key_t read_key; 54 pj_activesock_t *active_sock; 56 55 pj_ioqueue_op_key_t send_key; 57 pj_uint8_t pkt[PJ_TURN_MAX_PKT_LEN];58 56 }; 59 57 … … 72 70 unsigned ch_num); 73 71 static void turn_on_rx_data(pj_turn_session *sess, 74 const pj_uint8_t*pkt,72 void *pkt, 75 73 unsigned pkt_len, 76 74 const pj_sockaddr_t *peer_addr, … … 79 77 pj_turn_state_t old_state, 80 78 pj_turn_state_t new_state); 81 static void on_read_complete(pj_ioqueue_key_t *key, 82 pj_ioqueue_op_key_t *op_key, 83 pj_ssize_t bytes_read); 84 static void on_connect_complete(pj_ioqueue_key_t *key, 85 pj_status_t status); 79 80 static pj_bool_t on_data_read(pj_activesock_t *asock, 81 void *data, 82 pj_size_t size, 83 pj_status_t status, 84 pj_size_t *remainder); 85 static pj_bool_t on_connect_complete(pj_activesock_t *asock, 86 pj_status_t status); 87 86 88 87 89 … … 159 161 sess_cb.on_state = &turn_on_state; 160 162 status = pj_turn_session_create(cfg, pool->obj_name, af, conn_type, 161 &sess_cb, turn_sock, 0, &turn_sock->sess);163 &sess_cb, 0, turn_sock, &turn_sock->sess); 162 164 if (status != PJ_SUCCESS) { 163 165 destroy(turn_sock); … … 188 190 } 189 191 190 if (turn_sock->key) { 191 pj_ioqueue_unregister(turn_sock->key); 192 turn_sock->key = NULL; 193 turn_sock->sock = 0; 194 } else if (turn_sock->sock) { 195 pj_sock_close(turn_sock->sock); 196 turn_sock->sock = 0; 192 if (turn_sock->active_sock) { 193 pj_activesock_close(turn_sock->active_sock); 194 turn_sock->active_sock = NULL; 197 195 } 198 196 … … 272 270 { 273 271 show_err(turn_sock, title, status); 274 pj_turn_session_destroy(turn_sock->sess); 272 if (turn_sock->sess) 273 pj_turn_session_destroy(turn_sock->sess); 275 274 } 276 275 … … 281 280 void *user_data) 282 281 { 282 PJ_ASSERT_RETURN(turn_sock, PJ_EINVAL); 283 283 turn_sock->user_data = user_data; 284 284 return PJ_SUCCESS; … … 290 290 PJ_DEF(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock) 291 291 { 292 PJ_ASSERT_RETURN(turn_sock, NULL); 292 293 return turn_sock->user_data; 293 294 } … … 297 298 */ 298 299 PJ_DEF(pj_status_t) pj_turn_sock_get_info(pj_turn_sock *turn_sock, 299 pj_turn_session_info *info)300 pj_turn_session_info *info) 300 301 { 301 302 PJ_ASSERT_RETURN(turn_sock && info, PJ_EINVAL); … … 310 311 } 311 312 313 /** 314 * Lock the TURN socket. Application may need to call this function to 315 * synchronize access to other objects to avoid deadlock. 316 */ 317 PJ_DEF(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock) 318 { 319 return pj_lock_acquire(turn_sock->lock); 320 } 321 322 /** 323 * Unlock the TURN socket. 324 */ 325 PJ_DEF(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock) 326 { 327 return pj_lock_release(turn_sock->lock); 328 } 329 330 /* 331 * Set STUN message logging for this TURN session. 332 */ 333 PJ_DEF(void) pj_turn_sock_set_log( pj_turn_sock *turn_sock, 334 unsigned flags) 335 { 336 pj_turn_session_set_log(turn_sock->sess, flags); 337 } 338 312 339 /* 313 340 * Initialize. 314 341 */ 315 PJ_DEF(pj_status_t) pj_turn_sock_ init(pj_turn_sock *turn_sock,316 const pj_str_t *domain,317 int default_port,318 pj_dns_resolver *resolver,319 const pj_stun_auth_cred *cred,320 const pj_turn_alloc_param *param)342 PJ_DEF(pj_status_t) pj_turn_sock_alloc(pj_turn_sock *turn_sock, 343 const pj_str_t *domain, 344 int default_port, 345 pj_dns_resolver *resolver, 346 const pj_stun_auth_cred *cred, 347 const pj_turn_alloc_param *param) 321 348 { 322 349 pj_status_t status; … … 393 420 * Notification when outgoing TCP socket has been connected. 394 421 */ 395 static void on_connect_complete(pj_ioqueue_key_t *key,396 422 static pj_bool_t on_connect_complete(pj_activesock_t *asock, 423 pj_status_t status) 397 424 { 398 425 pj_turn_sock *turn_sock; 399 426 400 turn_sock = (pj_turn_sock*) pj_ ioqueue_get_user_data(key);427 turn_sock = (pj_turn_sock*) pj_activesock_get_user_data(asock); 401 428 402 429 if (status != PJ_SUCCESS) { 403 430 sess_fail(turn_sock, "TCP connect() error", status); 404 return ;431 return PJ_FALSE; 405 432 } 406 433 … … 410 437 411 438 /* Kick start pending read operation */ 412 pj_ioqueue_op_key_init(&turn_sock->read_key, sizeof(turn_sock->read_key));413 on_read_complete(turn_sock->key, &turn_sock->read_key, INIT);439 status = pj_activesock_start_read(asock, turn_sock->pool, 440 PJ_TURN_MAX_PKT_LEN, 0); 414 441 415 442 /* Init send_key */ … … 420 447 if (status != PJ_SUCCESS) { 421 448 sess_fail(turn_sock, "Error sending ALLOCATE", status); 422 return; 423 } 449 return PJ_FALSE; 450 } 451 452 return PJ_TRUE; 424 453 } 425 454 … … 427 456 * Notification from ioqueue when incoming UDP packet is received. 428 457 */ 429 static void on_read_complete(pj_ioqueue_key_t *key, 430 pj_ioqueue_op_key_t *op_key, 431 pj_ssize_t bytes_read) 432 { 433 enum { MAX_RETRY = 10 }; 458 static pj_bool_t on_data_read(pj_activesock_t *asock, 459 void *data, 460 pj_size_t size, 461 pj_status_t status, 462 pj_size_t *remainder) 463 { 434 464 pj_turn_sock *turn_sock; 435 int retry = 0; 436 pj_status_t status; 437 438 turn_sock = (pj_turn_sock*) pj_ioqueue_get_user_data(key); 465 pj_bool_t ret = PJ_TRUE; 466 467 turn_sock = (pj_turn_sock*) pj_activesock_get_user_data(asock); 439 468 pj_lock_acquire(turn_sock->lock); 440 469 441 do { 442 if (bytes_read == INIT) { 443 /* Special instruction to initialize pending read() */ 444 } else if (bytes_read > 0 && turn_sock->sess) { 445 /* Report incoming packet to TURN session */ 446 pj_turn_session_on_rx_pkt(turn_sock->sess, turn_sock->pkt, 447 bytes_read, 448 turn_sock->conn_type == PJ_TURN_TP_UDP); 449 } else if (bytes_read <= 0 && turn_sock->conn_type != PJ_TURN_TP_UDP) { 450 sess_fail(turn_sock, "TCP connection closed", -bytes_read); 451 goto on_return; 452 } 453 454 /* Read next packet */ 455 bytes_read = sizeof(turn_sock->pkt); 456 status = pj_ioqueue_recv(turn_sock->key, op_key, 457 turn_sock->pkt, &bytes_read, 0); 458 459 if (status != PJ_EPENDING && status != PJ_SUCCESS) { 460 char errmsg[PJ_ERR_MSG_SIZE]; 461 462 pj_strerror(status, errmsg, sizeof(errmsg)); 463 sess_fail(turn_sock, "Socket recv() error", status); 464 goto on_return; 465 } 466 467 } while (status != PJ_EPENDING && status != PJ_ECANCELLED && 468 ++retry < MAX_RETRY); 470 if (status == PJ_SUCCESS && turn_sock->sess) { 471 /* Report incoming packet to TURN session */ 472 PJ_TODO(REPORT_PARSED_LEN); 473 pj_turn_session_on_rx_pkt(turn_sock->sess, data, size); 474 } else if (status != PJ_SUCCESS && 475 turn_sock->conn_type != PJ_TURN_TP_UDP) 476 { 477 sess_fail(turn_sock, "TCP connection closed", status); 478 ret = PJ_FALSE; 479 goto on_return; 480 } 469 481 470 482 on_return: 471 483 pj_lock_release(turn_sock->lock); 484 485 return ret; 472 486 } 473 487 … … 483 497 { 484 498 pj_turn_sock *turn_sock = (pj_turn_sock*) 485 pj_turn_session_get_user_data(sess);499 pj_turn_session_get_user_data(sess); 486 500 pj_ssize_t len = pkt_len; 487 501 pj_status_t status; … … 496 510 PJ_UNUSED_ARG(dst_addr_len); 497 511 498 status = pj_ ioqueue_send(turn_sock->key, &turn_sock->send_key,499 512 status = pj_activesock_send(turn_sock->active_sock, &turn_sock->send_key, 513 pkt, &len, 0); 500 514 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 501 515 show_err(turn_sock, "socket send()", status); … … 525 539 */ 526 540 static void turn_on_rx_data(pj_turn_session *sess, 527 const pj_uint8_t*pkt,541 void *pkt, 528 542 unsigned pkt_len, 529 543 const pj_sockaddr_t *peer_addr, … … 560 574 } 561 575 562 if (new_state == PJ_TURN_STATE_RESOLVED) { 576 /* Notify app first */ 577 if (turn_sock->cb.on_state) { 578 (*turn_sock->cb.on_state)(turn_sock, old_state, new_state); 579 } 580 581 /* Make sure user hasn't destroyed us in the callback */ 582 if (turn_sock->sess && new_state == PJ_TURN_STATE_RESOLVED) { 583 pj_turn_session_info info; 584 pj_turn_session_get_info(turn_sock->sess, &info); 585 new_state = info.state; 586 } 587 588 if (turn_sock->sess && new_state == PJ_TURN_STATE_RESOLVED) { 563 589 /* 564 590 * Once server has been resolved, initiate outgoing TCP … … 568 594 char addrtxt[PJ_INET6_ADDRSTRLEN+8]; 569 595 int sock_type; 570 pj_ioqueue_callback ioq_cb; 596 pj_sock_t sock; 597 pj_activesock_cb asock_cb; 571 598 572 599 /* Close existing connection, if any. This happens when … … 574 601 * connection or ALLOCATE request failed. 575 602 */ 576 if (turn_sock->key) { 577 pj_ioqueue_unregister(turn_sock->key); 578 turn_sock->key = NULL; 579 turn_sock->sock = 0; 580 } else if (turn_sock->sock) { 581 pj_sock_close(turn_sock->sock); 582 turn_sock->sock = 0; 603 if (turn_sock->active_sock) { 604 pj_activesock_close(turn_sock->active_sock); 605 turn_sock->active_sock = NULL; 583 606 } 584 607 … … 592 615 593 616 /* Init socket */ 594 status = pj_sock_socket(turn_sock->af, sock_type, 0, 595 &turn_sock->sock); 617 status = pj_sock_socket(turn_sock->af, sock_type, 0, &sock); 596 618 if (status != PJ_SUCCESS) { 597 619 pj_turn_sock_destroy(turn_sock); … … 599 621 } 600 622 601 /* Register to ioqeuue */ 602 pj_bzero(&ioq_cb, sizeof(ioq_cb)); 603 ioq_cb.on_read_complete = &on_read_complete; 604 ioq_cb.on_connect_complete = &on_connect_complete; 605 status = pj_ioqueue_register_sock(turn_sock->pool, turn_sock->cfg.ioqueue, 606 turn_sock->sock, turn_sock, 607 &ioq_cb, &turn_sock->key); 623 /* Create active socket */ 624 pj_bzero(&asock_cb, sizeof(asock_cb)); 625 asock_cb.on_data_read = &on_data_read; 626 asock_cb.on_connect_complete = &on_connect_complete; 627 status = pj_activesock_create(turn_sock->pool, sock, 628 sock_type, NULL, 629 turn_sock->cfg.ioqueue, &asock_cb, 630 turn_sock, 631 &turn_sock->active_sock); 608 632 if (status != PJ_SUCCESS) { 609 633 pj_turn_sock_destroy(turn_sock); … … 617 641 618 642 /* Initiate non-blocking connect */ 619 status = pj_ioqueue_connect(turn_sock->key, &info.server, 620 pj_sockaddr_get_len(&info.server)); 643 status=pj_activesock_start_connect(turn_sock->active_sock, 644 turn_sock->pool, 645 &info.server, 646 pj_sockaddr_get_len(&info.server)); 621 647 if (status == PJ_SUCCESS) { 622 on_connect_complete(turn_sock-> key, PJ_SUCCESS);648 on_connect_complete(turn_sock->active_sock, PJ_SUCCESS); 623 649 } else if (status != PJ_EPENDING) { 624 650 pj_turn_sock_destroy(turn_sock); … … 631 657 } 632 658 633 if (turn_sock->cb.on_state) {634 (*turn_sock->cb.on_state)(turn_sock, old_state, new_state);635 }636 637 659 if (new_state >= PJ_TURN_STATE_DESTROYING && turn_sock->sess) { 638 660 pj_time_val delay = {0, 0}; -
pjproject/trunk/pjnath/src/pjturn-client/client_main.c
r1929 r1988 69 69 static int worker_thread(void *unused); 70 70 static void turn_on_rx_data(pj_turn_sock *relay, 71 const pj_uint8_t*pkt,71 void *pkt, 72 72 unsigned pkt_len, 73 73 const pj_sockaddr_t *peer_addr, … … 275 275 276 276 srv = pj_str(o.srv_addr); 277 CHECK( pj_turn_sock_init(g.relay, /* the relay */277 CHECK(pj_turn_sock_alloc(g.relay, /* the relay */ 278 278 &srv, /* srv addr */ 279 279 (o.srv_port?atoi(o.srv_port):PJ_STUN_PORT),/* def port */ … … 295 295 296 296 static void turn_on_rx_data(pj_turn_sock *relay, 297 const pj_uint8_t*pkt,297 void *pkt, 298 298 unsigned pkt_len, 299 299 const pj_sockaddr_t *peer_addr, -
pjproject/trunk/pjnath/src/pjturn-srv/auth.c
r1929 r1988 36 36 { "100", "100" }, 37 37 { "700", "700" }, 38 { "701", "701" }, 39 { "702", "702" } 38 { "701", "701" } 40 39 }; 41 40
Note: See TracChangeset
for help on using the changeset viewer.