Codebase list libnice / upstream/0.0.4
Imported Upstream version 0.0.4 Sjoerd Simons 15 years ago
48 changed file(s) with 3634 addition(s) and 1829 deletion(s). Raw diff Collapse all Expand all
129129 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
130130 NM = @NM@
131131 NMEDIT = @NMEDIT@
132 OBJDUMP = @OBJDUMP@
132133 OBJEXT = @OBJEXT@
133134 OTOOL = @OTOOL@
134135 OTOOL64 = @OTOOL64@
0 nice 0.0.4 (2008-12-17)
1 ========================
2
3 Fix compilation for 64bits systems
4 Revert the use of netbuffer in the gstreamer elements
5 Added support for pseudossl-tcp TURN relay for Google
6 Added support for SOCKS5 proxy servers for TCP relaying
7 Bug fixes and code cleaning
8
09 nice 0.0.3 (2008-11-25)
110 ========================
211
434434 # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
435435 # ---------------------------------------------------
436436 m4_define([lt_decl_varnames_tagged],
437 [_$0(m4_quote(m4_default([$1], [[, ]])),
438 m4_quote(m4_if([$2], [],
439 m4_quote(lt_decl_tag_varnames),
440 m4_quote(m4_shift($@)))),
441 m4_split(m4_normalize(m4_quote(_LT_TAGS))))])
442 m4_define([_lt_decl_varnames_tagged], [lt_combine([$1], [$2], [_], $3)])
437 [m4_assert([$# <= 2])dnl
438 _$0(m4_quote(m4_default([$1], [[, ]])),
439 m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
440 m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
441 m4_define([_lt_decl_varnames_tagged],
442 [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
443443
444444
445445 # lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
999999 _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
10001000 darwin1.*)
10011001 _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
1002 darwin*) # darwin 5.x on
1002 darwin*) # darwin 5.x on
10031003 # if running on 10.5 or later, the deployment target defaults
10041004 # to the OS version, if on x86, and 10.4, the deployment
1005 # target defaults to 10.4. Don't you love it?
1005 # target defaults to 10.4. Don't you love it?
10061006 case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10071007 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
10081008 _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
10441044 _LT_TAGVAR(whole_archive_flag_spec, $1)=''
10451045 _LT_TAGVAR(link_all_deplibs, $1)=yes
10461046 _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
1047 if test "$GCC" = "yes"; then
1047 case $cc_basename in
1048 ifort*) _lt_dar_can_shared=yes ;;
1049 *) _lt_dar_can_shared=$GCC ;;
1050 esac
1051 if test "$_lt_dar_can_shared" = "yes"; then
10481052 output_verbose_link_cmd=echo
10491053 _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
10501054 _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
15661570 lt_cv_sys_max_cmd_len=-1;
15671571 ;;
15681572
1569 cygwin* | mingw*)
1573 cygwin* | mingw* | cegcc*)
15701574 # On Win9x/ME, this test blows up -- it succeeds, but takes
15711575 # about 5 minutes as the teststring grows exponentially.
15721576 # Worse, since 9x/ME are not pre-emptively multitasking,
17341738 # endif
17351739 #endif
17361740
1737 #ifdef __cplusplus
1738 extern "C" void exit (int);
1739 #endif
1740
17411741 void fnord() { int i=42;}
17421742 int main ()
17431743 {
17531753 else
17541754 puts (dlerror ());
17551755
1756 exit (status);
1756 return status;
17571757 }]
17581758 _LT_EOF
17591759 if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
17921792 lt_cv_dlopen_self=yes
17931793 ;;
17941794
1795 mingw* | pw32*)
1795 mingw* | pw32* | cegcc*)
17961796 lt_cv_dlopen="LoadLibrary"
17971797 lt_cv_dlopen_libs=
17981798 ;;
20892089 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
20902090 m4_require([_LT_DECL_EGREP])dnl
20912091 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
2092 m4_require([_LT_DECL_OBJDUMP])dnl
20922093 m4_require([_LT_DECL_SED])dnl
20932094 AC_MSG_CHECKING([dynamic linker characteristics])
20942095 m4_if([$1],
22532254 # libtool to hard-code these into programs
22542255 ;;
22552256
2256 cygwin* | mingw* | pw32*)
2257 cygwin* | mingw* | pw32* | cegcc*)
22572258 version_type=windows
22582259 shrext_cmds=".dll"
22592260 need_version=no
22602261 need_lib_prefix=no
22612262
22622263 case $GCC,$host_os in
2263 yes,cygwin* | yes,mingw* | yes,pw32*)
2264 yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
22642265 library_names_spec='$libname.dll.a'
22652266 # DLL is installed to $(libdir)/../bin by postinstall_cmds
22662267 postinstall_cmds='base_file=`basename \${file}`~
22832284 soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
22842285 sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
22852286 ;;
2286 mingw*)
2287 mingw* | cegcc*)
22872288 # MinGW DLLs use traditional 'lib' prefix
22882289 soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
22892290 sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
27212722 version_type=linux
27222723 need_lib_prefix=no
27232724 need_version=no
2724 library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
2725 library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
27252726 shlibpath_var=LD_LIBRARY_PATH
27262727 shlibpath_overrides_runpath=no
27272728 hardcode_into_libs=yes
27452746 if test "$GCC" = yes; then
27462747 variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
27472748 fi
2748
2749
27492750 if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
27502751 sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
27512752 fi
30223023 # -- PORTME fill in with the dynamic library characteristics
30233024 m4_defun([_LT_CHECK_MAGIC_METHOD],
30243025 [m4_require([_LT_DECL_EGREP])
3026 m4_require([_LT_DECL_OBJDUMP])
30253027 AC_CACHE_CHECK([how to recognize dependent libraries],
30263028 lt_cv_deplibs_check_method,
30273029 [lt_cv_file_magic_cmd='$MAGIC_CMD'
30703072 lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
30713073 lt_cv_file_magic_cmd='$OBJDUMP -f'
30723074 fi
3075 ;;
3076
3077 cegcc)
3078 # use the weaker test based on 'objdump'. See mingw*.
3079 lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
3080 lt_cv_file_magic_cmd='$OBJDUMP -f'
30733081 ;;
30743082
30753083 darwin* | rhapsody*)
33833391 aix*)
33843392 symcode='[[BCDT]]'
33853393 ;;
3386 cygwin* | mingw* | pw32*)
3394 cygwin* | mingw* | pw32* | cegcc*)
33873395 symcode='[[ABCDGISTW]]'
33883396 ;;
33893397 hpux*)
36293637 beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
36303638 # PIC is the default for these OSes.
36313639 ;;
3632 mingw* | cygwin* | os2* | pw32*)
3640 mingw* | cygwin* | os2* | pw32* | cegcc*)
36333641 # This hack is so that the source file can tell whether it is being
36343642 # built for inclusion in a dll (and should export symbols for example).
36353643 # Although the cygwin gcc ignores -fPIC, still need this for old-style
36563664 fi
36573665 ;;
36583666 hpux*)
3659 # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
3660 # not for PA HP-UX.
3667 # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
3668 # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
3669 # sets the default TLS model and affects inlining.
36613670 case $host_cpu in
3662 hppa*64*|ia64*)
3671 hppa*64*)
36633672 ;;
36643673 *)
36653674 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
37573766 _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
37583767 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
37593768 ;;
3760 icpc* | ecpc* )
3761 # Intel C++
3769 ecpc* )
3770 # old Intel C++ for x86_64 which still supported -KPIC.
37623771 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
37633772 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
3773 _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
3774 ;;
3775 icpc* )
3776 # Intel C++, used to be incompatible with GCC.
3777 # ICC 10 doesn't accept -KPIC any more.
3778 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
3779 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
37643780 _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
37653781 ;;
37663782 pgCC* | pgcpp*)
39283944 # PIC is the default for these OSes.
39293945 ;;
39303946
3931 mingw* | cygwin* | pw32* | os2*)
3947 mingw* | cygwin* | pw32* | os2* | cegcc*)
39323948 # This hack is so that the source file can tell whether it is being
39333949 # built for inclusion in a dll (and should export symbols for example).
39343950 # Although the cygwin gcc ignores -fPIC, still need this for old-style
39443960 ;;
39453961
39463962 hpux*)
3947 # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
3948 # not for PA HP-UX.
3963 # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
3964 # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
3965 # sets the default TLS model and affects inlining.
39493966 case $host_cpu in
3950 hppa*64*|ia64*)
3967 hppa*64*)
39513968 # +Z the default
39523969 ;;
39533970 *)
39974014 fi
39984015 ;;
39994016
4000 mingw* | cygwin* | pw32* | os2*)
4017 mingw* | cygwin* | pw32* | os2* | cegcc*)
40014018 # This hack is so that the source file can tell whether it is being
40024019 # built for inclusion in a dll (and should export symbols for example).
40034020 m4_if([$1], [GCJ], [],
40284045
40294046 linux* | k*bsd*-gnu)
40304047 case $cc_basename in
4031 icc* | ecc* | ifort*)
4048 # old Intel for x86_64 which still supported -KPIC.
4049 ecc*)
40324050 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
40334051 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
40344052 _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
40354053 ;;
4054 # icc used to be incompatible with GCC.
4055 # ICC 10 doesn't accept -KPIC any more.
4056 icc* | ifort*)
4057 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
4058 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
4059 _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
4060 ;;
4061 # Lahey Fortran 8.1.
4062 lf95*)
4063 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
4064 _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
4065 _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
4066 ;;
40364067 pgcc* | pgf77* | pgf90* | pgf95*)
40374068 # Portland Group compilers (*not* the Pentium gcc compiler,
40384069 # which looks to be a dead project)
42144245 pw32*)
42154246 _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
42164247 ;;
4217 cygwin* | mingw*)
4248 cygwin* | mingw* | cegcc*)
42184249 _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
42194250 ;;
42204251 linux* | k*bsd*-gnu)
42694300 extract_expsyms_cmds=
42704301
42714302 case $host_os in
4272 cygwin* | mingw* | pw32*)
4303 cygwin* | mingw* | pw32* | cegcc*)
42734304 # FIXME: the MSVC++ port hasn't been tested in a loooong time
42744305 # When not using gcc, we currently assume that we are using
42754306 # Microsoft Visual C++.
43564387 fi
43574388 ;;
43584389
4359 cygwin* | mingw* | pw32*)
4390 cygwin* | mingw* | pw32* | cegcc*)
43604391 # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
43614392 # as there is no search path for DLLs.
43624393 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
44224453 tmp_addflag=' -i_dynamic -nofor_main' ;;
44234454 ifc* | ifort*) # Intel Fortran compiler
44244455 tmp_addflag=' -nofor_main' ;;
4456 lf95*) # Lahey Fortran 8.1
4457 _LT_TAGVAR(whole_archive_flag_spec, $1)=
4458 tmp_sharedflag='--shared' ;;
44254459 xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
44264460 tmp_sharedflag='-qmkshrobj'
44274461 tmp_addflag= ;;
46544688 fi
46554689 fi
46564690
4691 _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
46574692 # It seems that -bexpall does not export symbols beginning with
46584693 # underscore (_), so it is better to generate a list of symbols to export.
46594694 _LT_TAGVAR(always_export_symbols, $1)=yes
47084743 _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
47094744 ;;
47104745
4711 cygwin* | mingw* | pw32*)
4746 cygwin* | mingw* | pw32* | cegcc*)
47124747 # When not using gcc, we currently assume that we are using
47134748 # Microsoft Visual C++.
47144749 # hardcode_libdir_flag_spec is actually meaningless, as there is
48124847 _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
48134848 ;;
48144849 ia64*)
4815 _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
4850 _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
48164851 ;;
48174852 *)
48184853 _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
55935628 fi
55945629 fi
55955630
5631 _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
55965632 # It seems that -bexpall does not export symbols beginning with
55975633 # underscore (_), so it is better to generate a list of symbols to
55985634 # export.
56515687 esac
56525688 ;;
56535689
5654 cygwin* | mingw* | pw32*)
5690 cygwin* | mingw* | pw32* | cegcc*)
56555691 # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
56565692 # as there is no search path for DLLs.
56575693 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
70327068 ])
70337069
70347070
7071 # _LT_DECL_OBJDUMP
7072 # --------------
7073 # If we don't have a new enough Autoconf to choose the best objdump
7074 # available, choose the one first in the user's PATH.
7075 m4_defun([_LT_DECL_OBJDUMP],
7076 [AC_CHECK_TOOL(OBJDUMP, objdump, false)
7077 test -z "$OBJDUMP" && OBJDUMP=objdump
7078 _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
7079 AC_SUBST([OBJDUMP])
7080 ])
7081
7082
70357083 # _LT_DECL_SED
70367084 # ------------
70377085 # Check for a fully-functional sed program, that truncates
74927540 [enable_win32_dll=yes
74937541
74947542 case $host in
7495 *-*-cygwin* | *-*-mingw* | *-*-pw32*)
7543 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
74967544 AC_CHECK_TOOL(AS, as, false)
74977545 AC_CHECK_TOOL(DLLTOOL, dlltool, false)
74987546 AC_CHECK_TOOL(OBJDUMP, objdump, false)
77337781
77347782 # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
77357783 #
7736 # Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
7737 # Written by Gary V. Vaughan, 2004
7784 # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
7785 # Written by Gary V. Vaughan, 2004
77387786 #
77397787 # This file is free software; the Free Software Foundation gives
77407788 # unlimited permission to copy and/or distribute it, with or without
77417789 # modifications, as long as this notice is preserved.
77427790
7743 # serial 5 ltsugar.m4
7791 # serial 6 ltsugar.m4
77447792
77457793 # This is to help aclocal find these macros, as it can't see m4_define.
77467794 AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
77967844 # Produce a SEP delimited list of all paired combinations of elements of
77977845 # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
77987846 # has the form PREFIXmINFIXSUFFIXn.
7847 # Needed until we can rely on m4_combine added in Autoconf 2.62.
77997848 m4_define([lt_combine],
7800 [m4_if([$2], [], [],
7801 [m4_if([$4], [], [],
7802 [lt_join(m4_quote(m4_default([$1], [[, ]])),
7803 lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_prefix, [$2],
7804 [m4_foreach(_Lt_suffix, lt_car([m4_shiftn(3, $@)]),
7805 [_Lt_prefix[]$3[]_Lt_suffix ])])))))])])dnl
7806 ])
7849 [m4_if(m4_eval([$# > 3]), [1],
7850 [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
7851 [[m4_foreach([_Lt_prefix], [$2],
7852 [m4_foreach([_Lt_suffix],
7853 ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
7854 [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
78077855
78087856
78097857 # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
78667914
78677915 # Generated from ltversion.in.
78687916
7869 # serial 2976 ltversion.m4
7917 # serial 3012 ltversion.m4
78707918 # This file is part of GNU Libtool
78717919
7872 m4_define([LT_PACKAGE_VERSION], [2.2.4])
7873 m4_define([LT_PACKAGE_REVISION], [1.2976])
7920 m4_define([LT_PACKAGE_VERSION], [2.2.6])
7921 m4_define([LT_PACKAGE_REVISION], [1.3012])
78747922
78757923 AC_DEFUN([LTVERSION_VERSION],
7876 [macro_version='2.2.4'
7877 macro_revision='1.2976'
7924 [macro_version='2.2.6'
7925 macro_revision='1.3012'
78787926 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
78797927 _LT_DECL(, macro_revision, 0)
78807928 ])
173173 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
174174 NM = @NM@
175175 NMEDIT = @NMEDIT@
176 OBJDUMP = @OBJDUMP@
176177 OBJEXT = @OBJEXT@
177178 OTOOL = @OTOOL@
178179 OTOOL64 = @OTOOL64@
4949 #include "conncheck.h"
5050 #include "component.h"
5151 #include "stun/stunagent.h"
52 #include "stun/usages/turn.h"
53 #include "stun/usages/ice.h"
5254
5355 /* XXX: starting from ICE ID-18, Ta SHOULD now be set according
5456 * to session bandwidth -> this is not yet implemented in NICE */
7173 GTimeVal next_check_tv; /**< property: next conncheck timestamp */
7274 gchar *stun_server_ip; /**< property: STUN server IP */
7375 guint stun_server_port; /**< property: STUN server port */
76 gchar *proxy_ip; /**< property: Proxy server IP */
77 guint proxy_port; /**< property: Proxy server port */
78 NiceProxyType proxy_type; /**< property: Proxy type */
79 gchar *proxy_username; /**< property: Proxy username */
80 gchar *proxy_password; /**< property: Proxy password */
7481 gboolean controlling_mode; /**< property: controlling-mode */
7582 guint timer_ta; /**< property: timer Ta */
7683 guint max_conn_checks; /**< property: max connectivity checks */
139146 Component *component,
140147 NiceSocket *socket);
141148
149 StunUsageIceCompatibility agent_to_ice_compatibility (NiceAgent *agent);
150 StunUsageTurnCompatibility agent_to_turn_compatibility (NiceAgent *agent);
151 NiceTurnSocketCompatibility agent_to_turn_socket_compatibility (NiceAgent *agent);
152
142153 #endif /*_NICE_AGENT_PRIV_H */
8787 PROP_CONTROLLING_MODE,
8888 PROP_FULL_MODE,
8989 PROP_STUN_PACING_TIMER,
90 PROP_MAX_CONNECTIVITY_CHECKS
90 PROP_MAX_CONNECTIVITY_CHECKS,
91 PROP_PROXY_TYPE,
92 PROP_PROXY_IP,
93 PROP_PROXY_PORT,
94 PROP_PROXY_USERNAME,
95 PROP_PROXY_PASSWORD
9196 };
9297
9398
109114 Component *component);
110115 static void priv_detach_stream_component (Stream *stream, Component *component);
111116
112 static StunUsageTurnCompatibility
113 priv_agent_to_turn_compatibility (NiceAgent *agent) {
117 StunUsageIceCompatibility
118 agent_to_ice_compatibility (NiceAgent *agent)
119 {
120 return agent->compatibility == NICE_COMPATIBILITY_DRAFT19 ?
121 STUN_USAGE_ICE_COMPATIBILITY_DRAFT19 :
122 agent->compatibility == NICE_COMPATIBILITY_GOOGLE ?
123 STUN_USAGE_ICE_COMPATIBILITY_GOOGLE :
124 agent->compatibility == NICE_COMPATIBILITY_MSN ?
125 STUN_USAGE_ICE_COMPATIBILITY_MSN : STUN_USAGE_ICE_COMPATIBILITY_DRAFT19;
126 }
127
128
129 StunUsageTurnCompatibility
130 agent_to_turn_compatibility (NiceAgent *agent)
131 {
114132 return agent->compatibility == NICE_COMPATIBILITY_DRAFT19 ?
115133 STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 :
116134 agent->compatibility == NICE_COMPATIBILITY_GOOGLE ?
117135 STUN_USAGE_TURN_COMPATIBILITY_GOOGLE :
118136 agent->compatibility == NICE_COMPATIBILITY_MSN ?
119137 STUN_USAGE_TURN_COMPATIBILITY_MSN : STUN_USAGE_TURN_COMPATIBILITY_DRAFT9;
138 }
139
140 NiceTurnSocketCompatibility
141 agent_to_turn_socket_compatibility (NiceAgent *agent)
142 {
143 return agent->compatibility == NICE_COMPATIBILITY_DRAFT19 ?
144 NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 :
145 agent->compatibility == NICE_COMPATIBILITY_GOOGLE ?
146 NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE :
147 agent->compatibility == NICE_COMPATIBILITY_MSN ?
148 NICE_TURN_SOCKET_COMPATIBILITY_MSN :
149 NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9;
120150 }
121151
122152 Stream *agent_find_stream (NiceAgent *agent, guint stream_id)
273303 "Upper limit for the total number of connectivity checks performed",
274304 0, 0xffffffff,
275305 0, /* default set in init */
306 G_PARAM_READWRITE));
307
308 g_object_class_install_property (gobject_class, PROP_PROXY_IP,
309 g_param_spec_string (
310 "proxy-ip",
311 "Proxy server IP",
312 "The proxy server used to bypass a proxy firewall",
313 NULL,
314 G_PARAM_READWRITE));
315
316 g_object_class_install_property (gobject_class, PROP_PROXY_PORT,
317 g_param_spec_uint (
318 "proxy-port",
319 "Proxy server port",
320 "The Proxy server used to bypass a proxy firewall",
321 1, 65536,
322 1,
323 G_PARAM_READWRITE));
324
325 g_object_class_install_property (gobject_class, PROP_PROXY_TYPE,
326 g_param_spec_uint (
327 "proxy-type",
328 "Type of proxy to use",
329 "The type of proxy set in the proxy-ip property",
330 NICE_PROXY_TYPE_NONE, NICE_PROXY_TYPE_LAST,
331 NICE_PROXY_TYPE_NONE,
332 G_PARAM_READWRITE));
333
334 g_object_class_install_property (gobject_class, PROP_PROXY_USERNAME,
335 g_param_spec_string (
336 "proxy-username",
337 "Proxy server username",
338 "The username used to authenticate with the proxy",
339 NULL,
340 G_PARAM_READWRITE));
341
342 g_object_class_install_property (gobject_class, PROP_PROXY_PASSWORD,
343 g_param_spec_string (
344 "proxy-password",
345 "Proxy server password",
346 "The password used to authenticate with the proxy",
347 NULL,
276348 G_PARAM_READWRITE));
277349
278350 /* install signals */
510582 /* XXX: should we prune the list of already existing checks? */
511583 break;
512584
585 case PROP_PROXY_IP:
586 g_value_set_string (value, agent->proxy_ip);
587 break;
588
589 case PROP_PROXY_PORT:
590 g_value_set_uint (value, agent->proxy_port);
591 break;
592
593 case PROP_PROXY_TYPE:
594 g_value_set_uint (value, agent->proxy_type);
595 break;
596
597 case PROP_PROXY_USERNAME:
598 g_value_set_string (value, agent->proxy_username);
599 break;
600
601 case PROP_PROXY_PASSWORD:
602 g_value_set_string (value, agent->proxy_password);
603 break;
604
513605 default:
514606 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
515607 }
580672 agent->max_conn_checks = g_value_get_uint (value);
581673 break;
582674
675 case PROP_PROXY_IP:
676 agent->proxy_ip = g_value_dup_string (value);
677 break;
678
679 case PROP_PROXY_PORT:
680 agent->proxy_port = g_value_get_uint (value);
681 break;
682
683 case PROP_PROXY_TYPE:
684 agent->proxy_type = g_value_get_uint (value);
685 break;
686
687 case PROP_PROXY_USERNAME:
688 agent->proxy_username = g_value_dup_string (value);
689 break;
690
691 case PROP_PROXY_PASSWORD:
692 agent->proxy_password = g_value_dup_string (value);
693 break;
694
583695 default:
584696 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
585697 }
663775 rf_copy = g_strdup (remote_foundation);
664776
665777 if (component->selected_pair.local->type == NICE_CANDIDATE_TYPE_RELAYED) {
666 nice_udp_turn_socket_set_peer (component->selected_pair.local->sockptr,
778 nice_turn_socket_set_peer (component->selected_pair.local->sockptr,
667779 &component->selected_pair.remote->addr);
668780 }
669781
768880 cdisco = g_slice_new0 (CandidateDiscovery);
769881 if (cdisco) {
770882 modified_list = g_slist_append (agent->discovery_list, cdisco);
771 priv_agent_to_turn_compatibility (agent);
772883
773884 if (modified_list) {
774885 Component *component = stream_find_component_by_id (stream, component_id);
797908 }
798909 cdisco->nicesock = socket;
799910 } else {
800 cdisco->nicesock = nice_tcp_turn_socket_new (agent,
801 component->ctx,
802 &turn->server,
803 priv_agent_to_turn_compatibility (agent));
911 NiceAddress proxy_server;
912 socket = NULL;
913
914 if (agent->proxy_type != NICE_PROXY_TYPE_NONE &&
915 agent->proxy_ip != NULL &&
916 nice_address_set_from_string (&proxy_server, agent->proxy_ip)) {
917 nice_address_set_port (&proxy_server, agent->proxy_port);
918 socket = nice_tcp_bsd_socket_new (agent, component->ctx, &proxy_server);
919
920 if (socket &&
921 agent->proxy_type == NICE_PROXY_TYPE_SOCKS5) {
922 socket = nice_socks5_socket_new (socket, &turn->server,
923 agent->proxy_username, agent->proxy_password);
924 } else {
925 /* TODO add HTTP support */
926 nice_socket_free (socket);
927 socket = NULL;
928 }
929
930 }
931 if (socket == NULL) {
932 socket = nice_tcp_bsd_socket_new (agent, component->ctx, &turn->server);
933 }
934 if (turn->type == NICE_RELAY_TYPE_TURN_TLS &&
935 agent->compatibility == NICE_COMPATIBILITY_GOOGLE) {
936 socket = nice_pseudossl_socket_new (agent, socket);
937 }
938 cdisco->nicesock = nice_tcp_turn_socket_new (agent, socket,
939 agent_to_turn_socket_compatibility (agent));
940
804941 if (!cdisco->nicesock) {
805942 agent->discovery_list = g_slist_remove (modified_list, cdisco);
806943 g_slice_free (CandidateDiscovery, cdisco);
13101447
13111448 len = nice_socket_recv (socket, &from, buf_len, buf);
13121449
1450 if (len <= 0)
1451 return len;
1452
13131453 #ifndef NDEBUG
1314 if (len >= 0) {
1454 if (len > 0) {
13151455 gchar tmpbuf[INET6_ADDRSTRLEN];
13161456 nice_address_to_string (&from, tmpbuf);
13171457 nice_debug ("Agent %p : Packet received on local socket %u from [%s]:%u (%u octets).", agent,
13191459 }
13201460 #endif
13211461
1322 if (len == 0)
1323 return 0;
13241462
13251463 if ((guint)len > buf_len)
13261464 {
13421480 if (cand->type == NICE_CANDIDATE_TYPE_RELAYED &&
13431481 cand->stream_id == stream->id &&
13441482 cand->component_id == component->id) {
1345 len = nice_udp_turn_socket_parse_recv (cand->sockptr, &socket,
1483 len = nice_turn_socket_parse_recv (cand->sockptr, &socket,
13461484 &from, len, buf, &from, buf, len);
13471485 }
13481486 }
15431681 struct _IOCtx
15441682 {
15451683 GIOChannel *channel;
1684 GSource *source;
15461685 NiceAgent *agent;
15471686 Stream *stream;
15481687 Component *component;
15561695 Stream *stream,
15571696 Component *component,
15581697 NiceSocket *socket,
1559 GIOChannel *channel)
1698 GIOChannel *channel,
1699 GSource *source)
15601700 {
15611701 IOCtx *ctx;
15621702
15671707 ctx->component = component;
15681708 ctx->socket = socket;
15691709 ctx->channel = channel;
1710 ctx->source = source;
15701711 }
15711712 return ctx;
15721713 }
15811722
15821723 static gboolean
15831724 nice_agent_g_source_cb (
1584 GIOChannel *source,
1725 GIOChannel *io,
15851726 G_GNUC_UNUSED
15861727 GIOCondition condition,
15871728 gpointer data)
15931734 Stream *stream = ctx->stream;
15941735 Component *component = ctx->component;
15951736 gchar buf[MAX_BUFFER_SIZE];
1596 guint len;
1737 gint len;
15971738
15981739 g_static_rec_mutex_lock (&agent->mutex);
15991740
16001741 /* note: dear compiler, these are for you: */
1601 (void)source;
1742 (void)io;
16021743
16031744 len = _nice_agent_recv (agent, stream, component, ctx->socket,
16041745 MAX_BUFFER_SIZE, buf);
16051746
1606 if (len > 0 && component->g_source_io_cb)
1747 if (len > 0 && component->g_source_io_cb) {
16071748 component->g_source_io_cb (agent, stream->id, component->id,
16081749 len, buf, component->data);
1750 } else if (len < 0) {
1751 GSource *source = ctx->source;
1752 component->gsources = g_slist_remove (component->gsources, source);
1753 g_source_destroy (source);
1754 g_source_unref (source);
1755 /* We don't close the socket because it would be way too complicated to
1756 * take care of every path where the socket might still be used.. */
1757 nice_debug ("Agent %p: unable to recv from socket %p. Detaching", agent,
1758 ctx->socket);
1759 }
16091760
16101761 g_static_rec_mutex_unlock (&agent->mutex);
16111762 return TRUE;
16321783 /* note: without G_IO_ERR the glib mainloop goes into
16331784 * busyloop if errors are encountered */
16341785 source = g_io_create_watch (io, G_IO_IN | G_IO_ERR);
1635 ctx = io_ctx_new (agent, stream, component, socket, io);
1786 ctx = io_ctx_new (agent, stream, component, socket, io, source);
16361787 g_source_set_callback (source, (GSourceFunc) nice_agent_g_source_cb,
16371788 ctx, (GDestroyNotify) io_ctx_free);
16381789 nice_debug ("Agent %p : Attach source %p (stream %u).", agent, source, stream->id);
228228 } NiceCompatibility;
229229
230230 /**
231 * NiceProxyType:
232 * @NICE_PROXY_TYPE_NONE: Do not use a proxy
233 * @NICE_PROXY_TYPE_SOCKS5: Use a SOCKS5 proxy
234 * @NICE_PROXY_TYPE_HTTP: Use an HTTP proxy
235 * @NICE_PROXY_TYPE_LAST: Dummy last proxy type
236 *
237 * An enum to specify which proxy type to use for relaying.
238 * Note that the proxies will only be used with TCP TURN relaying.
239 * See #NiceAgent:proxy-type
240 */
241 typedef enum
242 {
243 NICE_PROXY_TYPE_NONE = 0,
244 NICE_PROXY_TYPE_SOCKS5,
245 NICE_PROXY_TYPE_HTTP,
246 NICE_PROXY_TYPE_LAST = NICE_PROXY_TYPE_HTTP,
247 } NiceProxyType;
248
249
250 /**
231251 * NiceAgentRecvFunc:
232252 * @agent: The #NiceAgent Object
233253 * @stream_id: The id of the stream
7070 now->tv_usec >= timer->tv_usec :
7171 now->tv_sec >= timer->tv_sec;
7272 }
73
74 static StunUsageIceCompatibility priv_agent_to_ice_compatibility (NiceAgent *agent) {
75 return agent->compatibility == NICE_COMPATIBILITY_DRAFT19 ?
76 STUN_USAGE_ICE_COMPATIBILITY_DRAFT19 :
77 agent->compatibility == NICE_COMPATIBILITY_GOOGLE ?
78 STUN_USAGE_ICE_COMPATIBILITY_GOOGLE :
79 agent->compatibility == NICE_COMPATIBILITY_MSN ?
80 STUN_USAGE_ICE_COMPATIBILITY_MSN : STUN_USAGE_ICE_COMPATIBILITY_DRAFT19;
81 }
82
83 static StunUsageTurnCompatibility priv_agent_to_turn_compatibility (NiceAgent *agent) {
84 return agent->compatibility == NICE_COMPATIBILITY_DRAFT19 ?
85 STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 :
86 agent->compatibility == NICE_COMPATIBILITY_GOOGLE ?
87 STUN_USAGE_TURN_COMPATIBILITY_GOOGLE :
88 agent->compatibility == NICE_COMPATIBILITY_MSN ?
89 STUN_USAGE_TURN_COMPATIBILITY_MSN : STUN_USAGE_TURN_COMPATIBILITY_DRAFT9;
90 }
91
9273
9374 /**
9475 * Finds the next connectivity check in WAITING state.
575556 cand->stun_resp_msg.buffer == NULL ? NULL : &cand->stun_resp_msg, -1,
576557 username, username_len,
577558 password, password_len,
578 priv_agent_to_turn_compatibility (cand->agent));
559 agent_to_turn_compatibility (cand->agent));
579560
580561 if (cand->agent->compatibility == NICE_COMPATIBILITY_MSN) {
581562 g_free (cand->msn_turn_username);
836817
837818 /* note: iterate the conncheck list for each component separately */
838819 for (c = 0; c < components; c++) {
820 Component *comp = NULL;
821 agent_find_component (agent, stream->id, c+1, NULL, &comp);
822
839823 for (i = stream->conncheck_list; i; i = i->next) {
840824 CandidateCheckPair *p = i->data;
841825
845829 break;
846830 }
847831 }
848 /* note: all checks have failed */
849 if (i == NULL)
832
833 /* note: all checks have failed
834 * Set the component to FAILED only if it actually had remote candidates
835 * that failed.. */
836 if (i == NULL && comp != NULL && comp->remote_candidates != NULL)
850837 agent_signal_component_state_change (agent,
851838 stream->id,
852839 (c + 1), /* component-id */
13221309 uname, uname_len, password, password_len,
13231310 cand_use, controlling, priority,
13241311 agent->tie_breaker,
1325 priv_agent_to_ice_compatibility (agent));
1312 agent_to_ice_compatibility (agent));
13261313
13271314 nice_debug ("Agent %p: conncheck created %d - %p", agent, buffer_len, pair->stun_message.buffer);
13281315
16871674
16881675 if (memcmp (discovery_id, response_id, sizeof(stun_transid_t)) == 0) {
16891676 res = stun_usage_ice_conncheck_process (resp, &sockaddr, &socklen,
1690 priv_agent_to_ice_compatibility (agent));
1677 agent_to_ice_compatibility (agent));
16911678 nice_debug ("Agent %p : stun_bind_process/conncheck for %p res %d "
16921679 "(controlling=%d).", agent, p, (int)res, agent->controlling_mode);
16931680
19211908 if (memcmp (discovery_id, response_id, sizeof(stun_transid_t)) == 0) {
19221909 res = stun_usage_turn_process (resp,
19231910 &relayaddr, &relayaddrlen, &sockaddr, &socklen, &alternate, &alternatelen,
1924 &bandwidth, &lifetime, priv_agent_to_turn_compatibility (agent));
1911 &bandwidth, &lifetime, agent_to_turn_compatibility (agent));
19251912 nice_debug ("Agent %p : stun_turn_process/disc for %p res %d.",
19261913 agent, d, (int)res);
19271914
20402027
20412028 if (memcmp (refresh_id, response_id, sizeof(stun_transid_t)) == 0) {
20422029 res = stun_usage_turn_refresh_process (resp,
2043 &lifetime, priv_agent_to_turn_compatibility (cand->agent));
2030 &lifetime, agent_to_turn_compatibility (cand->agent));
20442031 nice_debug ("Agent %p : stun_turn_refresh_process for %p res %d.",
20452032 agent, cand, (int)res);
20462033 if (res == STUN_USAGE_TURN_RETURN_RELAY_SUCCESS) {
24012388 res = stun_usage_ice_conncheck_create_reply (&agent->stun_agent, &req,
24022389 &msg, rbuf, &rbuf_len, &sockaddr, sizeof (sockaddr),
24032390 &control, agent->tie_breaker,
2404 priv_agent_to_ice_compatibility (agent));
2391 agent_to_ice_compatibility (agent));
24052392
24062393 if (agent->compatibility == NICE_COMPATIBILITY_MSN) {
24072394 g_free (req.key);
6565 now->tv_sec >= timer->tv_sec;
6666 }
6767
68 static StunUsageTurnCompatibility
69 priv_agent_to_turn_compatibility (NiceAgent *agent) {
70 return agent->compatibility == NICE_COMPATIBILITY_DRAFT19 ?
71 STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 :
72 agent->compatibility == NICE_COMPATIBILITY_GOOGLE ?
73 STUN_USAGE_TURN_COMPATIBILITY_GOOGLE :
74 agent->compatibility == NICE_COMPATIBILITY_MSN ?
75 STUN_USAGE_TURN_COMPATIBILITY_MSN : STUN_USAGE_TURN_COMPATIBILITY_DRAFT9;
76 }
77
78 static NiceUdpTurnSocketCompatibility
79 priv_agent_to_udp_turn_compatibility (NiceAgent *agent) {
80 return agent->compatibility == NICE_COMPATIBILITY_DRAFT19 ?
81 NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9 :
82 agent->compatibility == NICE_COMPATIBILITY_GOOGLE ?
83 NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE :
84 agent->compatibility == NICE_COMPATIBILITY_MSN ?
85 NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN :
86 NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9;
87 }
88
8968 /**
9069 * Frees the CandidateDiscovery structure pointed to
9170 * by 'user data'. Compatible with g_slist_foreach().
190169 cand->stun_resp_msg.buffer == NULL ? NULL : &cand->stun_resp_msg, 0,
191170 username, username_len,
192171 password, password_len,
193 priv_agent_to_turn_compatibility (agent));
172 agent_to_turn_compatibility (agent));
194173
195174 if (buffer_len > 0) {
196175 /* send the refresh twice since we won't do retransmissions */
309288 nice_address_get_port (&candidate->base_addr));
310289
311290 if (candidate->type == n->type &&
291 candidate->stream_id == n->stream_id &&
312292 nice_address_equal (&candidate->base_addr, &temp)) {
313293 /* note: currently only one STUN/TURN server per stream at a
314294 * time is supported, so there is no need to check
550530 candidate->turn = turn;
551531
552532 /* step: link to the base candidate+socket */
553 relay_socket = nice_udp_turn_socket_new (agent, address,
533 relay_socket = nice_turn_socket_new (agent, address,
554534 base_socket, &turn->server,
555535 turn->username, turn->password,
556 priv_agent_to_udp_turn_compatibility (agent));
536 agent_to_turn_socket_compatibility (agent));
557537 if (relay_socket) {
558538 candidate->sockptr = relay_socket;
559539 candidate->base_addr = base_socket->addr;
859839 -1, -1,
860840 username, username_len,
861841 password, password_len,
862 priv_agent_to_turn_compatibility (agent));
842 agent_to_turn_compatibility (agent));
863843
864844 if (agent->compatibility == NICE_COMPATIBILITY_MSN) {
865845 g_free (cand->msn_turn_username);
4747 #define USE_LOOPBACK 1
4848 #define TEST_GOOGLE 0
4949
50 #define PROXY_IP "127.0.0.1"
51 #define PROXY_PORT 1080
52 #define PROXY_TYPE NICE_PROXY_TYPE_SOCKS5
53 #define PROXY_USERNAME NULL
54 #define PROXY_PASSWORD NULL
55
56
5057 #if TEST_GOOGLE
5158 #define NICE_COMPATIBILITY NICE_COMPATIBILITY_GOOGLE
5259
5562 #define USE_LOOPBACK 0
5663
5764 #define TURN_IP "209.85.163.126"
58 #define TURN_PORT 19295
65 #define TURN_PORT 443
5966 #define TURN_USER "ih9ppiM0P6vN34DB"
6067 #define TURN_PASS ""
6168 #define TURN_USER2 TURN_USER
6269 #define TURN_PASS2 TURN_PASS
63 #define TURN_TYPE NICE_RELAY_TYPE_TURN_UDP
70 #define TURN_TYPE NICE_RELAY_TYPE_TURN_TLS
6471
6572 #endif
6673
9097 #define TURN_PASS TSORG_PASS
9198 #define TURN_USER2 TSORG_USER
9299 #define TURN_PASS2 TSORG_PASS
93 #define TURN_TYPE NICE_RELAY_TYPE_TURN_UDP
100 #define TURN_TYPE NICE_RELAY_TYPE_TURN_TCP
94101 #else
95102 #define TURN_IP NUMB_IP
96103 #define TURN_PORT NUMB_PORT
153160 if (strncmp ("12345678", buf, 8))
154161 return;
155162
156 if ((int)user_data == 2) {
163 if (GPOINTER_TO_UINT (user_data) == 2) {
157164 global_ragent_read = len;
158165 g_main_loop_quit (global_mainloop);
159166 }
163170 {
164171 g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
165172
166 if ((int)data == 1)
173 if (GPOINTER_TO_UINT (data) == 1)
167174 global_lagent_gathering_done = TRUE;
168 else if ((int)data == 2)
175 else if (GPOINTER_TO_UINT (data) == 2)
169176 global_ragent_gathering_done = TRUE;
170177
171178 if (global_lagent_gathering_done &&
180187 {
181188 g_debug ("test-fullmode:%s: %p", __func__, data);
182189
183 if ((int)data == 1)
190 if (GPOINTER_TO_UINT (data) == 1)
184191 global_lagent_state[component_id - 1] = state;
185 else if ((int)data == 2)
192 else if (GPOINTER_TO_UINT (data) == 2)
186193 global_ragent_state[component_id - 1] = state;
187194
188195 if (state == NICE_COMPONENT_STATE_READY)
217224 {
218225 g_debug ("test-fullmode:%s: %p", __func__, data);
219226
220 if ((int)data == 1)
227 if (GPOINTER_TO_UINT (data) == 1)
221228 ++global_lagent_cands;
222 else if ((int)data == 2)
229 else if (GPOINTER_TO_UINT (data) == 2)
223230 ++global_ragent_cands;
224231
225232 /* XXX: dear compiler, these are for you: */
239246 {
240247 g_debug ("test-fullmode:%s: %p", __func__, data);
241248
242 if ((int)data == 1)
249 if (GPOINTER_TO_UINT (data) == 1)
243250 global_lagent_ibr_received = TRUE;
244 else if ((int)data == 2)
251 else if (GPOINTER_TO_UINT (data) == 2)
245252 global_ragent_ibr_received = TRUE;
246253
247254 if (global_exit_when_ibr_received)
350357
351358 /* step: attach to mainloop (needed to register the fds) */
352359 nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
353 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1);
360 g_main_loop_get_context (global_mainloop), cb_nice_recv,
361 GUINT_TO_POINTER (1));
354362 nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP,
355 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1);
363 g_main_loop_get_context (global_mainloop), cb_nice_recv,
364 GUINT_TO_POINTER (1));
356365 nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
357 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2);
366 g_main_loop_get_context (global_mainloop), cb_nice_recv,
367 GUINT_TO_POINTER (2));
358368 nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP,
359 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2);
369 g_main_loop_get_context (global_mainloop), cb_nice_recv,
370 GUINT_TO_POINTER (2));
360371
361372 /* step: run mainloop until local candidates are ready
362373 * (see timer_cb() above) */
509520
510521 /* step: attach to mainloop (needed to register the fds) */
511522 nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
512 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1);
523 g_main_loop_get_context (global_mainloop), cb_nice_recv,
524 GUINT_TO_POINTER (1));
513525 nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP,
514 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1);
526 g_main_loop_get_context (global_mainloop), cb_nice_recv,
527 GUINT_TO_POINTER (1));
515528 nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
516 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2);
529 g_main_loop_get_context (global_mainloop), cb_nice_recv,
530 GUINT_TO_POINTER (2));
517531 nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP,
518 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2);
532 g_main_loop_get_context (global_mainloop), cb_nice_recv,
533 GUINT_TO_POINTER (2));
519534
520535 /* step: run mainloop until local candidates are ready
521536 * (see timer_cb() above) */
671686
672687 /* step: attach to mainloop (needed to register the fds) */
673688 nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
674 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1);
689 g_main_loop_get_context (global_mainloop), cb_nice_recv,
690 GUINT_TO_POINTER (1));
675691 nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
676 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2);
692 g_main_loop_get_context (global_mainloop), cb_nice_recv,
693 GUINT_TO_POINTER (2));
677694
678695 /* step: run mainloop until local candidates are ready
679696 * (see timer_cb() above) */
799816
800817 /* step: attach to mainloop (needed to register the fds) */
801818 nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
802 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1);
819 g_main_loop_get_context (global_mainloop), cb_nice_recv,
820 GUINT_TO_POINTER (1));
803821 nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
804 g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2);
822 g_main_loop_get_context (global_mainloop), cb_nice_recv,
823 GUINT_TO_POINTER (2));
805824
806825 /* step: run mainloop until local candidates are ready
807826 * (see timer_cb() above) */
923942 nice_agent_add_local_address (ragent, &baseaddr);
924943 #endif
925944
926 g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done",
927 G_CALLBACK (cb_candidate_gathering_done), (gpointer)1);
928 g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done",
929 G_CALLBACK (cb_candidate_gathering_done), (gpointer)2);
930 g_signal_connect (G_OBJECT (lagent), "component-state-changed",
931 G_CALLBACK (cb_component_state_changed), (gpointer)1);
932 g_signal_connect (G_OBJECT (ragent), "component-state-changed",
933 G_CALLBACK (cb_component_state_changed), (gpointer)2);
934 g_signal_connect (G_OBJECT (lagent), "new-selected-pair",
935 G_CALLBACK (cb_new_selected_pair), (gpointer)1);
936 g_signal_connect (G_OBJECT (ragent), "new-selected-pair",
937 G_CALLBACK (cb_new_selected_pair), (gpointer)2);
938 g_signal_connect (G_OBJECT (lagent), "new-candidate",
939 G_CALLBACK (cb_new_candidate), (gpointer)1);
940 g_signal_connect (G_OBJECT (ragent), "new-candidate",
941 G_CALLBACK (cb_new_candidate), (gpointer)2);
942 g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received",
943 G_CALLBACK (cb_initial_binding_request_received), (gpointer)1);
944 g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received",
945 G_CALLBACK (cb_initial_binding_request_received), (gpointer)2);
945 g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done",
946 G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1));
947 g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done",
948 G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2));
949 g_signal_connect (G_OBJECT (lagent), "component-state-changed",
950 G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1));
951 g_signal_connect (G_OBJECT (ragent), "component-state-changed",
952 G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2));
953 g_signal_connect (G_OBJECT (lagent), "new-selected-pair",
954 G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1));
955 g_signal_connect (G_OBJECT (ragent), "new-selected-pair",
956 G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2));
957 g_signal_connect (G_OBJECT (lagent), "new-candidate",
958 G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (1));
959 g_signal_connect (G_OBJECT (ragent), "new-candidate",
960 G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (2));
961 g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received",
962 G_CALLBACK (cb_initial_binding_request_received),
963 GUINT_TO_POINTER (1));
964 g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received",
965 G_CALLBACK (cb_initial_binding_request_received),
966 GUINT_TO_POINTER (2));
946967
947968 stun_server = getenv ("NICE_STUN_SERVER");
948969 stun_server_port = getenv ("NICE_STUN_SERVER_PORT");
952973 g_object_set (G_OBJECT (ragent), "stun-server", stun_server, NULL);
953974 g_object_set (G_OBJECT (ragent), "stun-server-port", atoi (stun_server_port), NULL);
954975 }
976
977 g_object_set (G_OBJECT (lagent), "proxy-ip", PROXY_IP, NULL);
978 g_object_set (G_OBJECT (lagent), "proxy-port", PROXY_PORT, NULL);
979 g_object_set (G_OBJECT (lagent), "proxy-type", PROXY_TYPE, NULL);
980 g_object_set (G_OBJECT (lagent), "proxy-username", PROXY_USERNAME, NULL);
981 g_object_set (G_OBJECT (lagent), "proxy-password", PROXY_PASSWORD, NULL);
982 g_object_set (G_OBJECT (ragent), "proxy-ip", PROXY_IP, NULL);
983 g_object_set (G_OBJECT (ragent), "proxy-port", PROXY_PORT, NULL);
984 g_object_set (G_OBJECT (ragent), "proxy-type", PROXY_TYPE, NULL);
985 g_object_set (G_OBJECT (ragent), "proxy-username", PROXY_USERNAME, NULL);
986 g_object_set (G_OBJECT (ragent), "proxy-password", PROXY_PASSWORD, NULL);
955987
956988 /* step: test setter/getter functions for properties */
957989 {
964996 g_free (string);
965997 g_object_get (G_OBJECT (lagent), "stun-server-port", &port, NULL);
966998 g_assert (stun_server_port == NULL || port == (guint)atoi (stun_server_port));
999 g_object_get (G_OBJECT (lagent), "proxy-ip", &string, NULL);
1000 g_assert (strcmp (string, PROXY_IP) == 0);
1001 g_free (string);
1002 g_object_get (G_OBJECT (lagent), "proxy-port", &port, NULL);
1003 g_assert (port == PROXY_PORT);
9671004 g_object_get (G_OBJECT (lagent), "controlling-mode", &mode, NULL);
9681005 g_assert (mode == TRUE);
9691006 g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 300, NULL);
9981035 g_assert (global_lagent_cands == 2);
9991036 g_assert (global_ragent_cands == 2);
10001037
1001 #ifdef TEST_GOOGLE
1038 #if TEST_GOOGLE
10021039 return result;
10031040 #endif
10041041
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.61 for nice 0.0.3.
2 # Generated by GNU Autoconf 2.61 for nice 0.0.4.
33 #
44 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
55 # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
720720 # Identity of this package.
721721 PACKAGE_NAME='nice'
722722 PACKAGE_TARNAME='nice'
723 PACKAGE_VERSION='0.0.3'
724 PACKAGE_STRING='nice 0.0.3'
723 PACKAGE_VERSION='0.0.4'
724 PACKAGE_STRING='nice 0.0.4'
725725 PACKAGE_BUGREPORT=''
726726
727727 ac_unique_file="agent/agent.c"
856856 ac_ct_DUMPBIN
857857 NM
858858 LN_S
859 OBJDUMP
859860 AR
860861 RANLIB
861862 lt_ECHO
14001401 # Omit some internal or obsolete options to make the list less imposing.
14011402 # This message is too long to be a string in the A/UX 3.1 sh.
14021403 cat <<_ACEOF
1403 \`configure' configures nice 0.0.3 to adapt to many kinds of systems.
1404 \`configure' configures nice 0.0.4 to adapt to many kinds of systems.
14041405
14051406 Usage: $0 [OPTION]... [VAR=VALUE]...
14061407
14701471
14711472 if test -n "$ac_init_help"; then
14721473 case $ac_init_help in
1473 short | recursive ) echo "Configuration of nice 0.0.3:";;
1474 short | recursive ) echo "Configuration of nice 0.0.4:";;
14741475 esac
14751476 cat <<\_ACEOF
14761477
15751576 test -n "$ac_init_help" && exit $ac_status
15761577 if $ac_init_version; then
15771578 cat <<\_ACEOF
1578 nice configure 0.0.3
1579 nice configure 0.0.4
15791580 generated by GNU Autoconf 2.61
15801581
15811582 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
15891590 This file contains any messages produced by compilers while
15901591 running configure, to aid debugging if configure makes a mistake.
15911592
1592 It was created by nice $as_me 0.0.3, which was
1593 It was created by nice $as_me 0.0.4, which was
15931594 generated by GNU Autoconf 2.61. Invocation command line was
15941595
15951596 $ $0 $@
22842285
22852286 # Define the identity of the package.
22862287 PACKAGE='nice'
2287 VERSION='0.0.3'
2288 VERSION='0.0.4'
22882289
22892290
22902291 cat >>confdefs.h <<_ACEOF
24342435
24352436
24362437 # Set the libtool C/A/R version info
2437 NICE_CURRENT=1
2438 NICE_CURRENT=2
24382439 NICE_REVISION=0
2439 NICE_AGE=1
2440 NICE_AGE=2
24402441 NICE_LIBVERSION=${NICE_CURRENT}:${NICE_REVISION}:${NICE_AGE}
24412442 NICE_LT_LDFLAGS="-version-info ${NICE_LIBVERSION}"
24422443
44384439
44394440
44404441
4441 macro_version='2.2.4'
4442 macro_revision='1.2976'
4442 macro_version='2.2.6'
4443 macro_revision='1.3012'
44434444
44444445
44454446
50295030 else
50305031 lt_cv_nm_interface="BSD nm"
50315032 echo "int some_variable = 0;" > conftest.$ac_ext
5032 (eval echo "\"\$as_me:5033: $ac_compile\"" >&5)
5033 (eval echo "\"\$as_me:5034: $ac_compile\"" >&5)
50335034 (eval "$ac_compile" 2>conftest.err)
50345035 cat conftest.err >&5
5035 (eval echo "\"\$as_me:5036: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
5036 (eval echo "\"\$as_me:5037: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
50365037 (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
50375038 cat conftest.err >&5
5038 (eval echo "\"\$as_me:5039: output\"" >&5)
5039 (eval echo "\"\$as_me:5040: output\"" >&5)
50395040 cat conftest.out >&5
50405041 if $GREP 'External.*some_variable' conftest.out > /dev/null; then
50415042 lt_cv_nm_interface="MS dumpbin"
50815082 lt_cv_sys_max_cmd_len=-1;
50825083 ;;
50835084
5084 cygwin* | mingw*)
5085 cygwin* | mingw* | cegcc*)
50855086 # On Win9x/ME, this test blows up -- it succeeds, but takes
50865087 # about 5 minutes as the teststring grows exponentially.
50875088 # Worse, since 9x/ME are not pre-emptively multitasking,
52825283
52835284
52845285
5286 if test -n "$ac_tool_prefix"; then
5287 # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
5288 set dummy ${ac_tool_prefix}objdump; ac_word=$2
5289 { echo "$as_me:$LINENO: checking for $ac_word" >&5
5290 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
5291 if test "${ac_cv_prog_OBJDUMP+set}" = set; then
5292 echo $ECHO_N "(cached) $ECHO_C" >&6
5293 else
5294 if test -n "$OBJDUMP"; then
5295 ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
5296 else
5297 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
5298 for as_dir in $PATH
5299 do
5300 IFS=$as_save_IFS
5301 test -z "$as_dir" && as_dir=.
5302 for ac_exec_ext in '' $ac_executable_extensions; do
5303 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
5304 ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
5305 echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
5306 break 2
5307 fi
5308 done
5309 done
5310 IFS=$as_save_IFS
5311
5312 fi
5313 fi
5314 OBJDUMP=$ac_cv_prog_OBJDUMP
5315 if test -n "$OBJDUMP"; then
5316 { echo "$as_me:$LINENO: result: $OBJDUMP" >&5
5317 echo "${ECHO_T}$OBJDUMP" >&6; }
5318 else
5319 { echo "$as_me:$LINENO: result: no" >&5
5320 echo "${ECHO_T}no" >&6; }
5321 fi
5322
5323
5324 fi
5325 if test -z "$ac_cv_prog_OBJDUMP"; then
5326 ac_ct_OBJDUMP=$OBJDUMP
5327 # Extract the first word of "objdump", so it can be a program name with args.
5328 set dummy objdump; ac_word=$2
5329 { echo "$as_me:$LINENO: checking for $ac_word" >&5
5330 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
5331 if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then
5332 echo $ECHO_N "(cached) $ECHO_C" >&6
5333 else
5334 if test -n "$ac_ct_OBJDUMP"; then
5335 ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
5336 else
5337 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
5338 for as_dir in $PATH
5339 do
5340 IFS=$as_save_IFS
5341 test -z "$as_dir" && as_dir=.
5342 for ac_exec_ext in '' $ac_executable_extensions; do
5343 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
5344 ac_cv_prog_ac_ct_OBJDUMP="objdump"
5345 echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
5346 break 2
5347 fi
5348 done
5349 done
5350 IFS=$as_save_IFS
5351
5352 fi
5353 fi
5354 ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
5355 if test -n "$ac_ct_OBJDUMP"; then
5356 { echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5
5357 echo "${ECHO_T}$ac_ct_OBJDUMP" >&6; }
5358 else
5359 { echo "$as_me:$LINENO: result: no" >&5
5360 echo "${ECHO_T}no" >&6; }
5361 fi
5362
5363 if test "x$ac_ct_OBJDUMP" = x; then
5364 OBJDUMP="false"
5365 else
5366 case $cross_compiling:$ac_tool_warned in
5367 yes:)
5368 { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
5369 whose name does not start with the host triplet. If you think this
5370 configuration is useful to you, please write to autoconf@gnu.org." >&5
5371 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
5372 whose name does not start with the host triplet. If you think this
5373 configuration is useful to you, please write to autoconf@gnu.org." >&2;}
5374 ac_tool_warned=yes ;;
5375 esac
5376 OBJDUMP=$ac_ct_OBJDUMP
5377 fi
5378 else
5379 OBJDUMP="$ac_cv_prog_OBJDUMP"
5380 fi
5381
5382 test -z "$OBJDUMP" && OBJDUMP=objdump
5383
5384
5385
5386
5387
5388
5389
5390
52855391
52865392 { echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5
52875393 echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6; }
53345440 lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
53355441 lt_cv_file_magic_cmd='$OBJDUMP -f'
53365442 fi
5443 ;;
5444
5445 cegcc)
5446 # use the weaker test based on 'objdump'. See mingw*.
5447 lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
5448 lt_cv_file_magic_cmd='$OBJDUMP -f'
53375449 ;;
53385450
53395451 darwin* | rhapsody*)
58865998 aix*)
58875999 symcode='[BCDT]'
58886000 ;;
5889 cygwin* | mingw* | pw32*)
6001 cygwin* | mingw* | pw32* | cegcc*)
58906002 symcode='[ABCDGISTW]'
58916003 ;;
58926004 hpux*)
61456257 ;;
61466258 *-*-irix6*)
61476259 # Find out which ABI we are using.
6148 echo '#line 6149 "configure"' > conftest.$ac_ext
6260 echo '#line 6261 "configure"' > conftest.$ac_ext
61496261 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
61506262 (eval $ac_compile) 2>&5
61516263 ac_status=$?
75187630 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
75197631 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
75207632 -e 's:$: $lt_compiler_flag:'`
7521 (eval echo "\"\$as_me:7522: $lt_compile\"" >&5)
7633 (eval echo "\"\$as_me:7634: $lt_compile\"" >&5)
75227634 (eval "$lt_compile" 2>conftest.err)
75237635 ac_status=$?
75247636 cat conftest.err >&5
7525 echo "$as_me:7526: \$? = $ac_status" >&5
7637 echo "$as_me:7638: \$? = $ac_status" >&5
75267638 if (exit $ac_status) && test -s "$ac_outfile"; then
75277639 # The compiler can only warn and ignore the option if not recognized
75287640 # So say no if there are warnings other than the usual output.
75907702 # PIC is the default for these OSes.
75917703 ;;
75927704
7593 mingw* | cygwin* | pw32* | os2*)
7705 mingw* | cygwin* | pw32* | os2* | cegcc*)
75947706 # This hack is so that the source file can tell whether it is being
75957707 # built for inclusion in a dll (and should export symbols for example).
75967708 # Although the cygwin gcc ignores -fPIC, still need this for old-style
76057717 ;;
76067718
76077719 hpux*)
7608 # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
7609 # not for PA HP-UX.
7720 # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
7721 # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
7722 # sets the default TLS model and affects inlining.
76107723 case $host_cpu in
7611 hppa*64*|ia64*)
7724 hppa*64*)
76127725 # +Z the default
76137726 ;;
76147727 *)
76587771 fi
76597772 ;;
76607773
7661 mingw* | cygwin* | pw32* | os2*)
7774 mingw* | cygwin* | pw32* | os2* | cegcc*)
76627775 # This hack is so that the source file can tell whether it is being
76637776 # built for inclusion in a dll (and should export symbols for example).
76647777 lt_prog_compiler_pic='-DDLL_EXPORT'
76887801
76897802 linux* | k*bsd*-gnu)
76907803 case $cc_basename in
7691 icc* | ecc* | ifort*)
7804 # old Intel for x86_64 which still supported -KPIC.
7805 ecc*)
76927806 lt_prog_compiler_wl='-Wl,'
76937807 lt_prog_compiler_pic='-KPIC'
76947808 lt_prog_compiler_static='-static'
76957809 ;;
7810 # icc used to be incompatible with GCC.
7811 # ICC 10 doesn't accept -KPIC any more.
7812 icc* | ifort*)
7813 lt_prog_compiler_wl='-Wl,'
7814 lt_prog_compiler_pic='-fPIC'
7815 lt_prog_compiler_static='-static'
7816 ;;
7817 # Lahey Fortran 8.1.
7818 lf95*)
7819 lt_prog_compiler_wl='-Wl,'
7820 lt_prog_compiler_pic='--shared'
7821 lt_prog_compiler_static='--static'
7822 ;;
76967823 pgcc* | pgf77* | pgf90* | pgf95*)
76977824 # Portland Group compilers (*not* the Pentium gcc compiler,
76987825 # which looks to be a dead project)
78427969 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
78437970 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
78447971 -e 's:$: $lt_compiler_flag:'`
7845 (eval echo "\"\$as_me:7846: $lt_compile\"" >&5)
7972 (eval echo "\"\$as_me:7973: $lt_compile\"" >&5)
78467973 (eval "$lt_compile" 2>conftest.err)
78477974 ac_status=$?
78487975 cat conftest.err >&5
7849 echo "$as_me:7850: \$? = $ac_status" >&5
7976 echo "$as_me:7977: \$? = $ac_status" >&5
78507977 if (exit $ac_status) && test -s "$ac_outfile"; then
78517978 # The compiler can only warn and ignore the option if not recognized
78527979 # So say no if there are warnings other than the usual output.
79478074 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
79488075 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
79498076 -e 's:$: $lt_compiler_flag:'`
7950 (eval echo "\"\$as_me:7951: $lt_compile\"" >&5)
8077 (eval echo "\"\$as_me:8078: $lt_compile\"" >&5)
79518078 (eval "$lt_compile" 2>out/conftest.err)
79528079 ac_status=$?
79538080 cat out/conftest.err >&5
7954 echo "$as_me:7955: \$? = $ac_status" >&5
8081 echo "$as_me:8082: \$? = $ac_status" >&5
79558082 if (exit $ac_status) && test -s out/conftest2.$ac_objext
79568083 then
79578084 # The compiler can only warn and ignore the option if not recognized
80028129 -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
80038130 -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
80048131 -e 's:$: $lt_compiler_flag:'`
8005 (eval echo "\"\$as_me:8006: $lt_compile\"" >&5)
8132 (eval echo "\"\$as_me:8133: $lt_compile\"" >&5)
80068133 (eval "$lt_compile" 2>out/conftest.err)
80078134 ac_status=$?
80088135 cat out/conftest.err >&5
8009 echo "$as_me:8010: \$? = $ac_status" >&5
8136 echo "$as_me:8137: \$? = $ac_status" >&5
80108137 if (exit $ac_status) && test -s out/conftest2.$ac_objext
80118138 then
80128139 # The compiler can only warn and ignore the option if not recognized
81068233 extract_expsyms_cmds=
81078234
81088235 case $host_os in
8109 cygwin* | mingw* | pw32*)
8236 cygwin* | mingw* | pw32* | cegcc*)
81108237 # FIXME: the MSVC++ port hasn't been tested in a loooong time
81118238 # When not using gcc, we currently assume that we are using
81128239 # Microsoft Visual C++.
81938320 fi
81948321 ;;
81958322
8196 cygwin* | mingw* | pw32*)
8323 cygwin* | mingw* | pw32* | cegcc*)
81978324 # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
81988325 # as there is no search path for DLLs.
81998326 hardcode_libdir_flag_spec='-L$libdir'
82598386 tmp_addflag=' -i_dynamic -nofor_main' ;;
82608387 ifc* | ifort*) # Intel Fortran compiler
82618388 tmp_addflag=' -nofor_main' ;;
8389 lf95*) # Lahey Fortran 8.1
8390 whole_archive_flag_spec=
8391 tmp_sharedflag='--shared' ;;
82628392 xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
82638393 tmp_sharedflag='-qmkshrobj'
82648394 tmp_addflag= ;;
84918621 fi
84928622 fi
84938623
8624 export_dynamic_flag_spec='${wl}-bexpall'
84948625 # It seems that -bexpall does not export symbols beginning with
84958626 # underscore (_), so it is better to generate a list of symbols to export.
84968627 always_export_symbols=yes
86578788 export_dynamic_flag_spec=-rdynamic
86588789 ;;
86598790
8660 cygwin* | mingw* | pw32*)
8791 cygwin* | mingw* | pw32* | cegcc*)
86618792 # When not using gcc, we currently assume that we are using
86628793 # Microsoft Visual C++.
86638794 # hardcode_libdir_flag_spec is actually meaningless, as there is
86888819 whole_archive_flag_spec=''
86898820 link_all_deplibs=yes
86908821 allow_undefined_flag="$_lt_dar_allow_undefined"
8691 if test "$GCC" = "yes"; then
8822 case $cc_basename in
8823 ifort*) _lt_dar_can_shared=yes ;;
8824 *) _lt_dar_can_shared=$GCC ;;
8825 esac
8826 if test "$_lt_dar_can_shared" = "yes"; then
86928827 output_verbose_link_cmd=echo
86938828 archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
86948829 module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
87808915 archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
87818916 ;;
87828917 ia64*)
8783 archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
8918 archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
87848919 ;;
87858920 *)
87868921 archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
95189653 # libtool to hard-code these into programs
95199654 ;;
95209655
9521 cygwin* | mingw* | pw32*)
9656 cygwin* | mingw* | pw32* | cegcc*)
95229657 version_type=windows
95239658 shrext_cmds=".dll"
95249659 need_version=no
95259660 need_lib_prefix=no
95269661
95279662 case $GCC,$host_os in
9528 yes,cygwin* | yes,mingw* | yes,pw32*)
9663 yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
95299664 library_names_spec='$libname.dll.a'
95309665 # DLL is installed to $(libdir)/../bin by postinstall_cmds
95319666 postinstall_cmds='base_file=`basename \${file}`~
95489683 soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
95499684 sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
95509685 ;;
9551 mingw*)
9686 mingw* | cegcc*)
95529687 # MinGW DLLs use traditional 'lib' prefix
95539688 soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
95549689 sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
1002910164 version_type=linux
1003010165 need_lib_prefix=no
1003110166 need_version=no
10032 library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
10167 library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
1003310168 shlibpath_var=LD_LIBRARY_PATH
1003410169 shlibpath_overrides_runpath=no
1003510170 hardcode_into_libs=yes
1020610341 lt_cv_dlopen_self=yes
1020710342 ;;
1020810343
10209 mingw* | pw32*)
10344 mingw* | pw32* | cegcc*)
1021010345 lt_cv_dlopen="LoadLibrary"
1021110346 lt_cv_dlopen_libs=
1021210347 ;;
1076310898 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
1076410899 lt_status=$lt_dlunknown
1076510900 cat > conftest.$ac_ext <<_LT_EOF
10766 #line 10767 "configure"
10901 #line 10902 "configure"
1076710902 #include "confdefs.h"
1076810903
1076910904 #if HAVE_DLFCN_H
1080410939 # endif
1080510940 #endif
1080610941
10807 #ifdef __cplusplus
10808 extern "C" void exit (int);
10809 #endif
10810
1081110942 void fnord() { int i=42;}
1081210943 int main ()
1081310944 {
1082310954 else
1082410955 puts (dlerror ());
1082510956
10826 exit (status);
10957 return status;
1082710958 }
1082810959 _LT_EOF
1082910960 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
1086310994 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
1086410995 lt_status=$lt_dlunknown
1086510996 cat > conftest.$ac_ext <<_LT_EOF
10866 #line 10867 "configure"
10997 #line 10998 "configure"
1086710998 #include "confdefs.h"
1086810999
1086911000 #if HAVE_DLFCN_H
1090411035 # endif
1090511036 #endif
1090611037
10907 #ifdef __cplusplus
10908 extern "C" void exit (int);
10909 #endif
10910
1091111038 void fnord() { int i=42;}
1091211039 int main ()
1091311040 {
1092311050 else
1092411051 puts (dlerror ());
1092511052
10926 exit (status);
11053 return status;
1092711054 }
1092811055 _LT_EOF
1092911056 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
1201912146 { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"
1202012147 gstreamer-0.10 >= 0.10.0
1202112148 gstreamer-base-0.10 >= 0.10.0
12022 gstreamer-netbuffer-0.10 >= 0.10.0
1202312149 \"") >&5
1202412150 ($PKG_CONFIG --exists --print-errors "
1202512151 gstreamer-0.10 >= 0.10.0
1202612152 gstreamer-base-0.10 >= 0.10.0
12027 gstreamer-netbuffer-0.10 >= 0.10.0
1202812153 ") 2>&5
1202912154 ac_status=$?
1203012155 echo "$as_me:$LINENO: \$? = $ac_status" >&5
1203212157 pkg_cv_GST_CFLAGS=`$PKG_CONFIG --cflags "
1203312158 gstreamer-0.10 >= 0.10.0
1203412159 gstreamer-base-0.10 >= 0.10.0
12035 gstreamer-netbuffer-0.10 >= 0.10.0
1203612160 " 2>/dev/null`
1203712161 else
1203812162 pkg_failed=yes
1204912173 { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"
1205012174 gstreamer-0.10 >= 0.10.0
1205112175 gstreamer-base-0.10 >= 0.10.0
12052 gstreamer-netbuffer-0.10 >= 0.10.0
1205312176 \"") >&5
1205412177 ($PKG_CONFIG --exists --print-errors "
1205512178 gstreamer-0.10 >= 0.10.0
1205612179 gstreamer-base-0.10 >= 0.10.0
12057 gstreamer-netbuffer-0.10 >= 0.10.0
1205812180 ") 2>&5
1205912181 ac_status=$?
1206012182 echo "$as_me:$LINENO: \$? = $ac_status" >&5
1206212184 pkg_cv_GST_LIBS=`$PKG_CONFIG --libs "
1206312185 gstreamer-0.10 >= 0.10.0
1206412186 gstreamer-base-0.10 >= 0.10.0
12065 gstreamer-netbuffer-0.10 >= 0.10.0
1206612187 " 2>/dev/null`
1206712188 else
1206812189 pkg_failed=yes
1208512206 GST_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "
1208612207 gstreamer-0.10 >= 0.10.0
1208712208 gstreamer-base-0.10 >= 0.10.0
12088 gstreamer-netbuffer-0.10 >= 0.10.0
1208912209 "`
1209012210 else
1209112211 GST_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "
1209212212 gstreamer-0.10 >= 0.10.0
1209312213 gstreamer-base-0.10 >= 0.10.0
12094 gstreamer-netbuffer-0.10 >= 0.10.0
1209512214 "`
1209612215 fi
1209712216 # Put the nasty error message in config.log where it belongs
1270412823 # report actual input values of CONFIG_FILES etc. instead of their
1270512824 # values after options handling.
1270612825 ac_log="
12707 This file was extended by nice $as_me 0.0.3, which was
12826 This file was extended by nice $as_me 0.0.4, which was
1270812827 generated by GNU Autoconf 2.61. Invocation command line was
1270912828
1271012829 CONFIG_FILES = $CONFIG_FILES
1275712876 _ACEOF
1275812877 cat >>$CONFIG_STATUS <<_ACEOF
1275912878 ac_cs_version="\\
12760 nice config.status 0.0.3
12879 nice config.status 0.0.4
1276112880 configured by $0, generated by GNU Autoconf 2.61,
1276212881 with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
1276312882
1289913018 lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
1290013019 reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
1290113020 reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
13021 OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
1290213022 deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
1290313023 file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
1290413024 AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
1300413124 lt_SP2NL \
1300513125 lt_NL2SP \
1300613126 reload_flag \
13127 OBJDUMP \
1300713128 deplibs_check_method \
1300813129 file_magic_cmd \
1300913130 AR \
1329713418 ac_ct_DUMPBIN!$ac_ct_DUMPBIN$ac_delim
1329813419 NM!$NM$ac_delim
1329913420 LN_S!$LN_S$ac_delim
13421 OBJDUMP!$OBJDUMP$ac_delim
1330013422 AR!$AR$ac_delim
13301 RANLIB!$RANLIB$ac_delim
1330213423 _ACEOF
1330313424
1330413425 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
1334013461 ac_delim='%!_!# '
1334113462 for ac_last_try in false false false false false :; do
1334213463 cat >conf$$subs.sed <<_ACEOF
13464 RANLIB!$RANLIB$ac_delim
1334313465 lt_ECHO!$lt_ECHO$ac_delim
1334413466 DSYMUTIL!$DSYMUTIL$ac_delim
1334513467 NMEDIT!$NMEDIT$ac_delim
1336713489 LTLIBOBJS!$LTLIBOBJS$ac_delim
1336813490 _ACEOF
1336913491
13370 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 25; then
13492 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 26; then
1337113493 break
1337213494 elif $ac_last_try; then
1337313495 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
1405614178 reload_flag=$lt_reload_flag
1405714179 reload_cmds=$lt_reload_cmds
1405814180
14181 # An object symbol dumper.
14182 OBJDUMP=$lt_OBJDUMP
14183
1405914184 # Method to check whether dependent libraries are shared objects.
1406014185 deplibs_check_method=$lt_deplibs_check_method
1406114186
22
33 dnl releases only do -Wall, cvs and prerelease does -Werror too
44 dnl use a three digit version number for releases, and four for cvs/prerelease
5 AC_INIT(nice, 0.0.3)
5 AC_INIT(nice, 0.0.4)
66 NICE_RELEASE="yes"
77
88 AC_CONFIG_SRCDIR([agent/agent.c])
2525 ])
2626
2727 # Set the libtool C/A/R version info
28 NICE_CURRENT=1
28 NICE_CURRENT=2
2929 NICE_REVISION=0
30 NICE_AGE=1
30 NICE_AGE=2
3131 NICE_LIBVERSION=${NICE_CURRENT}:${NICE_REVISION}:${NICE_AGE}
3232 NICE_LT_LDFLAGS="-version-info ${NICE_LIBVERSION}"
3333 AC_SUBST(NICE_LT_LDFLAGS)
8181 PKG_CHECK_MODULES(GST, [
8282 gstreamer-0.10 >= 0.10.0
8383 gstreamer-base-0.10 >= 0.10.0
84 gstreamer-netbuffer-0.10 >= 0.10.0
8584 ],
8685 [
8786 with_gstreamer=yes
105105 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
106106 NM = @NM@
107107 NMEDIT = @NMEDIT@
108 OBJDUMP = @OBJDUMP@
108109 OBJEXT = @OBJEXT@
109110 OTOOL = @OTOOL@
110111 OTOOL64 = @OTOOL64@
105105 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
106106 NM = @NM@
107107 NMEDIT = @NMEDIT@
108 OBJDUMP = @OBJDUMP@
108109 OBJEXT = @OBJEXT@
109110 OTOOL = @OTOOL@
110111 OTOOL64 = @OTOOL64@
100100 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
101101 NM = @NM@
102102 NMEDIT = @NMEDIT@
103 OBJDUMP = @OBJDUMP@
103104 OBJEXT = @OBJEXT@
104105 OTOOL = @OTOOL@
105106 OTOOL64 = @OTOOL64@
2121 </tr></table>
2222 <div class="chapter" lang="en">
2323 <div class="titlepage"><div><div><h2 class="title">
24 <a name="id2548431"></a>libnice's public API</h2></div></div></div>
24 <a name="id2970939"></a>libnice's public API</h2></div></div></div>
2525 <div class="toc"><dl>
2626 <dt>
2727 <span class="refentrytitle"><a href="libnice-NiceAgent.html">NiceAgent</a></span><span class="refpurpose"> — ICE agent API implementation</span>
3333 <ANCHOR id="NiceAgent--full-mode" href="libnice/libnice-NiceAgent.html#NiceAgent--full-mode">
3434 <ANCHOR id="NiceAgent--main-context" href="libnice/libnice-NiceAgent.html#NiceAgent--main-context">
3535 <ANCHOR id="NiceAgent--max-connectivity-checks" href="libnice/libnice-NiceAgent.html#NiceAgent--max-connectivity-checks">
36 <ANCHOR id="NiceAgent--proxy-ip" href="libnice/libnice-NiceAgent.html#NiceAgent--proxy-ip">
37 <ANCHOR id="NiceAgent--proxy-password" href="libnice/libnice-NiceAgent.html#NiceAgent--proxy-password">
38 <ANCHOR id="NiceAgent--proxy-port" href="libnice/libnice-NiceAgent.html#NiceAgent--proxy-port">
39 <ANCHOR id="NiceAgent--proxy-type" href="libnice/libnice-NiceAgent.html#NiceAgent--proxy-type">
40 <ANCHOR id="NiceAgent--proxy-username" href="libnice/libnice-NiceAgent.html#NiceAgent--proxy-username">
3641 <ANCHOR id="NiceAgent--stun-pacing-timer" href="libnice/libnice-NiceAgent.html#NiceAgent--stun-pacing-timer">
3742 <ANCHOR id="NiceAgent--stun-server" href="libnice/libnice-NiceAgent.html#NiceAgent--stun-server">
3843 <ANCHOR id="NiceAgent--stun-server-port" href="libnice/libnice-NiceAgent.html#NiceAgent--stun-server-port">
244244 "<a class="link" href="libnice-NiceAgent.html#NiceAgent--max-connectivity-checks" title='The "max-connectivity-checks" property'>max-connectivity-checks</a>" <a
245245 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#guint"
246246 >guint</a> : Read / Write
247 "<a class="link" href="libnice-NiceAgent.html#NiceAgent--proxy-ip" title='The "proxy-ip" property'>proxy-ip</a>" <a
248 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#gchar"
249 >gchar</a>* : Read / Write
250 "<a class="link" href="libnice-NiceAgent.html#NiceAgent--proxy-password" title='The "proxy-password" property'>proxy-password</a>" <a
251 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#gchar"
252 >gchar</a>* : Read / Write
253 "<a class="link" href="libnice-NiceAgent.html#NiceAgent--proxy-port" title='The "proxy-port" property'>proxy-port</a>" <a
254 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#guint"
255 >guint</a> : Read / Write
256 "<a class="link" href="libnice-NiceAgent.html#NiceAgent--proxy-type" title='The "proxy-type" property'>proxy-type</a>" <a
257 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#guint"
258 >guint</a> : Read / Write
259 "<a class="link" href="libnice-NiceAgent.html#NiceAgent--proxy-username" title='The "proxy-username" property'>proxy-username</a>" <a
260 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#gchar"
261 >gchar</a>* : Read / Write
247262 "<a class="link" href="libnice-NiceAgent.html#NiceAgent--stun-pacing-timer" title='The "stun-pacing-timer" property'>stun-pacing-timer</a>" <a
248263 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#guint"
249264 >guint</a> : Read / Write / Construct Only
277292 <p>
278293 </p>
279294 <div class="example">
280 <a name="id2565644"></a><p class="title"><b>Example 1. Simple example on how to use libnice</b></p>
295 <a name="id3035523"></a><p class="title"><b>Example 1. Simple example on how to use libnice</b></p>
281296 <div class="example-contents"><pre class="programlisting">
282297 NiceAddress base_addr;
283298 guint stream_id;
420435 component_id for RTP/RTCP usages.
421436 </p>
422437 <div class="example">
423 <a name="id2565973"></a><p class="title"><b>Example 2. Example of use.</b></p>
438 <a name="id3035852"></a><p class="title"><b>Example 2. Example of use.</b></p>
424439 <div class="example-contents"><pre class="programlisting">
425440 nice_agent_send (agent, stream_id, NICE_COMPONENT_TYPE_RTP, len, buf);
426441 </pre></div>
559574 GTimeVal next_check_tv; /**&lt; property: next conncheck timestamp */
560575 gchar *stun_server_ip; /**&lt; property: STUN server IP */
561576 guint stun_server_port; /**&lt; property: STUN server port */
577 gchar *proxy_ip; /**&lt; property: Proxy server IP */
578 guint proxy_port; /**&lt; property: Proxy server port */
579 NiceProxyType proxy_type; /**&lt; property: Proxy type */
580 gchar *proxy_username; /**&lt; property: Proxy username */
581 gchar *proxy_password; /**&lt; property: Proxy password */
562582 gboolean controlling_mode; /**&lt; property: controlling-mode */
563583 guint timer_ta; /**&lt; property: timer Ta */
564584 guint max_conn_checks; /**&lt; property: max connectivity checks */
15301550 </div>
15311551 <hr>
15321552 <div class="refsect2" lang="en">
1553 <a name="NiceAgent--proxy-ip"></a><h3>The <code class="literal">"proxy-ip"</code> property</h3>
1554 <pre class="programlisting"> "proxy-ip" <a
1555 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#gchar"
1556 >gchar</a>* : Read / Write</pre>
1557 <p>The proxy server used to bypass a proxy firewall.</p>
1558 <p>Default value: NULL</p>
1559 </div>
1560 <hr>
1561 <div class="refsect2" lang="en">
1562 <a name="NiceAgent--proxy-password"></a><h3>The <code class="literal">"proxy-password"</code> property</h3>
1563 <pre class="programlisting"> "proxy-password" <a
1564 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#gchar"
1565 >gchar</a>* : Read / Write</pre>
1566 <p>The password used to authenticate with the proxy.</p>
1567 <p>Default value: NULL</p>
1568 </div>
1569 <hr>
1570 <div class="refsect2" lang="en">
1571 <a name="NiceAgent--proxy-port"></a><h3>The <code class="literal">"proxy-port"</code> property</h3>
1572 <pre class="programlisting"> "proxy-port" <a
1573 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#guint"
1574 >guint</a> : Read / Write</pre>
1575 <p>The Proxy server used to bypass a proxy firewall.</p>
1576 <p>Allowed values: [1,65536]</p>
1577 <p>Default value: 1</p>
1578 </div>
1579 <hr>
1580 <div class="refsect2" lang="en">
1581 <a name="NiceAgent--proxy-type"></a><h3>The <code class="literal">"proxy-type"</code> property</h3>
1582 <pre class="programlisting"> "proxy-type" <a
1583 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#guint"
1584 >guint</a> : Read / Write</pre>
1585 <p>The type of proxy set in the proxy-ip property.</p>
1586 <p>Allowed values: &lt;= 2</p>
1587 <p>Default value: 0</p>
1588 </div>
1589 <hr>
1590 <div class="refsect2" lang="en">
1591 <a name="NiceAgent--proxy-username"></a><h3>The <code class="literal">"proxy-username"</code> property</h3>
1592 <pre class="programlisting"> "proxy-username" <a
1593 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#gchar"
1594 >gchar</a>* : Read / Write</pre>
1595 <p>The username used to authenticate with the proxy.</p>
1596 <p>Default value: NULL</p>
1597 </div>
1598 <hr>
1599 <div class="refsect2" lang="en">
15331600 <a name="NiceAgent--stun-pacing-timer"></a><h3>The <code class="literal">"stun-pacing-timer"</code> property</h3>
15341601 <pre class="programlisting"> "stun-pacing-timer" <a
15351602 href="/usr/share/gtk-doc/html/glib/glib-Basic-Types.html#guint"
3636 <function name="The &quot;full-mode&quot; property" link="libnice-NiceAgent.html#NiceAgent--full-mode"/>
3737 <function name="The &quot;main-context&quot; property" link="libnice-NiceAgent.html#NiceAgent--main-context"/>
3838 <function name="The &quot;max-connectivity-checks&quot; property" link="libnice-NiceAgent.html#NiceAgent--max-connectivity-checks"/>
39 <function name="The &quot;proxy-ip&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-ip"/>
40 <function name="The &quot;proxy-password&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-password"/>
41 <function name="The &quot;proxy-port&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-port"/>
42 <function name="The &quot;proxy-type&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-type"/>
43 <function name="The &quot;proxy-username&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-username"/>
3944 <function name="The &quot;stun-pacing-timer&quot; property" link="libnice-NiceAgent.html#NiceAgent--stun-pacing-timer"/>
4045 <function name="The &quot;stun-server&quot; property" link="libnice-NiceAgent.html#NiceAgent--stun-server"/>
4146 <function name="The &quot;stun-server-port&quot; property" link="libnice-NiceAgent.html#NiceAgent--stun-server-port"/>
3636 <keyword type="" name="The &quot;full-mode&quot; property" link="libnice-NiceAgent.html#NiceAgent--full-mode"/>
3737 <keyword type="" name="The &quot;main-context&quot; property" link="libnice-NiceAgent.html#NiceAgent--main-context"/>
3838 <keyword type="" name="The &quot;max-connectivity-checks&quot; property" link="libnice-NiceAgent.html#NiceAgent--max-connectivity-checks"/>
39 <keyword type="" name="The &quot;proxy-ip&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-ip"/>
40 <keyword type="" name="The &quot;proxy-password&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-password"/>
41 <keyword type="" name="The &quot;proxy-port&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-port"/>
42 <keyword type="" name="The &quot;proxy-type&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-type"/>
43 <keyword type="" name="The &quot;proxy-username&quot; property" link="libnice-NiceAgent.html#NiceAgent--proxy-username"/>
3944 <keyword type="" name="The &quot;stun-pacing-timer&quot; property" link="libnice-NiceAgent.html#NiceAgent--stun-pacing-timer"/>
4045 <keyword type="" name="The &quot;stun-server&quot; property" link="libnice-NiceAgent.html#NiceAgent--stun-server"/>
4146 <keyword type="" name="The &quot;stun-server-port&quot; property" link="libnice-NiceAgent.html#NiceAgent--stun-server-port"/>
155155
156156 </para>
157157
158 <!-- ##### ARG NiceAgent:proxy-ip ##### -->
159 <para>
160
161 </para>
162
163 <!-- ##### ARG NiceAgent:proxy-password ##### -->
164 <para>
165
166 </para>
167
168 <!-- ##### ARG NiceAgent:proxy-port ##### -->
169 <para>
170
171 </para>
172
173 <!-- ##### ARG NiceAgent:proxy-type ##### -->
174 <para>
175
176 </para>
177
178 <!-- ##### ARG NiceAgent:proxy-username ##### -->
179 <para>
180
181 </para>
182
158183 <!-- ##### ARG NiceAgent:stun-pacing-timer ##### -->
159184 <para>
160185
109109 &quot;<link linkend="NiceAgent--full-mode">full-mode</link>&quot; <link linkend="gboolean">gboolean</link> : Read / Write / Construct Only
110110 &quot;<link linkend="NiceAgent--main-context">main-context</link>&quot; <link linkend="gpointer">gpointer</link> : Read / Write / Construct Only
111111 &quot;<link linkend="NiceAgent--max-connectivity-checks">max-connectivity-checks</link>&quot; <link linkend="guint">guint</link> : Read / Write
112 &quot;<link linkend="NiceAgent--proxy-ip">proxy-ip</link>&quot; <link linkend="gchar">gchar</link>* : Read / Write
113 &quot;<link linkend="NiceAgent--proxy-password">proxy-password</link>&quot; <link linkend="gchar">gchar</link>* : Read / Write
114 &quot;<link linkend="NiceAgent--proxy-port">proxy-port</link>&quot; <link linkend="guint">guint</link> : Read / Write
115 &quot;<link linkend="NiceAgent--proxy-type">proxy-type</link>&quot; <link linkend="guint">guint</link> : Read / Write
116 &quot;<link linkend="NiceAgent--proxy-username">proxy-username</link>&quot; <link linkend="gchar">gchar</link>* : Read / Write
112117 &quot;<link linkend="NiceAgent--stun-pacing-timer">stun-pacing-timer</link>&quot; <link linkend="guint">guint</link> : Read / Write / Construct Only
113118 &quot;<link linkend="NiceAgent--stun-server">stun-server</link>&quot; <link linkend="gchar">gchar</link>* : Read / Write
114119 &quot;<link linkend="NiceAgent--stun-server-port">stun-server-port</link>&quot; <link linkend="guint">guint</link> : Read / Write
370375 GTimeVal next_check_tv; /**&lt; property: next conncheck timestamp */
371376 gchar *stun_server_ip; /**&lt; property: STUN server IP */
372377 guint stun_server_port; /**&lt; property: STUN server port */
378 gchar *proxy_ip; /**&lt; property: Proxy server IP */
379 guint proxy_port; /**&lt; property: Proxy server port */
380 NiceProxyType proxy_type; /**&lt; property: Proxy type */
381 gchar *proxy_username; /**&lt; property: Proxy username */
382 gchar *proxy_password; /**&lt; property: Proxy password */
373383 gboolean controlling_mode; /**&lt; property: controlling-mode */
374384 guint timer_ta; /**&lt; property: timer Ta */
375385 guint max_conn_checks; /**&lt; property: max connectivity checks */
908918 <indexterm zone="NiceAgent--max-connectivity-checks"><primary>NiceAgent:max-connectivity-checks</primary></indexterm><programlisting> &quot;max-connectivity-checks&quot; <link linkend="guint">guint</link> : Read / Write</programlisting>
909919 <para>Upper limit for the total number of connectivity checks performed.</para><para>Default value: 0</para>
910920 </refsect2>
921 <refsect2 id="NiceAgent--proxy-ip"><title>The <literal>&quot;proxy-ip&quot;</literal> property</title>
922 <indexterm zone="NiceAgent--proxy-ip"><primary>NiceAgent:proxy-ip</primary></indexterm><programlisting> &quot;proxy-ip&quot; <link linkend="gchar">gchar</link>* : Read / Write</programlisting>
923 <para>The proxy server used to bypass a proxy firewall.</para><para>Default value: NULL</para>
924 </refsect2>
925 <refsect2 id="NiceAgent--proxy-password"><title>The <literal>&quot;proxy-password&quot;</literal> property</title>
926 <indexterm zone="NiceAgent--proxy-password"><primary>NiceAgent:proxy-password</primary></indexterm><programlisting> &quot;proxy-password&quot; <link linkend="gchar">gchar</link>* : Read / Write</programlisting>
927 <para>The password used to authenticate with the proxy.</para><para>Default value: NULL</para>
928 </refsect2>
929 <refsect2 id="NiceAgent--proxy-port"><title>The <literal>&quot;proxy-port&quot;</literal> property</title>
930 <indexterm zone="NiceAgent--proxy-port"><primary>NiceAgent:proxy-port</primary></indexterm><programlisting> &quot;proxy-port&quot; <link linkend="guint">guint</link> : Read / Write</programlisting>
931 <para>The Proxy server used to bypass a proxy firewall.</para><para>Allowed values: [1,65536]</para>
932 <para>Default value: 1</para>
933 </refsect2>
934 <refsect2 id="NiceAgent--proxy-type"><title>The <literal>&quot;proxy-type&quot;</literal> property</title>
935 <indexterm zone="NiceAgent--proxy-type"><primary>NiceAgent:proxy-type</primary></indexterm><programlisting> &quot;proxy-type&quot; <link linkend="guint">guint</link> : Read / Write</programlisting>
936 <para>The type of proxy set in the proxy-ip property.</para><para>Allowed values: &lt;= 2</para>
937 <para>Default value: 0</para>
938 </refsect2>
939 <refsect2 id="NiceAgent--proxy-username"><title>The <literal>&quot;proxy-username&quot;</literal> property</title>
940 <indexterm zone="NiceAgent--proxy-username"><primary>NiceAgent:proxy-username</primary></indexterm><programlisting> &quot;proxy-username&quot; <link linkend="gchar">gchar</link>* : Read / Write</programlisting>
941 <para>The username used to authenticate with the proxy.</para><para>Default value: NULL</para>
942 </refsect2>
911943 <refsect2 id="NiceAgent--stun-pacing-timer"><title>The <literal>&quot;stun-pacing-timer&quot;</literal> property</title>
912944 <indexterm zone="NiceAgent--stun-pacing-timer"><primary>NiceAgent:stun-pacing-timer</primary></indexterm><programlisting> &quot;stun-pacing-timer&quot; <link linkend="guint">guint</link> : Read / Write / Construct Only</programlisting>
913945 <para>Timer 'Ta' (msecs) used in the IETF ICE specification for pacing candidate gathering and sending of connectivity checks.</para><para>Allowed values: &gt;= 1</para>
134134 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
135135 NM = @NM@
136136 NMEDIT = @NMEDIT@
137 OBJDUMP = @OBJDUMP@
137138 OBJEXT = @OBJEXT@
138139 OTOOL = @OTOOL@
139140 OTOOL64 = @OTOOL64@
194194 {
195195 GstBaseSrc *basesrc = GST_BASE_SRC (data);
196196 GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc);
197 GstNetBuffer *mybuf;
198197
199198 GST_LOG_OBJECT (agent, "Got buffer, getting out of the main loop");
200199
201 mybuf = gst_netbuffer_new ();
202 GST_BUFFER_MALLOCDATA (mybuf) = g_memdup (buf, len);
203 GST_BUFFER_SIZE (mybuf) = len;
204 GST_BUFFER_DATA (mybuf) = GST_BUFFER_MALLOCDATA (mybuf);
205 if (GST_PAD_CAPS (basesrc->srcpad))
206 GST_BUFFER_CAPS (mybuf) = gst_caps_ref (GST_PAD_CAPS (basesrc->srcpad));
207
208 mybuf->from = nicesrc->from;
209 mybuf->to = nicesrc->to;
210
211 nicesrc->outbuf = GST_BUFFER_CAST (mybuf);
200 nicesrc->flow_ret = gst_pad_alloc_buffer (basesrc->srcpad, nicesrc->offset,
201 len, GST_PAD_CAPS (basesrc->srcpad), &nicesrc->outbuf);
202 if (nicesrc->flow_ret == GST_FLOW_OK) {
203 memcpy (nicesrc->outbuf->data, buf, len);
204 nicesrc->outbuf->size = len;
205 }
212206
213207 g_main_loop_quit (nicesrc->mainloop);
214208 }
220214
221215 g_main_loop_quit (nicesrc->mainloop);
222216
223 GST_OBJECT_LOCK (nicesrc);
224217 g_source_unref (nicesrc->idle_source);
225218 nicesrc->idle_source = NULL;
226 GST_OBJECT_UNLOCK (nicesrc);
227219
228220 return FALSE;
229221 }
274266 GST_LOG_OBJECT (nicesrc, "create called");
275267
276268 nicesrc->outbuf = NULL;
269 nicesrc->offset = offset;
277270
278271 GST_OBJECT_LOCK (basesrc);
279272 if (nicesrc->unlocked) {
288281 GST_LOG_OBJECT (nicesrc, "Got buffer, pushing");
289282
290283 *buffer = nicesrc->outbuf;
291 GST_BUFFER_OFFSET (*buffer) = offset;
292
293 return GST_FLOW_OK;
284 return nicesrc->flow_ret;
294285 } else {
295286 GST_LOG_OBJECT (nicesrc, "Got interrupting, returning wrong-state");
296287 return GST_FLOW_WRONG_STATE;
297288 }
289
298290 }
299291
300292 static void
301293 gst_nice_src_dispose (GObject *object)
302294 {
303295 GstNiceSrc *src = GST_NICE_SRC (object);
304
305 if (src->new_selected_pair_id)
306 g_signal_handler_disconnect (src->agent, src->new_selected_pair_id);
307 src->new_selected_pair_id = 0;
308296
309297 if (src->agent)
310298 g_object_unref (src->agent);
377365 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
378366 break;
379367 }
380 }
381
382 static void
383 nice_address_to_gst_net_address (NiceAddress *niceaddr, GstNetAddress *gstaddr)
384 {
385 switch (niceaddr->s.addr.sa_family)
386 {
387 case AF_INET:
388 gst_netaddress_set_ip4_address (gstaddr,
389 niceaddr->s.ip4.sin_addr.s_addr,
390 niceaddr->s.ip4.sin_port);
391 break;
392 case AF_INET6:
393 gst_netaddress_set_ip6_address (gstaddr,
394 niceaddr->s.ip6.sin6_addr.s6_addr,
395 niceaddr->s.ip6.sin6_port);
396 break;
397 default:
398 break;
399 }
400 }
401
402 static void
403 new_selected_pair_cb (NiceAgent *agent, guint stream_id, guint component_id,
404 gchar *local_cand, gchar *remote_cand, GstNiceSrc *src)
405 {
406 GST_OBJECT_LOCK (src);
407
408 if (stream_id == src->stream_id && component_id == src->component_id)
409 {
410 GSList *local_candidates = nice_agent_get_local_candidates (
411 src->agent, stream_id, component_id);
412 GSList *remote_candidates = nice_agent_get_remote_candidates (
413 src->agent, stream_id, component_id);
414 GSList *item = NULL;
415
416 for (item = local_candidates; item; item = g_slist_next (item))
417 {
418 NiceCandidate *cand = item->data;
419 if (!strcmp (local_cand, cand->foundation))
420 {
421 nice_address_to_gst_net_address (&cand->addr, &src->to);
422 break;
423 }
424 }
425
426 for (item = remote_candidates; item; item = g_slist_next (item))
427 {
428 NiceCandidate *cand = item->data;
429 if (!strcmp (remote_cand, cand->foundation))
430 {
431 nice_address_to_gst_net_address (&cand->addr, &src->from);
432 break;
433 }
434 }
435
436 g_slist_foreach (local_candidates, (GFunc) nice_candidate_free, NULL);
437 g_slist_free (local_candidates);
438 g_slist_foreach (remote_candidates, (GFunc) nice_candidate_free, NULL);
439 g_slist_free (remote_candidates);
440 }
441
442 GST_OBJECT_UNLOCK (src);
443368 }
444369
445370 static GstStateChangeReturn
460385 }
461386 else
462387 {
463 GST_OBJECT_LOCK (src);
464388 nice_agent_attach_recv (src->agent, src->stream_id, src->component_id,
465389 g_main_loop_get_context (src->mainloop),
466390 gst_nice_src_read_callback, (gpointer) src);
467
468 if (!src->new_selected_pair_id)
469 src->new_selected_pair_id = g_signal_connect (src->agent,
470 "new-selected-pair", G_CALLBACK (new_selected_pair_cb), src);
471 GST_OBJECT_UNLOCK (src);
472391 }
473392 break;
474393 case GST_STATE_CHANGE_READY_TO_NULL:
475 GST_OBJECT_LOCK (src);
476394 nice_agent_attach_recv (src->agent, src->stream_id, src->component_id,
477395 g_main_loop_get_context (src->mainloop), NULL, NULL);
478 if (src->new_selected_pair_id)
479 g_signal_handler_disconnect (src->agent, src->new_selected_pair_id);
480 src->new_selected_pair_id = 0;
481 GST_OBJECT_UNLOCK (src);
482396 break;
483397 default:
484398 break;
3939
4040 #include <gst/gst.h>
4141 #include <gst/base/gstbasesrc.h>
42 #include <gst/netbuffer/gstnetbuffer.h>
4342
4443 #include <nice/nice.h>
4544
6261 {
6362 GstBaseSrc parent;
6463 GstPad *srcpad;
65 GMainLoop *mainloop;
66
67 /* Protected by the object lock */
68 gboolean unlocked;
69 GSource *idle_source;
7064 NiceAgent *agent;
7165 guint stream_id;
7266 guint component_id;
73
74 /* Protected by the stream lock */
67 GMainLoop *mainloop;
68 guint64 offset;
69 GstFlowReturn flow_ret;
7570 GstBuffer *outbuf;
76
77 /* Protected by the object lock */
78 gulong new_selected_pair_id;
79 GstNetAddress from;
80 GstNetAddress to;
71 gboolean unlocked;
72 GSource *idle_source;
8173 };
8274
8375 typedef struct _GstNiceSrcClass GstNiceSrcClass;
00 # Generated from ltmain.m4sh.
11
2 # ltmain.sh (GNU libtool) 2.2.4
2 # ltmain.sh (GNU libtool) 2.2.6
33 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
44
55 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
6464 # compiler: $LTCC
6565 # compiler flags: $LTCFLAGS
6666 # linker: $LD (gnu? $with_gnu_ld)
67 # $progname: (GNU libtool) 2.2.4 Debian-2.2.4-0ubuntu4
67 # $progname: (GNU libtool) 2.2.6 Debian-2.2.6a-1
6868 # automake: $automake_version
6969 # autoconf: $autoconf_version
7070 #
7272
7373 PROGRAM=ltmain.sh
7474 PACKAGE=libtool
75 VERSION="2.2.4 Debian-2.2.4-0ubuntu4"
75 VERSION="2.2.6 Debian-2.2.6a-1"
7676 TIMESTAMP=""
77 package_revision=1.2976
77 package_revision=1.3012
7878
7979 # Be Bourne compatible
8080 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
804804
805805
806806 case $host in
807 *cygwin* | *mingw* | *pw32*)
807 *cygwin* | *mingw* | *pw32* | *cegcc*)
808808 # don't eliminate duplications in $postdeps and $predeps
809809 opt_duplicate_compiler_generated_deps=:
810810 ;;
892892 # determined imposters.
893893 func_lalib_p ()
894894 {
895 $SED -e 4q "$1" 2>/dev/null \
896 | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
895 test -f "$1" &&
896 $SED -e 4q "$1" 2>/dev/null \
897 | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
897898 }
898899
899900 # func_lalib_unsafe_p file
906907 func_lalib_unsafe_p ()
907908 {
908909 lalib_p=no
909 if test -r "$1" && exec 5<&0 <"$1"; then
910 if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
910911 for lalib_p_l in 1 2 3 4
911912 do
912913 read lalib_p_line
12741275
12751276 # On Cygwin there's no "real" PIC flag so we must build both object types
12761277 case $host_os in
1277 cygwin* | mingw* | pw32* | os2*)
1278 cygwin* | mingw* | pw32* | os2* | cegcc*)
12781279 pic_mode=default
12791280 ;;
12801281 esac
20452046 'exit $?'
20462047 tstripme="$stripme"
20472048 case $host_os in
2048 cygwin* | mingw* | pw32*)
2049 cygwin* | mingw* | pw32* | cegcc*)
20492050 case $realname in
20502051 *.dll.a)
20512052 tstripme=""
21512152
21522153 # Do a test to see if this is really a libtool program.
21532154 case $host in
2154 *cygwin*|*mingw*)
2155 *cygwin* | *mingw*)
21552156 if func_ltwrapper_executable_p "$file"; then
21562157 func_ltwrapper_scriptname "$file"
21572158 wrapper=$func_ltwrapper_scriptname_result
23572358 $RM $export_symbols
23582359 eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
23592360 case $host in
2360 *cygwin* | *mingw* )
2361 *cygwin* | *mingw* | *cegcc* )
23612362 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
23622363 eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
23632364 ;;
23692370 eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
23702371 eval '$MV "$nlist"T "$nlist"'
23712372 case $host in
2372 *cygwin | *mingw* )
2373 *cygwin | *mingw* | *cegcc* )
23732374 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
23742375 eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
23752376 ;;
24252426 } lt_dlsymlist;
24262427 "
24272428 case $host in
2428 *cygwin* | *mingw* )
2429 *cygwin* | *mingw* | *cegcc* )
24292430 $ECHO >> "$output_objdir/$my_dlsyms" "\
24302431 /* DATA imports from DLLs on WIN32 con't be const, because
24312432 runtime relocations are performed -- see ld's documentation
25112512 # Transform the symbol file into the correct name.
25122513 symfileobj="$output_objdir/${my_outputname}S.$objext"
25132514 case $host in
2514 *cygwin* | *mingw* )
2515 *cygwin* | *mingw* | *cegcc* )
25152516 if test -f "$output_objdir/$my_outputname.def"; then
25162517 compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
25172518 finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
26902691
26912692
26922693
2693 # func_emit_wrapper arg
2694 # func_emit_wrapper_part1 [arg=no]
26942695 #
2695 # emit a libtool wrapper script on stdout
2696 # don't directly open a file because we may want to
2697 # incorporate the script contents within a cygwin/mingw
2698 # wrapper executable. Must ONLY be called from within
2699 # func_mode_link because it depends on a number of variable
2700 # set therein.
2701 #
2702 # arg is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
2703 # variable will take. If 'yes', then the emitted script
2704 # will assume that the directory in which it is stored is
2705 # the '.lib' directory. This is a cygwin/mingw-specific
2706 # behavior.
2707 func_emit_wrapper ()
2696 # Emit the first part of a libtool wrapper script on stdout.
2697 # For more information, see the description associated with
2698 # func_emit_wrapper(), below.
2699 func_emit_wrapper_part1 ()
27082700 {
2709 func_emit_wrapper_arg1=no
2701 func_emit_wrapper_part1_arg1=no
27102702 if test -n "$1" ; then
2711 func_emit_wrapper_arg1=$1
2703 func_emit_wrapper_part1_arg1=$1
27122704 fi
27132705
27142706 $ECHO "\
27932785 file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
27942786 file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
27952787 done
2788 "
2789 }
2790 # end: func_emit_wrapper_part1
2791
2792 # func_emit_wrapper_part2 [arg=no]
2793 #
2794 # Emit the second part of a libtool wrapper script on stdout.
2795 # For more information, see the description associated with
2796 # func_emit_wrapper(), below.
2797 func_emit_wrapper_part2 ()
2798 {
2799 func_emit_wrapper_part2_arg1=no
2800 if test -n "$1" ; then
2801 func_emit_wrapper_part2_arg1=$1
2802 fi
2803
2804 $ECHO "\
27962805
27972806 # Usually 'no', except on cygwin/mingw when embedded into
27982807 # the cwrapper.
2799 WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
2808 WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
28002809 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
28012810 # special case for '.'
28022811 if test \"\$thisdir\" = \".\"; then
28872896 "
28882897 case $host in
28892898 # Backslashes separate directories on plain windows
2890 *-*-mingw | *-*-os2*)
2899 *-*-mingw | *-*-os2* | *-cegcc*)
28912900 $ECHO "\
28922901 exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
28932902 "
29132922 fi\
29142923 "
29152924 }
2916 # end: func_emit_wrapper
2925 # end: func_emit_wrapper_part2
2926
2927
2928 # func_emit_wrapper [arg=no]
2929 #
2930 # Emit a libtool wrapper script on stdout.
2931 # Don't directly open a file because we may want to
2932 # incorporate the script contents within a cygwin/mingw
2933 # wrapper executable. Must ONLY be called from within
2934 # func_mode_link because it depends on a number of variables
2935 # set therein.
2936 #
2937 # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
2938 # variable will take. If 'yes', then the emitted script
2939 # will assume that the directory in which it is stored is
2940 # the $objdir directory. This is a cygwin/mingw-specific
2941 # behavior.
2942 func_emit_wrapper ()
2943 {
2944 func_emit_wrapper_arg1=no
2945 if test -n "$1" ; then
2946 func_emit_wrapper_arg1=$1
2947 fi
2948
2949 # split this up so that func_emit_cwrapperexe_src
2950 # can call each part independently.
2951 func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
2952 func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
2953 }
2954
2955
2956 # func_to_host_path arg
2957 #
2958 # Convert paths to host format when used with build tools.
2959 # Intended for use with "native" mingw (where libtool itself
2960 # is running under the msys shell), or in the following cross-
2961 # build environments:
2962 # $build $host
2963 # mingw (msys) mingw [e.g. native]
2964 # cygwin mingw
2965 # *nix + wine mingw
2966 # where wine is equipped with the `winepath' executable.
2967 # In the native mingw case, the (msys) shell automatically
2968 # converts paths for any non-msys applications it launches,
2969 # but that facility isn't available from inside the cwrapper.
2970 # Similar accommodations are necessary for $host mingw and
2971 # $build cygwin. Calling this function does no harm for other
2972 # $host/$build combinations not listed above.
2973 #
2974 # ARG is the path (on $build) that should be converted to
2975 # the proper representation for $host. The result is stored
2976 # in $func_to_host_path_result.
2977 func_to_host_path ()
2978 {
2979 func_to_host_path_result="$1"
2980 if test -n "$1" ; then
2981 case $host in
2982 *mingw* )
2983 lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
2984 case $build in
2985 *mingw* ) # actually, msys
2986 # awkward: cmd appends spaces to result
2987 lt_sed_strip_trailing_spaces="s/[ ]*\$//"
2988 func_to_host_path_tmp1=`( cmd //c echo "$1" |\
2989 $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
2990 func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
2991 $SED -e "$lt_sed_naive_backslashify"`
2992 ;;
2993 *cygwin* )
2994 func_to_host_path_tmp1=`cygpath -w "$1"`
2995 func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
2996 $SED -e "$lt_sed_naive_backslashify"`
2997 ;;
2998 * )
2999 # Unfortunately, winepath does not exit with a non-zero
3000 # error code, so we are forced to check the contents of
3001 # stdout. On the other hand, if the command is not
3002 # found, the shell will set an exit code of 127 and print
3003 # *an error message* to stdout. So we must check for both
3004 # error code of zero AND non-empty stdout, which explains
3005 # the odd construction:
3006 func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
3007 if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
3008 func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
3009 $SED -e "$lt_sed_naive_backslashify"`
3010 else
3011 # Allow warning below.
3012 func_to_host_path_result=""
3013 fi
3014 ;;
3015 esac
3016 if test -z "$func_to_host_path_result" ; then
3017 func_error "Could not determine host path corresponding to"
3018 func_error " '$1'"
3019 func_error "Continuing, but uninstalled executables may not work."
3020 # Fallback:
3021 func_to_host_path_result="$1"
3022 fi
3023 ;;
3024 esac
3025 fi
3026 }
3027 # end: func_to_host_path
3028
3029 # func_to_host_pathlist arg
3030 #
3031 # Convert pathlists to host format when used with build tools.
3032 # See func_to_host_path(), above. This function supports the
3033 # following $build/$host combinations (but does no harm for
3034 # combinations not listed here):
3035 # $build $host
3036 # mingw (msys) mingw [e.g. native]
3037 # cygwin mingw
3038 # *nix + wine mingw
3039 #
3040 # Path separators are also converted from $build format to
3041 # $host format. If ARG begins or ends with a path separator
3042 # character, it is preserved (but converted to $host format)
3043 # on output.
3044 #
3045 # ARG is a pathlist (on $build) that should be converted to
3046 # the proper representation on $host. The result is stored
3047 # in $func_to_host_pathlist_result.
3048 func_to_host_pathlist ()
3049 {
3050 func_to_host_pathlist_result="$1"
3051 if test -n "$1" ; then
3052 case $host in
3053 *mingw* )
3054 lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
3055 # Remove leading and trailing path separator characters from
3056 # ARG. msys behavior is inconsistent here, cygpath turns them
3057 # into '.;' and ';.', and winepath ignores them completely.
3058 func_to_host_pathlist_tmp2="$1"
3059 # Once set for this call, this variable should not be
3060 # reassigned. It is used in tha fallback case.
3061 func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
3062 $SED -e 's|^:*||' -e 's|:*$||'`
3063 case $build in
3064 *mingw* ) # Actually, msys.
3065 # Awkward: cmd appends spaces to result.
3066 lt_sed_strip_trailing_spaces="s/[ ]*\$//"
3067 func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
3068 $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
3069 func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
3070 $SED -e "$lt_sed_naive_backslashify"`
3071 ;;
3072 *cygwin* )
3073 func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
3074 func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
3075 $SED -e "$lt_sed_naive_backslashify"`
3076 ;;
3077 * )
3078 # unfortunately, winepath doesn't convert pathlists
3079 func_to_host_pathlist_result=""
3080 func_to_host_pathlist_oldIFS=$IFS
3081 IFS=:
3082 for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
3083 IFS=$func_to_host_pathlist_oldIFS
3084 if test -n "$func_to_host_pathlist_f" ; then
3085 func_to_host_path "$func_to_host_pathlist_f"
3086 if test -n "$func_to_host_path_result" ; then
3087 if test -z "$func_to_host_pathlist_result" ; then
3088 func_to_host_pathlist_result="$func_to_host_path_result"
3089 else
3090 func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
3091 fi
3092 fi
3093 fi
3094 IFS=:
3095 done
3096 IFS=$func_to_host_pathlist_oldIFS
3097 ;;
3098 esac
3099 if test -z "$func_to_host_pathlist_result" ; then
3100 func_error "Could not determine the host path(s) corresponding to"
3101 func_error " '$1'"
3102 func_error "Continuing, but uninstalled executables may not work."
3103 # Fallback. This may break if $1 contains DOS-style drive
3104 # specifications. The fix is not to complicate the expression
3105 # below, but for the user to provide a working wine installation
3106 # with winepath so that path translation in the cross-to-mingw
3107 # case works properly.
3108 lt_replace_pathsep_nix_to_dos="s|:|;|g"
3109 func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
3110 $SED -e "$lt_replace_pathsep_nix_to_dos"`
3111 fi
3112 # Now, add the leading and trailing path separators back
3113 case "$1" in
3114 :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
3115 ;;
3116 esac
3117 case "$1" in
3118 *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
3119 ;;
3120 esac
3121 ;;
3122 esac
3123 fi
3124 }
3125 # end: func_to_host_pathlist
29173126
29183127 # func_emit_cwrapperexe_src
29193128 # emit the source code for a wrapper executable on stdout
29503159 # include <stdint.h>
29513160 # ifdef __CYGWIN__
29523161 # include <io.h>
3162 # define HAVE_SETENV
3163 # ifdef __STRICT_ANSI__
3164 char *realpath (const char *, char *);
3165 int putenv (char *);
3166 int setenv (const char *, const char *, int);
3167 # endif
29533168 # endif
29543169 #endif
29553170 #include <malloc.h>
30563271 int check_executable (const char *path);
30573272 char *strendzap (char *str, const char *pat);
30583273 void lt_fatal (const char *message, ...);
3059
3060 static const char *script_text =
3274 void lt_setenv (const char *name, const char *value);
3275 char *lt_extend_str (const char *orig_value, const char *add, int to_end);
3276 void lt_opt_process_env_set (const char *arg);
3277 void lt_opt_process_env_prepend (const char *arg);
3278 void lt_opt_process_env_append (const char *arg);
3279 int lt_split_name_value (const char *arg, char** name, char** value);
3280 void lt_update_exe_path (const char *name, const char *value);
3281 void lt_update_lib_path (const char *name, const char *value);
3282
3283 static const char *script_text_part1 =
30613284 EOF
30623285
3063 func_emit_wrapper yes |
3286 func_emit_wrapper_part1 yes |
30643287 $SED -e 's/\([\\"]\)/\\\1/g' \
30653288 -e 's/^/ "/' -e 's/$/\\n"/'
30663289 echo ";"
3290 cat <<EOF
3291
3292 static const char *script_text_part2 =
3293 EOF
3294 func_emit_wrapper_part2 yes |
3295 $SED -e 's/\([\\"]\)/\\\1/g' \
3296 -e 's/^/ "/' -e 's/$/\\n"/'
3297 echo ";"
30673298
30683299 cat <<EOF
30693300 const char * MAGIC_EXE = "$magic_exe";
3301 const char * LIB_PATH_VARNAME = "$shlibpath_var";
3302 EOF
3303
3304 if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
3305 func_to_host_pathlist "$temp_rpath"
3306 cat <<EOF
3307 const char * LIB_PATH_VALUE = "$func_to_host_pathlist_result";
3308 EOF
3309 else
3310 cat <<"EOF"
3311 const char * LIB_PATH_VALUE = "";
3312 EOF
3313 fi
3314
3315 if test -n "$dllsearchpath"; then
3316 func_to_host_pathlist "$dllsearchpath:"
3317 cat <<EOF
3318 const char * EXE_PATH_VARNAME = "PATH";
3319 const char * EXE_PATH_VALUE = "$func_to_host_pathlist_result";
3320 EOF
3321 else
3322 cat <<"EOF"
3323 const char * EXE_PATH_VARNAME = "";
3324 const char * EXE_PATH_VALUE = "";
3325 EOF
3326 fi
3327
3328 if test "$fast_install" = yes; then
3329 cat <<EOF
3330 const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
3331 EOF
3332 else
3333 cat <<EOF
3334 const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
3335 EOF
3336 fi
3337
3338
3339 cat <<"EOF"
3340
3341 #define LTWRAPPER_OPTION_PREFIX "--lt-"
3342 #define LTWRAPPER_OPTION_PREFIX_LENGTH 5
3343
3344 static const size_t opt_prefix_len = LTWRAPPER_OPTION_PREFIX_LENGTH;
3345 static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
3346
3347 static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
3348
3349 static const size_t env_set_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
3350 static const char *env_set_opt = LTWRAPPER_OPTION_PREFIX "env-set";
3351 /* argument is putenv-style "foo=bar", value of foo is set to bar */
3352
3353 static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
3354 static const char *env_prepend_opt = LTWRAPPER_OPTION_PREFIX "env-prepend";
3355 /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
3356
3357 static const size_t env_append_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
3358 static const char *env_append_opt = LTWRAPPER_OPTION_PREFIX "env-append";
3359 /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
30703360
30713361 int
30723362 main (int argc, char *argv[])
30733363 {
30743364 char **newargz;
3365 int newargc;
30753366 char *tmp_pathspec;
30763367 char *actual_cwrapper_path;
3077 char *shwrapper_name;
3368 char *actual_cwrapper_name;
3369 char *target_name;
3370 char *lt_argv_zero;
30783371 intptr_t rval = 127;
3079 FILE *shwrapper;
3080
3081 const char *dumpscript_opt = "--lt-dump-script";
3372
30823373 int i;
30833374
30843375 program_name = (char *) xstrdup (base_name (argv[0]));
30983389 ;;
30993390 esac
31003391
3101 cat <<EOF
3102 printf ("%s", script_text);
3392 cat <<"EOF"
3393 printf ("%s", script_text_part1);
3394 printf ("%s", script_text_part2);
31033395 return 0;
31043396 }
31053397 }
31063398
3107 newargz = XMALLOC (char *, argc + 2);
3108 EOF
3109
3110 if test -n "$TARGETSHELL" ; then
3111 # no path translation at all
3112 lt_newargv0=$TARGETSHELL
3113 else
3114 case "$host" in
3115 *mingw* )
3116 # awkward: cmd appends spaces to result
3117 lt_sed_strip_trailing_spaces="s/[ ]*\$//"
3118 lt_newargv0=`( cmd //c echo $SHELL | $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo $SHELL`
3119 case $lt_newargv0 in
3120 *.exe | *.EXE) ;;
3121 *) lt_newargv0=$lt_newargv0.exe ;;
3122 esac
3123 ;;
3124 * ) lt_newargv0=$SHELL ;;
3125 esac
3126 fi
3127
3128 cat <<EOF
3129 newargz[0] = (char *) xstrdup ("$lt_newargv0");
3130 EOF
3131
3132 cat <<"EOF"
3399 newargz = XMALLOC (char *, argc + 1);
31333400 tmp_pathspec = find_executable (argv[0]);
31343401 if (tmp_pathspec == NULL)
31353402 lt_fatal ("Couldn't find %s", argv[0]);
31413408 actual_cwrapper_path));
31423409 XFREE (tmp_pathspec);
31433410
3144 shwrapper_name = (char *) xstrdup (base_name (actual_cwrapper_path));
3145 strendzap (actual_cwrapper_path, shwrapper_name);
3146
3147 /* shwrapper_name transforms */
3148 strendzap (shwrapper_name, ".exe");
3149 tmp_pathspec = XMALLOC (char, (strlen (shwrapper_name) +
3150 strlen ("_ltshwrapperTMP") + 1));
3151 strcpy (tmp_pathspec, shwrapper_name);
3152 strcat (tmp_pathspec, "_ltshwrapperTMP");
3153 XFREE (shwrapper_name);
3154 shwrapper_name = tmp_pathspec;
3411 actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
3412 strendzap (actual_cwrapper_path, actual_cwrapper_name);
3413
3414 /* wrapper name transforms */
3415 strendzap (actual_cwrapper_name, ".exe");
3416 tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
3417 XFREE (actual_cwrapper_name);
3418 actual_cwrapper_name = tmp_pathspec;
31553419 tmp_pathspec = 0;
3156 LTWRAPPER_DEBUGPRINTF (("(main) libtool shell wrapper name: %s\n",
3157 shwrapper_name));
3420
3421 /* target_name transforms -- use actual target program name; might have lt- prefix */
3422 target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
3423 strendzap (target_name, ".exe");
3424 tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
3425 XFREE (target_name);
3426 target_name = tmp_pathspec;
3427 tmp_pathspec = 0;
3428
3429 LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
3430 target_name));
31583431 EOF
31593432
31603433 cat <<EOF
3161 newargz[1] =
3434 newargz[0] =
31623435 XMALLOC (char, (strlen (actual_cwrapper_path) +
3163 strlen ("$objdir") + 1 + strlen (shwrapper_name) + 1));
3164 strcpy (newargz[1], actual_cwrapper_path);
3165 strcat (newargz[1], "$objdir");
3166 strcat (newargz[1], "/");
3167 strcat (newargz[1], shwrapper_name);
3436 strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
3437 strcpy (newargz[0], actual_cwrapper_path);
3438 strcat (newargz[0], "$objdir");
3439 strcat (newargz[0], "/");
31683440 EOF
31693441
3442 cat <<"EOF"
3443 /* stop here, and copy so we don't have to do this twice */
3444 tmp_pathspec = xstrdup (newargz[0]);
3445
3446 /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
3447 strcat (newargz[0], actual_cwrapper_name);
3448
3449 /* DO want the lt- prefix here if it exists, so use target_name */
3450 lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
3451 XFREE (tmp_pathspec);
3452 tmp_pathspec = NULL;
3453 EOF
31703454
31713455 case $host_os in
31723456 mingw*)
31733457 cat <<"EOF"
31743458 {
31753459 char* p;
3176 while ((p = strchr (newargz[1], '\\')) != NULL)
3460 while ((p = strchr (newargz[0], '\\')) != NULL)
3461 {
3462 *p = '/';
3463 }
3464 while ((p = strchr (lt_argv_zero, '\\')) != NULL)
31773465 {
31783466 *p = '/';
31793467 }
31833471 esac
31843472
31853473 cat <<"EOF"
3186 XFREE (shwrapper_name);
3474 XFREE (target_name);
31873475 XFREE (actual_cwrapper_path);
3188
3189 /* always write in binary mode */
3190 if ((shwrapper = fopen (newargz[1], FOPEN_WB)) == 0)
3476 XFREE (actual_cwrapper_name);
3477
3478 lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
3479 lt_setenv ("DUALCASE", "1"); /* for MSK sh */
3480 lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
3481 lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
3482
3483 newargc=0;
3484 for (i = 1; i < argc; i++)
31913485 {
3192 lt_fatal ("Could not open %s for writing", newargz[1]);
3486 if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
3487 {
3488 if (argv[i][env_set_opt_len] == '=')
3489 {
3490 const char *p = argv[i] + env_set_opt_len + 1;
3491 lt_opt_process_env_set (p);
3492 }
3493 else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
3494 {
3495 lt_opt_process_env_set (argv[++i]); /* don't copy */
3496 }
3497 else
3498 lt_fatal ("%s missing required argument", env_set_opt);
3499 continue;
3500 }
3501 if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
3502 {
3503 if (argv[i][env_prepend_opt_len] == '=')
3504 {
3505 const char *p = argv[i] + env_prepend_opt_len + 1;
3506 lt_opt_process_env_prepend (p);
3507 }
3508 else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
3509 {
3510 lt_opt_process_env_prepend (argv[++i]); /* don't copy */
3511 }
3512 else
3513 lt_fatal ("%s missing required argument", env_prepend_opt);
3514 continue;
3515 }
3516 if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
3517 {
3518 if (argv[i][env_append_opt_len] == '=')
3519 {
3520 const char *p = argv[i] + env_append_opt_len + 1;
3521 lt_opt_process_env_append (p);
3522 }
3523 else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
3524 {
3525 lt_opt_process_env_append (argv[++i]); /* don't copy */
3526 }
3527 else
3528 lt_fatal ("%s missing required argument", env_append_opt);
3529 continue;
3530 }
3531 if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
3532 {
3533 /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
3534 namespace, but it is not one of the ones we know about and
3535 have already dealt with, above (inluding dump-script), then
3536 report an error. Otherwise, targets might begin to believe
3537 they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
3538 namespace. The first time any user complains about this, we'll
3539 need to make LTWRAPPER_OPTION_PREFIX a configure-time option
3540 or a configure.ac-settable value.
3541 */
3542 lt_fatal ("Unrecognized option in %s namespace: '%s'",
3543 ltwrapper_option_prefix, argv[i]);
3544 }
3545 /* otherwise ... */
3546 newargz[++newargc] = xstrdup (argv[i]);
31933547 }
3194 fprintf (shwrapper, "%s", script_text);
3195 fclose (shwrapper);
3196
3197 make_executable (newargz[1]);
3198
3199 for (i = 1; i < argc; i++)
3200 newargz[i + 1] = xstrdup (argv[i]);
3201 newargz[argc + 1] = NULL;
3202
3203 for (i = 0; i < argc + 1; i++)
3548 newargz[++newargc] = NULL;
3549
3550 LTWRAPPER_DEBUGPRINTF (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
3551 for (i = 0; i < newargc; i++)
32043552 {
3205 LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, newargz[i]));
3553 LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
32063554 }
32073555
32083556 EOF
32093557
32103558 case $host_os in
32113559 mingw*)
3212 cat <<EOF
3560 cat <<"EOF"
32133561 /* execv doesn't actually work on mingw as expected on unix */
3214 rval = _spawnv (_P_WAIT, "$lt_newargv0", (const char * const *) newargz);
3562 rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
32153563 if (rval == -1)
32163564 {
32173565 /* failed to start process */
3218 LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"$lt_newargv0\": errno = %d\n", errno));
3566 LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
32193567 return 127;
32203568 }
32213569 return rval;
3222 }
32233570 EOF
32243571 ;;
32253572 *)
3226 cat <<EOF
3227 execv ("$lt_newargv0", newargz);
3573 cat <<"EOF"
3574 execv (lt_argv_zero, newargz);
32283575 return rval; /* =127, but avoids unused variable warning */
3229 }
32303576 EOF
32313577 ;;
32323578 esac
32333579
32343580 cat <<"EOF"
3581 }
32353582
32363583 void *
32373584 xmalloc (size_t num)
35053852 lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
35063853 va_end (ap);
35073854 }
3855
3856 void
3857 lt_setenv (const char *name, const char *value)
3858 {
3859 LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
3860 (name ? name : "<NULL>"),
3861 (value ? value : "<NULL>")));
3862 {
3863 #ifdef HAVE_SETENV
3864 /* always make a copy, for consistency with !HAVE_SETENV */
3865 char *str = xstrdup (value);
3866 setenv (name, str, 1);
3867 #else
3868 int len = strlen (name) + 1 + strlen (value) + 1;
3869 char *str = XMALLOC (char, len);
3870 sprintf (str, "%s=%s", name, value);
3871 if (putenv (str) != EXIT_SUCCESS)
3872 {
3873 XFREE (str);
3874 }
3875 #endif
3876 }
3877 }
3878
3879 char *
3880 lt_extend_str (const char *orig_value, const char *add, int to_end)
3881 {
3882 char *new_value;
3883 if (orig_value && *orig_value)
3884 {
3885 int orig_value_len = strlen (orig_value);
3886 int add_len = strlen (add);
3887 new_value = XMALLOC (char, add_len + orig_value_len + 1);
3888 if (to_end)
3889 {
3890 strcpy (new_value, orig_value);
3891 strcpy (new_value + orig_value_len, add);
3892 }
3893 else
3894 {
3895 strcpy (new_value, add);
3896 strcpy (new_value + add_len, orig_value);
3897 }
3898 }
3899 else
3900 {
3901 new_value = xstrdup (add);
3902 }
3903 return new_value;
3904 }
3905
3906 int
3907 lt_split_name_value (const char *arg, char** name, char** value)
3908 {
3909 const char *p;
3910 int len;
3911 if (!arg || !*arg)
3912 return 1;
3913
3914 p = strchr (arg, (int)'=');
3915
3916 if (!p)
3917 return 1;
3918
3919 *value = xstrdup (++p);
3920
3921 len = strlen (arg) - strlen (*value);
3922 *name = XMALLOC (char, len);
3923 strncpy (*name, arg, len-1);
3924 (*name)[len - 1] = '\0';
3925
3926 return 0;
3927 }
3928
3929 void
3930 lt_opt_process_env_set (const char *arg)
3931 {
3932 char *name = NULL;
3933 char *value = NULL;
3934
3935 if (lt_split_name_value (arg, &name, &value) != 0)
3936 {
3937 XFREE (name);
3938 XFREE (value);
3939 lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
3940 }
3941
3942 lt_setenv (name, value);
3943 XFREE (name);
3944 XFREE (value);
3945 }
3946
3947 void
3948 lt_opt_process_env_prepend (const char *arg)
3949 {
3950 char *name = NULL;
3951 char *value = NULL;
3952 char *new_value = NULL;
3953
3954 if (lt_split_name_value (arg, &name, &value) != 0)
3955 {
3956 XFREE (name);
3957 XFREE (value);
3958 lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
3959 }
3960
3961 new_value = lt_extend_str (getenv (name), value, 0);
3962 lt_setenv (name, new_value);
3963 XFREE (new_value);
3964 XFREE (name);
3965 XFREE (value);
3966 }
3967
3968 void
3969 lt_opt_process_env_append (const char *arg)
3970 {
3971 char *name = NULL;
3972 char *value = NULL;
3973 char *new_value = NULL;
3974
3975 if (lt_split_name_value (arg, &name, &value) != 0)
3976 {
3977 XFREE (name);
3978 XFREE (value);
3979 lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
3980 }
3981
3982 new_value = lt_extend_str (getenv (name), value, 1);
3983 lt_setenv (name, new_value);
3984 XFREE (new_value);
3985 XFREE (name);
3986 XFREE (value);
3987 }
3988
3989 void
3990 lt_update_exe_path (const char *name, const char *value)
3991 {
3992 LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
3993 (name ? name : "<NULL>"),
3994 (value ? value : "<NULL>")));
3995
3996 if (name && *name && value && *value)
3997 {
3998 char *new_value = lt_extend_str (getenv (name), value, 0);
3999 /* some systems can't cope with a ':'-terminated path #' */
4000 int len = strlen (new_value);
4001 while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
4002 {
4003 new_value[len-1] = '\0';
4004 }
4005 lt_setenv (name, new_value);
4006 XFREE (new_value);
4007 }
4008 }
4009
4010 void
4011 lt_update_lib_path (const char *name, const char *value)
4012 {
4013 LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
4014 (name ? name : "<NULL>"),
4015 (value ? value : "<NULL>")));
4016
4017 if (name && *name && value && *value)
4018 {
4019 char *new_value = lt_extend_str (getenv (name), value, 0);
4020 lt_setenv (name, new_value);
4021 XFREE (new_value);
4022 }
4023 }
4024
4025
35084026 EOF
35094027 }
35104028 # end: func_emit_cwrapperexe_src
35144032 {
35154033 $opt_debug
35164034 case $host in
3517 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
4035 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
35184036 # It is impossible to link a dll without this setting, and
35194037 # we shouldn't force the makefile maintainer to figure out
35204038 # which system we are compiling for in order to pass an extra
39584476 -L*)
39594477 func_stripname '-L' '' "$arg"
39604478 dir=$func_stripname_result
4479 if test -z "$dir"; then
4480 if test "$#" -gt 0; then
4481 func_fatal_error "require no space between \`-L' and \`$1'"
4482 else
4483 func_fatal_error "need path for \`-L' option"
4484 fi
4485 fi
39614486 # We need an absolute path.
39624487 case $dir in
39634488 [\\/]* | [A-Za-z]:[\\/]*) ;;
39764501 ;;
39774502 esac
39784503 case $host in
3979 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
4504 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
39804505 testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
39814506 case :$dllsearchpath: in
39824507 *":$dir:"*) ;;
4508 ::) dllsearchpath=$dir;;
39834509 *) dllsearchpath="$dllsearchpath:$dir";;
39844510 esac
39854511 case :$dllsearchpath: in
39864512 *":$testbindir:"*) ;;
4513 ::) dllsearchpath=$testbindir;;
39874514 *) dllsearchpath="$dllsearchpath:$testbindir";;
39884515 esac
39894516 ;;
39944521 -l*)
39954522 if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
39964523 case $host in
3997 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
4524 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
39984525 # These systems don't actually have a C or math library (as such)
39994526 continue
40004527 ;;
40714598
40724599 -no-install)
40734600 case $host in
4074 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
4601 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
40754602 # The PATH hackery in wrapper scripts is required on Windows
40764603 # and Darwin in order for the loader to find any dlls it needs.
40774604 func_warning "\`-no-install' is ignored for $host"
50315558 if test -n "$library_names" &&
50325559 { test "$use_static_libs" = no || test -z "$old_library"; }; then
50335560 case $host in
5034 *cygwin* | *mingw*)
5561 *cygwin* | *mingw* | *cegcc*)
50355562 # No point in relinking DLLs because paths are not encoded
50365563 notinst_deplibs="$notinst_deplibs $lib"
50375564 need_relink=no
51015628 elif test -n "$soname_spec"; then
51025629 # bleh windows
51035630 case $host in
5104 *cygwin* | mingw*)
5631 *cygwin* | mingw* | *cegcc*)
51055632 func_arith $current - $age
51065633 major=$func_arith_result
51075634 versuffix="-$major"
58836410 tempremovelist=`$ECHO "$output_objdir/*"`
58846411 for p in $tempremovelist; do
58856412 case $p in
5886 *.$objext)
6413 *.$objext | *.gcno)
58876414 ;;
58886415 $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
58896416 if test "X$precious_files_regex" != "X"; then
59546481 if test "$build_libtool_libs" = yes; then
59556482 if test -n "$rpath"; then
59566483 case $host in
5957 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
6484 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
59586485 # these systems don't actually have a c library (as such)!
59596486 ;;
59606487 *-*-rhapsody* | *-*-darwin1.[012])
64536980
64546981 orig_export_symbols=
64556982 case $host_os in
6456 cygwin* | mingw*)
6983 cygwin* | mingw* | cegcc*)
64576984 if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
64586985 # exporting using user supplied symfile
64596986 if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
70787605 esac
70797606 fi
70807607 case $host in
7081 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
7608 *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
70827609 testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
70837610 case :$dllsearchpath: in
70847611 *":$libdir:"*) ;;
7612 ::) dllsearchpath=$libdir;;
70857613 *) dllsearchpath="$dllsearchpath:$libdir";;
70867614 esac
70877615 case :$dllsearchpath: in
70887616 *":$testbindir:"*) ;;
7617 ::) dllsearchpath=$testbindir;;
70897618 *) dllsearchpath="$dllsearchpath:$testbindir";;
70907619 esac
70917620 ;;
71557684 wrappers_required=no
71567685 fi
71577686 ;;
7687 *cegcc)
7688 # Disable wrappers for cegcc, we are cross compiling anyway.
7689 wrappers_required=no
7690 ;;
71587691 *)
71597692 if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
71607693 wrappers_required=no
73077840
73087841 func_emit_cwrapperexe_src > $cwrappersource
73097842
7310 # we should really use a build-platform specific compiler
7311 # here, but OTOH, the wrappers (shell script and this C one)
7312 # are only useful if you want to execute the "real" binary.
7313 # Since the "real" binary is built for $host, then this
7314 # wrapper might as well be built for $host, too.
7843 # The wrapper executable is built using the $host compiler,
7844 # because it contains $host paths and files. If cross-
7845 # compiling, it, like the target executable, must be
7846 # executed on the $host or under an emulation environment.
73157847 $opt_dry_run || {
73167848 $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
73177849 $STRIP $cwrapper
75968128 # place dlname in correct position for cygwin
75978129 tdlname=$dlname
75988130 case $host,$output,$installed,$module,$dlname in
7599 *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
8131 *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
76008132 esac
76018133 $ECHO > $output "\
76028134 # $outputname - a libtool library file
138138 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
139139 NM = @NM@
140140 NMEDIT = @NMEDIT@
141 OBJDUMP = @OBJDUMP@
141142 OBJEXT = @OBJEXT@
142143 OTOOL = @OTOOL@
143144 OTOOL64 = @OTOOL64@
126126 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
127127 NM = @NM@
128128 NMEDIT = @NMEDIT@
129 OBJDUMP = @OBJDUMP@
129130 OBJEXT = @OBJEXT@
130131 OTOOL = @OTOOL@
131132 OTOOL64 = @OTOOL64@
2323 socket.c \
2424 udp-bsd.h \
2525 udp-bsd.c \
26 udp-turn.h \
27 udp-turn.c \
26 tcp-bsd.h \
27 tcp-bsd.c \
28 pseudossl.h \
29 pseudossl.c \
30 socks5.h \
31 socks5.c \
32 turn.h \
33 turn.c \
2834 tcp-turn.h \
2935 tcp-turn.c
3036
3541
3642 TESTS = $(check_PROGRAMS)
3743
38 pkginclude_HEADERS = socket.h udp-bsd.h udp-turn.h tcp-turn.h
44 pkginclude_HEADERS = socket.h udp-bsd.h tcp-bsd.h pseudossl.h turn.h tcp-turn.h socks5.h
3945
5353 CONFIG_CLEAN_FILES =
5454 LTLIBRARIES = $(noinst_LTLIBRARIES)
5555 libsocket_la_LIBADD =
56 am_libsocket_la_OBJECTS = socket.lo udp-bsd.lo udp-turn.lo tcp-turn.lo
56 am_libsocket_la_OBJECTS = socket.lo udp-bsd.lo tcp-bsd.lo pseudossl.lo \
57 socks5.lo turn.lo tcp-turn.lo
5758 libsocket_la_OBJECTS = $(am_libsocket_la_OBJECTS)
5859 test_bsd_SOURCES = test-bsd.c
5960 test_bsd_OBJECTS = test-bsd.$(OBJEXT)
138139 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
139140 NM = @NM@
140141 NMEDIT = @NMEDIT@
142 OBJDUMP = @OBJDUMP@
141143 OBJEXT = @OBJEXT@
142144 OTOOL = @OTOOL@
143145 OTOOL64 = @OTOOL64@
237239 socket.c \
238240 udp-bsd.h \
239241 udp-bsd.c \
240 udp-turn.h \
241 udp-turn.c \
242 tcp-bsd.h \
243 tcp-bsd.c \
244 pseudossl.h \
245 pseudossl.c \
246 socks5.h \
247 socks5.c \
248 turn.h \
249 turn.c \
242250 tcp-turn.h \
243251 tcp-turn.c
244252
245253 test_bsd_LDADD = $(COMMON_LDADD)
246254 TESTS = $(check_PROGRAMS)
247 pkginclude_HEADERS = socket.h udp-bsd.h udp-turn.h tcp-turn.h
255 pkginclude_HEADERS = socket.h udp-bsd.h tcp-bsd.h pseudossl.h turn.h tcp-turn.h socks5.h
248256 all: all-am
249257
250258 .SUFFIXES:
306314 distclean-compile:
307315 -rm -f *.tab.c
308316
317 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pseudossl.Plo@am__quote@
309318 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Plo@am__quote@
319 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socks5.Plo@am__quote@
320 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp-bsd.Plo@am__quote@
310321 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp-turn.Plo@am__quote@
311322 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-bsd.Po@am__quote@
323 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/turn.Plo@am__quote@
312324 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udp-bsd.Plo@am__quote@
313 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udp-turn.Plo@am__quote@
314325
315326 .c.o:
316327 @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2006-2008 Collabora Ltd.
4 * Contact: Dafydd Harries
5 * Contact: Olivier Crete
6 * (C) 2006, 2007 Nokia Corporation. All rights reserved.
7 * Contact: Kai Vehmanen
8 *
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
13 *
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
17 * License.
18 *
19 * The Original Code is the Nice GLib ICE library.
20 *
21 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22 * Corporation. All Rights Reserved.
23 *
24 * Contributors:
25 * Dafydd Harries, Collabora Ltd.
26 * Olivier Crete, Collabora Ltd.
27 * Rémi Denis-Courmont, Nokia
28 * Kai Vehmanen
29 *
30 * Alternatively, the contents of this file may be used under the terms of the
31 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
32 * case the provisions of LGPL are applicable instead of those above. If you
33 * wish to allow use of your version of this file only under the terms of the
34 * LGPL and not to allow others to use your version of this file under the
35 * MPL, indicate your decision by deleting the provisions above and replace
36 * them with the notice and other provisions required by the LGPL. If you do
37 * not delete the provisions above, a recipient may use your version of this
38 * file under either the MPL or the LGPL.
39 */
40
41 /*
42 * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See
43 * http://en.wikipedia.org/wiki/Berkeley_sockets.)
44 */
45 #ifdef HAVE_CONFIG_H
46 # include "config.h"
47 #endif
48
49 #include "pseudossl.h"
50
51 #include <string.h>
52
53 #ifndef G_OS_WIN32
54 #include <unistd.h>
55 #endif
56
57 typedef struct {
58 gboolean handshaken;
59 NiceSocket *base_socket;
60 GQueue send_queue;
61 } PseudoSSLPriv;
62
63
64 struct to_be_sent {
65 guint length;
66 gchar *buf;
67 NiceAddress to;
68 };
69
70
71 static const gchar SSL_SERVER_HANDSHAKE[] = {
72 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00,
73 0x46, 0x03, 0x01, 0x42, 0x85, 0x45, 0xa7, 0x27,
74 0xa9, 0x5d, 0xa0, 0xb3, 0xc5, 0xe7, 0x53, 0xda,
75 0x48, 0x2b, 0x3f, 0xc6, 0x5a, 0xca, 0x89, 0xc1,
76 0x58, 0x52, 0xa1, 0x78, 0x3c, 0x5b, 0x17, 0x46,
77 0x00, 0x85, 0x3f, 0x20, 0x0e, 0xd3, 0x06, 0x72,
78 0x5b, 0x5b, 0x1b, 0x5f, 0x15, 0xac, 0x13, 0xf9,
79 0x88, 0x53, 0x9d, 0x9b, 0xe8, 0x3d, 0x7b, 0x0c,
80 0x30, 0x32, 0x6e, 0x38, 0x4d, 0xa2, 0x75, 0x57,
81 0x41, 0x6c, 0x34, 0x5c, 0x00, 0x04, 0x00};
82
83 static const gchar SSL_CLIENT_HANDSHAKE[] = {
84 0x80, 0x46, 0x01, 0x03, 0x01, 0x00, 0x2d, 0x00,
85 0x00, 0x00, 0x10, 0x01, 0x00, 0x80, 0x03, 0x00,
86 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x40, 0x02,
87 0x00, 0x80, 0x04, 0x00, 0x80, 0x00, 0x00, 0x04,
88 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, 0x00, 0xfe,
89 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, 0x00,
90 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06,
91 0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc,
92 0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea};
93
94
95 static void socket_close (NiceSocket *sock);
96 static gint socket_recv (NiceSocket *sock, NiceAddress *from,
97 guint len, gchar *buf);
98 static gboolean socket_send (NiceSocket *sock, const NiceAddress *to,
99 guint len, const gchar *buf);
100 static gboolean socket_is_reliable (NiceSocket *sock);
101
102 static void add_to_be_sent (NiceSocket *sock, const NiceAddress *to,
103 const gchar *buf, guint len);
104 static void free_to_be_sent (struct to_be_sent *tbs);
105
106
107 NiceSocket *
108 nice_pseudossl_socket_new (NiceAgent *agent, NiceSocket *base_socket)
109 {
110 PseudoSSLPriv *priv;
111 NiceSocket *sock = g_slice_new0 (NiceSocket);
112 sock->priv = priv = g_slice_new0 (PseudoSSLPriv);
113
114 priv->handshaken = FALSE;
115 priv->base_socket = base_socket;
116
117 sock->fileno = priv->base_socket->fileno;
118 sock->addr = priv->base_socket->addr;
119 sock->send = socket_send;
120 sock->recv = socket_recv;
121 sock->is_reliable = socket_is_reliable;
122 sock->close = socket_close;
123
124 /* We send 'to' NULL because it will always be to an already connected
125 * TCP base socket, which ignores the destination */
126 nice_socket_send (priv->base_socket, NULL,
127 sizeof(SSL_CLIENT_HANDSHAKE), SSL_CLIENT_HANDSHAKE);
128
129 return sock;
130 }
131
132
133 static void
134 socket_close (NiceSocket *sock)
135 {
136 PseudoSSLPriv *priv = sock->priv;
137
138 if (priv->base_socket)
139 nice_socket_free (priv->base_socket);
140
141 g_queue_foreach (&priv->send_queue, (GFunc) free_to_be_sent, NULL);
142 g_queue_clear (&priv->send_queue);
143
144 g_slice_free(PseudoSSLPriv, sock->priv);
145 }
146
147
148 static gint
149 socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
150 {
151 PseudoSSLPriv *priv = sock->priv;
152
153 if (priv->handshaken) {
154 if (priv->base_socket)
155 return nice_socket_recv (priv->base_socket, from, len, buf);
156 } else {
157 gchar data[sizeof(SSL_SERVER_HANDSHAKE)];
158 gint ret = -1;
159
160 if (priv->base_socket)
161 ret = nice_socket_recv (priv->base_socket, from, sizeof(data), data);
162
163 if (ret <= 0) {
164 return ret;
165 } else if ((guint) ret == sizeof(SSL_SERVER_HANDSHAKE) &&
166 memcmp(SSL_SERVER_HANDSHAKE, data, sizeof(SSL_SERVER_HANDSHAKE)) == 0) {
167 priv->handshaken = TRUE;
168 struct to_be_sent *tbs = NULL;
169 while ((tbs = g_queue_pop_head (&priv->send_queue))) {
170 nice_socket_send (priv->base_socket, &tbs->to, tbs->length, tbs->buf);
171 g_free (tbs->buf);
172 g_slice_free (struct to_be_sent, tbs);
173 }
174 } else {
175 if (priv->base_socket)
176 nice_socket_free (priv->base_socket);
177 priv->base_socket = NULL;
178
179 return -1;
180 }
181 }
182 return 0;
183 }
184
185 static gboolean
186 socket_send (NiceSocket *sock, const NiceAddress *to,
187 guint len, const gchar *buf)
188 {
189 PseudoSSLPriv *priv = sock->priv;
190
191 if (priv->handshaken) {
192 if (priv->base_socket)
193 return nice_socket_send (priv->base_socket, to, len, buf);
194 else
195 return FALSE;
196 } else {
197 add_to_be_sent (sock, to, buf, len);
198 }
199 return TRUE;
200 }
201
202
203 static gboolean
204 socket_is_reliable (NiceSocket *sock)
205 {
206 return TRUE;
207 }
208
209
210 static void
211 add_to_be_sent (NiceSocket *sock, const NiceAddress *to,
212 const gchar *buf, guint len)
213 {
214 PseudoSSLPriv *priv = sock->priv;
215 struct to_be_sent *tbs = NULL;
216
217 if (len <= 0)
218 return;
219
220 tbs = g_slice_new0 (struct to_be_sent);
221 tbs->buf = g_memdup (buf, len);
222 tbs->length = len;
223 if (to)
224 tbs->to = *to;
225 g_queue_push_tail (&priv->send_queue, tbs);
226
227 }
228
229 static void
230 free_to_be_sent (struct to_be_sent *tbs)
231 {
232 g_free (tbs->buf);
233 g_slice_free (struct to_be_sent, tbs);
234 }
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2006, 2007 Collabora Ltd.
4 * Contact: Dafydd Harries
5 * (C) 2006, 2007 Nokia Corporation. All rights reserved.
6 * Contact: Kai Vehmanen
7 *
8 * The contents of this file are subject to the Mozilla Public License Version
9 * 1.1 (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
12 *
13 * Software distributed under the License is distributed on an "AS IS" basis,
14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15 * for the specific language governing rights and limitations under the
16 * License.
17 *
18 * The Original Code is the Nice GLib ICE library.
19 *
20 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21 * Corporation. All Rights Reserved.
22 *
23 * Contributors:
24 * Dafydd Harries, Collabora Ltd.
25 *
26 * Alternatively, the contents of this file may be used under the terms of the
27 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28 * case the provisions of LGPL are applicable instead of those above. If you
29 * wish to allow use of your version of this file only under the terms of the
30 * LGPL and not to allow others to use your version of this file under the
31 * MPL, indicate your decision by deleting the provisions above and replace
32 * them with the notice and other provisions required by the LGPL. If you do
33 * not delete the provisions above, a recipient may use your version of this
34 * file under either the MPL or the LGPL.
35 */
36
37 #ifndef _PSEUDOSSL_H
38 #define _PSEUDOSSL_H
39
40 #include "socket.h"
41 #include "agent.h"
42
43 G_BEGIN_DECLS
44
45
46 NiceSocket *
47 nice_pseudossl_socket_new (NiceAgent *agent, NiceSocket *base_socket);
48
49
50 G_END_DECLS
51
52 #endif /* _PSEUDOSSL_H */
53
4444
4545
4646 gint
47 nice_socket_recv (
48 NiceSocket *sock,
49 NiceAddress *from,
50 guint len,
51 gchar *buf)
47 nice_socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
5248 {
5349 return sock->recv (sock, from, len, buf);
5450 }
5551
5652 gboolean
57 nice_socket_send (
58 NiceSocket *sock,
59 const NiceAddress *to,
60 guint len,
61 const gchar *buf)
53 nice_socket_send (NiceSocket *sock, const NiceAddress *to,
54 guint len, const gchar *buf)
6255 {
6356 return sock->send (sock, to, len, buf);
6457 }
6868
6969 G_GNUC_WARN_UNUSED_RESULT
7070 gint
71 nice_socket_recv (
72 NiceSocket *sock,
73 NiceAddress *from,
74 guint len,
75 gchar *buf);
71 nice_socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf);
7672
7773 gboolean
78 nice_socket_send (
79 NiceSocket *sock,
80 const NiceAddress *to,
81 guint len,
82 const gchar *buf);
74 nice_socket_send (NiceSocket *sock, const NiceAddress *to,
75 guint len, const gchar *buf);
8376
8477 gboolean
8578 nice_socket_is_reliable (NiceSocket *sock);
8982 nice_socket_free (NiceSocket *sock);
9083
9184 #include "udp-bsd.h"
92 #include "udp-turn.h"
85 #include "tcp-bsd.h"
86 #include "pseudossl.h"
87 #include "socks5.h"
88 #include "turn.h"
9389 #include "tcp-turn.h"
9490
9591 G_END_DECLS
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2008 Collabora Ltd.
4 * Contact: Youness Alaoui
5 * (C) 2008 Nokia Corporation. All rights reserved.
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is the Nice GLib ICE library.
18 *
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
21 *
22 * Contributors:
23 * Youness Alaoui, Collabora Ltd.
24 *
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
34 */
35
36 /*
37 * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See
38 * http://en.wikipedia.org/wiki/Berkeley_sockets.)
39 */
40 #ifdef HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include "socks5.h"
45
46 #include <string.h>
47
48 #ifndef G_OS_WIN32
49 #include <unistd.h>
50 #endif
51
52 typedef enum {
53 SOCKS_STATE_INIT,
54 SOCKS_STATE_AUTH,
55 SOCKS_STATE_CONNECT,
56 SOCKS_STATE_CONNECTED,
57 SOCKS_STATE_ERROR
58 } SocksState;
59
60 typedef struct {
61 SocksState state;
62 NiceSocket *base_socket;
63 NiceAddress addr;
64 gchar *username;
65 gchar *password;
66 GQueue send_queue;
67 } Socks5Priv;
68
69
70 struct to_be_sent {
71 guint length;
72 gchar *buf;
73 NiceAddress to;
74 };
75
76
77 static void socket_close (NiceSocket *sock);
78 static gint socket_recv (NiceSocket *sock, NiceAddress *from,
79 guint len, gchar *buf);
80 static gboolean socket_send (NiceSocket *sock, const NiceAddress *to,
81 guint len, const gchar *buf);
82 static gboolean socket_is_reliable (NiceSocket *sock);
83
84 static void add_to_be_sent (NiceSocket *sock, const NiceAddress *to,
85 const gchar *buf, guint len);
86 static void free_to_be_sent (struct to_be_sent *tbs);
87
88
89 NiceSocket *
90 nice_socks5_socket_new (NiceSocket *base_socket,
91 NiceAddress *addr, gchar *username, gchar *password)
92 {
93 Socks5Priv *priv;
94 NiceSocket *sock = NULL;
95
96 if (addr) {
97 sock = g_slice_new0 (NiceSocket);
98 sock->priv = priv = g_slice_new0 (Socks5Priv);
99
100 priv->base_socket = base_socket;
101 priv->addr = *addr;
102 priv->username = g_strdup (username);
103 priv->password = g_strdup (password);
104
105 sock->fileno = priv->base_socket->fileno;
106 sock->addr = priv->base_socket->addr;
107 sock->send = socket_send;
108 sock->recv = socket_recv;
109 sock->is_reliable = socket_is_reliable;
110 sock->close = socket_close;
111
112 /* Send SOCKS5 handshake */
113 {
114 gchar msg[4];
115 gint len = 3;
116
117 msg[0] = 0x05; /* SOCKS version */
118 msg[1] = 0x01; /* number of methods supported */
119 msg[2] = 0x00; /* no authentication method*/
120
121 g_debug ("user/pass : %s - %s", username, password);
122 /* add support for authentication method */
123 if (username || password) {
124 msg[1] = 0x02; /* number of methods supported */
125 msg[3] = 0x02; /* authentication method */
126 len++;
127 }
128
129 /* We send 'to' NULL because it will always be to an already connected
130 * TCP base socket, which ignores the destination */
131 nice_socket_send (priv->base_socket, NULL, len, msg);
132 priv->state = SOCKS_STATE_INIT;
133 }
134 }
135
136 return sock;
137 }
138
139
140 static void
141 socket_close (NiceSocket *sock)
142 {
143 Socks5Priv *priv = sock->priv;
144
145 if (priv->base_socket)
146 nice_socket_free (priv->base_socket);
147
148 if (priv->username)
149 g_free (priv->username);
150
151 if (priv->password)
152 g_free (priv->password);
153
154 g_queue_foreach (&priv->send_queue, (GFunc) free_to_be_sent, NULL);
155 g_queue_clear (&priv->send_queue);
156
157 g_slice_free(Socks5Priv, sock->priv);
158 }
159
160
161 static gint
162 socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
163 {
164 Socks5Priv *priv = sock->priv;
165
166 switch (priv->state) {
167 case SOCKS_STATE_CONNECTED:
168 if (priv->base_socket)
169 return nice_socket_recv (priv->base_socket, from, len, buf);
170 break;
171 case SOCKS_STATE_INIT:
172 {
173 gchar data[2];
174 gint ret = -1;
175
176 nice_debug ("Socks5 state Init");
177
178 if (priv->base_socket)
179 ret = nice_socket_recv (priv->base_socket, from, sizeof(data), data);
180
181 if (ret <= 0) {
182 return ret;
183 } else if(ret == sizeof(data)) {
184 if (data[0] == 0x05) {
185 if (data[1] == 0x02) {
186 gchar msg[515];
187 gint len = 0;
188
189 if (priv->username || priv->password) {
190 gint ulen = 0;
191 gint plen = 0;
192
193 if (priv->username)
194 ulen = strlen (priv->username);
195
196 if (priv->password)
197 plen = strlen (priv->password);
198
199 msg[len++] = 0x01; /* auth version */
200 msg[len++] = ulen; /* username length */
201 memcpy (msg + len, priv->username, ulen); /* Username */
202 len += ulen;
203 msg[len++] = plen; /* Password length */
204 memcpy (msg + len, priv->password, plen); /* Password */
205 len += plen;
206
207 nice_socket_send (priv->base_socket, NULL, len, msg);
208 priv->state = SOCKS_STATE_AUTH;
209 } else {
210 /* Authentication required but no auth info available */
211 goto error;
212 }
213 } else if (data[1] == 0x00) {
214 goto send_connect;
215 } else {
216 /* method not supported by socks server */
217 goto error;
218 }
219 } else {
220 /* invalid SOCKS server version */
221 goto error;
222 }
223 } else {
224 /* read error */
225 goto error;
226 }
227 }
228 break;
229 case SOCKS_STATE_AUTH:
230 {
231 gchar data[2];
232 gint ret = -1;
233
234 nice_debug ("Socks5 state auth");
235 if (priv->base_socket)
236 ret = nice_socket_recv (priv->base_socket, from, sizeof(data), data);
237
238 if (ret <= 0) {
239 return ret;
240 } else if(ret == sizeof(data)) {
241 if (data[0] == 0x01 && data[1] == 0x00) {
242 /* Authenticated */
243 goto send_connect;
244 } else {
245 /* Authentication failed */
246 goto error;
247 }
248 }
249 }
250 break;
251 case SOCKS_STATE_CONNECT:
252 {
253 gchar data[22];
254 gint ret = -1;
255
256 nice_debug ("Socks5 state connect");
257 if (priv->base_socket)
258 ret = nice_socket_recv (priv->base_socket, from, 4, data);
259
260 if (ret <= 0) {
261 return ret;
262 } else if(ret == 4) {
263 if (data[0] == 0x05) {
264 switch (data[1]) {
265 case 0x00:
266 if (data[2] == 0x00) {
267 struct to_be_sent *tbs = NULL;
268 switch (data[3]) {
269 case 0x01: /* IPV4 bound address */
270 ret = nice_socket_recv (priv->base_socket, from, 6, data);
271 if (ret != 6) {
272 /* Could not read server bound address */
273 goto error;
274 }
275 break;
276 case 0x04: /* IPV6 bound address */
277 ret = nice_socket_recv (priv->base_socket, from, 18, data);
278 if (ret != 18) {
279 /* Could not read server bound address */
280 goto error;
281 }
282 break;
283 default:
284 /* Unsupported address type */
285 goto error;
286 }
287 while ((tbs = g_queue_pop_head (&priv->send_queue))) {
288 nice_socket_send (priv->base_socket, &tbs->to,
289 tbs->length, tbs->buf);
290 g_free (tbs->buf);
291 g_slice_free (struct to_be_sent, tbs);
292 }
293 priv->state = SOCKS_STATE_CONNECTED;
294 } else {
295 /* Wrong reserved value */
296 goto error;
297 }
298 break;
299 case 0x01: /* general SOCKS server failure */
300 case 0x02: /* connection not allowed by ruleset */
301 case 0x03: /* Network unreachable */
302 case 0x04: /* Host unreachable */
303 case 0x05: /* Connection refused */
304 case 0x06: /* TTL expired */
305 case 0x07: /* Command not supported */
306 case 0x08: /* Address type not supported */
307 default: /* Unknown error */
308 goto error;
309 break;
310 }
311 } else {
312 /* Wrong server version */
313 goto error;
314 }
315 } else {
316 /* Invalid data received */
317 goto error;
318 }
319 }
320 break;
321 default:
322 /* Unknown status */
323 goto error;
324 }
325
326 return 0;
327
328 send_connect:
329 {
330 gchar msg[22];
331 gint len = 0;
332 struct sockaddr_storage name;
333 nice_address_copy_to_sockaddr(&priv->addr, (struct sockaddr *)&name);
334
335 msg[len++] = 0x05; /* SOCKS version */
336 msg[len++] = 0x01; /* connect command */
337 msg[len++] = 0x00; /* reserved */
338 if (name.ss_family == AF_INET) {
339 msg[len++] = 0x01; /* IPV4 address type */
340 /* Address */
341 memcpy (msg + len, &((struct sockaddr_in *) &name)->sin_addr, 4);
342 len += 4;
343 /* Port */
344 memcpy (msg + len, &((struct sockaddr_in *) &name)->sin_port, 2);
345 len += 2;
346 } else if (name.ss_family == AF_INET6) {
347 msg[len++] = 0x04; /* IPV6 address type */
348 /* Address */
349 memcpy (msg + len, &((struct sockaddr_in6 *) &name)->sin6_addr, 16);
350 len += 16;
351 /* Port */
352 memcpy (msg + len, &((struct sockaddr_in6 *) &name)->sin6_port, 2);
353 len += 2;
354 }
355
356 nice_socket_send (priv->base_socket, NULL, len, msg);
357 priv->state = SOCKS_STATE_CONNECT;
358
359 return 0;
360 }
361 error:
362 nice_debug ("Socks5 error");
363 if (priv->base_socket)
364 nice_socket_free (priv->base_socket);
365 priv->base_socket = NULL;
366 priv->state = SOCKS_STATE_ERROR;
367
368 return -1;
369 }
370
371 static gboolean
372 socket_send (NiceSocket *sock, const NiceAddress *to,
373 guint len, const gchar *buf)
374 {
375 Socks5Priv *priv = sock->priv;
376
377 if (priv->state == SOCKS_STATE_CONNECTED) {
378 if (priv->base_socket)
379 return nice_socket_send (priv->base_socket, to, len, buf);
380 else
381 return FALSE;
382 } else if (priv->state == SOCKS_STATE_ERROR) {
383 return FALSE;
384 } else {
385 add_to_be_sent (sock, to, buf, len);
386 }
387 return TRUE;
388 }
389
390
391 static gboolean
392 socket_is_reliable (NiceSocket *sock)
393 {
394 return TRUE;
395 }
396
397
398 static void
399 add_to_be_sent (NiceSocket *sock, const NiceAddress *to,
400 const gchar *buf, guint len)
401 {
402 Socks5Priv *priv = sock->priv;
403 struct to_be_sent *tbs = NULL;
404
405 if (len <= 0)
406 return;
407
408 tbs = g_slice_new0 (struct to_be_sent);
409 tbs->buf = g_memdup (buf, len);
410 tbs->length = len;
411 if (to)
412 tbs->to = *to;
413 g_queue_push_tail (&priv->send_queue, tbs);
414
415 }
416
417
418 static void
419 free_to_be_sent (struct to_be_sent *tbs)
420 {
421 g_free (tbs->buf);
422 g_slice_free (struct to_be_sent, tbs);
423 }
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2008 Collabora Ltd.
4 * Contact: Youness Alaoui
5 * (C) 2008 Nokia Corporation. All rights reserved.
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is the Nice GLib ICE library.
18 *
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
21 *
22 * Contributors:
23 * Youness Alaoui, Collabora Ltd.
24 *
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
34 */
35
36 #ifndef _SOCKS5_H
37 #define _SOCKS5_H
38
39 #include "socket.h"
40 #include "agent.h"
41
42 G_BEGIN_DECLS
43
44
45 NiceSocket *
46 nice_socks5_socket_new (NiceSocket *base_socket,
47 NiceAddress *addr, gchar *username, gchar *password);
48
49
50 G_END_DECLS
51
52 #endif /* _SOCKS5_H */
53
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2006-2008 Collabora Ltd.
4 * Contact: Dafydd Harries
5 * Contact: Olivier Crete
6 * (C) 2006, 2007 Nokia Corporation. All rights reserved.
7 * Contact: Kai Vehmanen
8 *
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
13 *
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
17 * License.
18 *
19 * The Original Code is the Nice GLib ICE library.
20 *
21 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22 * Corporation. All Rights Reserved.
23 *
24 * Contributors:
25 * Dafydd Harries, Collabora Ltd.
26 * Olivier Crete, Collabora Ltd.
27 * Rémi Denis-Courmont, Nokia
28 * Kai Vehmanen
29 *
30 * Alternatively, the contents of this file may be used under the terms of the
31 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
32 * case the provisions of LGPL are applicable instead of those above. If you
33 * wish to allow use of your version of this file only under the terms of the
34 * LGPL and not to allow others to use your version of this file under the
35 * MPL, indicate your decision by deleting the provisions above and replace
36 * them with the notice and other provisions required by the LGPL. If you do
37 * not delete the provisions above, a recipient may use your version of this
38 * file under either the MPL or the LGPL.
39 */
40
41 /*
42 * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See
43 * http://en.wikipedia.org/wiki/Berkeley_sockets.)
44 */
45 #ifdef HAVE_CONFIG_H
46 # include "config.h"
47 #endif
48
49 #include "tcp-bsd.h"
50 #include "agent-priv.h"
51
52 #include <string.h>
53 #include <errno.h>
54 #include <fcntl.h>
55
56 #ifndef G_OS_WIN32
57 #include <unistd.h>
58 #endif
59
60 typedef struct {
61 NiceAgent *agent;
62 NiceAddress server_addr;
63 GQueue send_queue;
64 GMainContext *context;
65 GIOChannel *io_channel;
66 GSource *io_source;
67 } TcpPriv;
68
69 struct to_be_sent {
70 guint length;
71 gchar *buf;
72 };
73
74
75 static void socket_close (NiceSocket *sock);
76 static gint socket_recv (NiceSocket *sock, NiceAddress *from,
77 guint len, gchar *buf);
78 static gboolean socket_send (NiceSocket *sock, const NiceAddress *to,
79 guint len, const gchar *buf);
80 static gboolean socket_is_reliable (NiceSocket *sock);
81
82
83 static void add_to_be_sent (NiceSocket *sock, const gchar *buf, guint len,
84 gboolean head);
85 static void free_to_be_sent (struct to_be_sent *tbs);
86 static gboolean socket_send_more (GIOChannel *source, GIOCondition condition,
87 gpointer data);
88
89 NiceSocket *
90 nice_tcp_bsd_socket_new (NiceAgent *agent, GMainContext *ctx, NiceAddress *addr)
91 {
92 int sockfd = -1;
93 int ret;
94 struct sockaddr_storage name;
95 guint name_len = sizeof (name);
96 NiceSocket *sock = g_slice_new0 (NiceSocket);
97 TcpPriv *priv;
98
99 if (addr != NULL) {
100 nice_address_copy_to_sockaddr(addr, (struct sockaddr *)&name);
101 } else {
102 memset (&name, 0, sizeof (name));
103 name.ss_family = AF_UNSPEC;
104 }
105
106 if ((sockfd == -1) &&
107 ((name.ss_family == AF_UNSPEC) ||
108 (name.ss_family == AF_INET))) {
109 sockfd = socket (PF_INET, SOCK_STREAM, 0);
110 name.ss_family = AF_INET;
111 #ifdef HAVE_SA_LEN
112 name.ss_len = sizeof (struct sockaddr_in);
113 #endif
114 }
115
116 if (sockfd == -1) {
117 g_slice_free (NiceSocket, sock);
118 return NULL;
119 }
120
121 #ifdef FD_CLOEXEC
122 fcntl (sockfd, F_SETFD, fcntl (sockfd, F_GETFD) | FD_CLOEXEC);
123 #endif
124 #ifdef O_NONBLOCK
125 fcntl (sockfd, F_SETFL, fcntl (sockfd, F_GETFL) | O_NONBLOCK);
126 #endif
127
128 name_len = name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
129 sizeof(struct sockaddr_in6);
130 ret = connect (sockfd, (const struct sockaddr *)&name, name_len);
131
132 #ifdef G_OS_WIN32
133 if (ret < 0 && WSAGetLastError () != WSAEINPROGRESS) {
134 closesocket (sockfd);
135 #else
136 if (ret < 0 && errno != EINPROGRESS) {
137 close (sockfd);
138 #endif
139 g_slice_free (NiceSocket, sock);
140 return NULL;
141 }
142
143 name_len = name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
144 sizeof(struct sockaddr_in6);
145 if (getsockname (sockfd, (struct sockaddr *) &name, &name_len) < 0) {
146 g_slice_free (NiceSocket, sock);
147 #ifdef G_OS_WIN32
148 closesocket(sockfd);
149 #else
150 close (sockfd);
151 #endif
152 return NULL;
153 }
154
155 nice_address_set_from_sockaddr (&sock->addr, (struct sockaddr *)&name);
156
157 sock->priv = priv = g_slice_new0 (TcpPriv);
158
159 priv->agent = agent;
160 priv->context = ctx;
161 priv->server_addr = *addr;
162
163 sock->fileno = sockfd;
164 sock->send = socket_send;
165 sock->recv = socket_recv;
166 sock->is_reliable = socket_is_reliable;
167 sock->close = socket_close;
168
169 return sock;
170 }
171
172
173 static void
174 socket_close (NiceSocket *sock)
175 {
176 TcpPriv *priv = sock->priv;
177
178 #ifdef G_OS_WIN32
179 closesocket(sock->fileno);
180 #else
181 close (sock->fileno);
182 #endif
183 if (priv->io_source) {
184 g_source_destroy (priv->io_source);
185 g_source_unref (priv->io_source);
186 }
187 if (priv->io_channel)
188 g_io_channel_unref (priv->io_channel);
189 g_queue_foreach (&priv->send_queue, (GFunc) free_to_be_sent, NULL);
190 g_queue_clear (&priv->send_queue);
191
192 g_slice_free(TcpPriv, sock->priv);
193 }
194
195 static gint
196 socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
197 {
198 TcpPriv *priv = sock->priv;
199 int ret;
200
201 ret = recv (sock->fileno, buf, len, 0);
202
203 /* recv returns 0 when the peer performed a shutdown.. we must return -1 here
204 * so that the agent destroys the g_source */
205 if (ret == 0)
206 return -1;
207
208 if (ret < 0) {
209 #ifdef G_OS_WIN32
210 if (WSAGetLastError () == WSAEWOULDBLOCK)
211 #else
212 if (errno == EAGAIN)
213 #endif
214 return 0;
215 else
216 return ret;
217 }
218
219 if (from)
220 *from = priv->server_addr;
221 return ret;
222 }
223
224
225 static gboolean
226 socket_send (NiceSocket *sock, const NiceAddress *to,
227 guint len, const gchar *buf)
228 {
229 TcpPriv *priv = sock->priv;
230 int ret;
231
232 /* First try to send the data, don't send it later if it can be sent now
233 this way we avoid allocating memory on every send */
234 if (g_queue_is_empty (&priv->send_queue)) {
235 ret = send (sock->fileno, buf, len, 0);
236
237 if (ret < 0) {
238 #ifdef G_OS_WIN32
239 if (WSAGetLastError () == WSAEWOULDBLOCK) {
240 #else
241 if (errno == EAGAIN) {
242 #endif
243 add_to_be_sent (sock, buf, len, FALSE);
244 return TRUE;
245 } else {
246 return FALSE;
247 }
248 } else if ((guint)ret < len) {
249 add_to_be_sent (sock, buf + ret, len - ret, FALSE);
250 return TRUE;
251 }
252 } else {
253 add_to_be_sent (sock, buf, len, FALSE);
254 }
255
256 return TRUE;
257 }
258
259 static gboolean
260 socket_is_reliable (NiceSocket *sock)
261 {
262 return TRUE;
263 }
264
265
266 /*
267 * Returns:
268 * -1 = error
269 * 0 = have more to send
270 * 1 = sent everything
271 */
272
273 static gboolean
274 socket_send_more (
275 GIOChannel *source,
276 GIOCondition condition,
277 gpointer data)
278 {
279 NiceSocket *sock = (NiceSocket *) data;
280 TcpPriv *priv = sock->priv;
281 struct to_be_sent *tbs = NULL;
282
283 g_static_rec_mutex_lock (&priv->agent->mutex);
284
285 while ((tbs = g_queue_pop_head (&priv->send_queue))) {
286 int ret;
287
288 ret = send (sock->fileno, tbs->buf, tbs->length, 0);
289
290 if (ret < 0) {
291 #ifdef G_OS_WIN32
292 if (WSAGetLastError () == WSAEWOULDBLOCK) {
293 #else
294 if (errno == EAGAIN) {
295 #endif
296 add_to_be_sent (sock, tbs->buf, tbs->length, TRUE);
297 g_free (tbs->buf);
298 g_slice_free (struct to_be_sent, tbs);
299 break;
300 }
301 } else if (ret < (int) tbs->length) {
302 add_to_be_sent (sock, tbs->buf + ret, tbs->length - ret, TRUE);
303 g_free (tbs->buf);
304 g_slice_free (struct to_be_sent, tbs);
305 break;
306 }
307
308 g_free (tbs->buf);
309 g_slice_free (struct to_be_sent, tbs);
310 }
311
312 if (g_queue_is_empty (&priv->send_queue)) {
313 g_io_channel_unref (priv->io_channel);
314 priv->io_channel = NULL;
315 g_source_destroy (priv->io_source);
316 g_source_unref (priv->io_source);
317 priv->io_source = NULL;
318
319 g_static_rec_mutex_unlock (&priv->agent->mutex);
320 return FALSE;
321 }
322
323 g_static_rec_mutex_unlock (&priv->agent->mutex);
324 return TRUE;
325 }
326
327
328 static void
329 add_to_be_sent (NiceSocket *sock, const gchar *buf, guint len, gboolean head)
330 {
331 TcpPriv *priv = sock->priv;
332 struct to_be_sent *tbs = NULL;
333
334 if (len <= 0)
335 return;
336
337 tbs = g_slice_new0 (struct to_be_sent);
338 tbs->buf = g_memdup (buf, len);
339 tbs->length = len;
340 if (head)
341 g_queue_push_head (&priv->send_queue, tbs);
342 else
343 g_queue_push_tail (&priv->send_queue, tbs);
344
345 if (priv->io_channel == NULL) {
346 priv->io_channel = g_io_channel_unix_new (sock->fileno);
347 priv->io_source = g_io_create_watch (priv->io_channel, G_IO_OUT);
348 g_source_set_callback (priv->io_source, (GSourceFunc) socket_send_more,
349 sock, NULL);
350 g_source_attach (priv->io_source, priv->context);
351 }
352 }
353
354
355
356 static void
357 free_to_be_sent (struct to_be_sent *tbs)
358 {
359 g_free (tbs->buf);
360 g_slice_free (struct to_be_sent, tbs);
361 }
362
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2006, 2007 Collabora Ltd.
4 * Contact: Dafydd Harries
5 * (C) 2006, 2007 Nokia Corporation. All rights reserved.
6 * Contact: Kai Vehmanen
7 *
8 * The contents of this file are subject to the Mozilla Public License Version
9 * 1.1 (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
12 *
13 * Software distributed under the License is distributed on an "AS IS" basis,
14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15 * for the specific language governing rights and limitations under the
16 * License.
17 *
18 * The Original Code is the Nice GLib ICE library.
19 *
20 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21 * Corporation. All Rights Reserved.
22 *
23 * Contributors:
24 * Dafydd Harries, Collabora Ltd.
25 *
26 * Alternatively, the contents of this file may be used under the terms of the
27 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28 * case the provisions of LGPL are applicable instead of those above. If you
29 * wish to allow use of your version of this file only under the terms of the
30 * LGPL and not to allow others to use your version of this file under the
31 * MPL, indicate your decision by deleting the provisions above and replace
32 * them with the notice and other provisions required by the LGPL. If you do
33 * not delete the provisions above, a recipient may use your version of this
34 * file under either the MPL or the LGPL.
35 */
36
37 #ifndef _TCP_BSD_H
38 #define _TCP_BSD_H
39
40 #include "socket.h"
41 #include "agent.h"
42
43 G_BEGIN_DECLS
44
45
46 NiceSocket *
47 nice_tcp_bsd_socket_new (NiceAgent *agent, GMainContext *ctx, NiceAddress *addr);
48
49
50 G_END_DECLS
51
52 #endif /* _TCP_BSD_H */
53
5757 #endif
5858
5959 typedef struct {
60 NiceUdpTurnSocketCompatibility compatibility;
61 GQueue send_queue;
60 NiceTurnSocketCompatibility compatibility;
6261 gchar recv_buf[65536];
6362 guint recv_buf_len;
6463 guint expecting_len;
65 NiceAddress server_addr;
66 GMainContext *context;
67 GIOChannel *io_channel;
68 GSource *io_source;
64 NiceSocket *base_socket;
6965 } TurnTcpPriv;
7066
71 struct to_be_sent {
72 guint length;
73 gchar *buf;
74 };
75
76 /*** NiceSocket ***/
67
68 static void socket_close (NiceSocket *sock);
69 static gint socket_recv (NiceSocket *sock, NiceAddress *from,
70 guint len, gchar *buf);
71 static gboolean socket_send (NiceSocket *sock, const NiceAddress *to,
72 guint len, const gchar *buf);
73 static gboolean socket_is_reliable (NiceSocket *sock);
74
75 NiceSocket *
76 nice_tcp_turn_socket_new (NiceAgent *agent, NiceSocket *base_socket,
77 NiceTurnSocketCompatibility compatibility)
78 {
79 TurnTcpPriv *priv;
80 NiceSocket *sock = g_slice_new0 (NiceSocket);
81 sock->priv = priv = g_slice_new0 (TurnTcpPriv);
82
83 priv->compatibility = compatibility;
84 priv->base_socket = base_socket;
85
86 sock->fileno = priv->base_socket->fileno;
87 sock->addr = priv->base_socket->addr;
88 sock->send = socket_send;
89 sock->recv = socket_recv;
90 sock->is_reliable = socket_is_reliable;
91 sock->close = socket_close;
92
93 return sock;
94 }
95
96
97 static void
98 socket_close (NiceSocket *sock)
99 {
100 TurnTcpPriv *priv = sock->priv;
101
102 if (priv->base_socket)
103 nice_socket_free (priv->base_socket);
104
105 g_slice_free(TurnTcpPriv, sock->priv);
106 }
107
77108
78109 static gint
79 socket_recv (
80 NiceSocket *sock,
81 NiceAddress *from,
82 guint len,
83 gchar *buf)
110 socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
84111 {
85112 TurnTcpPriv *priv = sock->priv;
86113 int ret;
89116 if (priv->expecting_len == 0) {
90117 guint headerlen = 0;
91118
92 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9)
119 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9)
93120 headerlen = 4;
94 else if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE)
121 else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE)
95122 headerlen = 2;
96123 else
97 g_assert_not_reached();
98
99 ret = recv (sock->fileno, priv->recv_buf + priv->recv_buf_len,
100 headerlen - priv->recv_buf_len, 0);
101 if (ret < 0) {
102 #ifdef G_OS_WIN32
103 if (WSAGetLastError () == WSAEWOULDBLOCK)
104 #else
105 if (errno == EAGAIN)
106 #endif
107 return 0;
108 else
124 return -1;
125
126 ret = nice_socket_recv (priv->base_socket, from,
127 headerlen - priv->recv_buf_len, priv->recv_buf + priv->recv_buf_len);
128 if (ret < 0)
109129 return ret;
110 }
111130
112131 priv->recv_buf_len += ret;
113132
114133 if (priv->recv_buf_len < headerlen)
115134 return 0;
116135
117 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
136 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
118137 guint16 magic = ntohs (*(guint16*)priv->recv_buf);
119138 guint16 packetlen = ntohs (*(guint16*)(priv->recv_buf + 2));
120139
126145 priv->expecting_len = 4 + packetlen;
127146 }
128147 }
129 else if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
148 else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
130149 guint len = ntohs (*(guint16*)priv->recv_buf);
131150 priv->expecting_len = len;
132151 priv->recv_buf_len = 0;
133152 }
134153 }
135154
136 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9)
155 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9)
137156 padlen = (priv->expecting_len % 4) ? 4 - (priv->expecting_len % 4) : 0;
138157 else
139158 padlen = 0;
140159
141 ret = recv (sock->fileno, priv->recv_buf + priv->recv_buf_len,
142 priv->expecting_len + padlen - priv->recv_buf_len, 0);
143 if (ret < 0) {
144 #ifdef G_OS_WIN32
145 if (WSAGetLastError () == WSAEWOULDBLOCK)
146 #else
147 if (errno == EAGAIN)
148 #endif
149 return 0;
150 else
160 ret = nice_socket_recv (priv->base_socket, from,
161 priv->expecting_len + padlen - priv->recv_buf_len,
162 priv->recv_buf + priv->recv_buf_len);
163
164 if (ret < 0)
151165 return ret;
152 }
153166
154167 priv->recv_buf_len += ret;
155168
158171 memcpy (buf, priv->recv_buf, copy_len);
159172 priv->expecting_len = 0;
160173 priv->recv_buf_len = 0;
161 if (from)
162 *from = priv->server_addr;
174
163175 return copy_len;
164176 }
165177
166178 return 0;
167179 }
168 static void
169 add_to_be_sent (NiceSocket *sock, const gchar *buf, guint len, gboolean head);
170
171
172
173 /*
174 * Returns:
175 * -1 = error
176 * 0 = have more to send
177 * 1 = sent everything
178 */
179180
180181 static gboolean
181 socket_send_more (
182 GIOChannel *source,
183 G_GNUC_UNUSED
184 GIOCondition condition,
185 gpointer data)
186 {
187 NiceSocket *sock = (NiceSocket *) data;
188 TurnTcpPriv *priv = sock->priv;
189 struct to_be_sent *tbs = NULL;
190
191 while ((tbs = g_queue_pop_head (&priv->send_queue))) {
192 int ret;
193
194 ret = send (sock->fileno, tbs->buf, tbs->length, 0);
195
196 if (ret < 0) {
197 #ifdef G_OS_WIN32
198 if (WSAGetLastError () == WSAEWOULDBLOCK) {
199 #else
200 if (errno == EAGAIN) {
201 #endif
202 add_to_be_sent (sock, tbs->buf, tbs->length, TRUE);
203 g_free (tbs->buf);
204 g_slice_free (struct to_be_sent, tbs);
205 break;
206 }
207 } else if (ret < (int) tbs->length) {
208 add_to_be_sent (sock, tbs->buf + ret, tbs->length - ret, TRUE);
209 g_free (tbs->buf);
210 g_slice_free (struct to_be_sent, tbs);
211 break;
212 }
213
214 g_free (tbs->buf);
215 g_slice_free (struct to_be_sent, tbs);
216 }
217
218 if (g_queue_is_empty (&priv->send_queue)) {
219 g_io_channel_unref (priv->io_channel);
220 priv->io_channel = NULL;
221 g_source_destroy (priv->io_source);
222 g_source_unref (priv->io_source);
223 priv->io_source = NULL;
224 return FALSE;
225 }
226
227 return TRUE;
228 }
229
230
231 static void
232 add_to_be_sent (NiceSocket *sock, const gchar *buf, guint len, gboolean head)
233 {
234 TurnTcpPriv *priv = sock->priv;
235 struct to_be_sent *tbs = g_slice_new (struct to_be_sent);
236
237 if (len <= 0)
238 return;
239
240 tbs->buf = g_memdup (buf, len);
241 tbs->length = len;
242 if (head)
243 g_queue_push_head (&priv->send_queue, tbs);
244 else
245 g_queue_push_tail (&priv->send_queue, tbs);
246
247 if (priv->io_channel == NULL) {
248 priv->io_channel = g_io_channel_unix_new (sock->fileno);
249 priv->io_source = g_io_create_watch (priv->io_channel, G_IO_OUT);
250 g_source_set_callback (priv->io_source, (GSourceFunc) socket_send_more,
251 sock, NULL);
252 g_source_attach (priv->io_source, priv->context);
253 }
254 }
255
256
257 static gboolean
258 socket_send (
259 NiceSocket *sock,
260 const NiceAddress *to,
261 guint len,
262 const gchar *buf)
263 {
264 int ret;
182 socket_send (NiceSocket *sock, const NiceAddress *to,
183 guint len, const gchar *buf)
184 {
185 gboolean ret = TRUE;
265186 TurnTcpPriv *priv = sock->priv;
266187 gchar padbuf[3] = {0, 0, 0};
267188 int padlen = (len%4) ? 4 - (len%4) : 0;
268189
269 if (priv->compatibility != NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9)
190 if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9)
270191 padlen = 0;
271192
272 /* First try to send the data, don't send it later if it can be sent now
273 this way we avoid allocating memory on every send */
274 if (g_queue_is_empty (&priv->send_queue)) {
275 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
276 guint16 tmpbuf = htons (len);
277 ret = send (sock->fileno, (void *) &tmpbuf, sizeof(guint16), 0);
278
279 if (ret < 0) {
280 #ifdef G_OS_WIN32
281 if (WSAGetLastError () == WSAEWOULDBLOCK) {
282 #else
283 if (errno == EAGAIN) {
284 #endif
285 add_to_be_sent (sock, (gchar *) &tmpbuf, sizeof(guint16), FALSE);
286 add_to_be_sent (sock, buf, len, FALSE);
287 return TRUE;
288 } else {
289 return FALSE;
290 }
291 } else if ((guint)ret < sizeof(guint16)) {
292 add_to_be_sent (sock, ((gchar *) &tmpbuf) + ret,
293 sizeof(guint16) - ret, FALSE);
294 add_to_be_sent (sock, buf, len, FALSE);
295 return TRUE;
296 }
297 }
298
299 ret = send (sock->fileno, buf, len, 0);
300
301 if (ret < 0) {
302 #ifdef G_OS_WIN32
303 if (WSAGetLastError () == WSAEWOULDBLOCK) {
304 #else
305 if (errno == EAGAIN) {
306 #endif
307 add_to_be_sent (sock, buf, len, FALSE);
308 add_to_be_sent (sock, padbuf, padlen, FALSE);
309 return TRUE;
310 } else {
311 return FALSE;
312 }
313 } else if ((guint)ret < len) {
314 add_to_be_sent (sock, buf + ret, len - ret, FALSE);
315 add_to_be_sent (sock, padbuf, padlen, FALSE);
316 return TRUE;
317 }
318
319 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9 &&
320 len % 4) {
321
322 ret = send (sock->fileno, padbuf, padlen, 0);
323
324 if (ret < 0) {
325 #ifdef G_OS_WIN32
326 if (WSAGetLastError () == WSAEWOULDBLOCK) {
327 #else
328 if (errno == EAGAIN) {
329 #endif
330 add_to_be_sent (sock, padbuf, padlen, FALSE);
331 return TRUE;
332 } else {
333 return FALSE;
334 }
335 } else if (ret < padlen) {
336 add_to_be_sent (sock, padbuf, padlen - ret, FALSE);
337 return TRUE;
338 }
339 }
340 } else {
341 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
342 guint16 tmpbuf = htons (len);
343 add_to_be_sent (sock, (gchar*) &tmpbuf, sizeof(guint16), FALSE);
344 }
345 add_to_be_sent (sock, buf, len, FALSE);
346 add_to_be_sent (sock, padbuf, padlen, FALSE);
193 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
194 guint16 tmpbuf = htons (len);
195 ret = nice_socket_send (priv->base_socket, to,
196 sizeof(guint16), (gchar *)&tmpbuf);
197
198 if (!ret)
199 return ret;
347200 }
348201
349 return TRUE;
350 }
351
352 static void
353 free_to_be_sent (struct to_be_sent *tbs)
354 {
355 g_free (tbs->buf);
356 g_slice_free (struct to_be_sent, tbs);
357 }
358
359 static void
360 socket_close (NiceSocket *sock)
361 {
362 TurnTcpPriv *priv = sock->priv;
363 #ifdef G_OS_WIN32
364 closesocket(sock->fileno);
365 #else
366 close (sock->fileno);
367 #endif
368 g_queue_foreach (&priv->send_queue, (GFunc) free_to_be_sent, NULL);
369 g_queue_clear (&priv->send_queue);
370 if (priv->io_channel)
371 g_io_channel_unref (priv->io_channel);
372 if (priv->io_source) {
373 g_source_destroy (priv->io_source);
374 g_source_unref (priv->io_source);
375 }
376 g_slice_free(TurnTcpPriv, sock->priv);
377 }
202 ret = nice_socket_send (priv->base_socket, to, len, buf);
203
204 if (!ret)
205 return ret;
206
207 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9)
208 ret = nice_socket_send (priv->base_socket, to, padlen, padbuf);
209
210 return ret;
211 }
212
378213
379214 static gboolean
380215 socket_is_reliable (NiceSocket *sock)
382217 return TRUE;
383218 }
384219
385
386 NiceSocket *
387 nice_tcp_turn_socket_new (
388 NiceAgent *agent,
389 GMainContext *ctx,
390 NiceAddress *addr,
391 NiceUdpTurnSocketCompatibility compatibility)
392 {
393 int sockfd = -1;
394 int ret;
395 struct sockaddr_storage name;
396 guint name_len = sizeof (name);
397 NiceSocket *sock = g_slice_new0 (NiceSocket);
398 TurnTcpPriv *priv;
399
400 if (addr != NULL) {
401 nice_address_copy_to_sockaddr(addr, (struct sockaddr *)&name);
402 } else {
403 memset (&name, 0, sizeof (name));
404 name.ss_family = AF_UNSPEC;
405 }
406
407 if ((sockfd == -1) &&
408 ((name.ss_family == AF_UNSPEC) ||
409 (name.ss_family == AF_INET))) {
410 sockfd = socket (PF_INET, SOCK_STREAM, 0);
411 name.ss_family = AF_INET;
412 #ifdef HAVE_SA_LEN
413 name.ss_len = sizeof (struct sockaddr_in);
414 #endif
415 }
416
417 if (sockfd == -1) {
418 g_slice_free (NiceSocket, sock);
419 return NULL;
420 }
421
422 #ifdef FD_CLOEXEC
423 fcntl (sockfd, F_SETFD, fcntl (sockfd, F_GETFD) | FD_CLOEXEC);
424 #endif
425 #ifdef O_NONBLOCK
426 fcntl (sockfd, F_SETFL, fcntl (sockfd, F_GETFL) | O_NONBLOCK);
427 #endif
428
429 name_len = name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
430 sizeof(struct sockaddr_in6);
431 ret = connect (sockfd, (const struct sockaddr *)&name, name_len);
432
433 #ifdef G_OS_WIN32
434 if (ret < 0 && WSAGetLastError () != WSAEINPROGRESS) {
435 closesocket (sockfd);
436 #else
437 if (ret < 0 && errno != EINPROGRESS) {
438 close (sockfd);
439 #endif
440 g_slice_free (NiceSocket, sock);
441 return NULL;
442 }
443
444 name_len = name.ss_family == AF_INET? sizeof (struct sockaddr_in) :
445 sizeof(struct sockaddr_in6);
446 if (getsockname (sockfd, (struct sockaddr *) &name, &name_len) < 0) {
447 g_slice_free (NiceSocket, sock);
448 #ifdef G_OS_WIN32
449 closesocket(sockfd);
450 #else
451 close (sockfd);
452 #endif
453 return NULL;
454 }
455
456 nice_address_set_from_sockaddr (&sock->addr, (struct sockaddr *)&name);
457
458 sock->priv = priv = g_slice_new0 (TurnTcpPriv);
459
460 priv->compatibility = compatibility;
461 priv->server_addr = *addr;
462 priv->context = ctx;
463
464 sock->fileno = sockfd;
465 sock->send = socket_send;
466 sock->recv = socket_recv;
467 sock->is_reliable = socket_is_reliable;
468 sock->close = socket_close;
469
470 return sock;
471 }
4444
4545
4646 NiceSocket *
47 nice_tcp_turn_socket_new (
48 NiceAgent *agent,
49 GMainContext *ctx,
50 NiceAddress *addr,
51 NiceUdpTurnSocketCompatibility compatibility);
47 nice_tcp_turn_socket_new (NiceAgent *agent, NiceSocket *base_socket,
48 NiceTurnSocketCompatibility compatibility);
5249
5350
5451 G_END_DECLS
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2008 Collabora Ltd.
4 * (C) 2008 Nokia Corporation
5 * Contact: Youness Alaoui
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is the Nice GLib ICE library.
18 *
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
21 *
22 * Contributors:
23 * Dafydd Harries, Collabora Ltd.
24 * Youness Alaoui, Collabora Ltd.
25 * Rémi Denis-Courmont, Nokia
26 * Kai Vehmanen
27 *
28 * Alternatively, the contents of this file may be used under the terms of the
29 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
30 * case the provisions of LGPL are applicable instead of those above. If you
31 * wish to allow use of your version of this file only under the terms of the
32 * LGPL and not to allow others to use your version of this file under the
33 * MPL, indicate your decision by deleting the provisions above and replace
34 * them with the notice and other provisions required by the LGPL. If you do
35 * not delete the provisions above, a recipient may use your version of this
36 * file under either the MPL or the LGPL.
37 */
38
39 /*
40 * Implementation of TURN
41 */
42 #ifdef HAVE_CONFIG_H
43 # include "config.h"
44 #endif
45
46 #include <string.h>
47 #include <errno.h>
48 #include <fcntl.h>
49
50 #include "turn.h"
51 #include "stun/stunagent.h"
52 #include "stun/usages/timer.h"
53 #include "agent-priv.h"
54
55 typedef struct {
56 StunMessage message;
57 uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
58 stun_timer_t timer;
59 } TURNMessage;
60
61
62 typedef struct {
63 NiceAddress peer;
64 uint16_t channel;
65 } ChannelBinding;
66
67 typedef struct {
68 NiceAgent *nice;
69 StunAgent agent;
70 GList *channels;
71 GList *pending_bindings;
72 ChannelBinding *current_binding;
73 TURNMessage *current_binding_msg;
74 GSource *tick_source;
75 NiceSocket *base_socket;
76 NiceAddress server_addr;
77 uint8_t *username;
78 size_t username_len;
79 uint8_t *password;
80 size_t password_len;
81 NiceTurnSocketCompatibility compatibility;
82 } TurnPriv;
83
84
85
86 static void socket_close (NiceSocket *sock);
87 static gint socket_recv (NiceSocket *sock, NiceAddress *from,
88 guint len, gchar *buf);
89 static gboolean socket_send (NiceSocket *sock, const NiceAddress *to,
90 guint len, const gchar *buf);
91 static gboolean socket_is_reliable (NiceSocket *sock);
92
93 static void priv_process_pending_bindings (TurnPriv *priv);
94 static gboolean priv_retransmissions_tick_unlocked (TurnPriv *priv);
95 static gboolean priv_retransmissions_tick (gpointer pointer);
96 static void priv_schedule_tick (TurnPriv *priv);
97 static void priv_send_turn_message (TurnPriv *priv, TURNMessage *msg);
98 static gboolean priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
99 uint16_t channel, NiceAddress *peer);
100 static gboolean priv_add_channel_binding (TurnPriv *priv, NiceAddress *peer);
101
102
103
104 NiceSocket *
105 nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr,
106 NiceSocket *base_socket, NiceAddress *server_addr,
107 gchar *username, gchar *password, NiceTurnSocketCompatibility compatibility)
108 {
109 TurnPriv *priv = g_new0 (TurnPriv, 1);
110 NiceSocket *sock = g_slice_new0 (NiceSocket);
111
112 if (!sock) {
113 return NULL;
114 }
115
116 if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
117 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
118 STUN_COMPATIBILITY_RFC5389,
119 STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS);
120 } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) {
121 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
122 STUN_COMPATIBILITY_RFC3489,
123 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
124 STUN_AGENT_USAGE_NO_INDICATION_AUTH);
125 } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
126 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
127 STUN_COMPATIBILITY_RFC3489,
128 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
129 STUN_AGENT_USAGE_IGNORE_CREDENTIALS);
130 }
131
132 priv->nice = agent;
133 priv->channels = NULL;
134 priv->current_binding = NULL;
135 priv->base_socket = base_socket;
136
137 if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) {
138 priv->username = g_base64_decode (username, &priv->username_len);
139 priv->password = g_base64_decode (password, &priv->password_len);
140 } else {
141 priv->username = (uint8_t *)g_strdup (username);
142 priv->username_len = (size_t) strlen (username);
143 if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
144 priv->password = NULL;
145 priv->password_len = 0;
146 } else {
147 priv->password = (uint8_t *)g_strdup (password);
148 priv->password_len = (size_t) strlen (password);
149 }
150 }
151 priv->server_addr = *server_addr;
152 priv->compatibility = compatibility;
153 sock->addr = *addr;
154 sock->fileno = base_socket->fileno;
155 sock->send = socket_send;
156 sock->recv = socket_recv;
157 sock->is_reliable = socket_is_reliable;
158 sock->close = socket_close;
159 sock->priv = (void *) priv;
160 return sock;
161 }
162
163
164 static void
165 socket_close (NiceSocket *sock)
166 {
167 TurnPriv *priv = (TurnPriv *) sock->priv;
168 GList *i = NULL;
169 for (i = priv->channels; i; i = i->next) {
170 ChannelBinding *b = i->data;
171 g_free (b);
172 }
173 g_list_free (priv->channels);
174
175 for (i = priv->pending_bindings; i; i = i->next) {
176 ChannelBinding *b = i->data;
177 g_free (b);
178 }
179 g_list_free (priv->pending_bindings);
180
181 if (priv->tick_source != NULL) {
182 g_source_destroy (priv->tick_source);
183 g_source_unref (priv->tick_source);
184 priv->tick_source = NULL;
185 }
186
187 g_free (priv->current_binding);
188 g_free (priv->current_binding_msg);
189 g_free (priv->username);
190 g_free (priv->password);
191 g_free (priv);
192 }
193
194 static gint
195 socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
196 {
197 TurnPriv *priv = (TurnPriv *) sock->priv;
198 uint8_t recv_buf[STUN_MAX_MESSAGE_SIZE];
199 gint recv_len;
200 NiceAddress recv_from;
201 NiceSocket *dummy;;
202
203 recv_len = nice_socket_recv (priv->base_socket, &recv_from,
204 sizeof(recv_buf), (gchar *) recv_buf);
205
206 return nice_turn_socket_parse_recv (sock, &dummy, from, len, buf,
207 &recv_from, (gchar *) recv_buf, (guint) recv_len);
208 }
209
210 static gboolean
211 socket_send (NiceSocket *sock, const NiceAddress *to,
212 guint len, const gchar *buf)
213 {
214 TurnPriv *priv = (TurnPriv *) sock->priv;
215 StunMessage msg;
216 uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
217 size_t msg_len;
218 struct sockaddr_storage sa;
219 GList *i = priv->channels;
220 ChannelBinding *binding = NULL;
221
222 for (; i; i = i->next) {
223 ChannelBinding *b = i->data;
224 if (nice_address_equal (&b->peer, to)) {
225 binding = b;
226 break;
227 }
228 }
229
230 nice_address_copy_to_sockaddr (to, (struct sockaddr *)&sa);
231
232 if (binding) {
233 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 &&
234 len + sizeof(uint32_t) <= sizeof(buffer)) {
235 uint16_t len16 = htons ((uint16_t) len);
236 uint16_t channel16 = htons (binding->channel);
237 memcpy (buffer, &channel16, sizeof(uint16_t));
238 memcpy (buffer + sizeof(uint16_t), &len16,sizeof(uint16_t));
239 memcpy (buffer + sizeof(uint32_t), buf, len);
240 msg_len = len + sizeof(uint32_t);
241 } else {
242 return nice_socket_send (priv->base_socket, &priv->server_addr, len, buf);
243 }
244 } else {
245 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
246 if (!stun_agent_init_indication (&priv->agent, &msg,
247 buffer, sizeof(buffer), STUN_IND_SEND))
248 goto send;
249 if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS,
250 (struct sockaddr *)&sa, sizeof(sa)) != 0)
251 goto send;
252 } else {
253 if (!stun_agent_init_request (&priv->agent, &msg,
254 buffer, sizeof(buffer), STUN_SEND))
255 goto send;
256
257 if (stun_message_append32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
258 TURN_MAGIC_COOKIE) != 0)
259 goto send;
260 if (priv->username != NULL && priv->username_len > 0) {
261 if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_USERNAME,
262 priv->username, priv->username_len) != 0)
263 goto send;
264 }
265 if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_DESTINATION_ADDRESS,
266 (struct sockaddr *)&sa, sizeof(sa)) != 0)
267 goto send;
268
269 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE &&
270 priv->current_binding &&
271 nice_address_equal (&priv->current_binding->peer, to)) {
272 stun_message_append32 (&msg, STUN_ATTRIBUTE_OPTIONS, 1);
273 }
274 }
275
276 if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_DATA, buf, len) != 0)
277 goto send;
278
279 msg_len = stun_agent_finish_message (&priv->agent, &msg,
280 priv->password, priv->password_len);
281 }
282
283 if (msg_len > 0) {
284 return nice_socket_send (priv->base_socket, &priv->server_addr,
285 msg_len, (gchar *)buffer);
286 }
287 send:
288 return nice_socket_send (priv->base_socket, to, len, buf);
289 }
290
291 static gboolean
292 socket_is_reliable (NiceSocket *sock)
293 {
294 TurnPriv *priv = (TurnPriv *) sock->priv;
295 return nice_socket_is_reliable (priv->base_socket);
296 }
297
298
299
300 gint
301 nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
302 NiceAddress *from, guint len, gchar *buf,
303 NiceAddress *recv_from, gchar *recv_buf, guint recv_len)
304 {
305
306 TurnPriv *priv = (TurnPriv *) sock->priv;
307 StunValidationStatus valid;
308 StunMessage msg;
309 struct sockaddr_storage sa;
310 socklen_t from_len = sizeof (sa);
311 GList *i = priv->channels;
312 ChannelBinding *binding = NULL;
313
314 if (nice_address_equal (&priv->server_addr, recv_from)) {
315 valid = stun_agent_validate (&priv->agent, &msg,
316 (uint8_t *) recv_buf, (size_t) recv_len, NULL, NULL);
317
318 if (valid == STUN_VALIDATION_SUCCESS) {
319 if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
320 uint32_t cookie;
321 if (stun_message_find32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
322 &cookie) != 0)
323 goto recv;
324 if (cookie != TURN_MAGIC_COOKIE)
325 goto recv;
326 }
327
328 if (stun_message_get_method (&msg) == STUN_SEND) {
329 if (stun_message_get_class (&msg) == STUN_RESPONSE &&
330 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
331 uint32_t opts = 0;
332 if (stun_message_find32 (&msg, STUN_ATTRIBUTE_OPTIONS, &opts) == 0 &&
333 opts & 0x1)
334 goto msn_google_lock;
335 }
336 return 0;
337 } else if (stun_message_get_method (&msg) == STUN_OLD_SET_ACTIVE_DST) {
338 stun_transid_t request_id;
339 stun_transid_t response_id;
340 if (priv->current_binding && priv->current_binding_msg) {
341 stun_message_id (&msg, response_id);
342 stun_message_id (&priv->current_binding_msg->message, request_id);
343 if (memcmp (request_id, response_id, sizeof(stun_transid_t)) == 0) {
344 g_free (priv->current_binding_msg);
345 priv->current_binding_msg = NULL;
346
347 if (stun_message_get_class (&msg) == STUN_RESPONSE &&
348 priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) {
349 goto msn_google_lock;
350 } else {
351 g_free (priv->current_binding);
352 priv->current_binding = NULL;
353 }
354 }
355 }
356
357 return 0;
358 } else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) {
359 stun_transid_t request_id;
360 stun_transid_t response_id;
361 if (priv->current_binding && priv->current_binding_msg) {
362 stun_message_id (&msg, response_id);
363 stun_message_id (&priv->current_binding_msg->message, request_id);
364 if (memcmp (request_id, response_id, sizeof(stun_transid_t)) == 0) {
365 if (stun_message_get_class (&msg) == STUN_ERROR) {
366 int code = -1;
367 uint8_t *sent_realm = NULL;
368 uint8_t *recv_realm = NULL;
369 uint16_t sent_realm_len = 0;
370 uint16_t recv_realm_len = 0;
371
372 sent_realm = (uint8_t *) stun_message_find (
373 &priv->current_binding_msg->message,
374 STUN_ATTRIBUTE_REALM, &sent_realm_len);
375 recv_realm = (uint8_t *) stun_message_find (&msg,
376 STUN_ATTRIBUTE_REALM, &recv_realm_len);
377
378 /* check for unauthorized error response */
379 if (stun_message_find_error (&msg, &code) == 0 &&
380 (code == 438 || (code == 401 &&
381 !(recv_realm != NULL &&
382 recv_realm_len > 0 &&
383 recv_realm_len == sent_realm_len &&
384 sent_realm != NULL &&
385 memcmp (sent_realm, recv_realm, sent_realm_len) == 0)))) {
386 g_free (priv->current_binding_msg);
387 priv->current_binding_msg = NULL;
388 if (priv->current_binding) {
389 priv_send_channel_bind (priv, &msg,
390 priv->current_binding->channel,
391 &priv->current_binding->peer);
392 }
393 } else {
394 g_free (priv->current_binding);
395 priv->current_binding = NULL;
396 g_free (priv->current_binding_msg);
397 priv->current_binding_msg = NULL;
398 priv_process_pending_bindings (priv);
399 }
400 } else if (stun_message_get_class (&msg) == STUN_RESPONSE) {
401 g_free (priv->current_binding_msg);
402 priv->current_binding_msg = NULL;
403 if (priv->current_binding) {
404 priv->channels = g_list_append (priv->channels,
405 priv->current_binding);
406 priv->current_binding = NULL;
407 }
408 priv_process_pending_bindings (priv);
409 }
410 }
411 }
412 return 0;
413 } else if (stun_message_get_class (&msg) == STUN_INDICATION &&
414 stun_message_get_method (&msg) == STUN_IND_DATA) {
415 uint16_t data_len;
416 uint8_t *data;
417
418 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
419 if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
420 (struct sockaddr *)&sa, &from_len) != 0)
421 goto recv;
422 } else {
423 if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
424 (struct sockaddr *)&sa, &from_len) != 0)
425 goto recv;
426 }
427
428 data = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_DATA,
429 &data_len);
430
431 if (data == NULL)
432 goto recv;
433
434 nice_address_set_from_sockaddr (from, (struct sockaddr *)&sa);
435
436 *from_sock = sock;
437 memmove (buf, data, len > data_len ? data_len : len);
438 return len > data_len ? data_len : len;
439 } else {
440 goto recv;
441 }
442 }
443 }
444
445 recv:
446 for (i = priv->channels; i; i = i->next) {
447 ChannelBinding *b = i->data;
448 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
449 if (b->channel == ntohs(((uint16_t *)recv_buf)[0])) {
450 recv_len = ntohs (((uint16_t *)recv_buf)[1]);
451 recv_buf += sizeof(uint32_t);
452 binding = b;
453 break;
454 }
455 } else {
456 binding = b;
457 break;
458 }
459 }
460
461 if (binding) {
462 *from = binding->peer;
463 *from_sock = sock;
464 } else {
465 *from = *recv_from;
466 }
467
468 memmove (buf, recv_buf, len > recv_len ? recv_len : len);
469 return len > recv_len ? recv_len : len;
470
471 msn_google_lock:
472
473 if (priv->current_binding) {
474 GList *i = priv->channels;
475 for (; i; i = i->next) {
476 ChannelBinding *b = i->data;
477 g_free (b);
478 }
479 g_list_free (priv->channels);
480 priv->channels = g_list_append (NULL, priv->current_binding);
481 priv->current_binding = NULL;
482 priv_process_pending_bindings (priv);
483 }
484
485 return 0;
486 }
487
488 gboolean
489 nice_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer)
490 {
491 TurnPriv *priv = (TurnPriv *) sock->priv;
492 return priv_add_channel_binding (priv, peer);
493 }
494
495 static void
496 priv_process_pending_bindings (TurnPriv *priv)
497 {
498 gboolean ret = FALSE;
499 while (priv->pending_bindings != NULL && ret == FALSE) {
500 NiceAddress *peer = priv->pending_bindings->data;
501 ret = priv_add_channel_binding (priv, peer);
502 priv->pending_bindings = g_list_remove (priv->pending_bindings, peer);
503 nice_address_free (peer);
504 }
505 }
506
507 static gboolean
508 priv_retransmissions_tick_unlocked (TurnPriv *priv)
509 {
510 if (priv->current_binding_msg) {
511 guint timeout = stun_timer_refresh (&priv->current_binding_msg->timer);
512 switch (timeout) {
513 case -1:
514 /* Time out */
515 g_free (priv->current_binding);
516 priv->current_binding = NULL;
517 g_free (priv->current_binding_msg);
518 priv->current_binding_msg = NULL;
519 priv_process_pending_bindings (priv);
520 break;
521 case 0:
522 /* Retransmit */
523 nice_socket_send (priv->base_socket, &priv->server_addr,
524 stun_message_length (&priv->current_binding_msg->message),
525 (gchar *)priv->current_binding_msg->buffer);
526 break;
527 default:
528 break;
529 }
530 }
531
532 priv_schedule_tick (priv);
533 return FALSE;
534 }
535
536
537 static gboolean
538 priv_retransmissions_tick (gpointer pointer)
539 {
540 TurnPriv *priv = pointer;
541 gboolean ret;
542
543 g_static_rec_mutex_lock (&priv->nice->mutex);
544 ret = priv_retransmissions_tick_unlocked (priv);
545 g_static_rec_mutex_unlock (&priv->nice->mutex);
546
547 return ret;
548 }
549
550 static void
551 priv_schedule_tick (TurnPriv *priv)
552 {
553 if (priv->tick_source != NULL) {
554 g_source_destroy (priv->tick_source);
555 g_source_unref (priv->tick_source);
556 priv->tick_source = NULL;
557 }
558
559 if (priv->current_binding_msg) {
560 guint timeout = stun_timer_remainder (&priv->current_binding_msg->timer);
561 if (timeout > 0) {
562 priv->tick_source = agent_timeout_add_with_context (priv->nice, timeout,
563 priv_retransmissions_tick, priv);
564 } else {
565 priv_retransmissions_tick_unlocked (priv);
566 }
567 }
568 }
569
570 static void
571 priv_send_turn_message (TurnPriv *priv, TURNMessage *msg)
572 {
573 size_t stun_len = stun_message_length (&msg->message);
574
575 if (priv->current_binding_msg) {
576 g_free (priv->current_binding_msg);
577 priv->current_binding_msg = NULL;
578 }
579
580 nice_socket_send (priv->base_socket, &priv->server_addr,
581 stun_len, (gchar *)msg->buffer);
582
583 if (nice_socket_is_reliable (priv->base_socket)) {
584 stun_timer_start_reliable (&msg->timer);
585 } else {
586 stun_timer_start (&msg->timer);
587 }
588
589 priv->current_binding_msg = msg;
590 priv_schedule_tick (priv);
591 }
592
593 static gboolean
594 priv_send_channel_bind (TurnPriv *priv, StunMessage *resp,
595 uint16_t channel, NiceAddress *peer)
596 {
597 uint32_t channel_attr = channel << 16;
598 size_t stun_len;
599 struct sockaddr_storage sa;
600 TURNMessage *msg = g_new0 (TURNMessage, 1);
601
602 nice_address_copy_to_sockaddr (peer, (struct sockaddr *)&sa);
603
604 if (!stun_agent_init_request (&priv->agent, &msg->message,
605 msg->buffer, sizeof(msg->buffer), STUN_CHANNELBIND)) {
606 g_free (msg);
607 return FALSE;
608 }
609
610 if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_CHANNEL_NUMBER,
611 channel_attr) != 0) {
612 g_free (msg);
613 return FALSE;
614 }
615
616 if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS,
617 (struct sockaddr *)&sa, sizeof(sa)) != 0) {
618 g_free (msg);
619 return FALSE;
620 }
621
622 if (priv->username != NULL && priv->username_len > 0) {
623 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
624 priv->username, priv->username_len) != 0) {
625 g_free (msg);
626 return FALSE;
627 }
628 }
629
630 if (resp) {
631 uint8_t *realm;
632 uint8_t *nonce;
633 uint16_t len;
634
635 realm = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_REALM, &len);
636 if (realm != NULL) {
637 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_REALM,
638 realm, len) != 0) {
639 g_free (msg);
640 return 0;
641 }
642 }
643 nonce = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_NONCE, &len);
644 if (nonce != NULL) {
645 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_NONCE,
646 nonce, len) != 0) {
647 g_free (msg);
648 return 0;
649 }
650 }
651 }
652
653 stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
654 priv->password, priv->password_len);
655
656 if (stun_len > 0) {
657 priv_send_turn_message (priv, msg);
658 return TRUE;
659 }
660
661 g_free (msg);
662 return FALSE;
663 }
664
665 static gboolean
666 priv_add_channel_binding (TurnPriv *priv, NiceAddress *peer)
667 {
668 size_t stun_len;
669 struct sockaddr_storage sa;
670
671 nice_address_copy_to_sockaddr (peer, (struct sockaddr *)&sa);
672
673 if (priv->current_binding) {
674 NiceAddress * pending= nice_address_new ();
675 *pending = *peer;
676 priv->pending_bindings = g_list_append (priv->pending_bindings, pending);
677 return FALSE;
678 }
679
680 if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
681 uint16_t channel = 0x4000;
682 GList *i = priv->channels;
683 for (; i; i = i->next) {
684 ChannelBinding *b = i->data;
685 if (channel == b->channel) {
686 i = priv->channels;
687 channel++;
688 continue;
689 }
690 }
691
692 if (channel >= 0x4000 && channel < 0xffff) {
693 gboolean ret = priv_send_channel_bind (priv, NULL, channel, peer);
694 if (ret) {
695 priv->current_binding = g_new0 (ChannelBinding, 1);
696 priv->current_binding->channel = channel;
697 priv->current_binding->peer = *peer;
698 }
699 return ret;
700 }
701 return FALSE;
702 } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) {
703 TURNMessage *msg = g_new0 (TURNMessage, 1);
704 if (!stun_agent_init_request (&priv->agent, &msg->message,
705 msg->buffer, sizeof(msg->buffer), STUN_OLD_SET_ACTIVE_DST)) {
706 g_free (msg);
707 return FALSE;
708 }
709
710 if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_MAGIC_COOKIE,
711 TURN_MAGIC_COOKIE) != 0) {
712 g_free (msg);
713 return FALSE;
714 }
715
716 if (priv->username != NULL && priv->username_len > 0) {
717 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
718 priv->username, priv->username_len) != 0) {
719 g_free (msg);
720 return FALSE;
721 }
722 }
723
724 if (stun_message_append_addr (&msg->message,
725 STUN_ATTRIBUTE_DESTINATION_ADDRESS,
726 (struct sockaddr *)&sa, sizeof(sa)) != 0) {
727 g_free (msg);
728 return FALSE;
729 }
730
731 stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
732 priv->password, priv->password_len);
733
734 if (stun_len > 0) {
735 priv->current_binding = g_new0 (ChannelBinding, 1);
736 priv->current_binding->channel = 0;
737 priv->current_binding->peer = *peer;
738 priv_send_turn_message (priv, msg);
739 return TRUE;
740 }
741 g_free (msg);
742 return FALSE;
743 } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
744 priv->current_binding = g_new0 (ChannelBinding, 1);
745 priv->current_binding->channel = 0;
746 priv->current_binding->peer = *peer;
747 return TRUE;
748 } else {
749 return FALSE;
750 }
751
752 return FALSE;
753 }
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2008 Collabora Ltd.
4 * (C) 2008 Nokia Corporation
5 * Contact: Youness Alaoui
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is the Nice GLib ICE library.
18 *
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
21 *
22 * Contributors:
23 * Dafydd Harries, Collabora Ltd.
24 * Youness Alaoui, Collabora Ltd.
25 *
26 * Alternatively, the contents of this file may be used under the terms of the
27 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28 * case the provisions of LGPL are applicable instead of those above. If you
29 * wish to allow use of your version of this file only under the terms of the
30 * LGPL and not to allow others to use your version of this file under the
31 * MPL, indicate your decision by deleting the provisions above and replace
32 * them with the notice and other provisions required by the LGPL. If you do
33 * not delete the provisions above, a recipient may use your version of this
34 * file under either the MPL or the LGPL.
35 */
36
37 #ifndef _TURN_H
38 #define _TURN_H
39
40
41 typedef enum {
42 NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9,
43 NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE,
44 NICE_TURN_SOCKET_COMPATIBILITY_MSN,
45 } NiceTurnSocketCompatibility;
46
47 #include "socket.h"
48 #include "agent.h"
49
50
51 G_BEGIN_DECLS
52
53 gint
54 nice_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock,
55 NiceAddress *from, guint len, gchar *buf,
56 NiceAddress *recv_from, gchar *recv_buf, guint recv_len);
57
58 gboolean
59 nice_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer);
60
61 NiceSocket *
62 nice_turn_socket_new (NiceAgent *agent, NiceAddress *addr,
63 NiceSocket *base_socket, NiceAddress *server_addr,
64 gchar *username, gchar *password, NiceTurnSocketCompatibility compatibility);
65
66
67 G_END_DECLS
68
69 #endif /* _TURN_H */
70
5757 #include <unistd.h>
5858 #endif
5959
60 /*** NiceSocket ***/
61 static int sock_recv_err (int fd)
62 {
63 #ifdef MSG_ERRQUEUE
64 /* Silently dequeue any error message if any */
65 struct msghdr hdr;
66 int saved = errno, val;
6760
68 memset (&hdr, 0, sizeof (hdr));
69 val = recvmsg (fd, &hdr, MSG_ERRQUEUE);
70 errno = saved;
71 return val == 0;
72 #else
73 return 0;
74 #endif
75 }
76
77
78 static gint
79 socket_recv (
80 NiceSocket *sock,
81 NiceAddress *from,
82 guint len,
83 gchar *buf)
84 {
85 gint recvd;
86 struct sockaddr_storage sa;
87 socklen_t from_len = sizeof (sa);
88
89 recvd = recvfrom (sock->fileno, buf, len, 0, (struct sockaddr *) &sa,
90 &from_len);
91 if (recvd == -1)
92 {
93 sock_recv_err (sock->fileno);
94 return -1;
95 }
96
97 nice_address_set_from_sockaddr (from, (struct sockaddr *)&sa);
98 return recvd;
99 }
100
101 static gboolean
102 socket_send (
103 NiceSocket *sock,
104 const NiceAddress *to,
105 guint len,
106 const gchar *buf)
107 {
108 struct sockaddr_storage sa;
109 ssize_t sent;
110
111 nice_address_copy_to_sockaddr (to, (struct sockaddr *)&sa);
112
113 do
114 sent = sendto (sock->fileno, buf, len, 0, (struct sockaddr *) &sa,
115 sa.ss_family == AF_INET? sizeof (struct sockaddr_in) :
116 sizeof(struct sockaddr_in6));
117 while ((sent == -1) && sock_recv_err (sock->fileno));
118
119 return sent == (ssize_t)len;
120 }
121
122 static gboolean
123 socket_is_reliable (NiceSocket *sock)
124 {
125 return FALSE;
126 }
127
128 static void
129 socket_close (NiceSocket *sock)
130 {
131 #ifdef G_OS_WIN32
132 closesocket(sock->fileno);
133 #else
134 close (sock->fileno);
135 #endif
136 }
137
61 static void socket_close (NiceSocket *sock);
62 static gint socket_recv (NiceSocket *sock, NiceAddress *from,
63 guint len, gchar *buf);
64 static gboolean socket_send (NiceSocket *sock, const NiceAddress *to,
65 guint len, const gchar *buf);
66 static gboolean socket_is_reliable (NiceSocket *sock);
13867
13968 NiceSocket *
14069 nice_udp_bsd_socket_new (NiceAddress *addr)
14877 return NULL;
14978 }
15079
151 if (addr != NULL)
152 {
153 nice_address_copy_to_sockaddr(addr, (struct sockaddr *)&name);
154 }
155 else
156 {
157 memset (&name, 0, sizeof (name));
158 name.ss_family = AF_UNSPEC;
159 }
80 if (addr != NULL) {
81 nice_address_copy_to_sockaddr(addr, (struct sockaddr *)&name);
82 } else {
83 memset (&name, 0, sizeof (name));
84 name.ss_family = AF_UNSPEC;
85 }
16086
161 #if 0
162 if ((name.ss_family == AF_INET6) || (name.ss_family == AF_UNSPEC))
163 {
164 sockfd = socket (PF_INET6, SOCK_DGRAM, 0);
165 if (sockfd != -1)
166 {
167 int v6 = name.ss_family == AF_INET6;
168
169 #if defined (IPV6_V6ONLY)
170 if (setsockopt (sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &v6, sizeof (v6)))
171 #else
172 if (!v6)
87 if (name.ss_family == AF_UNSPEC || name.ss_family == AF_INET) {
88 sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
89 name.ss_family = AF_INET;
90 #ifdef HAVE_SA_LEN
91 name.ss_len = sizeof (struct sockaddr_in);
17392 #endif
174 {
175 #ifdef G_OS_WIN32
176 closesocket(sock->fileno);
177 #else
178 close (sockfd);
179 #endif
180 sockfd = -1;
181 }
182 else
183 {
184 # ifdef IPV6_RECVERR
185 int yes = 1;
186 setsockopt (sockfd, SOL_IPV6, IPV6_RECVERR, &yes, sizeof (yes));
187 # endif
188 name.ss_family = AF_INET6;
189 # ifdef HAVE_SA_LEN
190 name.ss_len = sizeof (struct sockaddr_in6);
191 # endif
192 }
193 }
194 }
195 #endif
196 if ((sockfd == -1)
197 && ((name.ss_family == AF_UNSPEC) || (name.ss_family == AF_INET)))
198 {
199 sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
200 name.ss_family = AF_INET;
201 #ifdef HAVE_SA_LEN
202 name.ss_len = sizeof (struct sockaddr_in);
203 #endif
204 }
93 }
20594
20695 if (sockfd == -1) {
20796 g_slice_free (NiceSocket, sock);
20897 return NULL;
20998 }
210
211 #ifdef IP_RECVERR
212 else
213 {
214 int yes = 1;
215 setsockopt (sockfd, SOL_IP, IP_RECVERR, &yes, sizeof (yes));
216 }
217 #endif
21899
219100 #ifdef FD_CLOEXEC
220101 fcntl (sockfd, F_SETFD, fcntl (sockfd, F_GETFD) | FD_CLOEXEC);
248129 }
249130
250131 nice_address_set_from_sockaddr (&sock->addr, (struct sockaddr *)&name);
132 sock->fileno = sockfd;
251133
252 sock->fileno = sockfd;
253134 sock->send = socket_send;
254135 sock->recv = socket_recv;
255136 sock->is_reliable = socket_is_reliable;
256137 sock->close = socket_close;
138
257139 return sock;
258140 }
141
142 static void
143 socket_close (NiceSocket *sock)
144 {
145 #ifdef G_OS_WIN32
146 closesocket(sock->fileno);
147 #else
148 close (sock->fileno);
149 #endif
150 }
151
152 static gint
153 socket_recv (NiceSocket *sock, NiceAddress *from, guint len, gchar *buf)
154 {
155 gint recvd;
156 struct sockaddr_storage sa;
157 socklen_t from_len = sizeof (sa);
158
159 recvd = recvfrom (sock->fileno, buf, len, 0, (struct sockaddr *) &sa,
160 &from_len);
161
162 if (recvd > 0)
163 nice_address_set_from_sockaddr (from, (struct sockaddr *)&sa);
164
165 return recvd;
166 }
167
168 static gboolean
169 socket_send (NiceSocket *sock, const NiceAddress *to,
170 guint len, const gchar *buf)
171 {
172 struct sockaddr_storage sa;
173 ssize_t sent;
174
175 nice_address_copy_to_sockaddr (to, (struct sockaddr *)&sa);
176
177 sent = sendto (sock->fileno, buf, len, 0, (struct sockaddr *) &sa,
178 sa.ss_family == AF_INET? sizeof (struct sockaddr_in) :
179 sizeof(struct sockaddr_in6));
180
181 return sent == (ssize_t)len;
182 }
183
184 static gboolean
185 socket_is_reliable (NiceSocket *sock)
186 {
187 return FALSE;
188 }
189
+0
-759
socket/udp-turn.c less more
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2008 Collabora Ltd.
4 * (C) 2008 Nokia Corporation
5 * Contact: Youness Alaoui
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is the Nice GLib ICE library.
18 *
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
21 *
22 * Contributors:
23 * Dafydd Harries, Collabora Ltd.
24 * Youness Alaoui, Collabora Ltd.
25 * Rémi Denis-Courmont, Nokia
26 * Kai Vehmanen
27 *
28 * Alternatively, the contents of this file may be used under the terms of the
29 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
30 * case the provisions of LGPL are applicable instead of those above. If you
31 * wish to allow use of your version of this file only under the terms of the
32 * LGPL and not to allow others to use your version of this file under the
33 * MPL, indicate your decision by deleting the provisions above and replace
34 * them with the notice and other provisions required by the LGPL. If you do
35 * not delete the provisions above, a recipient may use your version of this
36 * file under either the MPL or the LGPL.
37 */
38
39 /*
40 * Implementation of UDP socket interface using Berkeley sockets. (See
41 * http://en.wikipedia.org/wiki/Berkeley_sockets.)
42 */
43 #ifdef HAVE_CONFIG_H
44 # include "config.h"
45 #endif
46
47 #include <string.h>
48 #include <errno.h>
49 #include <fcntl.h>
50
51 #include "udp-turn.h"
52 #include "udp-bsd.h"
53 #include "stun/stunagent.h"
54 #include "stun/usages/timer.h"
55 #include "agent-priv.h"
56
57 typedef struct {
58 StunMessage message;
59 uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
60 stun_timer_t timer;
61 } TURNMessage;
62
63
64 typedef struct {
65 NiceAddress peer;
66 uint16_t channel;
67 } ChannelBinding;
68
69 typedef struct {
70 NiceAgent *nice;
71 StunAgent agent;
72 GList *channels;
73 GList *pending_bindings;
74 ChannelBinding *current_binding;
75 TURNMessage *current_binding_msg;
76 GSource *tick_source;
77 NiceSocket *base_socket;
78 NiceAddress server_addr;
79 uint8_t *username;
80 size_t username_len;
81 uint8_t *password;
82 size_t password_len;
83 NiceUdpTurnSocketCompatibility compatibility;
84 } turn_priv;
85
86 static void
87 priv_schedule_tick (turn_priv *priv);
88
89 static gboolean
90 priv_add_channel_binding (turn_priv *priv, NiceAddress *peer);
91
92
93 static void
94 priv_process_pending_bindings (turn_priv *priv)
95 {
96 gboolean ret = FALSE;
97 while (priv->pending_bindings != NULL && ret == FALSE) {
98 NiceAddress *peer = priv->pending_bindings->data;
99 ret = priv_add_channel_binding (priv, peer);
100 priv->pending_bindings = g_list_remove (priv->pending_bindings, peer);
101 nice_address_free (peer);
102 }
103 }
104
105 static gboolean
106 priv_retransmissions_tick_unlocked (turn_priv *priv)
107 {
108 if (priv->current_binding_msg) {
109 guint timeout = stun_timer_refresh (&priv->current_binding_msg->timer);
110 switch (timeout) {
111 case -1:
112 /* Time out */
113 g_free (priv->current_binding);
114 priv->current_binding = NULL;
115 g_free (priv->current_binding_msg);
116 priv->current_binding_msg = NULL;
117 priv_process_pending_bindings (priv);
118 break;
119 case 0:
120 /* Retransmit */
121 nice_socket_send (priv->base_socket, &priv->server_addr,
122 stun_message_length (&priv->current_binding_msg->message),
123 (gchar *)priv->current_binding_msg->buffer);
124 break;
125 default:
126 break;
127 }
128 }
129
130 priv_schedule_tick (priv);
131 return FALSE;
132 }
133
134
135 static gboolean
136 priv_retransmissions_tick (gpointer pointer)
137 {
138 turn_priv *priv = pointer;
139 gboolean ret;
140
141 g_static_rec_mutex_lock (&priv->nice->mutex);
142 ret = priv_retransmissions_tick_unlocked (priv);
143 g_static_rec_mutex_unlock (&priv->nice->mutex);
144
145 return ret;
146 }
147
148 static void
149 priv_schedule_tick (turn_priv *priv)
150 {
151 if (priv->tick_source != NULL) {
152 g_source_destroy (priv->tick_source);
153 g_source_unref (priv->tick_source);
154 priv->tick_source = NULL;
155 }
156
157 if (priv->current_binding_msg) {
158 guint timeout = stun_timer_remainder (&priv->current_binding_msg->timer);
159 if (timeout > 0) {
160 priv->tick_source = agent_timeout_add_with_context (priv->nice, timeout,
161 priv_retransmissions_tick, priv);
162 } else {
163 priv_retransmissions_tick_unlocked (priv);
164 }
165 }
166 }
167
168 static void
169 priv_send_turn_message (turn_priv *priv, TURNMessage *msg)
170 {
171 size_t stun_len = stun_message_length (&msg->message);
172
173 if (priv->current_binding_msg) {
174 g_free (priv->current_binding_msg);
175 priv->current_binding_msg = NULL;
176 }
177
178 nice_socket_send (priv->base_socket, &priv->server_addr,
179 stun_len, (gchar *)msg->buffer);
180
181 if (nice_socket_is_reliable (priv->base_socket)) {
182 stun_timer_start_reliable (&msg->timer);
183 } else {
184 stun_timer_start (&msg->timer);
185 }
186
187 priv->current_binding_msg = msg;
188 priv_schedule_tick (priv);
189 }
190
191 static gboolean
192 priv_send_channel_bind (turn_priv *priv, StunMessage *resp,
193 uint16_t channel, NiceAddress *peer) {
194 uint32_t channel_attr = channel << 16;
195 size_t stun_len;
196 struct sockaddr_storage sa;
197 TURNMessage *msg = g_new0 (TURNMessage, 1);
198
199 nice_address_copy_to_sockaddr (peer, (struct sockaddr *)&sa);
200
201 if (!stun_agent_init_request (&priv->agent, &msg->message,
202 msg->buffer, sizeof(msg->buffer), STUN_CHANNELBIND)) {
203 g_free (msg);
204 return FALSE;
205 }
206
207 if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_CHANNEL_NUMBER,
208 channel_attr) != 0) {
209 g_free (msg);
210 return FALSE;
211 }
212
213 if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS,
214 (struct sockaddr *)&sa, sizeof(sa)) != 0) {
215 g_free (msg);
216 return FALSE;
217 }
218
219 if (priv->username != NULL && priv->username_len > 0) {
220 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
221 priv->username, priv->username_len) != 0) {
222 g_free (msg);
223 return FALSE;
224 }
225 }
226
227 if (resp) {
228 uint8_t *realm;
229 uint8_t *nonce;
230 uint16_t len;
231
232 realm = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_REALM, &len);
233 if (realm != NULL) {
234 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_REALM,
235 realm, len) != 0) {
236 g_free (msg);
237 return 0;
238 }
239 }
240 nonce = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_NONCE, &len);
241 if (nonce != NULL) {
242 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_NONCE,
243 nonce, len) != 0) {
244 g_free (msg);
245 return 0;
246 }
247 }
248 }
249
250 stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
251 priv->password, priv->password_len);
252
253 if (stun_len > 0) {
254 priv_send_turn_message (priv, msg);
255 return TRUE;
256 }
257
258 g_free (msg);
259 return FALSE;
260 }
261
262 static gboolean
263 priv_add_channel_binding (turn_priv *priv, NiceAddress *peer)
264 {
265 size_t stun_len;
266 struct sockaddr_storage sa;
267
268 nice_address_copy_to_sockaddr (peer, (struct sockaddr *)&sa);
269
270 if (priv->current_binding) {
271 NiceAddress * pending= nice_address_new ();
272 *pending = *peer;
273 priv->pending_bindings = g_list_append (priv->pending_bindings, pending);
274 return FALSE;
275 }
276
277 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
278 uint16_t channel = 0x4000;
279 GList *i = priv->channels;
280 for (; i; i = i->next) {
281 ChannelBinding *b = i->data;
282 if (channel == b->channel) {
283 i = priv->channels;
284 channel++;
285 continue;
286 }
287 }
288
289 if (channel >= 0x4000 && channel < 0xffff) {
290 gboolean ret = priv_send_channel_bind (priv, NULL, channel, peer);
291 if (ret) {
292 priv->current_binding = g_new0 (ChannelBinding, 1);
293 priv->current_binding->channel = channel;
294 priv->current_binding->peer = *peer;
295 }
296 return ret;
297 }
298 return FALSE;
299 } else if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN) {
300 TURNMessage *msg = g_new0 (TURNMessage, 1);
301 if (!stun_agent_init_request (&priv->agent, &msg->message,
302 msg->buffer, sizeof(msg->buffer), STUN_OLD_SET_ACTIVE_DST)) {
303 g_free (msg);
304 return FALSE;
305 }
306
307 if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_MAGIC_COOKIE,
308 TURN_MAGIC_COOKIE) != 0) {
309 g_free (msg);
310 return FALSE;
311 }
312
313 if (priv->username != NULL && priv->username_len > 0) {
314 if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME,
315 priv->username, priv->username_len) != 0) {
316 g_free (msg);
317 return FALSE;
318 }
319 }
320
321 if (stun_message_append_addr (&msg->message,
322 STUN_ATTRIBUTE_DESTINATION_ADDRESS,
323 (struct sockaddr *)&sa, sizeof(sa)) != 0) {
324 g_free (msg);
325 return FALSE;
326 }
327
328 stun_len = stun_agent_finish_message (&priv->agent, &msg->message,
329 priv->password, priv->password_len);
330
331 if (stun_len > 0) {
332 priv->current_binding = g_new0 (ChannelBinding, 1);
333 priv->current_binding->channel = 0;
334 priv->current_binding->peer = *peer;
335 priv_send_turn_message (priv, msg);
336 return TRUE;
337 }
338 g_free (msg);
339 return FALSE;
340 } else if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
341 priv->current_binding = g_new0 (ChannelBinding, 1);
342 priv->current_binding->channel = 0;
343 priv->current_binding->peer = *peer;
344 return TRUE;
345 } else {
346 return FALSE;
347 }
348
349 return FALSE;
350 }
351
352 gboolean
353 nice_udp_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer)
354 {
355 turn_priv *priv = (turn_priv *) sock->priv;
356 return priv_add_channel_binding (priv, peer);
357 }
358
359
360 gint
361 nice_udp_turn_socket_parse_recv (
362 NiceSocket *sock,
363 NiceSocket **from_sock,
364 NiceAddress *from,
365 guint len,
366 gchar *buf,
367 NiceAddress *recv_from,
368 gchar *recv_buf,
369 guint recv_len)
370 {
371
372 turn_priv *priv = (turn_priv *) sock->priv;
373 StunValidationStatus valid;
374 StunMessage msg;
375 struct sockaddr_storage sa;
376 socklen_t from_len = sizeof (sa);
377 GList *i = priv->channels;
378 ChannelBinding *binding = NULL;
379
380 if (nice_address_equal (&priv->server_addr, recv_from)) {
381 valid = stun_agent_validate (&priv->agent, &msg,
382 (uint8_t *) recv_buf, (size_t) recv_len, NULL, NULL);
383
384 if (valid == STUN_VALIDATION_SUCCESS) {
385 if (priv->compatibility != NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
386 uint32_t cookie;
387 if (stun_message_find32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
388 &cookie) != 0)
389 goto recv;
390 if (cookie != TURN_MAGIC_COOKIE)
391 goto recv;
392 }
393
394 if (stun_message_get_method (&msg) == STUN_SEND) {
395 if (stun_message_get_class (&msg) == STUN_RESPONSE &&
396 priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
397 uint32_t opts = 0;
398 if (stun_message_find32 (&msg, STUN_ATTRIBUTE_OPTIONS, &opts) == 0 &&
399 opts & 0x1)
400 goto msn_google_lock;
401 }
402 return 0;
403 } else if (stun_message_get_method (&msg) == STUN_OLD_SET_ACTIVE_DST) {
404 stun_transid_t request_id;
405 stun_transid_t response_id;
406 if (priv->current_binding && priv->current_binding_msg) {
407 stun_message_id (&msg, response_id);
408 stun_message_id (&priv->current_binding_msg->message, request_id);
409 if (memcmp (request_id, response_id, sizeof(stun_transid_t)) == 0) {
410 g_free (priv->current_binding_msg);
411 priv->current_binding_msg = NULL;
412
413 if (stun_message_get_class (&msg) == STUN_RESPONSE &&
414 priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN) {
415 goto msn_google_lock;
416 } else {
417 g_free (priv->current_binding);
418 priv->current_binding = NULL;
419 }
420 }
421 }
422
423 return 0;
424 } else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) {
425 stun_transid_t request_id;
426 stun_transid_t response_id;
427 if (priv->current_binding && priv->current_binding_msg) {
428 stun_message_id (&msg, response_id);
429 stun_message_id (&priv->current_binding_msg->message, request_id);
430 if (memcmp (request_id, response_id, sizeof(stun_transid_t)) == 0) {
431 if (stun_message_get_class (&msg) == STUN_ERROR) {
432 int code = -1;
433 uint8_t *sent_realm = NULL;
434 uint8_t *recv_realm = NULL;
435 uint16_t sent_realm_len = 0;
436 uint16_t recv_realm_len = 0;
437
438 sent_realm = (uint8_t *) stun_message_find (
439 &priv->current_binding_msg->message,
440 STUN_ATTRIBUTE_REALM, &sent_realm_len);
441 recv_realm = (uint8_t *) stun_message_find (&msg,
442 STUN_ATTRIBUTE_REALM, &recv_realm_len);
443
444 /* check for unauthorized error response */
445 if (stun_message_find_error (&msg, &code) == 0 &&
446 (code == 438 || (code == 401 &&
447 !(recv_realm != NULL &&
448 recv_realm_len > 0 &&
449 recv_realm_len == sent_realm_len &&
450 sent_realm != NULL &&
451 memcmp (sent_realm, recv_realm, sent_realm_len) == 0)))) {
452 g_free (priv->current_binding_msg);
453 priv->current_binding_msg = NULL;
454 if (priv->current_binding) {
455 priv_send_channel_bind (priv, &msg,
456 priv->current_binding->channel,
457 &priv->current_binding->peer);
458 }
459 } else {
460 g_free (priv->current_binding);
461 priv->current_binding = NULL;
462 g_free (priv->current_binding_msg);
463 priv->current_binding_msg = NULL;
464 priv_process_pending_bindings (priv);
465 }
466 } else if (stun_message_get_class (&msg) == STUN_RESPONSE) {
467 g_free (priv->current_binding_msg);
468 priv->current_binding_msg = NULL;
469 if (priv->current_binding) {
470 priv->channels = g_list_append (priv->channels,
471 priv->current_binding);
472 priv->current_binding = NULL;
473 }
474 priv_process_pending_bindings (priv);
475 }
476 }
477 }
478 return 0;
479 } else if (stun_message_get_class (&msg) == STUN_INDICATION &&
480 stun_message_get_method (&msg) == STUN_IND_DATA) {
481 uint16_t data_len;
482 uint8_t *data;
483
484 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
485 if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
486 (struct sockaddr *)&sa, &from_len) != 0)
487 goto recv;
488 } else {
489 if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS,
490 (struct sockaddr *)&sa, &from_len) != 0)
491 goto recv;
492 }
493
494 data = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_DATA,
495 &data_len);
496
497 if (data == NULL)
498 goto recv;
499
500 nice_address_set_from_sockaddr (from, (struct sockaddr *)&sa);
501
502 *from_sock = sock;
503 memmove (buf, data, len > data_len ? data_len : len);
504 return len > data_len ? data_len : len;
505 } else {
506 goto recv;
507 }
508 }
509 }
510
511 recv:
512 for (i = priv->channels; i; i = i->next) {
513 ChannelBinding *b = i->data;
514 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
515 if (b->channel == ntohs(((uint16_t *)recv_buf)[0])) {
516 recv_len = ntohs (((uint16_t *)recv_buf)[1]);
517 recv_buf += sizeof(uint32_t);
518 binding = b;
519 break;
520 }
521 } else {
522 binding = b;
523 break;
524 }
525 }
526
527 if (binding) {
528 *from = binding->peer;
529 *from_sock = sock;
530 } else {
531 *from = *recv_from;
532 }
533
534 memmove (buf, recv_buf, len > recv_len ? recv_len : len);
535 return len > recv_len ? recv_len : len;
536
537 msn_google_lock:
538
539 if (priv->current_binding) {
540 GList *i = priv->channels;
541 for (; i; i = i->next) {
542 ChannelBinding *b = i->data;
543 g_free (b);
544 }
545 g_list_free (priv->channels);
546 priv->channels = g_list_append (NULL, priv->current_binding);
547 priv->current_binding = NULL;
548 priv_process_pending_bindings (priv);
549 }
550
551 return 0;
552 }
553
554 static gint
555 socket_recv (
556 NiceSocket *sock,
557 NiceAddress *from,
558 guint len,
559 gchar *buf)
560 {
561 turn_priv *priv = (turn_priv *) sock->priv;
562 uint8_t recv_buf[STUN_MAX_MESSAGE_SIZE];
563 gint recv_len;
564 NiceAddress recv_from;
565 NiceSocket *dummy;;
566
567 recv_len = nice_socket_recv (priv->base_socket, &recv_from,
568 sizeof(recv_buf), (gchar *) recv_buf);
569
570 return nice_udp_turn_socket_parse_recv (sock, &dummy, from, len, buf,
571 &recv_from, (gchar *) recv_buf, (guint) recv_len);
572 }
573
574 static gboolean
575 socket_send (
576 NiceSocket *sock,
577 const NiceAddress *to,
578 guint len,
579 const gchar *buf)
580 {
581 turn_priv *priv = (turn_priv *) sock->priv;
582 StunMessage msg;
583 uint8_t buffer[STUN_MAX_MESSAGE_SIZE];
584 size_t msg_len;
585 struct sockaddr_storage sa;
586 GList *i = priv->channels;
587 ChannelBinding *binding = NULL;
588
589 for (; i; i = i->next) {
590 ChannelBinding *b = i->data;
591 if (nice_address_equal (&b->peer, to)) {
592 binding = b;
593 break;
594 }
595 }
596
597 nice_address_copy_to_sockaddr (to, (struct sockaddr *)&sa);
598
599 if (binding) {
600 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9 &&
601 len + sizeof(uint32_t) <= sizeof(buffer)) {
602 uint16_t len16 = htons ((uint16_t) len);
603 uint16_t channel16 = htons (binding->channel);
604 memcpy (buffer, &channel16, sizeof(uint16_t));
605 memcpy (buffer + sizeof(uint16_t), &len16,sizeof(uint16_t));
606 memcpy (buffer + sizeof(uint32_t), buf, len);
607 msg_len = len + sizeof(uint32_t);
608 } else {
609 return nice_socket_send (priv->base_socket, &priv->server_addr, len, buf);
610 }
611 } else {
612 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
613 if (!stun_agent_init_indication (&priv->agent, &msg,
614 buffer, sizeof(buffer), STUN_IND_SEND))
615 goto send;
616 if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS,
617 (struct sockaddr *)&sa, sizeof(sa)) != 0)
618 goto send;
619 } else {
620 if (!stun_agent_init_request (&priv->agent, &msg,
621 buffer, sizeof(buffer), STUN_SEND))
622 goto send;
623
624 if (stun_message_append32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE,
625 TURN_MAGIC_COOKIE) != 0)
626 goto send;
627 if (priv->username != NULL && priv->username_len > 0) {
628 if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_USERNAME,
629 priv->username, priv->username_len) != 0)
630 goto send;
631 }
632 if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_DESTINATION_ADDRESS,
633 (struct sockaddr *)&sa, sizeof(sa)) != 0)
634 goto send;
635
636 if (priv->compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE &&
637 priv->current_binding &&
638 nice_address_equal (&priv->current_binding->peer, to)) {
639 stun_message_append32 (&msg, STUN_ATTRIBUTE_OPTIONS, 1);
640 }
641 }
642
643 if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_DATA, buf, len) != 0)
644 goto send;
645
646 msg_len = stun_agent_finish_message (&priv->agent, &msg,
647 priv->password, priv->password_len);
648 }
649
650 if (msg_len > 0) {
651 return nice_socket_send (priv->base_socket, &priv->server_addr,
652 msg_len, (gchar *)buffer);
653 }
654 send:
655 return nice_socket_send (priv->base_socket, to, len, buf);
656 }
657
658 static gboolean
659 socket_is_reliable (NiceSocket *sock)
660 {
661 turn_priv *priv = (turn_priv *) sock->priv;
662 return nice_socket_is_reliable (priv->base_socket);
663 }
664
665 static void
666 socket_close (NiceSocket *sock)
667 {
668 turn_priv *priv = (turn_priv *) sock->priv;
669 GList *i = NULL;
670 for (i = priv->channels; i; i = i->next) {
671 ChannelBinding *b = i->data;
672 g_free (b);
673 }
674 g_list_free (priv->channels);
675
676 for (i = priv->pending_bindings; i; i = i->next) {
677 ChannelBinding *b = i->data;
678 g_free (b);
679 }
680 g_list_free (priv->pending_bindings);
681
682 if (priv->tick_source != NULL) {
683 g_source_destroy (priv->tick_source);
684 g_source_unref (priv->tick_source);
685 priv->tick_source = NULL;
686 }
687
688 g_free (priv->current_binding);
689 g_free (priv->current_binding_msg);
690 g_free (priv->username);
691 g_free (priv->password);
692 g_free (priv);
693 }
694
695
696 NiceSocket *
697 nice_udp_turn_socket_new (
698 NiceAgent *agent,
699 NiceAddress *addr,
700 NiceSocket *base_socket,
701 NiceAddress *server_addr,
702 gchar *username,
703 gchar *password,
704 NiceUdpTurnSocketCompatibility compatibility)
705 {
706 turn_priv *priv = g_new0 (turn_priv, 1);
707 NiceSocket *sock = g_slice_new0 (NiceSocket);
708
709 if (!sock) {
710 return NULL;
711 }
712
713 if (compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9) {
714 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
715 STUN_COMPATIBILITY_RFC5389,
716 STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS);
717 } else if (compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN) {
718 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
719 STUN_COMPATIBILITY_RFC3489,
720 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
721 STUN_AGENT_USAGE_NO_INDICATION_AUTH);
722 } else if (compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
723 stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES,
724 STUN_COMPATIBILITY_RFC3489,
725 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
726 STUN_AGENT_USAGE_IGNORE_CREDENTIALS);
727 }
728
729 priv->nice = agent;
730 priv->channels = NULL;
731 priv->current_binding = NULL;
732 priv->base_socket = base_socket;
733
734 if (compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN) {
735 priv->username = g_base64_decode (username, &priv->username_len);
736 priv->password = g_base64_decode (password, &priv->password_len);
737 } else {
738 priv->username = (uint8_t *)g_strdup (username);
739 priv->username_len = (size_t) strlen (username);
740 if (compatibility == NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE) {
741 priv->password = NULL;
742 priv->password_len = 0;
743 } else {
744 priv->password = (uint8_t *)g_strdup (password);
745 priv->password_len = (size_t) strlen (password);
746 }
747 }
748 priv->server_addr = *server_addr;
749 priv->compatibility = compatibility;
750 sock->addr = *addr;
751 sock->fileno = base_socket->fileno;
752 sock->send = socket_send;
753 sock->recv = socket_recv;
754 sock->is_reliable = socket_is_reliable;
755 sock->close = socket_close;
756 sock->priv = (void *) priv;
757 return sock;
758 }
+0
-82
socket/udp-turn.h less more
0 /*
1 * This file is part of the Nice GLib ICE library.
2 *
3 * (C) 2008 Collabora Ltd.
4 * (C) 2008 Nokia Corporation
5 * Contact: Youness Alaoui
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is the Nice GLib ICE library.
18 *
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
21 *
22 * Contributors:
23 * Dafydd Harries, Collabora Ltd.
24 * Youness Alaoui, Collabora Ltd.
25 *
26 * Alternatively, the contents of this file may be used under the terms of the
27 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28 * case the provisions of LGPL are applicable instead of those above. If you
29 * wish to allow use of your version of this file only under the terms of the
30 * LGPL and not to allow others to use your version of this file under the
31 * MPL, indicate your decision by deleting the provisions above and replace
32 * them with the notice and other provisions required by the LGPL. If you do
33 * not delete the provisions above, a recipient may use your version of this
34 * file under either the MPL or the LGPL.
35 */
36
37 #ifndef _UDP_TURN_H
38 #define _UDP_TURN_H
39
40
41 typedef enum {
42 NICE_UDP_TURN_SOCKET_COMPATIBILITY_DRAFT9,
43 NICE_UDP_TURN_SOCKET_COMPATIBILITY_GOOGLE,
44 NICE_UDP_TURN_SOCKET_COMPATIBILITY_MSN,
45 } NiceUdpTurnSocketCompatibility;
46
47 #include "socket.h"
48 #include "agent.h"
49
50
51 G_BEGIN_DECLS
52
53 gint
54 nice_udp_turn_socket_parse_recv (
55 NiceSocket *sock,
56 NiceSocket **from_sock,
57 NiceAddress *from,
58 guint len,
59 gchar *buf,
60 NiceAddress *recv_from,
61 gchar *recv_buf,
62 guint recv_len);
63
64 gboolean
65 nice_udp_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer);
66
67 NiceSocket *
68 nice_udp_turn_socket_new (
69 NiceAgent *agent,
70 NiceAddress *addr,
71 NiceSocket *udp_socket,
72 NiceAddress *server_addr,
73 gchar *username,
74 gchar *password,
75 NiceUdpTurnSocketCompatibility compatibility);
76
77
78 G_END_DECLS
79
80 #endif /* _UDP_TURN_H */
81
134134 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
135135 NM = @NM@
136136 NMEDIT = @NMEDIT@
137 OBJDUMP = @OBJDUMP@
137138 OBJEXT = @OBJEXT@
138139 OTOOL = @OTOOL@
139140 OTOOL64 = @OTOOL64@
144144 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
145145 NM = @NM@
146146 NMEDIT = @NMEDIT@
147 OBJDUMP = @OBJDUMP@
147148 OBJEXT = @OBJEXT@
148149 OTOOL = @OTOOL@
149150 OTOOL64 = @OTOOL64@
129129 NICE_LT_LDFLAGS = @NICE_LT_LDFLAGS@
130130 NM = @NM@
131131 NMEDIT = @NMEDIT@
132 OBJDUMP = @OBJDUMP@
132133 OBJEXT = @OBJEXT@
133134 OTOOL = @OTOOL@
134135 OTOOL64 = @OTOOL64@