Changeset 1988


Ignore:
Timestamp:
Jun 6, 2008 2:47:10 PM (16 years ago)
Author:
bennylp
Message:

Major major modifications related to ticket #485 (support for TURN-07):

  • Added STUN socket transport pj_stun_sock
  • Integration of TURN-07 to ICE
  • Major refactoring in ICE stream transport to make it simpler
  • Major modification (i.e. API change) in almost everywhere else
  • Much more elaborate STUN, TURN, and ICE tests in pjnath-test
Location:
pjproject/trunk
Files:
6 added
35 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/build.symbian/pjnath.mmp

    r1913 r1988  
    3838SOURCE  stun_msg_dump.c 
    3939SOURCE  stun_session.c 
     40SOURCE  stun_sock.c 
    4041SOURCE  stun_transaction.c 
    4142SOURCE  turn_session.c 
  • pjproject/trunk/pjnath/build/Makefile

    r1916 r1988  
    3232export PJNATH_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ 
    3333                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.o 
     34                stun_msg.o stun_msg_dump.o stun_session.o stun_sock.o \ 
     35                stun_transaction.o turn_session.o turn_sock.o 
    3636export PJNATH_CFLAGS += $(_CFLAGS) 
    3737 
     
    4040# 
    4141export PJNATH_TEST_SRCDIR = ../src/pjnath-test 
    42 export PJNATH_TEST_OBJS += ice_test.o stun.o sess_auth.o test.o 
     42export PJNATH_TEST_OBJS += ice_test.o stun.o sess_auth.o server.o \ 
     43                            stun_sock_test.o turn_sock_test.o test.o 
    4344export PJNATH_TEST_CFLAGS += $(_CFLAGS) 
    4445export PJNATH_TEST_LDFLAGS += $(_LDFLAGS) 
  • pjproject/trunk/pjnath/build/pjnath.dsp

    r1913 r1988  
    122122# Begin Source File 
    123123 
     124SOURCE=..\src\pjnath\stun_sock.c 
     125# End Source File 
     126# Begin Source File 
     127 
    124128SOURCE=..\src\pjnath\stun_transaction.c 
    125129# End Source File 
     
    175179 
    176180SOURCE=..\include\pjnath\stun_session.h 
     181# End Source File 
     182# Begin Source File 
     183 
     184SOURCE=..\include\pjnath\stun_sock.h 
    177185# End Source File 
    178186# Begin Source File 
  • pjproject/trunk/pjnath/build/pjnath.vcproj

    r1913 r1988  
    299299                        </File> 
    300300                        <File 
     301                                RelativePath="..\src\pjnath\stun_sock.c" 
     302                                > 
     303                        </File> 
     304                        <File 
    301305                                RelativePath="..\src\pjnath\stun_transaction.c" 
    302306                                > 
  • pjproject/trunk/pjnath/build/pjnath_test.dsp

    r1877 r1988  
    8989 
    9090SOURCE="..\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 
    9198# End Source File 
    9299# Begin Source File 
    93100 
    94101SOURCE="..\src\pjnath-test\main.c" 
     102# End Source File 
     103# Begin Source File 
     104 
     105SOURCE="..\src\pjnath-test\server.c" 
    95106# End Source File 
    96107# Begin Source File 
     
    104115# Begin Source File 
    105116 
     117SOURCE="..\src\pjnath-test\stun_sock_test.c" 
     118# End Source File 
     119# Begin Source File 
     120 
    106121SOURCE="..\src\pjnath-test\test.c" 
     122# End Source File 
     123# Begin Source File 
     124 
     125SOURCE="..\src\pjnath-test\turn_sock_test.c" 
    107126# End Source File 
    108127# End Group 
     
    110129 
    111130# PROP Default_Filter "h;hpp;hxx;hm;inl" 
     131# Begin Source File 
     132 
     133SOURCE="..\src\pjnath-test\server.h" 
     134# End Source File 
    112135# Begin Source File 
    113136 
  • pjproject/trunk/pjnath/build/wince-evc4/pjnath_wince.vcp

    r1913 r1988  
    582582 
    583583DEP_CPP_ERRNO=\ 
     584        "..\..\..\pjlib\include\pj\activesock.h"\ 
    584585        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    585586        "..\..\..\pjlib\include\pj\array.h"\ 
     
    627628        "..\..\..\pjlib\include\pj\lock.h"\ 
    628629        "..\..\..\pjlib\include\pj\log.h"\ 
     630        "..\..\..\pjlib\include\pj\math.h"\ 
    629631        "..\..\..\pjlib\include\pj\os.h"\ 
    630632        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    12571259 
    12581260DEP_CPP_ICE_S=\ 
     1261        "..\..\..\pjlib\include\pj\activesock.h"\ 
    12591262        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    12601263        "..\..\..\pjlib\include\pj\array.h"\ 
     
    13021305        "..\..\..\pjlib\include\pj\lock.h"\ 
    13031306        "..\..\..\pjlib\include\pj\log.h"\ 
     1307        "..\..\..\pjlib\include\pj\math.h"\ 
    13041308        "..\..\..\pjlib\include\pj\os.h"\ 
    13051309        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    19861990        "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 
    19871991        "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 
     1992        "..\..\..\pjlib\include\pj\activesock.h"\ 
    19881993        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    19891994        "..\..\..\pjlib\include\pj\array.h"\ 
     
    20322037        "..\..\..\pjlib\include\pj\lock.h"\ 
    20332038        "..\..\..\pjlib\include\pj\log.h"\ 
     2039        "..\..\..\pjlib\include\pj\math.h"\ 
    20342040        "..\..\..\pjlib\include\pj\os.h"\ 
    20352041        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    20552061        "..\..\include\pjnath\stun_msg.h"\ 
    20562062        "..\..\include\pjnath\stun_session.h"\ 
     2063        "..\..\include\pjnath\stun_sock.h"\ 
    20572064        "..\..\include\pjnath\stun_transaction.h"\ 
     2065        "..\..\include\pjnath\turn_session.h"\ 
     2066        "..\..\include\pjnath\turn_sock.h"\ 
    20582067        "..\..\include\pjnath\types.h"\ 
    20592068         
     
    27402749 
    27412750DEP_CPP_NAT_D=\ 
     2751        "..\..\..\pjlib\include\pj\activesock.h"\ 
    27422752        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    27432753        "..\..\..\pjlib\include\pj\array.h"\ 
     
    27862796        "..\..\..\pjlib\include\pj\lock.h"\ 
    27872797        "..\..\..\pjlib\include\pj\log.h"\ 
     2798        "..\..\..\pjlib\include\pj\math.h"\ 
    27882799        "..\..\..\pjlib\include\pj\os.h"\ 
    27892800        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    34703481        "..\..\..\pjlib-util\include\pjlib-util\md5.h"\ 
    34713482        "..\..\..\pjlib-util\include\pjlib-util\sha1.h"\ 
     3483        "..\..\..\pjlib\include\pj\activesock.h"\ 
    34723484        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    34733485        "..\..\..\pjlib\include\pj\array.h"\ 
     
    35153527        "..\..\..\pjlib\include\pj\lock.h"\ 
    35163528        "..\..\..\pjlib\include\pj\log.h"\ 
     3529        "..\..\..\pjlib\include\pj\math.h"\ 
    35173530        "..\..\..\pjlib\include\pj\os.h"\ 
    35183531        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    41674180        "..\..\..\pjlib-util\include\pjlib-util\sha1.h"\ 
    41684181        "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 
     4182        "..\..\..\pjlib\include\pj\activesock.h"\ 
    41694183        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    41704184        "..\..\..\pjlib\include\pj\array.h"\ 
     
    42124226        "..\..\..\pjlib\include\pj\lock.h"\ 
    42134227        "..\..\..\pjlib\include\pj\log.h"\ 
     4228        "..\..\..\pjlib\include\pj\math.h"\ 
    42144229        "..\..\..\pjlib\include\pj\os.h"\ 
    42154230        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    48484863 
    48494864DEP_CPP_STUN_MS=\ 
     4865        "..\..\..\pjlib\include\pj\activesock.h"\ 
    48504866        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    48514867        "..\..\..\pjlib\include\pj\array.h"\ 
     
    48934909        "..\..\..\pjlib\include\pj\lock.h"\ 
    48944910        "..\..\..\pjlib\include\pj\log.h"\ 
     4911        "..\..\..\pjlib\include\pj\math.h"\ 
    48954912        "..\..\..\pjlib\include\pj\os.h"\ 
    48964913        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    55155532 
    55165533DEP_CPP_STUN_S=\ 
     5534        "..\..\..\pjlib\include\pj\activesock.h"\ 
    55175535        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    55185536        "..\..\..\pjlib\include\pj\array.h"\ 
     
    55605578        "..\..\..\pjlib\include\pj\lock.h"\ 
    55615579        "..\..\..\pjlib\include\pj\log.h"\ 
     5580        "..\..\..\pjlib\include\pj\math.h"\ 
    55625581        "..\..\..\pjlib\include\pj\os.h"\ 
    55635582        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    59265945# Begin Source File 
    59275946 
    5928 SOURCE=..\..\src\pjnath\stun_transaction.c 
     5947SOURCE=..\..\src\pjnath\stun_sock.c 
    59295948 
    59305949!IF  "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Release" 
    59315950 
    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=\ 
     5951DEP_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"\ 
    59985958        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    59995959        "..\..\..\pjlib\include\pj\array.h"\ 
     
    60416001        "..\..\..\pjlib\include\pj\lock.h"\ 
    60426002        "..\..\..\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"\ 
    60606022        "..\..\include\pjnath\stun_config.h"\ 
    60616023        "..\..\include\pjnath\stun_msg.h"\ 
     6024        "..\..\include\pjnath\stun_session.h"\ 
     6025        "..\..\include\pjnath\stun_sock.h"\ 
    60626026        "..\..\include\pjnath\stun_transaction.h"\ 
    60636027        "..\..\include\pjnath\types.h"\ 
    60646028         
    60656029 
    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 
     6032DEP_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"\ 
    61996039        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    62006040        "..\..\..\pjlib\include\pj\array.h"\ 
     
    62426082        "..\..\..\pjlib\include\pj\lock.h"\ 
    62436083        "..\..\..\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 
     6113DEP_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 
     6194DEP_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 
     6275DEP_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 
     6356DEP_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 
     6437DEP_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 
     6518DEP_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 
     6599DEP_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 
     6680DEP_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 
     6764SOURCE=..\..\src\pjnath\stun_transaction.c 
     6765 
     6766!IF  "$(CFG)" == "pjnath_wince - Win32 (WCE emulator) Release" 
     6767 
     6768DEP_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 
     6833DEP_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 
     6904DEP_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 
     6969DEP_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 
     7034DEP_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"\ 
    62447082        "..\..\..\pjlib\include\pj\os.h"\ 
    62457083        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    69277765        "..\..\..\pjlib-util\include\pjlib-util\srv_resolver.h"\ 
    69287766        "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 
     7767        "..\..\..\pjlib\include\pj\activesock.h"\ 
    69297768        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    69307769        "..\..\..\pjlib\include\pj\array.h"\ 
     
    69727811        "..\..\..\pjlib\include\pj\lock.h"\ 
    69737812        "..\..\..\pjlib\include\pj\log.h"\ 
     7813        "..\..\..\pjlib\include\pj\math.h"\ 
    69747814        "..\..\..\pjlib\include\pj\os.h"\ 
    69757815        "..\..\..\pjlib\include\pj\pool.h"\ 
     
    77198559        "..\..\..\pjlib-util\include\pjlib-util\resolver.h"\ 
    77208560        "..\..\..\pjlib-util\include\pjlib-util\types.h"\ 
     8561        "..\..\..\pjlib\include\pj\activesock.h"\ 
    77218562        "..\..\..\pjlib\include\pj\addr_resolv.h"\ 
    77228563        "..\..\..\pjlib\include\pj\array.h"\ 
     
    77648605        "..\..\..\pjlib\include\pj\lock.h"\ 
    77658606        "..\..\..\pjlib\include\pj\log.h"\ 
     8607        "..\..\..\pjlib\include\pj\math.h"\ 
    77668608        "..\..\..\pjlib\include\pj\os.h"\ 
    77678609        "..\..\..\pjlib\include\pj\pool.h"\ 
  • pjproject/trunk/pjnath/include/pjnath.h

    r1913 r1988  
    2727#include <pjnath/stun_msg.h> 
    2828#include <pjnath/stun_session.h> 
     29#include <pjnath/stun_sock.h> 
    2930#include <pjnath/stun_transaction.h> 
    3031#include <pjnath/turn_session.h> 
  • pjproject/trunk/pjnath/include/pjnath/config.h

    r1654 r1988  
    143143 
    144144/* ************************************************************************** 
     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/* ************************************************************************** 
    145223 * ICE CONFIGURATION 
    146224 */ 
  • pjproject/trunk/pjnath/include/pjnath/errno.h

    r1862 r1988  
    122122 
    123123 
     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 
    124133 
    125134/************************************************************ 
  • pjproject/trunk/pjnath/include/pjnath/ice_session.h

    r1654 r1988  
    130130 
    131131/** 
     132 * Forward declaration for checklist. 
     133 */ 
     134typedef struct pj_ice_sess_checklist pj_ice_sess_checklist; 
     135 
     136/** 
    132137 * This enumeration describes the type of an ICE candidate. 
    133138 */ 
     
    192197 
    193198} pj_ice_sess_comp; 
     199 
     200 
     201/** 
     202 * Data structure to be attached to internal message processing. 
     203 */ 
     204typedef 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; 
    194217 
    195218 
     
    205228{ 
    206229    /** 
     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    /** 
    207243     * The component ID of this candidate. Note that component IDs starts 
    208244     * with one for RTP and two for RTCP. In other words, it's not zero 
    209245     * based. 
    210246     */ 
    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; 
    217258 
    218259    /** 
     
    384425 * candidate pairs that an agent will use to generate checks. 
    385426 */ 
    386 typedef struct pj_ice_sess_checklist 
     427struct pj_ice_sess_checklist 
    387428{ 
    388429    /** 
     
    406447    pj_timer_entry           timer; 
    407448 
    408 } pj_ice_sess_checklist; 
     449}; 
    409450 
    410451 
     
    431472     * @param ice           The ICE session. 
    432473     * @param comp_id       ICE component ID. 
     474     * @param transport_id  Transport ID. 
    433475     * @param pkt           The STUN packet. 
    434476     * @param size          The size of the packet. 
     
    437479     */ 
    438480    pj_status_t (*on_tx_pkt)(pj_ice_sess *ice, unsigned comp_id,  
     481                             unsigned transport_id, 
    439482                             const void *pkt, pj_size_t size, 
    440483                             const pj_sockaddr_t *dst_addr, 
     
    447490     * @param ice           The ICE session. 
    448491     * @param comp_id       ICE component ID. 
     492     * @param transport_id  Transport ID. 
    449493     * @param pkt           The whole packet. 
    450494     * @param size          Size of the packet. 
     
    454498     */ 
    455499    void        (*on_rx_data)(pj_ice_sess *ice, unsigned comp_id, 
     500                              unsigned transport_id,  
    456501                              void *pkt, pj_size_t size, 
    457502                              const pj_sockaddr_t *src_addr, 
     
    497542 
    498543    unsigned             comp_id;       /**< Component ID.              */ 
     544    unsigned             transport_id;  /**< Transport ID.              */ 
    499545 
    500546    pj_sockaddr          src_addr;      /**< Source address of request  */ 
     
    553599    unsigned             rcand_cnt;                 /**< # of remote cand.  */ 
    554600    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]; 
    555604 
    556605    /* List of eearly checks */ 
     
    580629 */ 
    581630PJ_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 */ 
     641PJ_DECL(const char*) pj_ice_sess_role_name(pj_ice_sess_role role); 
    582642 
    583643 
     
    686746 * @param ice           ICE session instance. 
    687747 * @param comp_id       Component ID of this candidate. 
     748 * @param transport_id  Transport ID to be used to send packets for this 
     749 *                      candidate. 
    688750 * @param type          Candidate type. 
    689751 * @param local_pref    Local preference for this candidate, which 
     
    700762PJ_DECL(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, 
    701763                                          unsigned comp_id, 
     764                                          unsigned transport_id, 
    702765                                          pj_ice_cand_type type, 
    703766                                          pj_uint16_t local_pref, 
     
    798861 * @param ice           The ICE session. 
    799862 * @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. 
    800866 * @param pkt           Incoming packet. 
    801867 * @param pkt_size      Size of incoming packet. 
     
    807873PJ_DECL(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 
    808874                                           unsigned comp_id, 
     875                                           unsigned transport_id, 
    809876                                           void *pkt, 
    810877                                           pj_size_t pkt_size, 
  • pjproject/trunk/pjnath/include/pjnath/ice_strans.h

    r1487 r1988  
    2626 */ 
    2727#include <pjnath/ice_session.h> 
     28#include <pjnath/stun_sock.h> 
     29#include <pjnath/turn_sock.h> 
    2830#include <pjlib-util/resolver.h> 
    2931#include <pj/ioqueue.h> 
     
    4547 * 
    4648 * ICE stream transport, as represented by #pj_ice_strans structure, is an ICE 
    47  * capable component for transporting media streams within a media session.  
     49 * capable class for transporting media streams within a media session.  
    4850 * It consists of one or more transport sockets (typically two for RTP 
    4951 * based communication - one for RTP and one for RTCP), and an  
     
    5153 * various candidates of the transport addresses. 
    5254 * 
    53  * \section PJNATH_ICE_STREAM_TRANSPORT_USING Using the ICE Stream Transport 
    54  * 
    55  * Application may use the ICE stream transport in two ways: 
    56  *  - it can create the ICE stream transports once during application  
    57  *    initialization and keep them alive throughout application lifetime, or 
    58  *  - it can create and destroy the ICE stream transport as needed everytime  
    59  *     a call is made and destroyed.  
    60  * 
    61  * Keeping the ICE stream transport alive throughout 
    62  * application's lifetime is normally preferable, as initializing the 
    63  * ICE stream transport may incur delay because the ICE stream transport 
    64  * would need to communicate with the STUN/TURN server to get the 
    65  * server reflexive and relayed candidates for the transports. 
    66  * 
    67  * Regardless of which usage scenario is being used, the ICE stream 
    68  * transport is capable for restarting the ICE session being used and to 
    69  * send STUN keep-alives for its STUN server reflexive and relayed 
    70  * candidates. When ICE stream transport detects that the STUN mapped 
    71  * address has changed in the keep-alive response, it will automatically 
    72  * update its address to the new address, and notify the application via 
    73  * \a on_addr_change() function of the #pj_ice_strans_cb callback. 
    74  * 
    75  * \subsection PJNATH_ICE_ST_TRA_INIT Initialization 
    76  * 
    77  * Application creates the ICE stream transport by calling  
    78  * #pj_ice_strans_create() function. Among other things, application needs 
    79  * to specify: 
    80  *      - STUN configuration (pj_stun_config), containing STUN settings 
    81  *        such as timeout values and the instances of timer heap and 
    82  *        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 session 
    86  *        with some application's data structure. 
    87  *      - A callback (#pj_ice_strans_cb) to receive events from the ICE 
    88  *        stream transport. Two of the most important fields in this 
    89  *        callback structure are \a on_rx_data() to notify application 
    90  *        about incoming data (perhaps RTP or RTCP packet), and 
    91  *        \a on_ice_complete() to notify application that ICE negotiation 
    92  *        has completed, either successfully or with failure. 
    93  * 
    94  * After the ICE stream transport is created, application may set up the 
    95  * STUN servers to be used to obtain STUN server reflexive and relayed 
    96  * candidate, by calling #pj_ice_strans_set_stun_domain() or  
    97  * #pj_ice_strans_set_stun_srv(). 
    98  * 
    99  * Application then creates each component by calling  
    100  * #pj_ice_strans_create_comp(); this would create an actual socket 
    101  * which listens to the specified local address, and it would also 
    102  * perform lookup to find various transport address candidates for this 
    103  * socket. 
    104  * 
    105  * Adding component may involve contacting STUN and TURN servers to get 
    106  * STUN mapped address and allocate TURN relay channel, and this process 
    107  * may take some time to complete. Once application has added all 
    108  * components, it can check whether server reflexive and relayed  
    109  * candidates have been acquired, by calling #pj_ice_strans_get_comps_status(). 
    110  *  
    111  * \subsection PJNATH_ICE_ST_TRA_INIT_ICE Starting ICE Session 
    112  * 
    113  * When application is about to send an offer containing ICE capability, 
    114  * or when it receives an offer containing ICE capability, it would 
    115  * create the ICE session by calling #pj_ice_strans_init_ice(). This would 
    116  * register all transport address aliases for each component to the ICE 
    117  * session as candidates. After this application can enumerate all local 
    118  * candidates by calling #pj_ice_strans_enum_cands(), and encode these 
    119  * candidates in the SDP to be sent to remote agent. 
    120  * 
    121  * \subsection PJNATH_ICE_ST_TRA_START Starting Connectivity Checks 
    122  * 
    123  * Once application receives the SDP from remote, it pairs local candidates 
    124  * with remote candidates, and can start ICE connectivity checks. This is 
    125  * done by calling #pj_ice_strans_start_ice(), specifying 
    126  * the remote candidate list, and remote username and password. If the 
    127  * pairing process is successful, ICE connectivity checks will begin 
    128  * immediately. The ICE session/transport will then notify the application  
    129  * via the callback when ICE connectivity checks completes, either  
    130  * successfully or with failure. 
    131  * 
    132  * \subsection PJNATH_ICE_ST_TRA_SEND_RECV Sending and Receiving Data 
    133  * 
    134  * Application can send data (normally RTP or RTCP packets) at any time 
    135  * by calling #pj_ice_strans_sendto(). This function takes a destination 
    136  * address as one of the arguments, and this destination address should 
    137  * be taken from the default transport address of the component (that is 
    138  * 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 data  
    140  * to the destination address. Otherwise if ICE negotiation has completed 
    141  * successfully, this function will send the data to the nominated remote  
    142  * address, as negotiated by ICE. 
    143  * 
    144  * Upon receiving incoming data (that is a non-STUN  message), the ICE 
    145  * 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 Session 
    149  * 
    150  * Once the call is terminated, application no longer needs to keep the 
    151  * ICE session, so it should call #pj_ice_strans_stop_ice() to destroy the 
    152  * ICE session within this ICE stream transport. Note that this WILL NOT 
    153  * destroy the sockets/transports, it only destroys the ICE session 
    154  * within this ICE stream transport. It is recommended that application  
    155  * retains the ICE stream transport to speed up the process of setting up 
    156  * the next call. The ICE stream transport will continue to send STUN  
    157  * keep-alive packets to keep the NAT binding open and to detect change  
    158  * in STUN mapped address. 
    159  * 
    160  * \subsection PJNATH_ICE_ST_TRA_RESTART Restarting ICE Session 
    161  * 
    162  * When a new call is made, application can repeat the above 
    163  * #pj_ice_strans_init_ice() to #pj_ice_strans_stop_ice() cycle for  
    164  * the new call, using this same ICE stream transport. 
    165  * 
    166  * \subsection PJNATH_ICE_ST_TRA_DESTROY Destroying ICE Stream Transport 
    167  * 
    168  * Finally, when the ICE stream transport itself is no longer needed, 
    169  * for example when the application quits, application should call 
    170  * #pj_ice_strans_destroy() to release back all resources allocated by this 
    171  * ICE stream transport. 
    172  * 
    17355 */ 
    17456 
    17557/** Forward declaration for ICE stream transport. */ 
    17658typedef struct pj_ice_strans pj_ice_strans; 
     59 
     60/** Transport operation types to be reported on \a on_status() callback */ 
     61typedef 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; 
    17770 
    17871/**  
     
    20194 
    20295    /** 
    203      * This callback will be called when ICE checks have completed. 
    204      * This callback is optional. 
     96     * Callback to report status. 
    20597     *  
    20698     * @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. 
    208101     */ 
    209102    void    (*on_ice_complete)(pj_ice_strans *ice_st,  
     103                               pj_ice_strans_op op, 
    210104                               pj_status_t status); 
    211105 
    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 */ 
     114typedef 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. 
    215126     * 
    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. 
    258135     * 
    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 */ 
     269PJ_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 */ 
     279PJ_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 * 
    391288 * @param name          Optional name for logging identification. 
     289 * @param cfg           Configuration. 
    392290 * @param comp_cnt      Number of components. 
    393291 * @param user_data     Arbitrary user data to be associated with this 
     
    400298 *                      successfully. 
    401299 */ 
    402 PJ_DECL(pj_status_t) pj_ice_strans_create(pj_stun_config *stun_cfg, 
    403                                           const char *name, 
     300PJ_DECL(pj_status_t) pj_ice_strans_create(const char *name, 
     301                                          const pj_ice_strans_cfg *cfg, 
    404302                                          unsigned comp_cnt, 
    405303                                          void *user_data, 
     
    420318 
    421319/** 
    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 */ 
     326PJ_DECL(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st); 
     327 
    546328 
    547329/** 
    548330 * 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. 
    549338 * 
    550339 * @param ice_st        The ICE stream transport. 
     
    561350 
    562351/** 
    563  * Enumerate the local candidates. This function can only be called 
    564  * 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. 
    567356 * @param count         On input, it specifies the maximum number of 
    568357 *                      elements. On output, it will be filled with 
     
    574363 */ 
    575364PJ_DECL(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st, 
     365                                              unsigned comp_id, 
    576366                                              unsigned *count, 
    577367                                              pj_ice_sess_cand cand[]); 
    578368 
    579369/** 
     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 */ 
     381PJ_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 */ 
     393PJ_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 */ 
     408PJ_DECL(pj_status_t) pj_ice_strans_change_role(pj_ice_strans *ice_st, 
     409                                               pj_ice_sess_role new_role); 
     410 
     411 
     412/** 
    580413 * 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. 
    588423 * 
    589424 * @param ice_st        The ICE stream transport. 
     
    592427 * @param rem_passwd    Remote password, as seen in the SDP received from 
    593428 *                      the remote agent. 
    594  * @param rem_cand_cnt  Number of remote candidates. 
    595  * @param rem_cand      Remote candidate array. 
     429 * @param rcand_cnt     Number of remote candidates in the array. 
     430 * @param rcand         Remote candidates array. 
    596431 * 
    597432 * @return              PJ_SUCCESS, or the appropriate error code. 
    598433 */ 
    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. 
     434PJ_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 */ 
     451PJ_DECL(const pj_ice_sess_check*)  
     452pj_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. 
    608472 * 
    609473 * @param ice_st        The ICE stream transport. 
     
    615479 
    616480/** 
    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. 
    622491 * 
    623492 * @param ice_st        The ICE stream transport. 
  • pjproject/trunk/pjnath/include/pjnath/nat_detect.h

    r1501 r1988  
    3333 * @defgroup PJNATH_NAT_DETECT NAT Classification/Detection Tool 
    3434 * @brief NAT Classification/Detection Tool 
    35  * @ingroup PJNATH_ICE 
    3635 * @{ 
    3736 * 
  • pjproject/trunk/pjnath/include/pjnath/stun_config.h

    r1374 r1988  
    2626 
    2727#include <pjnath/stun_msg.h> 
     28#include <pj/assert.h> 
     29#include <pj/errno.h> 
    2830#include <pj/string.h> 
    2931 
     
    104106 
    105107/** 
     108 * Check that STUN config is valid. 
     109 */ 
     110PJ_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/** 
    106119 * @} 
    107120 */ 
  • pjproject/trunk/pjnath/include/pjnath/stun_msg.h

    r1924 r1988  
    3535/** 
    3636 * @defgroup PJNATH_STUN_MSG STUN Message Representation and Parsing 
     37 * @ingroup PJNATH_STUN 
    3738 * @brief Low-level representation and parsing of STUN messages. 
    38  * @ingroup PJNATH_STUN 
    3939 * @{ 
    4040 */ 
     
    956956 * This describes the TURN REQUESTED-PROPS attribute, encoded as 
    957957 * 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(). 
    961960 *  
    962961 * This attribute allows the client to request certain properties for 
     
    11651164     * #pj_stun_msg_check() and #pj_stun_msg_decode() to disable the  
    11661165     * 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. 
    11681167     */ 
    11691168    PJ_STUN_NO_FINGERPRINT_CHECK = 8 
     
    12931292 * 
    12941293 * If application wants to apply credential to the message, it MUST 
    1295  * include a blank MESSAGE-INTEGRITY attribute in the message, as the 
     1294 * include a blank MESSAGE-INTEGRITY attribute in the message as the 
    12961295 * last attribute or the attribute before FINGERPRINT. This function will 
    12971296 * calculate the HMAC digest from the message using  the supplied key in 
     
    13211320PJ_DECL(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg, 
    13221321                                        pj_uint8_t *pkt_buf, 
    1323                                         unsigned buf_size, 
     1322                                        pj_size_t buf_size, 
    13241323                                        unsigned options, 
    13251324                                        const pj_str_t *key, 
    1326                                         unsigned *p_msg_len); 
     1325                                        pj_size_t *p_msg_len); 
    13271326 
    13281327/** 
     
    13461345 */ 
    13471346PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu,  
    1348                                        unsigned pdu_len, unsigned options); 
     1347                                       pj_size_t pdu_len, unsigned options); 
    13491348 
    13501349 
     
    13721371PJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, 
    13731372                                        const pj_uint8_t *pdu, 
    1374                                         unsigned pdu_len, 
     1373                                        pj_size_t pdu_len, 
    13751374                                        unsigned options, 
    13761375                                        pj_stun_msg **p_msg, 
    1377                                         unsigned *p_parsed_len, 
     1376                                        pj_size_t *p_parsed_len, 
    13781377                                        pj_stun_msg **p_response); 
    13791378 
  • pjproject/trunk/pjnath/include/pjnath/stun_session.h

    r1913 r1988  
    214214struct pj_stun_tx_data 
    215215{ 
     216    /** PJLIB list interface */ 
    216217    PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data); 
    217218 
     
    238239    pj_timer_entry       res_timer;     /**< Response cache timer.          */ 
    239240}; 
     241 
     242 
     243/** 
     244 * These are the flags to control the message logging in the STUN session. 
     245 */ 
     246typedef 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; 
    240256 
    241257 
     
    259275 
    260276/** 
    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. 
    266287 */ 
    267288PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess); 
     
    334355                                                pj_stun_auth_type auth_type, 
    335356                                                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 */ 
     363PJ_DECL(void) pj_stun_session_set_log(pj_stun_session *sess, 
     364                                      unsigned flags); 
    336365 
    337366/** 
     
    382411 * 
    383412 * @param sess      The STUN session instance. 
    384  * @param req       The STUN request where the response is to be created. 
     413 * @param rdata     The STUN request where the response is to be created. 
    385414 * @param err_code  Error code to be set in the response, if error response 
    386415 *                  is to be created, according to pj_stun_status enumeration. 
     
    433462 * 
    434463 * @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. 
    435467 */ 
    436468PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess, 
     
    450482 * @param sess      The STUN session instance. 
    451483 * @param rdata     The STUN request message to be responded. 
    452  * @param err_code  Error code to be set in the response, if error response 
     484 * @param code      Error code to be set in the response, if error response 
    453485 *                  is to be created, according to pj_stun_status enumeration. 
    454486 *                  This argument MUST be zero if successful response is 
     
    473505 * 
    474506 * @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. 
    475510 */ 
    476511PJ_DECL(pj_status_t) pj_stun_session_respond(pj_stun_session *sess,  
     
    497532 * 
    498533 * @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. 
    499537 */ 
    500538PJ_DECL(pj_status_t) pj_stun_session_cancel_req(pj_stun_session *sess, 
     
    512550 * 
    513551 * @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. 
    514555 */ 
    515556PJ_DECL(pj_status_t) pj_stun_session_retransmit_req(pj_stun_session *sess, 
     
    549590 * 
    550591 * @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. 
    551595 */ 
    552596PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, 
  • pjproject/trunk/pjnath/include/pjnath/stun_transaction.h

    r1374 r1988  
    9090     * 
    9191     * @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. 
    9395     */ 
    9496    pj_status_t (*on_send_msg)(pj_stun_client_tsx *tsx, 
     
    162164 * @param tsx           The STUN transaction. 
    163165 * 
    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. 
    165168 */ 
    166169PJ_DECL(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx); 
     
    215218 * @param pkt_len       Length of STUN packet. 
    216219 * 
    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. 
    218224 */ 
    219225PJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx, 
     
    229235 * @param tsx           The STUN client transaction instance. 
    230236 * 
    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. 
    232241 */ 
    233242PJ_DECL(pj_status_t) pj_stun_client_tsx_retransmit(pj_stun_client_tsx *tsx); 
  • pjproject/trunk/pjnath/include/pjnath/turn_session.h

    r1914 r1988  
    3030PJ_BEGIN_DECL 
    3131 
     32/** 
     33 * @defgroup PJNATH_TURN TURN Client Library 
     34 */ 
     35 
     36 
    3237/* **************************************************************************/ 
    3338/** 
    34  * @defgroup PJNATH_TURN_SESSION TURN client session 
     39 * @defgroup PJNATH_TURN_SESSION Transport independent TURN client session 
    3540 * @brief Transport independent TURN client session 
    36  * @ingroup PJNATH_STUN 
     41 * @ingroup PJNATH_TURN 
    3742 * @{ 
     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. 
    3851 */ 
    3952 
     
    4255 */ 
    4356typedef struct pj_turn_session pj_turn_session; 
    44  
    45  
    46 #define PJ_TURN_INVALID_CHANNEL     0xFFFF 
    47 #define PJ_TURN_CHANNEL_MIN         0x4000 
    48 #define PJ_TURN_CHANNEL_MAX         0xFFFE  /* inclusive */ 
    49 #define PJ_TURN_NO_TIMEOUT          ((long)0x7FFFFFFF) 
    50 #define PJ_TURN_MAX_PKT_LEN         3000 
    51 #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  60 
    54 #define PJ_TURN_KEEP_ALIVE_SEC      15 
    55 #define PJ_TURN_PEER_HTABLE_SIZE    8 
    5657 
    5758 
     
    134135 
    135136 
    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 */ 
    137143typedef struct pj_turn_channel_data 
    138144{ 
    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.    */ 
    141147} pj_turn_channel_data; 
    142148 
     149 
     150#pragma pack() 
    143151 
    144152 
     
    152160     * needs to send outgoing message. Since the TURN session doesn't 
    153161     * 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.  
    154171     */ 
    155172    pj_status_t (*on_send_pkt)(pj_turn_session *sess, 
     
    157174                               unsigned pkt_len, 
    158175                               const pj_sockaddr_t *dst_addr, 
    159                                unsigned dst_addr_len); 
     176                               unsigned addr_len); 
    160177 
    161178    /** 
     
    163180     * a channel number. 
    164181     * 
    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. 
    166189     */ 
    167190    void (*on_channel_bound)(pj_turn_session *sess, 
     
    174197     * Data indication or ChannelData message from the TURN server. 
    175198     * 
    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. 
    177206     */ 
    178207    void (*on_rx_data)(pj_turn_session *sess, 
    179                        const pj_uint8_t *pkt, 
     208                       void *pkt, 
    180209                       unsigned pkt_len, 
    181210                       const pj_sockaddr_t *peer_addr, 
     
    186215     * implement this callback at least to know that the TURN session is 
    187216     * 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, 
    190224                     pj_turn_state_t new_state); 
    191225 
     
    194228 
    195229/** 
    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. 
    197234 */ 
    198235typedef struct pj_turn_alloc_param 
    199236{ 
     237    /** 
     238     * The requested BANDWIDTH. Default is zero to not request any 
     239     * specific bandwidth. 
     240     */ 
    200241    int     bandwidth; 
     242 
     243    /** 
     244     * The requested LIFETIME. Default is zero to not request any 
     245     * explicit allocation lifetime. 
     246     */ 
    201247    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     */ 
    202254    int     ka_interval; 
     255 
    203256} pj_turn_alloc_param; 
    204257 
    205258 
    206259/** 
    207  * TURN session info. 
     260 * This structure describes TURN session info. 
    208261 */ 
    209262typedef struct pj_turn_session_info 
     
    215268 
    216269    /** 
     270     * Last error (if session was terminated because of error) 
     271     */ 
     272    pj_status_t     last_status; 
     273 
     274    /** 
    217275     * Type of connection to the TURN server. 
    218276     */ 
    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; 
    220288 
    221289    /** 
     
    225293 
    226294    /** 
    227      * The selected TURN server address. 
    228      */ 
    229     pj_sockaddr     server; 
    230  
    231     /** 
    232295     * Current seconds before allocation expires. 
    233296     */ 
     
    238301 
    239302/** 
    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. 
    241306 */ 
    242307PJ_DECL(void) pj_turn_alloc_param_default(pj_turn_alloc_param *prm); 
    243308 
     309 
    244310/** 
    245311 * 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. 
    246316 */ 
    247317PJ_DECL(void) pj_turn_alloc_param_copy(pj_pool_t *pool,  
     
    250320 
    251321/** 
    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. 
    253327 */ 
    254328PJ_DECL(const char*) pj_turn_state_name(pj_turn_state_t state); 
     
    256330 
    257331/** 
    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 */ 
     354PJ_DECL(pj_status_t) pj_turn_session_create(const pj_stun_config *cfg, 
    261355                                            const char *name, 
    262356                                            int af, 
    263357                                            pj_turn_tp_type conn_type, 
    264358                                            const pj_turn_session_cb *cb, 
     359                                            unsigned options, 
    265360                                            void *user_data, 
    266                                             unsigned options, 
    267361                                            pj_turn_session **p_sess); 
    268362 
    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. 
    272371 */ 
    273372PJ_DECL(pj_status_t) pj_turn_session_shutdown(pj_turn_session *sess); 
     
    275374 
    276375/** 
    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. 
    278384 */ 
    279385PJ_DECL(pj_status_t) pj_turn_session_destroy(pj_turn_session *sess); 
     
    281387 
    282388/** 
    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. 
    284398 */ 
    285399PJ_DECL(pj_status_t) pj_turn_session_get_info(pj_turn_session *sess, 
     
    287401 
    288402/** 
    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. 
    290411 */ 
    291412PJ_DECL(pj_status_t) pj_turn_session_set_user_data(pj_turn_session *sess, 
     
    293414 
    294415/** 
    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. 
    296422 */ 
    297423PJ_DECL(void*) pj_turn_session_get_user_data(pj_turn_session *sess); 
    298424 
    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 */ 
     432PJ_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. 
    301470 */ 
    302471PJ_DECL(pj_status_t) pj_turn_session_set_server(pj_turn_session *sess, 
     
    307476 
    308477/** 
    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. 
    310487 */ 
    311488PJ_DECL(pj_status_t) pj_turn_session_set_credential(pj_turn_session *sess, 
     
    314491 
    315492/** 
    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. 
    317513 */ 
    318514PJ_DECL(pj_status_t) pj_turn_session_alloc(pj_turn_session *sess, 
     
    321517 
    322518/** 
    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. 
    324540 */ 
    325541PJ_DECL(pj_status_t) pj_turn_session_sendto(pj_turn_session *sess, 
    326542                                            const pj_uint8_t *pkt, 
    327543                                            unsigned pkt_len, 
    328                                             const pj_sockaddr_t *addr, 
     544                                            const pj_sockaddr_t *peer_addr, 
    329545                                            unsigned addr_len); 
    330546 
    331547/** 
    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. 
    333565 */ 
    334566PJ_DECL(pj_status_t) pj_turn_session_bind_channel(pj_turn_session *sess, 
     
    337569 
    338570/** 
    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; 
    341588 */ 
    342589PJ_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); 
    346592 
    347593 
  • pjproject/trunk/pjnath/include/pjnath/turn_sock.h

    r1913 r1988  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
    1818 */ 
    19 #ifndef __PJNATH_turn_sock_H__ 
    20 #define __PJNATH_turn_sock_H__ 
     19#ifndef __PJNATH_TURN_SOCK_H__ 
     20#define __PJNATH_TURN_SOCK_H__ 
    2121 
    2222/** 
     
    3232/* **************************************************************************/ 
    3333/** 
    34  * @defgroup PJNATH_TURN_UDP TURN TCP client 
    35  * @brief TURN relay using TCP client as transport protocol 
    36  * @ingroup PJNATH_STUN 
     34 * @defgroup PJNATH_TURN_SOCK TURN client transport 
     35 * @brief Client transport utilizing TURN relay 
     36 * @ingroup PJNATH_TURN 
    3737 * @{ 
     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. 
    3845 */ 
    3946 
    4047 
    4148/**  
    42  * Opaque declaration for TURN TCP client. 
     49 * Opaque declaration for TURN client. 
    4350 */ 
    4451typedef struct pj_turn_sock pj_turn_sock; 
    4552 
    46  
     53/** 
     54 * This structure contains callbacks that will be called by the TURN 
     55 * transport. 
     56 */ 
    4757typedef struct pj_turn_sock_cb 
    4858{ 
    4959    /** 
    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). 
    5265     * 
    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. 
    5471     */ 
    5572    void (*on_rx_data)(pj_turn_sock *turn_sock, 
    56                        const pj_uint8_t *pkt, 
     73                       void *pkt, 
    5774                       unsigned pkt_len, 
    5875                       const pj_sockaddr_t *peer_addr, 
     
    6178    /** 
    6279     * 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. 
    6585     */ 
    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, 
    6788                     pj_turn_state_t new_state); 
    6889 
     
    7192 
    7293/** 
    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. 
    74115 */ 
    75116PJ_DECL(pj_status_t) pj_turn_sock_create(pj_stun_config *cfg, 
     
    82123 
    83124/** 
    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. 
    85132 */ 
    86133PJ_DECL(void) pj_turn_sock_destroy(pj_turn_sock *turn_sock); 
    87134 
    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. 
    90145 */ 
    91146PJ_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. 
    96156 */ 
    97157PJ_DECL(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock); 
     
    99159 
    100160/** 
    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. 
    102169 */ 
    103170PJ_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 */ 
     183PJ_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 */ 
     194PJ_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 */ 
     204PJ_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 */ 
     242PJ_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. 
    118267 */  
    119268PJ_DECL(pj_status_t) pj_turn_sock_sendto(pj_turn_sock *turn_sock, 
    120269                                        const pj_uint8_t *pkt, 
    121270                                        unsigned pkt_len, 
    122                                         const pj_sockaddr_t *addr, 
     271                                        const pj_sockaddr_t *peer_addr, 
    123272                                        unsigned addr_len); 
    124273 
    125274/** 
    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. 
    127289 */ 
    128290PJ_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); 
    131293 
    132294 
     
    139301 
    140302 
    141 #endif  /* __PJNATH_turn_sock_H__ */ 
    142  
     303#endif  /* __PJNATH_TURN_SOCK_H__ */ 
     304 
  • pjproject/trunk/pjnath/include/pjnath/types.h

    r1914 r1988  
    3636 
    3737/** 
     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/** 
    3845 * Initialize pjnath library. 
    3946 * 
     
    4451 
    4552/** 
    46  * Display error to the log. 
     53 * Display error to the log.  
    4754 * 
    4855 * @param sender    The sender name. 
     
    6875 
    6976/** 
    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 
     81This is the documentation of PJNATH, an Open Source library providing 
     82NAT traversal helper functionalities by using standard based protocols 
     83such as STUN, TURN, and ICE. 
     84 
     85\n 
     86\n 
     87 
     88\section lib_comps Library Components 
     89 
     90\subsection comp_stun STUN 
     91 
     92Session Traversal Utilities (STUN, or previously known as Simple  
     93Traversal of User Datagram Protocol (UDP) Through Network Address  
     94Translators (NAT)s), is a lightweight protocol that serves as a tool for 
     95application protocols in dealing with NAT traversal. It allows a client 
     96to determine the IP address and port allocated to them by a NAT and to  
     97keep NAT bindings open. 
     98 
     99This 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 
     107Traversal Using Relays around NAT (TURN) allows the host to control the 
     108operation of the relay and to exchange packets with its peers using the relay. 
     109 
     110This version of PJNATH implements both TCP and UDP client transport and it 
     111complies 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 
     119Interactive Connectivity Establishment (ICE) is a standard based  
     120methodology for traversing Network Address Translator (NAT). This 
     121implementation is aimed to provide a usable and generic ICE transports 
     122for different types of application, including but not limited to 
     123the usage of ICE in SIP/SDP offer/answer. 
     124 
     125 
     126This 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 
     133The PJNATH library also provides NAT classification utility as  
     134described in <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>. 
     135While the practice to detect the NAT type to assist NAT traversal 
     136has been deprecated in favor of ICE, the information may still be 
     137useful for troubleshooting purposes, hence the utility is provided. 
     138 
     139 
     140\n 
     141\n 
     142 
     143\section lib_org Library Organization 
     144 
     145The PJNATH library consists of many components with each providing 
     146specific functionality that may or may not be of the interests of  
     147applications (or application developers). This section attempts to  
     148give brief overview on the components provided by PJNATH. 
     149 
     150The PJNATH components from the highest layer to the lower layer are 
     151as follows. 
     152 
     153 
     154\n 
     155 
     156\subsection user_comp High-level Transport Objects 
     157 
     158PJNATH library provides some high-level objects that may be used 
     159by applications: 
     160 
     161 
     162\subsubsection stun_sock STUN Transport 
     163 
     164The \ref PJNATH_STUN_SOCK provides asynchronous UDP like socket transport 
     165with the additional capability to query the publicly mapped transport 
     166address (using STUN resolution), to refresh the NAT binding, and to 
     167demultiplex internal STUN messages from application data (the  
     168application data may be a STUN message as well). 
     169 
     170 
     171\subsubsection turn_sock TURN Client Transport 
     172 
     173The \ref PJNATH_TURN_SOCK may be used by the application to send and 
     174receive data via TURN server. For more information please see the 
     175documentation of \ref PJNATH_TURN_SOCK. 
     176 
     177 
     178\subsubsection ice_strans ICE Stream Transport 
     179 
     180The \ref PJNATH_ICE_STREAM_TRANSPORT provides transport interface to 
     181send and receive data through connection that is negotiated 
     182with ICE protocol. The \ref PJNATH_ICE_STREAM_TRANSPORT naturally  
     183contains both STUN Transport and \ref PJNATH_TURN_SOCK. 
     184 
     185The \ref PJNATH_ICE_STREAM_TRANSPORT interface is suitable for both 
     186SIP or non-SIP use. For SIP use, application may prefer to use the 
     187ICE media transport in PJMEDIA instead where it has been integrated 
     188with the SDP offer and answer mechanism. 
     189 
     190 
     191\subsubsection natck NAT Classification Utility 
     192 
     193PJNATH also provides \a PJNATH_NAT_DETECT to assist troubleshooting 
     194of problems related to NAT traversal. 
     195 
     196 
     197 
     198\n 
     199 
     200 
     201\subsection sessions Transport Independent Sessions Layer 
     202 
     203Right below the high level transports objects are the transport 
     204independent sessions. These sessions don't have access to sockets, 
     205so higher level objects (such as transports) must give incoming 
     206packets to the sessions and provide callback to be called by 
     207sessions to send outgoing packets. 
     208 
     209 
     210\subsubsection ice_sess ICE Session 
     211 
     212The \ref PJNATH_ICE_SESSION is used by the \ref PJNATH_ICE_STREAM_TRANSPORT 
     213and contains the actual logic of the ICE negotiation. 
     214 
     215 
     216\subsubsection turn_sess TURN Session 
     217 
     218The \ref PJNATH_TURN_SESSION is used by the \ref PJNATH_TURN_SOCK 
     219and it contains TURN protocol logic. Implementors may implement 
     220other types of TURN client connection (such as TURN TLS client) 
     221by utilizing this session. 
     222 
     223 
     224\subsubsection stun_sess STUN Session 
     225 
     226The \ref PJNATH_STUN_SESSION manages STUN message exchange between 
     227a client and server (or vice versa). It manages \ref PJNATH_STUN_TRANSACTION 
     228for sending or receiving requests and \ref PJNATH_STUN_AUTH for both 
     229both incoming and outgoing STUN messages.  
     230 
     231The \ref PJNATH_STUN_SESSION is naturally used by the \ref PJNATH_TURN_SESSION 
     232and \ref PJNATH_ICE_SESSION 
     233 
     234 
     235\n 
     236 
     237\subsection stun_tsx STUN Transaction Layer 
     238 
     239The \ref PJNATH_STUN_TRANSACTION is a thin layer to manage retransmission 
     240of STUN requests. 
     241 
     242 
     243\n 
     244 
     245 
     246\subsection stun_msg STUN Messaging Layer 
     247 
     248At the very bottom of the PJNATH components is the \ref PJNATH_STUN_MSG 
     249layer. The API contains various representation of STUN messaging components 
     250and 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 
     260The following class diagram shows the interactions between objects in 
     261PJNATH: 
     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 
     274Some sample applications have been provided with PJNATH, and it's available 
     275under <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*/ 
    231287 
    232288/** 
  • pjproject/trunk/pjnath/src/pjnath-test/ice_test.c

    r1288 r1988  
    1818 */ 
    1919#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 
     22enum 
     23{ 
     24    NO  = 0, 
     25    YES = 1, 
     26    SRV = 3, 
    3627}; 
    3728 
    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 */ 
     35enum 
     36{ 
     37    WRONG_TURN  = 1, 
     38    DEL_ON_ERR  = 2, 
     39}; 
     40 
     41 
     42/* Test results */ 
     43struct 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 */ 
     52struct 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 */ 
     69struct 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 */ 
     80struct 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 
     94static 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); 
     99static void ice_on_ice_complete(pj_ice_strans *ice_st,  
     100                                pj_ice_strans_op op, 
     101                                pj_status_t status); 
     102static void destroy_sess(struct test_sess *sess, unsigned wait_msec); 
     103 
     104/* Create ICE stream transport */ 
     105static 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; 
    48183} 
    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 */ 
     186static 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 */ 
     259static 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 
     290static 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); 
    70300    PJ_UNUSED_ARG(src_addr); 
    71301    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]++; 
    72305} 
    73306 
    74307 
    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); 
     308static 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    } 
    86329} 
    87330 
    88331 
    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 */ 
     335static 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; 
    94339    pj_status_t status; 
    95340 
    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 */ 
     364static 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    } 
    107420 
    108421    return 0; 
     
    110423 
    111424 
    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 
     441static 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 
     576on_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; 
    171589    } 
    172590 
     
    174592} 
    175593 
    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 
     597int ice_test(void) 
     598{ 
     599    pj_pool_t *pool; 
     600    pj_stun_config stun_cfg; 
    238601    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    } 
    416869 
    417870on_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); 
    520872    pj_pool_release(pool); 
    521873    return rc; 
  • pjproject/trunk/pjnath/src/pjnath-test/sess_auth.c

    r1929 r1988  
    10991099    /* If REALM doesn't match, server must respond with 401 
    11001100     */ 
     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 
    11011106    rc = run_client_test("Invalid REALM (long term)",  // title 
    11021107                         PJ_TRUE,           // server responding 
     
    11171122        goto done; 
    11181123    } 
     1124#endif 
    11191125 
    11201126    /* Invalid HMAC */ 
  • pjproject/trunk/pjnath/src/pjnath-test/test.c

    r1877 r1988  
    3030} 
    3131 
     32pj_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 
     56void 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 
     68void 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 
     101void 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 
     111int 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, &current_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 
    32135#define DO_TEST(test)   do { \ 
    33136                            PJ_LOG(3, ("test", "Running %s...", #test));  \ 
     
    65168    pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 ); 
    66169 
     170    pjlib_util_init(); 
    67171    pjnath_init(); 
    68172 
     
    74178#if INCLUDE_ICE_TEST 
    75179    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()); 
    76188#endif 
    77189 
  • pjproject/trunk/pjnath/src/pjnath-test/test.h

    r1877 r1988  
    2323#define INCLUDE_STUN_TEST           1 
    2424#define INCLUDE_ICE_TEST            1 
     25#define INCLUDE_STUN_SOCK_TEST      1 
     26#define INCLUDE_TURN_SOCK_TEST      1 
    2527 
    2628int stun_test(void); 
    2729int sess_auth_test(void); 
     30int stun_sock_test(void); 
     31int turn_sock_test(void); 
    2832int ice_test(void); 
    2933int test_main(void); 
     
    3236extern pj_pool_factory *mem; 
    3337 
     38//////////////////////////////////// 
     39/* 
     40 * Utilities 
     41 */ 
     42pj_status_t create_stun_config(pj_pool_t *pool, pj_stun_config *stun_cfg); 
     43void destroy_stun_config(pj_stun_config *stun_cfg); 
     44 
     45void poll_events(pj_stun_config *stun_cfg, unsigned msec, 
     46                 pj_bool_t first_event_only); 
     47 
     48typedef 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 
     55void capture_pjlib_state(pj_stun_config *cfg, struct pjlib_state *st); 
     56int 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  
    5353    PJ_BUILD_ERR( PJNATH_ESTUNINSERVER,     "Invalid STUN server or server not configured"), 
    5454 
     55    PJ_BUILD_ERR( PJNATH_ESTUNDESTROYED,    "STUN object has been destoyed"), 
     56 
    5557    /* ICE related errors */ 
    5658    PJ_BUILD_ERR( PJNATH_ENOICE,            "ICE session not available"), 
  • pjproject/trunk/pjnath/src/pjnath/ice_session.c

    r1913 r1988  
    2222#include <pj/assert.h> 
    2323#include <pj/guid.h> 
     24#include <pj/hash.h> 
    2425#include <pj/log.h> 
    2526#include <pj/os.h> 
     
    100101    pj_ice_sess_checklist   *clist; 
    101102} timer_data; 
     103 
     104 
     105/* This is the data that will be attached as token to outgoing 
     106 * STUN messages. 
     107 */ 
    102108 
    103109 
     
    170176 
    171177 
     178PJ_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 
    172193/* Get the prefix for the foundation */ 
    173194static int get_type_prefix(pj_ice_cand_type type) 
     
    184205} 
    185206 
    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 */ 
    187213PJ_DEF(void) pj_ice_calc_foundation(pj_pool_t *pool, 
    188214                                    pj_str_t *foundation, 
     
    191217{ 
    192218    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    } 
    194227    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); 
    197229    pj_strdup2(pool, foundation, buf); 
    198230} 
     
    264296 
    265297    if (name == NULL) 
    266         name = "ice%p"; 
     298        name = "icess%p"; 
    267299 
    268300    pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_SESS,  
     
    299331            return status; 
    300332        } 
     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; 
    301339    } 
    302340 
     
    552590PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice, 
    553591                                         unsigned comp_id, 
     592                                         unsigned transport_id, 
    554593                                         pj_ice_cand_type type, 
    555594                                         pj_uint16_t local_pref, 
     
    577616 
    578617    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; 
    580620    lcand->type = type; 
    581621    pj_strdup(ice->pool, &lcand->foundation, foundation); 
     
    583623    pj_memcpy(&lcand->addr, addr, addr_len); 
    584624    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); 
    590626 
    591627    pj_ansi_strcpy(ice->tmp.txt, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); 
     
    13231359 
    13241360    /* 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; 
    13281368 
    13291369    /* Init timer entry in the checklist. Initially the timer ID is FALSE 
     
    13461386} 
    13471387 
    1348  
    1349 /* This is the data that will be attached as user data to outgoing 
    1350  * STUN requests, and it will be given back when we receive completion 
    1351  * status of the request. 
    1352  */ 
    1353 struct req_data 
    1354 { 
    1355     pj_ice_sess             *ice; 
    1356     pj_ice_sess_checklist   *clist; 
    1357     unsigned                 ckid; 
    1358 }; 
    1359  
    1360  
    13611388/* Perform check on the specified candidate pair */ 
    13621389static pj_status_t perform_check(pj_ice_sess *ice,  
     
    13651392{ 
    13661393    pj_ice_sess_comp *comp; 
    1367     struct req_data *rd; 
     1394    pj_ice_msg_data *msg_data; 
    13681395    pj_ice_sess_check *check; 
    13691396    const pj_ice_sess_cand *lcand; 
     
    13931420     * completes and on_stun_request_complete() callback is called. 
    13941421     */ 
    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; 
    13991428 
    14001429    /* Add PRIORITY */ 
     
    14281457 
    14291458    /* 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,  
    14311460                                      PJ_TRUE, &rcand->addr,  
    14321461                                      sizeof(pj_sockaddr_in), check->tdata); 
     
    16561685    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 
    16571686    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); 
    16641691} 
    16651692 
     
    16741701                                     unsigned src_addr_len) 
    16751702{ 
    1676     struct req_data *rd = (struct req_data*) token; 
     1703    pj_ice_msg_data *msg_data = (pj_ice_msg_data*) token; 
    16771704    pj_ice_sess *ice; 
    16781705    pj_ice_sess_check *check, *new_check; 
     
    16851712    PJ_UNUSED_ARG(src_addr_len); 
    16861713 
    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     
    16901720 
    16911721    /* Mark STUN transaction as complete */ 
     
    17401770            LOG4((ice->obj_name, "Resending check because of role conflict")); 
    17411771            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); 
    17431773            pj_mutex_unlock(ice->mutex); 
    17441774            return; 
     
    18471877        /* Add new peer reflexive candidate */ 
    18481878        status = pj_ice_sess_add_cand(ice, check->lcand->comp_id,  
     1879                                      msg_data->transport_id, 
    18491880                                      PJ_ICE_CAND_TYPE_PRFLX, 
    18501881                                      65535, &foundation, 
     
    19201951    stun_data *sd; 
    19211952    const pj_stun_msg *msg = rdata->msg; 
     1953    pj_ice_msg_data *msg_data; 
    19221954    pj_ice_sess *ice; 
    19231955    pj_stun_priority_attr *prio_attr; 
     
    19301962    PJ_UNUSED_ARG(pkt); 
    19311963    PJ_UNUSED_ARG(pkt_len); 
    1932     PJ_UNUSED_ARG(token); 
    1933  
     1964     
    19341965    /* Reject any requests except Binding request */ 
    19351966    if (msg->hdr.type != PJ_STUN_BINDING_REQUEST) { 
    19361967        pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,  
    1937                                 NULL, NULL, PJ_TRUE,  
     1968                                NULL, token, PJ_TRUE,  
    19381969                                src_addr, src_addr_len); 
    19391970        return PJ_SUCCESS; 
     
    20022033            /* Generate 487 response */ 
    20032034            pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT,  
    2004                                     NULL, NULL, PJ_TRUE,  
     2035                                    NULL, token, PJ_TRUE,  
    20052036                                    src_addr, src_addr_len); 
    20062037            pj_mutex_unlock(ice->mutex); 
     
    20142045            /* Generate 487 response */ 
    20152046            pj_stun_session_respond(sess, rdata, PJ_STUN_SC_ROLE_CONFLICT,  
    2016                                     NULL, NULL, PJ_TRUE,  
     2047                                    NULL, token, PJ_TRUE,  
    20172048                                    src_addr, src_addr_len); 
    20182049            pj_mutex_unlock(ice->mutex); 
     
    20352066    } 
    20362067 
     2068    /* Add XOR-MAPPED-ADDRESS attribute */ 
    20372069    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,  
    20382070                                           PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
    20392071                                           PJ_TRUE, src_addr, src_addr_len); 
    20402072 
    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, 
    20422080                                      src_addr, src_addr_len, tdata); 
    20432081 
     
    20592097    /* Init rcheck */ 
    20602098    rcheck->comp_id = sd->comp_id; 
     2099    rcheck->transport_id = ((pj_ice_msg_data*)token)->transport_id; 
    20612100    rcheck->src_addr_len = src_addr_len; 
    20622101    pj_memcpy(&rcheck->src_addr, src_addr, src_addr_len); 
     
    20912130    pj_ice_sess_cand *rcand; 
    20922131    unsigned i; 
    2093     pj_bool_t is_relayed; 
    20942132 
    20952133    comp = find_comp(ice, rcheck->comp_id); 
     
    21102148    if (i == ice->rcand_cnt) { 
    21112149        rcand = &ice->rcand[ice->rcand_cnt++]; 
    2112         rcand->comp_id = rcheck->comp_id; 
     2150        rcand->comp_id = (pj_uint8_t)rcheck->comp_id; 
    21132151        rcand->type = PJ_ICE_CAND_TYPE_PRFLX; 
    21142152        rcand->prio = rcheck->priority; 
     
    21482186    } 
    21492187#else 
    2150     /* Just get candidate with the highest priority for the specified  
    2151      * 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. 
    21522190     */ 
    21532191    for (i=0; i<ice->clist.count; ++i) { 
    21542192        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        { 
    21562196            lcand = c->lcand; 
    21572197            break; 
     
    21712211     * Create candidate pair for this request.  
    21722212     */ 
    2173     /* First check if the source address is the source address of the  
    2174      * 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; 
    21782213 
    21792214    /*  
     
    23102345    pj_status_t status = PJ_SUCCESS; 
    23112346    pj_ice_sess_comp *comp; 
     2347    pj_ice_sess_cand *cand; 
    23122348 
    23132349    PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL); 
     
    23332369    } 
    23342370 
    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,  
    23362374                                  &comp->valid_check->rcand->addr,  
    23372375                                  sizeof(pj_sockaddr_in)); 
     
    23452383PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 
    23462384                                          unsigned comp_id, 
     2385                                          unsigned transport_id, 
    23472386                                          void *pkt, 
    23482387                                          pj_size_t pkt_size, 
     
    23522391    pj_status_t status = PJ_SUCCESS; 
    23532392    pj_ice_sess_comp *comp; 
     2393    pj_ice_msg_data *msg_data = NULL; 
     2394    unsigned i; 
    23542395    pj_status_t stun_status; 
    23552396 
     
    23642405    } 
    23652406 
     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 
    23662420    stun_status = pj_stun_msg_check((const pj_uint8_t*)pkt, pkt_size,  
    23672421                                    PJ_STUN_IS_DATAGRAM); 
    23682422    if (stun_status == PJ_SUCCESS) { 
    23692423        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, 
    23712425                                           NULL, src_addr, src_addr_len); 
    23722426        if (status != PJ_SUCCESS) { 
     
    23762430        } 
    23772431    } 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,  
    23792433                              src_addr, src_addr_len); 
    23802434    } 
  • pjproject/trunk/pjnath/src/pjnath/ice_strans.c

    r1913 r1988  
    2020#include <pjnath/errno.h> 
    2121#include <pj/addr_resolv.h> 
     22#include <pj/array.h> 
    2223#include <pj/assert.h> 
    2324#include <pj/ip_helper.h> 
    2425#include <pj/log.h> 
     26#include <pj/os.h> 
    2527#include <pj/pool.h> 
    2628#include <pj/rand.h> 
     
    3638 
    3739 
     40/* Transport IDs */ 
     41enum 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 
    3853 
    3954/* ICE callbacks */ 
     
    4156static pj_status_t ice_tx_pkt(pj_ice_sess *ice,  
    4257                              unsigned comp_id, 
     58                              unsigned transport_id, 
    4359                              const void *pkt, pj_size_t size, 
    4460                              const pj_sockaddr_t *dst_addr, 
    4561                              unsigned dst_addr_len); 
    4662static 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. */ 
     72static 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. */ 
     78static 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. */ 
     82static 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 */ 
     88static 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); 
     93static 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 */ 
     99static void destroy_ice_st(pj_ice_strans *ice_st); 
    81100#define ice_st_perror(ice_st,msg,rc) pjnath_perror(ice_st->obj_name,msg,rc) 
     101static void sess_init_update(pj_ice_strans *ice_st); 
     102 
     103static void sess_add_ref(pj_ice_strans *ice_st); 
     104static 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 */ 
     117typedef 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 */ 
     136struct 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 */ 
     159static 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 */ 
     174PJ_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 */ 
     191PJ_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 */ 
     208static 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 
    82395 
    83396/*  
    84397 * Create ICE stream transport  
    85398 */ 
    86 PJ_DEF(pj_status_t) pj_ice_strans_create( pj_stun_config *stun_cfg, 
    87                                           const char *name, 
     399PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name, 
     400                                          const pj_ice_strans_cfg *cfg, 
    88401                                          unsigned comp_cnt, 
    89402                                          void *user_data, 
     
    93406    pj_pool_t *pool; 
    94407    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); 
    98416 
    99417    if (name == NULL) 
    100         name = "icstr%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, 
    103421                          PJNATH_POOL_INC_ICE_STRANS, NULL); 
    104422    ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans); 
    105423    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; 
    107425    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)); 
    108433     
     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 
    109440    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); 
    116454 
    117455    PJ_LOG(4,(ice_st->obj_name, "ICE stream transport created")); 
     
    122460 
    123461/* Destroy ICE */ 
    124 static void destroy_ice_st(pj_ice_strans *ice_st, pj_status_t reason) 
     462static void destroy_ice_st(pj_ice_strans *ice_st) 
    125463{ 
    126464    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); 
    136465 
    137466    /* Destroy ICE if we have ICE */ 
     
    144473    for (i=0; i<ice_st->comp_cnt; ++i) { 
    145474        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            } 
    148485        } 
    149486    } 
    150487    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    } 
    151495 
    152496    /* Done */ 
    153497    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 */ 
     501static 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 */ 
     519static 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); 
    158545} 
    159546 
     
    163550PJ_DEF(pj_status_t) pj_ice_strans_destroy(pj_ice_strans *ice_st) 
    164551{ 
    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")); 
    166567    return PJ_SUCCESS; 
    167568} 
    168569 
    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 */ 
     574static 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 */ 
     583static 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; 
    196590    } 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 */ 
     598PJ_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 
    823604 
    824605/* 
     
    833614    unsigned i; 
    834615    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 }; 
    836617 
    837618    /* Check arguments */ 
     
    849630 
    850631    /* 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, 
    852633                                ice_st->comp_cnt, &ice_cb,  
    853634                                local_ufrag, local_passwd, &ice_st->ice); 
     
    858639    ice_st->ice->user_data = (void*)ice_st; 
    859640 
     641#if 0 
    860642    /* If default candidate for components are SRFLX one, upload a custom 
    861643     * type priority to ICE session so that SRFLX candidates will get 
     
    868650        pj_ice_sess_set_prefs(ice_st->ice, srflx_prio); 
    869651    } 
    870  
    871  
    872     /* Add candidates */ 
     652#endif 
     653 
     654    /* Add components/candidates */ 
    873655    for (i=0; i<ice_st->comp_cnt; ++i) { 
    874656        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        } 
    876666 
    877667        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; 
    879670 
    880671            /* Skip if candidate is not ready */ 
    881672            if (cand->status != PJ_SUCCESS) { 
    882673                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)", 
    884675                          j, i)); 
    885676                continue; 
    886677            } 
    887678 
     679            /* Must have address */ 
     680            pj_assert(pj_sockaddr_has_addr(&cand->addr)); 
     681 
     682            /* Add the candidate */ 
    888683            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,  
    890686                                          &cand->foundation, &cand->addr,  
    891                                           &comp->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); 
    894690            if (status != PJ_SUCCESS) 
    895691                goto on_error; 
     
    908704 */ 
    909705PJ_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[]) 
    912709{ 
    913710    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; 
    920718    cnt = (cnt > *count) ? *count : cnt; 
    921     *count = 0; 
    922719 
    923720    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)); 
    926722    } 
    927723 
    928724    *count = cnt; 
    929725    return PJ_SUCCESS; 
     726} 
     727 
     728/* 
     729 * Get default candidate. 
     730 */ 
     731PJ_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 */ 
     755PJ_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 */ 
     764PJ_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); 
    930769} 
    931770 
     
    941780    pj_status_t status; 
    942781 
     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 */ 
    943789    status = pj_ice_sess_create_check_list(ice_st->ice, rem_ufrag, rem_passwd, 
    944790                                           rem_cand_cnt, rem_cand); 
     
    946792        return status; 
    947793 
     794    /* Start ICE negotiation! */ 
    948795    status = pj_ice_sess_start_check(ice_st->ice); 
    949796    if (status != PJ_SUCCESS) { 
     
    955802 
    956803/* 
     804 * Get valid pair. 
     805 */ 
     806PJ_DEF(const pj_ice_sess_check*)  
     807pj_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/* 
    957820 * Stop ICE! 
    958821 */ 
    959822PJ_DEF(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st) 
    960823{ 
    961     unsigned i; 
    962  
    963824    if (ice_st->ice) { 
    964825        pj_ice_sess_destroy(ice_st->ice); 
     
    966827    } 
    967828 
    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  
    976829    return PJ_SUCCESS; 
    977830} 
    978831 
    979832/* 
    980  * Send packet using non-ICE means (e.g. when ICE was not negotiated). 
     833 * Application wants to send outgoing packet. 
    981834 */ 
    982835PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st, 
     
    998851    /* If ICE is available, send data with ICE */ 
    999852    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; 
    1012871} 
    1013872 
     
    1019878{ 
    1020879    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 
    1021889    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); 
    1024953} 
    1025954 
     
    1029958static pj_status_t ice_tx_pkt(pj_ice_sess *ice,  
    1030959                              unsigned comp_id,  
     960                              unsigned transport_id, 
    1031961                              const void *pkt, pj_size_t size, 
    1032962                              const pj_sockaddr_t *dst_addr, 
     
    1034964{ 
    1035965    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; 
    1038967    pj_status_t status; 
    1039968 
    1040     PJ_TODO(TX_TO_RELAY); 
    1041  
    1042969    PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); 
     970 
    1043971    comp = ice_st->comp[comp_id-1]; 
    1044972 
    1045973    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,  
    1048976              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    } 
    1055996     
    1056997    return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 
     
    10621003static void ice_rx_data(pj_ice_sess *ice,  
    10631004                        unsigned comp_id,  
     1005                        unsigned transport_id, 
    10641006                        void *pkt, pj_size_t size, 
    10651007                        const pj_sockaddr_t *src_addr, 
     
    10681010    pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data; 
    10691011 
     1012    PJ_UNUSED_ARG(transport_id); 
     1013 
    10701014    if (ice_st->cb.on_rx_data) { 
    10711015        (*ice_st->cb.on_rx_data)(ice_st, comp_id, pkt, size,  
     
    10741018} 
    10751019 
    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 */ 
     1023static 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) 
    10851028{ 
    10861029    pj_ice_strans_comp *comp; 
    1087     pj_ssize_t pkt_size; 
     1030    pj_ice_strans *ice_st; 
    10881031    pj_status_t status; 
    10891032 
    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 */ 
     1067static 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. */ 
     1078static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,  
     1079                                pj_stun_sock_op op, 
     1080                                pj_status_t status) 
    11121081{ 
    11131082    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: 
    11301104        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 */ 
     1178static 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",  
    11321216                          status); 
    11331217        } 
     1218    } 
     1219 
     1220    sess_dec_ref(comp->ice_st); 
     1221} 
     1222 
     1223 
     1224/* Callback when TURN client state has changed */ 
     1225static 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         */ 
    11341235        return; 
    11351236    } 
    11361237 
    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; 
    11421269 
    11431270        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  
    15581558PJ_DEF(pj_status_t) pj_stun_msg_add_unknown_attr(pj_pool_t *pool, 
    15591559                                                 pj_stun_msg *msg, 
    1560                                                  unsigned attr_cnt, 
     1560                                                 pj_size_t attr_cnt, 
    15611561                                                 const pj_uint16_t attr_types[]) 
    15621562{ 
     
    16471647                                               int attr_type, 
    16481648                                               const pj_uint8_t *data, 
    1649                                                unsigned length, 
     1649                                               pj_size_t length, 
    16501650                                               pj_stun_binary_attr **p_attr) 
    16511651{ 
     
    16741674                                                int attr_type, 
    16751675                                                const pj_uint8_t *data, 
    1676                                                 unsigned length) 
     1676                                                pj_size_t length) 
    16771677{ 
    16781678    pj_stun_binary_attr *attr = NULL; 
     
    18341834 * Check that the PDU is potentially a valid STUN message. 
    18351835 */ 
    1836 PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsigned pdu_len, 
     1836PJ_DEF(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, pj_size_t pdu_len, 
    18371837                                      unsigned options) 
    18381838{ 
    1839     unsigned msg_len; 
     1839    pj_size_t msg_len; 
    18401840 
    18411841    PJ_ASSERT_RETURN(pdu, PJ_EINVAL); 
     
    19391939PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, 
    19401940                                       const pj_uint8_t *pdu, 
    1941                                        unsigned pdu_len, 
     1941                                       pj_size_t pdu_len, 
    19421942                                       unsigned options, 
    19431943                                       pj_stun_msg **p_msg, 
    1944                                        unsigned *p_parsed_len, 
     1944                                       pj_size_t *p_parsed_len, 
    19451945                                       pj_stun_msg **p_response) 
    19461946{ 
     
    21912191PJ_DEF(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg, 
    21922192                                       pj_uint8_t *buf, unsigned buf_size, 
    2193                                        unsigned options, 
     2193                                       pj_size_t options, 
    21942194                                       const pj_str_t *key, 
    2195                                        unsigned *p_msg_len) 
     2195                                       pj_size_t *p_msg_len) 
    21962196{ 
    21972197    pj_uint8_t *start = buf; 
  • pjproject/trunk/pjnath/src/pjnath/stun_session.c

    r1913 r1988  
    3030    void                *user_data; 
    3131 
     32    pj_atomic_t         *busy; 
     33    pj_bool_t            destroy_request; 
     34 
    3235    pj_bool_t            use_fingerprint; 
    3336 
     37    pj_pool_t           *rx_pool; 
     38 
     39#if PJ_LOG_MAX_LEVEL >= 5 
    3440    char                 dump_buf[1000]; 
     41#endif 
     42    unsigned             log_flag; 
    3543 
    3644    pj_stun_auth_type    auth_type; 
     
    3846    int                  auth_retry; 
    3947    pj_str_t             next_nonce; 
     48    pj_str_t             server_realm; 
    4049 
    4150    pj_str_t             srv_name; 
     
    8089                           pj_stun_tx_data *tdata) 
    8190{ 
    82     pj_list_push_back(&sess->pending_request_list, tdata); 
     91    pj_list_push_front(&sess->pending_request_list, tdata); 
    8392    return PJ_SUCCESS; 
    8493} 
     
    139148 
    140149    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 
     150    tsx_erase(tdata->sess, tdata); 
     151 
    141152    pj_stun_client_tsx_destroy(tsx); 
    142153    pj_pool_release(tdata->pool); 
    143154} 
    144155 
    145 static void destroy_tdata(pj_stun_tx_data *tdata) 
     156static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force) 
    146157{ 
    147158    if (tdata->res_timer.id != PJ_FALSE) { 
     
    152163    } 
    153164 
    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); 
    159171 
    160172    } 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        } 
    162180    } 
    163181} 
     
    170188{ 
    171189    PJ_UNUSED_ARG(sess); 
    172     destroy_tdata(tdata); 
     190    destroy_tdata(tdata, PJ_FALSE); 
    173191} 
    174192 
     
    290308    { 
    291309        const pj_stun_nonce_attr *anonce; 
     310        const pj_stun_realm_attr *arealm; 
    292311        pj_stun_tx_data *tdata; 
    293312        unsigned i; 
     
    317336        pj_strdup(sess->pool, &sess->next_nonce, &anonce->value); 
    318337 
     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 
    319345        /* Create new request */ 
    320346        status = pj_stun_session_create_req(sess, request->msg->hdr.type, 
     
    325351 
    326352        /* 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. 
    328355         */ 
    329356        for (i=0; i<request->msg->attr_count; ++i) { 
     
    374401    sess = tdata->sess; 
    375402 
     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 
    376407    /* Handle authentication challenge */ 
    377408    handle_auth_challenge(sess, tdata, response, src_addr, 
     
    388419    pj_stun_msg_destroy_tdata(sess, tdata); 
    389420    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    } 
    390428} 
    391429 
     
    395433{ 
    396434    pj_stun_tx_data *tdata; 
     435    pj_stun_session *sess; 
     436    pj_status_t status; 
    397437 
    398438    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    } 
    403456} 
    404457 
     
    429482    pj_memcpy(&sess->cb, cb, sizeof(*cb)); 
    430483    sess->use_fingerprint = fingerprint; 
     484    sess->log_flag = 0xFFFF; 
    431485     
    432486    sess->srv_name.ptr = (char*) pj_pool_alloc(pool, 32); 
     
    434488                                           "pj_stun-%s", pj_get_version()); 
    435489 
     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 
    436494    pj_list_init(&sess->pending_request_list); 
    437495    pj_list_init(&sess->cached_response_list); 
     
    444502    sess->delete_lock = PJ_TRUE; 
    445503 
     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 
    446511    *p_sess = sess; 
    447512 
     
    454519 
    455520    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 
    456529    while (!pj_list_empty(&sess->pending_request_list)) { 
    457530        pj_stun_tx_data *tdata = sess->pending_request_list.next; 
    458         destroy_tdata(tdata); 
    459     } 
     531        destroy_tdata(tdata, PJ_TRUE); 
     532    } 
     533 
    460534    while (!pj_list_empty(&sess->cached_response_list)) { 
    461535        pj_stun_tx_data *tdata = sess->cached_response_list.next; 
    462         destroy_tdata(tdata); 
     536        destroy_tdata(tdata, PJ_TRUE); 
    463537    } 
    464538    pj_lock_release(sess->lock); 
     
    466540    if (sess->delete_lock) { 
    467541        pj_lock_destroy(sess->lock); 
     542    } 
     543 
     544    if (sess->rx_pool) { 
     545        pj_pool_release(sess->rx_pool); 
     546        sess->rx_pool = NULL; 
    468547    } 
    469548 
     
    539618} 
    540619 
     620PJ_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} 
    541626 
    542627static pj_status_t get_auth(pj_stun_session *sess, 
     
    544629{ 
    545630    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; 
    547633        tdata->auth_info.username = sess->cred.data.static_cred.username; 
    548634        tdata->auth_info.nonce = sess->cred.data.static_cred.nonce; 
     
    634720            } 
    635721            tdata->auth_info.nonce = sess->next_nonce; 
     722            tdata->auth_info.realm = sess->server_realm; 
    636723        } 
    637724 
     
    715802                        unsigned pkt_size, const pj_sockaddr_t *addr) 
    716803{ 
    717     char dst_name[80]; 
     804    char dst_name[PJ_INET6_ADDRSTRLEN+10]; 
    718805     
     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 
    719816    pj_sockaddr_print(addr, dst_name, sizeof(dst_name), 3); 
    720817 
     
    750847    tdata->retransmit = retransmit; 
    751848 
    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); 
    753851    pj_lock_acquire(sess->lock); 
    754852 
     
    758856    if (status != PJ_SUCCESS) { 
    759857        pj_stun_msg_destroy_tdata(sess, tdata); 
    760         pj_lock_release(sess->lock); 
    761858        LOG_ERR_(sess, "Error applying options", status); 
    762         return status; 
     859        goto on_return; 
    763860    } 
    764861 
     
    770867    if (status != PJ_SUCCESS) { 
    771868        pj_stun_msg_destroy_tdata(sess, tdata); 
    772         pj_lock_release(sess->lock); 
    773869        LOG_ERR_(sess, "STUN encode() error", status); 
    774         return status; 
     870        goto on_return; 
    775871    } 
    776872 
     
    798894        if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
    799895            pj_stun_msg_destroy_tdata(sess, tdata); 
    800             pj_lock_release(sess->lock); 
    801896            LOG_ERR_(sess, "Error sending STUN request", status); 
    802             return status; 
     897            goto on_return; 
    803898        } 
    804899 
     
    825920                                            &timeout); 
    826921            if (status != PJ_SUCCESS) { 
     922                tdata->res_timer.id = PJ_FALSE; 
    827923                pj_stun_msg_destroy_tdata(sess, tdata); 
    828                 pj_lock_release(sess->lock); 
    829924                LOG_ERR_(sess, "Error scheduling response timer", status); 
    830                 return status; 
     925                goto on_return; 
    831926            } 
    832927 
     
    839934 
    840935        if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
     936            pj_stun_msg_destroy_tdata(sess, tdata); 
    841937            LOG_ERR_(sess, "Error sending STUN request", status); 
     938            goto on_return; 
    842939        } 
    843940 
     
    848945    } 
    849946 
    850  
     947on_return: 
    851948    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 
    852956    return status; 
    853957} 
     
    893997    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL); 
    894998 
     999    /* Lock the session and prevent user from destroying us in the callback */ 
     1000    pj_atomic_inc(sess->busy); 
    8951001    pj_lock_acquire(sess->lock); 
    8961002 
     
    9041010 
    9051011    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 
    9061018    return PJ_SUCCESS; 
    9071019} 
     
    9181030    PJ_ASSERT_RETURN(PJ_STUN_IS_REQUEST(tdata->msg->hdr.type), PJ_EINVAL); 
    9191031 
     1032    /* Lock the session and prevent user from destroying us in the callback */ 
     1033    pj_atomic_inc(sess->busy); 
    9201034    pj_lock_acquire(sess->lock); 
    9211035 
     
    9231037 
    9241038    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    } 
    9251044 
    9261045    return status; 
     
    11661285 
    11671286 
     1287/* Print outgoing message to log */ 
     1288static 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 */ 
    11681317PJ_DEF(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, 
    11691318                                              const void *packet, 
     
    11761325{ 
    11771326    pj_stun_msg *msg, *response; 
    1178     pj_pool_t *tmp_pool; 
    1179     char *dump; 
    11801327    pj_status_t status; 
    11811328 
    11821329    PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL); 
    11831330 
    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); 
    11891337 
    11901338    /* 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, 
    11921340                                pkt_size, options,  
    11931341                                &msg, parsed_len, &response); 
     
    11951343        LOG_ERR_(sess, "STUN msg_decode() error", status); 
    11961344        if (response) { 
    1197             send_response(sess, token, tmp_pool, response, NULL, 
     1345            send_response(sess, token, sess->rx_pool, response, NULL, 
    11981346                          PJ_FALSE, src_addr, src_addr_len); 
    11991347        } 
    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); 
    12161352 
    12171353    /* 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,  
    12191355                                   src_addr, src_addr_len); 
    12201356    if (status == PJ_SUCCESS) { 
     
    12321368    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 
    12331369 
    1234         status = on_incoming_request(sess, options, token, tmp_pool,  
     1370        status = on_incoming_request(sess, options, token, sess->rx_pool,  
    12351371                                     (const pj_uint8_t*) packet, pkt_size,  
    12361372                                     msg, src_addr, src_addr_len); 
     
    12381374    } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) { 
    12391375 
    1240         status = on_incoming_indication(sess, token, tmp_pool,  
     1376        status = on_incoming_indication(sess, token, sess->rx_pool,  
    12411377                                        (const pj_uint8_t*) packet, pkt_size, 
    12421378                                        msg, src_addr, src_addr_len); 
     
    12501386    pj_lock_release(sess->lock); 
    12511387 
    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 
    12531396    return status; 
    12541397} 
    12551398 
    1256  
    1257  
  • pjproject/trunk/pjnath/src/pjnath/stun_transaction.c

    r1410 r1988  
    3232{ 
    3333    char                 obj_name[PJ_MAX_OBJ_NAME]; 
    34     pj_stun_config      *cfg; 
    3534    pj_stun_tsx_cb       cb; 
    3635    void                *user_data; 
     
    3938 
    4039    pj_bool_t            require_retransmit; 
     40    unsigned             rto_msec; 
    4141    pj_timer_entry       retransmit_timer; 
    4242    unsigned             transmit_count; 
    4343    pj_time_val          retransmit_time; 
     44    pj_timer_heap_t     *timer_heap; 
    4445 
    4546    pj_timer_entry       destroy_timer; 
     
    7172 
    7273    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; 
    7476    pj_memcpy(&tsx->cb, cb, sizeof(*cb)); 
    7577 
     
    100102    /* Cancel previously registered timer */ 
    101103    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); 
    103105        tsx->destroy_timer.id = 0; 
    104106    } 
     
    106108    /* Stop retransmission, just in case */ 
    107109    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, 
    113115                                    &tsx->destroy_timer, delay); 
    114116    if (status != PJ_SUCCESS) 
     
    116118 
    117119    tsx->destroy_timer.id = TIMER_ACTIVE; 
     120    tsx->cb.on_complete = NULL; 
    118121 
    119122    return PJ_SUCCESS; 
     
    129132 
    130133    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); 
    132135        tsx->retransmit_timer.id = 0; 
    133136    } 
    134137    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); 
    136139        tsx->destroy_timer.id = 0; 
    137140    } 
     
    187190        if (tsx->transmit_count == 0) { 
    188191            tsx->retransmit_time.sec = 0; 
    189             tsx->retransmit_time.msec = tsx->cfg->rto_msec; 
     192            tsx->retransmit_time.msec = tsx->rto_msec; 
    190193 
    191194        } else if (tsx->transmit_count < PJ_STUN_MAX_TRANSMIT_COUNT-1) { 
     
    206209         * cancel transmission). 
    207210         */; 
    208         status = pj_timer_heap_schedule(tsx->cfg->timer_heap,  
     211        status = pj_timer_heap_schedule(tsx->timer_heap,  
    209212                                        &tsx->retransmit_timer, 
    210213                                        &tsx->retransmit_time); 
     
    224227    /* Send message */ 
    225228    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) { 
    227233        if (tsx->retransmit_timer.id != 0) { 
    228             pj_timer_heap_cancel(tsx->cfg->timer_heap,  
     234            pj_timer_heap_cancel(tsx->timer_heap,  
    229235                                 &tsx->retransmit_timer); 
    230236            tsx->retransmit_timer.id = 0; 
     
    280286            } 
    281287        } 
     288        /* We might have been destroyed, don't try to access the object */ 
    282289        return; 
    283290    } 
     
    285292    tsx->retransmit_timer.id = 0; 
    286293    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) { 
    288297        tsx->retransmit_timer.id = 0; 
    289298        if (!tsx->complete) { 
     
    293302            } 
    294303        } 
     304        /* We might have been destroyed, don't try to access the object */ 
    295305    } 
    296306} 
     
    306316 
    307317    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); 
    309319        tsx->retransmit_timer.id = 0; 
    310320    } 
     
    352362     */ 
    353363    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); 
    355365        tsx->retransmit_timer.id = 0; 
    356366    } 
     
    385395            tsx->cb.on_complete(tsx, status, msg, src_addr, src_addr_len); 
    386396        } 
     397        /* We might have been destroyed, don't try to access the object */ 
    387398    } 
    388399 
  • pjproject/trunk/pjnath/src/pjnath/turn_session.c

    r1929 r1988  
    3030#include <pj/sock.h> 
    3131 
    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 
    3435 
    3536static const char *state_names[] =  
     
    6768    pj_turn_session_cb   cb; 
    6869    void                *user_data; 
     70    pj_stun_config       stun_cfg; 
    6971 
    7072    pj_lock_t           *lock; 
     
    7274 
    7375    pj_turn_state_t      state; 
     76    pj_status_t          last_status; 
    7477    pj_bool_t            pending_destroy; 
    7578    pj_bool_t            destroy_notified; 
     
    8891 
    8992    pj_uint16_t          af; 
    90     pj_turn_tp_type      tp_type; 
     93    pj_turn_tp_type      conn_type; 
    9194    pj_uint16_t          srv_addr_cnt; 
    9295    pj_sockaddr         *srv_addr_list; 
     
    9699    pj_turn_alloc_param  alloc_param; 
    97100 
     101    pj_sockaddr          mapped_addr; 
    98102    pj_sockaddr          relay_addr; 
    99103 
     
    177181 * Create TURN client session. 
    178182 */ 
    179 PJ_DEF(pj_status_t) pj_turn_session_create( pj_stun_config *cfg, 
     183PJ_DEF(pj_status_t) pj_turn_session_create( const pj_stun_config *cfg, 
    180184                                            const char *name, 
    181185                                            int af, 
    182                                             pj_turn_tp_type tp_type, 
     186                                            pj_turn_tp_type conn_type, 
    183187                                            const pj_turn_session_cb *cb, 
     188                                            unsigned options, 
    184189                                            void *user_data, 
    185                                             unsigned options, 
    186190                                            pj_turn_session **p_sess) 
    187191{ 
     
    207211    sess->timer_heap = cfg->timer_heap; 
    208212    sess->af = (pj_uint16_t)af; 
    209     sess->tp_type = tp_type; 
     213    sess->conn_type = conn_type; 
    210214    sess->ka_interval = PJ_TURN_KEEP_ALIVE_SEC; 
    211215    sess->user_data = user_data; 
    212216    sess->next_ch = PJ_TURN_CHANNEL_MIN; 
     217 
     218    /* Copy STUN session */ 
     219    pj_memcpy(&sess->stun_cfg, cfg, sizeof(pj_stun_config)); 
    213220 
    214221    /* Copy callback */ 
     
    234241    stun_cb.on_request_complete = &stun_on_request_complete; 
    235242    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); 
    238245    if (status != PJ_SUCCESS) { 
    239246        do_destroy(sess); 
     
    334341        break; 
    335342    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        } 
    339347        break; 
    340348    case PJ_TURN_STATE_RESOLVED: 
     
    366374        pj_time_val delay = {0, 0}; 
    367375 
     376        set_state(sess, PJ_TURN_STATE_DESTROYING); 
     377 
    368378        if (sess->timer.id != TIMER_NONE) { 
    369379            pj_timer_heap_cancel(sess->timer_heap, &sess->timer); 
     
    371381        } 
    372382 
    373         set_state(sess, PJ_TURN_STATE_DESTROYING); 
    374  
    375383        sess->timer.id = TIMER_DESTROY; 
    376384        pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay); 
     
    401409PJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess) 
    402410{ 
     411    PJ_ASSERT_RETURN(sess, PJ_EINVAL); 
     412 
    403413    set_state(sess, PJ_TURN_STATE_DEALLOCATED); 
    404414    sess_shutdown(sess, PJ_SUCCESS); 
     
    420430 
    421431    info->state = sess->state; 
    422     info->tp_type = sess->tp_type; 
     432    info->conn_type = sess->conn_type; 
    423433    info->lifetime = sess->expiry.sec - now.sec; 
     434    info->last_status = sess->last_status; 
    424435 
    425436    if (sess->srv_addr) 
     
    428439        pj_bzero(&info->server, sizeof(info->server)); 
    429440 
    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)); 
    431445 
    432446    return PJ_SUCCESS; 
     
    451465{ 
    452466    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 */ 
     476PJ_DEF(void) pj_turn_session_set_log( pj_turn_session *sess, 
     477                                      unsigned flags) 
     478{ 
     479    pj_stun_session_set_log(sess->stun, flags); 
    453480} 
    454481 
     
    462489                                                pj_dns_resolver *resolver) 
    463490{ 
     491    pj_sockaddr tmp_addr; 
     492    pj_bool_t is_ip_addr; 
    464493    pj_status_t status; 
    465494 
     
    469498    pj_lock_acquire(sess->lock); 
    470499 
    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) { 
    472507        /* Resolve with DNS SRV resolution, and fallback to DNS A resolution 
    473508         * if default_port is specified. 
     
    476511        pj_str_t res_name; 
    477512 
    478         switch (sess->tp_type) { 
     513        switch (sess->conn_type) { 
    479514        case PJ_TURN_TP_UDP: 
    480515            res_name = pj_str("_turn._udp."); 
     
    502537        set_state(sess, PJ_TURN_STATE_RESOLVING); 
    503538 
     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 
    504545        status = pj_dns_srv_resolve(domain, &res_name, default_port,  
    505546                                    sess->pool, resolver, opt, sess,  
     
    521562        sess->default_port = (pj_uint16_t)default_port; 
    522563 
    523         cnt = MAX_SRV_CNT; 
     564        cnt = PJ_TURN_MAX_DNS_SRV_CNT; 
    524565        ai = (pj_addrinfo*) 
    525566             pj_pool_calloc(sess->pool, cnt, sizeof(pj_addrinfo)); 
     
    527568        PJ_LOG(5,(sess->obj_name, "Resolving %.*s with DNS A", 
    528569                  (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        } 
    529577 
    530578        status = pj_getaddrinfo(sess->af, domain, &cnt, ai); 
     
    637685    /* Send request */ 
    638686    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); 
    640688    status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE,  
    641689                                      retransmit, sess->srv_addr, 
     
    682730 
    683731    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), 
    685733                                      sess->srv_addr, 
    686734                                      pj_sockaddr_get_len(sess->srv_addr),  
     
    834882     */ 
    835883    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), 
    837885                                      sess->srv_addr, 
    838886                                      pj_sockaddr_get_len(sess->srv_addr), 
     
    850898 */ 
    851899PJ_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) 
    855902{ 
    856903    pj_bool_t is_stun; 
    857904    pj_status_t status; 
     905    pj_bool_t is_datagram; 
    858906 
    859907    /* Packet could be ChannelData or STUN message (response or 
     
    864912    pj_lock_acquire(sess->lock); 
    865913 
     914    is_datagram = (sess->conn_type==PJ_TURN_TP_UDP); 
     915 
    866916    /* Quickly check if this is STUN message */ 
    867     is_stun = ((pkt[0] & 0xC0) == 0); 
     917    is_stun = ((((pj_uint8_t*)pkt)[0] & 0xC0) == 0); 
    868918 
    869919    if (is_stun) { 
     
    871921        unsigned options; 
    872922 
    873         options = PJ_STUN_CHECK_PACKET; 
     923        options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK; 
    874924        if (is_datagram) 
    875925            options |= PJ_STUN_IS_DATAGRAM; 
     
    906956 
    907957        /* 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, 
    910960                               pj_sockaddr_get_len(&peer->addr)); 
    911961 
     
    9541004                             const pj_str_t *reason) 
    9551005{ 
     1006    sess->last_status = status; 
     1007 
    9561008    do { 
    9571009        pj_str_t reason1; 
     
    10111063    const pj_stun_lifetime_attr *lf_attr; 
    10121064    const pj_stun_relay_addr_attr *raddr_attr; 
     1065    const pj_stun_sockaddr_attr *mapped_attr; 
    10131066    pj_str_t s; 
    10141067    pj_time_val timeout; 
     
    10701123                                    " address family is not supported " 
    10711124                                    "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")); 
    10721131        return; 
    10731132    } 
     
    10921151    } 
    10931152 
     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 
    10941161    /* Success */ 
    10951162 
     
    11331200 
    11341201    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 
    11351213        /* Handle ALLOCATE response */ 
    11361214        if (status==PJ_SUCCESS &&  
     
    12991377{ 
    13001378    pj_turn_session *sess = (pj_turn_session*) user_data; 
    1301     unsigned i, cnt; 
     1379    unsigned i, cnt, tot_cnt; 
    13021380 
    13031381    /* Clear async resolver */ 
     
    13101388    } 
    13111389 
     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 
    13121404    /* 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) { 
    13141406        unsigned j; 
    13151407 
    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        { 
    13171411            pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4; 
    13181412 
  • pjproject/trunk/pjnath/src/pjnath/turn_sock.c

    r1914 r1988  
    1818 */ 
    1919#include <pjnath/turn_sock.h> 
     20#include <pj/activesock.h> 
    2021#include <pj/assert.h> 
    2122#include <pj/errno.h> 
     
    5152    int                  af; 
    5253    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; 
    5655    pj_ioqueue_op_key_t  send_key; 
    57     pj_uint8_t           pkt[PJ_TURN_MAX_PKT_LEN]; 
    5856}; 
    5957 
     
    7270                                  unsigned ch_num); 
    7371static void turn_on_rx_data(pj_turn_session *sess, 
    74                             const pj_uint8_t *pkt, 
     72                            void *pkt, 
    7573                            unsigned pkt_len, 
    7674                            const pj_sockaddr_t *peer_addr, 
     
    7977                          pj_turn_state_t old_state, 
    8078                          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 
     80static 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); 
     85static pj_bool_t on_connect_complete(pj_activesock_t *asock, 
     86                                     pj_status_t status); 
     87 
    8688 
    8789 
     
    159161    sess_cb.on_state = &turn_on_state; 
    160162    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); 
    162164    if (status != PJ_SUCCESS) { 
    163165        destroy(turn_sock); 
     
    188190    } 
    189191 
    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; 
    197195    } 
    198196 
     
    272270{ 
    273271    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); 
    275274} 
    276275 
     
    281280                                               void *user_data) 
    282281{ 
     282    PJ_ASSERT_RETURN(turn_sock, PJ_EINVAL); 
    283283    turn_sock->user_data = user_data; 
    284284    return PJ_SUCCESS; 
     
    290290PJ_DEF(void*) pj_turn_sock_get_user_data(pj_turn_sock *turn_sock) 
    291291{ 
     292    PJ_ASSERT_RETURN(turn_sock, NULL); 
    292293    return turn_sock->user_data; 
    293294} 
     
    297298 */ 
    298299PJ_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) 
    300301{ 
    301302    PJ_ASSERT_RETURN(turn_sock && info, PJ_EINVAL); 
     
    310311} 
    311312 
     313/** 
     314 * Lock the TURN socket. Application may need to call this function to 
     315 * synchronize access to other objects to avoid deadlock. 
     316 */ 
     317PJ_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 */ 
     325PJ_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 */ 
     333PJ_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 
    312339/* 
    313340 * Initialize. 
    314341 */ 
    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) 
     342PJ_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) 
    321348{ 
    322349    pj_status_t status; 
     
    393420 * Notification when outgoing TCP socket has been connected. 
    394421 */ 
    395 static void on_connect_complete(pj_ioqueue_key_t *key,  
    396                                 pj_status_t status) 
     422static pj_bool_t on_connect_complete(pj_activesock_t *asock, 
     423                                     pj_status_t status) 
    397424{ 
    398425    pj_turn_sock *turn_sock; 
    399426 
    400     turn_sock = (pj_turn_sock*) pj_ioqueue_get_user_data(key); 
     427    turn_sock = (pj_turn_sock*) pj_activesock_get_user_data(asock); 
    401428 
    402429    if (status != PJ_SUCCESS) { 
    403430        sess_fail(turn_sock, "TCP connect() error", status); 
    404         return; 
     431        return PJ_FALSE; 
    405432    } 
    406433 
     
    410437 
    411438    /* 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); 
    414441 
    415442    /* Init send_key */ 
     
    420447    if (status != PJ_SUCCESS) { 
    421448        sess_fail(turn_sock, "Error sending ALLOCATE", status); 
    422         return; 
    423     } 
     449        return PJ_FALSE; 
     450    } 
     451 
     452    return PJ_TRUE; 
    424453} 
    425454 
     
    427456 * Notification from ioqueue when incoming UDP packet is received. 
    428457 */ 
    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 }; 
     458static 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{ 
    434464    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); 
    439468    pj_lock_acquire(turn_sock->lock); 
    440469 
    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    } 
    469481 
    470482on_return: 
    471483    pj_lock_release(turn_sock->lock); 
     484 
     485    return ret; 
    472486} 
    473487 
     
    483497{ 
    484498    pj_turn_sock *turn_sock = (pj_turn_sock*)  
    485                            pj_turn_session_get_user_data(sess); 
     499                              pj_turn_session_get_user_data(sess); 
    486500    pj_ssize_t len = pkt_len; 
    487501    pj_status_t status; 
     
    496510    PJ_UNUSED_ARG(dst_addr_len); 
    497511 
    498     status = pj_ioqueue_send(turn_sock->key, &turn_sock->send_key,  
    499                              pkt, &len, 0); 
     512    status = pj_activesock_send(turn_sock->active_sock, &turn_sock->send_key, 
     513                                pkt, &len, 0); 
    500514    if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
    501515        show_err(turn_sock, "socket send()", status); 
     
    525539 */ 
    526540static void turn_on_rx_data(pj_turn_session *sess, 
    527                             const pj_uint8_t *pkt, 
     541                            void *pkt, 
    528542                            unsigned pkt_len, 
    529543                            const pj_sockaddr_t *peer_addr, 
     
    560574    } 
    561575 
    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) { 
    563589        /* 
    564590         * Once server has been resolved, initiate outgoing TCP 
     
    568594        char addrtxt[PJ_INET6_ADDRSTRLEN+8]; 
    569595        int sock_type; 
    570         pj_ioqueue_callback ioq_cb; 
     596        pj_sock_t sock; 
     597        pj_activesock_cb asock_cb; 
    571598 
    572599        /* Close existing connection, if any. This happens when 
     
    574601         * connection or ALLOCATE request failed. 
    575602         */ 
    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; 
    583606        } 
    584607 
     
    592615 
    593616        /* 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); 
    596618        if (status != PJ_SUCCESS) { 
    597619            pj_turn_sock_destroy(turn_sock); 
     
    599621        } 
    600622 
    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); 
    608632        if (status != PJ_SUCCESS) { 
    609633            pj_turn_sock_destroy(turn_sock); 
     
    617641 
    618642        /* 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)); 
    621647        if (status == PJ_SUCCESS) { 
    622             on_connect_complete(turn_sock->key, PJ_SUCCESS); 
     648            on_connect_complete(turn_sock->active_sock, PJ_SUCCESS); 
    623649        } else if (status != PJ_EPENDING) { 
    624650            pj_turn_sock_destroy(turn_sock); 
     
    631657    } 
    632658 
    633     if (turn_sock->cb.on_state) { 
    634         (*turn_sock->cb.on_state)(turn_sock, old_state, new_state); 
    635     } 
    636  
    637659    if (new_state >= PJ_TURN_STATE_DESTROYING && turn_sock->sess) { 
    638660        pj_time_val delay = {0, 0}; 
  • pjproject/trunk/pjnath/src/pjturn-client/client_main.c

    r1929 r1988  
    6969static int worker_thread(void *unused); 
    7070static void turn_on_rx_data(pj_turn_sock *relay, 
    71                             const pj_uint8_t *pkt, 
     71                            void *pkt, 
    7272                            unsigned pkt_len, 
    7373                            const pj_sockaddr_t *peer_addr, 
     
    275275 
    276276    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 */ 
    278278                            &srv,                                /* srv addr */ 
    279279                            (o.srv_port?atoi(o.srv_port):PJ_STUN_PORT),/* def port */ 
     
    295295 
    296296static void turn_on_rx_data(pj_turn_sock *relay, 
    297                             const pj_uint8_t *pkt, 
     297                            void *pkt, 
    298298                            unsigned pkt_len, 
    299299                            const pj_sockaddr_t *peer_addr, 
  • pjproject/trunk/pjnath/src/pjturn-srv/auth.c

    r1929 r1988  
    3636    { "100", "100" }, 
    3737    { "700", "700" }, 
    38     { "701", "701" }, 
    39     { "702", "702" } 
     38    { "701", "701" } 
    4039}; 
    4140 
Note: See TracChangeset for help on using the changeset viewer.