libnice-0.1.14/0000775000076400007640000000000013070512356010217 500000000000000libnice-0.1.14/README.win320000664000076400007640000000411312520743534011762 00000000000000Microsoft Visual Studio v9.0 (aka Microsoft Visual Studio 2008) --------------------------------------------------------------- 1) Download prerequisites (glib, zlib and gettext-runtime) Go to http://www.gtk.org/download/win32.php Download GLib Run-time and Dev packages. At time of writing GLib current version is 2.28.8. Links are http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib_2.28.8-1_win32.zip http://ftp.gnome.org/pub/gnome/binaries/win32/glib/2.28/glib-dev_2.28.8-1_win32.zip Download zlib and gettext-runtime Run-time package. At time of writing zlib current version is 1.2.5 and gettext-runtime current version is 0.18.1.1 Links are http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/zlib_1.2.5-2_win32.zip http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/gettext-runtime_0.18.1.1-2_win32.zip Please not: these packages are no longer supported by libnice and newer packages are not provided. You could use a gstreamer windows build for a current GLib build. Install the devel and runtime installer and copy the glib directory over to your libnice source file as described below http://gstreamer.freedesktop.org/data/pkg/windows/ libnice compiles fine with the version 1.4.5 2) Put glib in the correct path Create a folder glib under libnice root as in the following picture: libnice |--- agent |--- docs |--- glib <-------------- |--- gst | ... |--- tests |--- win32 | AUTHORS | ... | TODO Expand glib__win32.zip, glib-dev__win32.zip, zlib__win32.zip and gettext-runtime__win32.zip under glib folder. The tree should be like the following picture: libnice |--- ... |--- glib |-------- bin |-------- etc |-------- include |-------- lib |-------- manifest |-------- share |-------- src |--- ... 3) Open win32/libnice.sln with Microsoft Visual Studio 2008 Build solution, output will be on libnice/win32/vs9/libnice/bin/Win32_Debug or libnice/win32/vs9/libnice/bin/Win32_Release depending on the configuration chosen. libnice-0.1.14/missing0000755000076400007640000001533013067560510011537 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnice-0.1.14/autogen.sh0000775000076400007640000000170312717676416012160 00000000000000#!/bin/sh # Run this to generate all the initial makefiles, etc. test -n "$srcdir" || srcdir=$(dirname "$0") test -n "$srcdir" || srcdir=. olddir=$(pwd) cd $srcdir (test -f configure.ac) || { echo "*** ERROR: Directory '$srcdir' does not look like the top-level project directory ***" exit 1 } # shellcheck disable=SC2016 PKG_NAME=$(autoconf --trace 'AC_INIT:$1' configure.ac) if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then echo "*** WARNING: I am going to run 'configure' with no arguments." >&2 echo "*** If you wish to pass any to it, please specify them on the" >&2 echo "*** '$0' command line." >&2 echo "" >&2 fi aclocal --install || exit 1 gtkdocize --copy || exit 1 autoreconf --verbose --force --install || exit 1 cd "$olddir" if [ "$NOCONFIGURE" = "" ]; then $srcdir/configure "$@" || exit 1 if [ "$1" = "--help" ]; then exit 0 else echo "Now type 'make' to compile $PKG_NAME" || exit 1 fi else echo "Skipping configure process." fi libnice-0.1.14/common.mk0000664000076400007640000000030112363772107011760 00000000000000CLEANFILES = *.gcno *.gcda pkgincludedir = $(includedir)/nice check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind libnice-0.1.14/Makefile.in0000664000076400007640000007132013070512350012201 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(dist_check_SCRIPTS) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/common.mk \ $(srcdir)/config.h.in AUTHORS COPYING ChangeLog INSTALL NEWS \ README TODO ar-lib compile config.guess config.sub depcomp \ install-sh ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda win32/vs9/libnice.def ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} SUBDIRS = \ stun \ socket \ random \ agent \ nice \ gst \ tests \ docs \ examples DISTCHECK_CONFIGURE_FLAGS = --disable-assert -enable-gtk-doc --enable-introspection EXTRA_DIST = \ COPYING.LGPL \ COPYING.MPL \ README.win32 \ autogen.sh \ common.mk \ scripts/lcov.mk \ scripts/lcov.sh \ scripts/valgrind.sh \ win32 \ win32/vs9/libnice.def \ m4/introspection.m4 MAINTAINERCLEANFILES = ar-lib dist_check_SCRIPTS = \ scripts/check-symbols.sh \ scripts/make-symbol-list.sh all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS) check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool clean-local cscope cscopelist-am ctags ctags-am \ dist dist-all dist-bzip2 dist-gzip dist-lzip dist-shar \ dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind # Generate the win32 DLL symbol export file. # The stun_*() symbols at the end have historically been exported on Windows # but not Linux, for no particular reason. They can’t be removed without # breaking ABI. FIXME: Remove them when we next break ABI. win32/vs9/libnice.def: nice/libnice.sym $(MKDIR_P) $(dir $@) $(AM_V_GEN)(echo "LIBRARY libnice"; \ echo ""; \ echo "EXPORTS"; \ echo ""; \ cat $<; \ echo "stun_debug"; \ echo "stun_debug_bytes"; \ echo "stun_hash_creds") > $@ lcov: find -name '*.gcda' -delete $(MAKE) $(AM_MAKEFLAGS) check find -type d -name '.libs' | while read d ; do \ mv -fv $$d/*.gc* $$d/.. 2>/dev/null || true ; \ done $(MAKE) lcov-report lcov-report: mkdir -p lcov lcov -d . -c > lcov/lcov.info lcov -l lcov/lcov.info 2>/dev/null | \ egrep '(^/usr|/test.*\.c)' | \ cut -d: -f1 > lcov/lcov.remove lcov -r lcov/lcov.info `cat lcov/lcov.remove` 2>/dev/null > lcov/lcov.info.clean genhtml -o lcov lcov/lcov.info.clean clean-local: rm -rf doc .PHONY: doc lcov-report lcov # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/Makefile.am0000664000076400007640000000355313067566654012221 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include common.mk ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} SUBDIRS = \ stun \ socket \ random \ agent \ nice \ gst \ tests \ docs \ examples DISTCHECK_CONFIGURE_FLAGS = --disable-assert -enable-gtk-doc --enable-introspection EXTRA_DIST = \ COPYING.LGPL \ COPYING.MPL \ README.win32 \ autogen.sh \ common.mk \ scripts/lcov.mk \ scripts/lcov.sh \ scripts/valgrind.sh \ win32 \ win32/vs9/libnice.def \ m4/introspection.m4 MAINTAINERCLEANFILES = ar-lib dist_check_SCRIPTS = \ scripts/check-symbols.sh \ scripts/make-symbol-list.sh # Generate the win32 DLL symbol export file. # The stun_*() symbols at the end have historically been exported on Windows # but not Linux, for no particular reason. They can’t be removed without # breaking ABI. FIXME: Remove them when we next break ABI. win32/vs9/libnice.def: nice/libnice.sym $(MKDIR_P) $(dir $@) $(AM_V_GEN)(echo "LIBRARY libnice"; \ echo ""; \ echo "EXPORTS"; \ echo ""; \ cat $<; \ echo "stun_debug"; \ echo "stun_debug_bytes"; \ echo "stun_hash_creds") > $@ CLEANFILES += win32/vs9/libnice.def lcov: find -name '*.gcda' -delete $(MAKE) $(AM_MAKEFLAGS) check find -type d -name '.libs' | while read d ; do \ mv -fv $$d/*.gc* $$d/.. 2>/dev/null || true ; \ done $(MAKE) lcov-report lcov-report: mkdir -p lcov lcov -d . -c > lcov/lcov.info lcov -l lcov/lcov.info 2>/dev/null | \ egrep '(^/usr|/test.*\.c)' | \ cut -d: -f1 > lcov/lcov.remove lcov -r lcov/lcov.info `cat lcov/lcov.remove` 2>/dev/null > lcov/lcov.info.clean genhtml -o lcov lcov/lcov.info.clean clean-local: rm -rf doc .PHONY: doc lcov-report lcov libnice-0.1.14/ChangeLog0000644000076400007640000000000011241364464011700 00000000000000libnice-0.1.14/aclocal.m40000664000076400007640000012656213070512347012013 00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/as-compiler-flag.m4]) m4_include([m4/gtk-doc.m4]) m4_include([m4/introspection.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/pkg.m4]) libnice-0.1.14/INSTALL0000644000076400007640000003661013067560510011175 00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command `./configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX `make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as `configure' are involved. Use GNU `make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. libnice-0.1.14/tests/0000775000076400007640000000000013070512356011361 500000000000000libnice-0.1.14/tests/test-dribble.c0000664000076400007640000003456512661700132014036 00000000000000/* * This file is part of the Nice GLib ICE library. * * Unit test for ICE in dribble mode (adding remote candidates while the * machine is running). * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include #include static NiceComponentState global_lagent_state = NICE_COMPONENT_STATE_LAST; static NiceComponentState global_ragent_state = NICE_COMPONENT_STATE_LAST; static guint global_components_ready = 0; static guint global_components_ready_exit = 0; static guint global_components_failed = 0; static guint global_components_failed_exit = 0; static GMainLoop *global_mainloop = NULL; static gboolean global_lagent_gathering_done = FALSE; static gboolean global_ragent_gathering_done = FALSE; static gboolean global_lagent_ibr_received = FALSE; static gboolean global_ragent_ibr_received = FALSE; static int global_lagent_cands = 0; static int global_ragent_cands = 0; static gint global_ragent_read = 0; static void priv_print_global_status (void) { g_debug ("\tgathering_done=%d", global_lagent_gathering_done && global_ragent_gathering_done); g_debug ("\tlstate=%d", global_lagent_state); g_debug ("\trstate=%d", global_ragent_state); g_debug ("\tL cands=%d R cands=%d", global_lagent_cands, global_ragent_cands); } static gboolean timer_cb (gpointer pointer) { g_debug ("test-dribble:%s: %p", G_STRFUNC, pointer); /* signal status via a global variable */ /* note: should not be reached, abort */ g_error ("ERROR: test has got stuck, aborting..."); return FALSE; } static gboolean quit_loop_cb (gpointer pointer) { g_debug ("test-dribble:%s: %p", G_STRFUNC, pointer); g_main_loop_quit (global_mainloop); return FALSE; } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { g_debug ("test-dribble:%s: %p", G_STRFUNC, user_data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)buf; /* * Lets ignore stun packets that got through */ if (len < 8) return; if (strncmp ("12345678", buf, 8)) return; if (GPOINTER_TO_UINT (user_data) == 2) { global_ragent_read = len; g_main_loop_quit (global_mainloop); } } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-dribble:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) global_lagent_gathering_done = TRUE; else if (GPOINTER_TO_UINT (data) == 2) global_ragent_gathering_done = TRUE; if (global_lagent_gathering_done && global_ragent_gathering_done) g_main_loop_quit (global_mainloop); /* XXX: dear compiler, these are for you: */ (void)agent; } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { gboolean ready_to_connected = FALSE; g_debug ("test-dribble:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) { if (global_lagent_state == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_lagent_state = state; } else if (GPOINTER_TO_UINT (data) == 2) { if (global_ragent_state == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_ragent_state = state; } if (state == NICE_COMPONENT_STATE_READY) global_components_ready++; else if (state == NICE_COMPONENT_STATE_CONNECTED && ready_to_connected) global_components_ready--; if (state == NICE_COMPONENT_STATE_FAILED) global_components_failed++; g_debug ("test-dribble: checks READY/EXIT-AT %u/%u.", global_components_ready, global_components_ready_exit); g_debug ("test-dribble: checks FAILED/EXIT-AT %u/%u.", global_components_failed, global_components_failed_exit); /* signal status via a global variable */ if (global_components_ready == global_components_ready_exit && global_components_failed == global_components_failed_exit) { g_main_loop_quit (global_mainloop); return; } /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data) { g_debug ("test-dribble:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) ++global_lagent_cands; else if (GPOINTER_TO_UINT (data) == 2) ++global_ragent_cands; /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)lfoundation; (void)rfoundation; } static void cb_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer data) { g_debug ("test-dribble:%s: %p", G_STRFUNC, data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; (void)foundation; } static void cb_initial_binding_request_received(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-dribble:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) global_lagent_ibr_received = TRUE; else if (GPOINTER_TO_UINT (data) == 2) global_ragent_ibr_received = TRUE; /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; } int main (void) { NiceAgent *lagent, *ragent; /* agent's L and R */ NiceAddress baseaddr; guint timer_id; GSList *cands, *i; guint ls_id, rs_id; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif global_mainloop = g_main_loop_new (NULL, FALSE); /* step: create the agents L and R */ lagent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_GOOGLE); ragent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_GOOGLE); if (!nice_address_set_from_string (&baseaddr, "127.0.0.1")) g_assert_not_reached (); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); /* step: add a timer to catch state changes triggered by signals */ timer_id = g_timeout_add (30000, timer_cb, NULL); g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (2)); /* step: run test */ g_debug ("test-dribble: running test"); /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = 2; global_components_failed = 0; global_components_failed_exit = 0; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_lagent_cands = global_ragent_cands = 0; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 1); rs_id = nice_agent_add_stream (ragent, 1); g_assert (ls_id > 0); g_assert (rs_id > 0); nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-dribble: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } { gchar *ufrag = NULL, *password = NULL; nice_agent_get_local_credentials(lagent, ls_id, &ufrag, &password); nice_agent_set_remote_credentials (ragent, rs_id, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials(ragent, rs_id, &ufrag, &password); nice_agent_set_remote_credentials (lagent, ls_id, ufrag, password); g_free (ufrag); g_free (password); } cands = nice_agent_get_local_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP); nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); cands = nice_agent_get_local_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP); nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); g_debug ("test-dribble: Set properties, next running mainloop until connectivity checks succeed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ g_main_loop_run (global_mainloop); /* note: verify that STUN binding requests were sent */ g_assert (global_lagent_ibr_received == TRUE); g_assert (global_ragent_ibr_received == TRUE); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY); /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 1); g_assert (global_ragent_cands == 1); g_debug ("test-dribble: agents are ready.. now adding new buggy candidate"); g_timeout_add (500, quit_loop_cb, NULL); g_main_loop_run (global_mainloop); //global_components_ready--; cands = nice_agent_get_local_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP); nice_address_set_port(&((NiceCandidate *) cands->data)->addr, 80); nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); g_assert (global_lagent_state == NICE_COMPONENT_STATE_CONNECTED); g_main_loop_run (global_mainloop); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); /* g_debug ("test-dribble: buggy candidate worked, testing lower priority cand"); cands = nice_agent_get_local_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP); nice_address_set_port(&((NiceCandidate *) cands->data)->addr, 80); ((NiceCandidate *) cands->data)->priority -= 100; nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY);*/ /* note: test payload send and receive */ global_ragent_read = 0; g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16); g_main_loop_run (global_mainloop); g_assert (global_ragent_read == 16); g_debug ("test-dribble: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); priv_print_global_status (); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED); /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 1); g_assert (global_ragent_cands == 1); g_object_unref (lagent); g_object_unref (ragent); g_main_loop_unref (global_mainloop); global_mainloop = NULL; g_source_remove (timer_id); #ifdef G_OS_WIN32 WSACleanup(); #endif return 0; } libnice-0.1.14/tests/test-address.c0000664000076400007640000001237312363772107014063 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "address.h" static void test_ipv4 (void) { NiceAddress addr; NiceAddress other; gchar str[NICE_ADDRESS_STRING_LEN]; nice_address_init (&addr); nice_address_init (&other); nice_address_set_ipv4 (&addr, 0x01020304); g_assert (addr.s.ip4.sin_family == AF_INET); nice_address_to_string (&addr, str); g_assert (0 == strcmp (str, "1.2.3.4")); nice_address_to_string (&addr, str); /* same address */ nice_address_set_ipv4 (&other, 0x01020304); g_assert (TRUE == nice_address_equal (&addr, &other)); /* from sockaddr_in */ nice_address_set_port (&other, 9876); /* in native byte order */ other.s.ip4.sin_family = AF_INET; nice_address_set_from_string (&addr, "1.2.3.4"); nice_address_set_port (&addr, 9876); /* in native byte order */ nice_address_to_string (&addr, str); nice_address_to_string (&other, str); g_assert (TRUE == nice_address_equal (&addr, &other)); /* different IP */ nice_address_set_ipv4 (&other, 0x01020305); g_assert (FALSE == nice_address_equal (&addr, &other)); /* different port */ nice_address_set_ipv4 (&other, 0x01020304); nice_address_set_port (&addr, 1); g_assert (FALSE == nice_address_equal (&addr, &other)); /* test private address check */ { NiceAddress *heap_addr = nice_address_new (); g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1") == TRUE); g_assert (nice_address_is_private (heap_addr) == TRUE); g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1.1") != TRUE); nice_address_free (heap_addr); } } static void test_ipv6 (void) { NiceAddress addr, other, v4addr; gchar str[NICE_ADDRESS_STRING_LEN]; union { struct sockaddr_in6 in6; struct sockaddr addr; } sin, sin2; g_assert (nice_address_set_from_string (&v4addr, "172.1.0.1") == TRUE); memset (&sin, 0, sizeof (sin)); memset (&sin2, 0, sizeof (sin2)); memset (&addr, 0, sizeof (NiceAddress)); memset (&other, 0, sizeof (NiceAddress)); nice_address_init (&addr); nice_address_init (&other); nice_address_set_ipv6 (&addr, (guchar *) "\x00\x11\x22\x33" "\x44\x55\x66\x77" "\x88\x99\xaa\xbb" "\xcc\xdd\xee\xff"); g_assert (addr.s.ip6.sin6_family == AF_INET6); nice_address_to_string (&addr, str); g_assert (0 == strcmp (str, "11:2233:4455:6677:8899:aabb:ccdd:eeff")); nice_address_set_port (&addr, 9876); /* in native byte order */ nice_address_set_from_string (&other, "11:2233:4455:6677:8899:aabb:ccdd:eeff"); nice_address_set_port (&other, 9876); /* in native byte order */ nice_address_copy_to_sockaddr (&other, &sin2.addr); nice_address_copy_to_sockaddr (&addr, &sin.addr); g_assert (nice_address_equal (&addr, &other) == TRUE); nice_address_to_string (&addr, str); nice_address_to_string (&other, str); g_assert (memcmp (&sin, &sin2, sizeof(sin)) == 0); /* private IPv6 address */ nice_address_set_ipv6 (&addr, (guchar *) "\xfc\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x01"); g_assert (nice_address_is_private (&addr) == TRUE); nice_address_set_ipv6 (&addr, (guchar *) "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x01"); g_assert (nice_address_is_private (&addr) == TRUE); /* mismatching address families */ g_assert (nice_address_equal (&addr, &v4addr) != TRUE); /* mismatched type */ addr.s.addr.sa_family = AF_UNSPEC; /*g_assert (nice_address_equal (&addr, &v4addr) != TRUE);*/ } int main (void) { #ifdef G_OS_WIN32 WSADATA w; #endif #ifdef G_OS_WIN32 WSAStartup(0x0202, &w); #endif test_ipv4 (); test_ipv6 (); #ifdef G_OS_WIN32 WSACleanup(); #endif return 0; } libnice-0.1.14/tests/test.c0000664000076400007640000000754112661700132012427 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "agent.h" #include "agent-priv.h" /* Waits about 10 seconds for @var to be NULL/FALSE */ #define WAIT_UNTIL_UNSET(var, context) \ if (var) \ { \ int _i; \ \ for (_i = 0; _i < 13 && (var); _i++) \ { \ g_usleep (1000 * (1 << _i)); \ g_main_context_iteration (context, FALSE); \ } \ \ g_assert (!(var)); \ } gint main (void) { NiceAgent *agent; NiceAddress addr_local, addr_remote; NiceCandidate *candidate; GSList *candidates, *i; guint stream_id; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif nice_address_init (&addr_local); nice_address_init (&addr_remote); g_assert (nice_address_set_from_string (&addr_local, "127.0.0.1")); g_assert (nice_address_set_from_string (&addr_remote, "127.0.0.1")); nice_address_set_port (&addr_remote, 2345); agent = nice_agent_new ( NULL, NICE_COMPATIBILITY_RFC5245); g_object_set (G_OBJECT (agent), "ice-tcp", FALSE, NULL); g_assert (agent->local_addresses == NULL); /* add one local address */ nice_agent_add_local_address (agent, &addr_local); g_assert (agent->local_addresses != NULL); g_assert (g_slist_length (agent->local_addresses) == 1); g_assert (nice_address_equal (agent->local_addresses->data, &addr_local)); /* add a stream */ stream_id = nice_agent_add_stream (agent, 1); nice_agent_gather_candidates (agent, stream_id); /* adding a stream should cause host candidates to be generated */ candidates = nice_agent_get_local_candidates (agent, stream_id, 1); g_assert (g_slist_length (candidates) == 1); candidate = candidates->data; /* socket manager uses random port number */ nice_address_set_port (&addr_local, 1); nice_address_set_port (&(candidate->addr), 1); g_assert (nice_address_equal (&(candidate->addr), &addr_local)); g_assert (strncmp (candidate->foundation, "1", 1) == 0); for (i = candidates; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (candidates); /* clean up */ nice_agent_remove_stream (agent, stream_id); g_object_add_weak_pointer (G_OBJECT (agent), (gpointer *) &agent); g_object_unref (agent); WAIT_UNTIL_UNSET (agent, NULL); #ifdef G_OS_WIN32 WSACleanup(); #endif return 0; } libnice-0.1.14/tests/test-new-dribble.c0000664000076400007640000006210312717676416014635 00000000000000/* * This file is part of the Nice GLib ICE library. * * Unit test for ICE in dribble mode (adding remote candidates while gathering * local candidates). * * (C) 2012 Collabora Ltd. * Contact: Rohan Garg * Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. * * Contributors: * Rohan Garg * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #include #include #include #include #include #include #include #include #include #include #include "stunagent.h" #include "agent-priv.h" #include "agent.h" #define USE_UPNP 0 #define LEFT_AGENT GINT_TO_POINTER(1) #define RIGHT_AGENT GINT_TO_POINTER(2) static GMutex stun_mutex; static GMutex *stun_mutex_ptr = &stun_mutex; static GCond stun_signal; static GCond *stun_signal_ptr = &stun_signal; static GMutex stun_thread_mutex; static GMutex *stun_thread_mutex_ptr = &stun_thread_mutex; static GCond stun_thread_signal; static GCond *stun_thread_signal_ptr = &stun_thread_signal; static NiceComponentState global_lagent_state = NICE_COMPONENT_STATE_LAST; static NiceComponentState global_ragent_state = NICE_COMPONENT_STATE_LAST; static GCancellable *global_cancellable; static gboolean exit_stun_thread = FALSE; static gboolean lagent_candidate_gathering_done = FALSE; static gboolean ragent_candidate_gathering_done = FALSE; static guint global_ls_id, global_rs_id; static gboolean data_received = FALSE; static gboolean drop_stun_packets = FALSE; static gboolean got_stun_packet = FALSE; static gboolean send_stun = FALSE; static guint stun_port; static const uint16_t known_attributes[] = { 0 }; /* Waits about 10 seconds for @var to be NULL/FALSE */ #define WAIT_UNTIL_UNSET(var, context) \ if (var) \ { \ int _i; \ \ for (_i = 0; _i < 13 && (var); _i++) \ { \ g_usleep (1000 * (1 << _i)); \ g_main_context_iteration (context, FALSE); \ } \ \ g_assert (!(var)); \ } /* * Creates a listening socket */ static int listen_socket (unsigned int *port) { union { struct sockaddr_in in; struct sockaddr addr; } addr; int fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd == -1) { perror ("Error opening IP port"); return -1; } memset (&addr, 0, sizeof (addr)); addr.in.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &addr.in.sin_addr); addr.in.sin_port = 0; if (bind (fd, &addr.addr, sizeof (struct sockaddr_in))) { perror ("Error opening IP port"); goto error; } if (port) { socklen_t socklen = sizeof(addr); if (getsockname (fd, &addr.addr, &socklen) < 0) g_error ("getsockname failed: %s", strerror (errno)); g_assert (socklen == sizeof(struct sockaddr_in)); *port = ntohs (addr.in.sin_port); g_assert (*port != 0); } return fd; error: close (fd); return -1; } static int dgram_process (int sock, StunAgent *oldagent, StunAgent *newagent) { union { struct sockaddr_storage storage; struct sockaddr addr; } addr; socklen_t addr_len; uint8_t buf[STUN_MAX_MESSAGE_SIZE]; size_t buf_len = 0; size_t len = 0; StunMessage request; StunMessage response; StunValidationStatus validation; StunAgent *agent = NULL; gint ret; addr_len = sizeof (struct sockaddr_in); recv_packet: len = recvfrom (sock, buf, sizeof(buf), 0, &addr.addr, &addr_len); if (drop_stun_packets) { g_debug ("Dropping STUN packet as requested"); return -1; } if (len == (size_t)-1) { return -1; } validation = stun_agent_validate (newagent, &request, buf, len, NULL, 0); if (validation == STUN_VALIDATION_SUCCESS) { agent = newagent; } else { validation = stun_agent_validate (oldagent, &request, buf, len, NULL, 0); agent = oldagent; } /* Unknown attributes */ if (validation == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE) { buf_len = stun_agent_build_unknown_attributes_error (agent, &response, buf, sizeof (buf), &request); goto send_buf; } /* Mal-formatted packets */ if (validation != STUN_VALIDATION_SUCCESS || stun_message_get_class (&request) != STUN_REQUEST) { goto recv_packet; } switch (stun_message_get_method (&request)) { case STUN_BINDING: stun_agent_init_response (agent, &response, buf, sizeof (buf), &request); if (stun_message_has_cookie (&request)) stun_message_append_xor_addr (&response, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr.storage, addr_len); else stun_message_append_addr (&response, STUN_ATTRIBUTE_MAPPED_ADDRESS, &addr.addr, addr_len); break; case STUN_SHARED_SECRET: case STUN_ALLOCATE: case STUN_SET_ACTIVE_DST: case STUN_CONNECT: case STUN_OLD_SET_ACTIVE_DST: case STUN_IND_DATA: case STUN_IND_CONNECT_STATUS: case STUN_CHANNELBIND: default: if (!stun_agent_init_error (agent, &response, buf, sizeof (buf), &request, STUN_ERROR_BAD_REQUEST)) { g_debug ("STUN error message not initialized properly"); g_assert_not_reached(); } } buf_len = stun_agent_finish_message (agent, &response, NULL, 0); send_buf: g_cancellable_cancel (global_cancellable); g_debug ("Ready to send a STUN response"); g_assert (g_mutex_trylock (stun_mutex_ptr)); got_stun_packet = TRUE; while (send_stun) { g_debug ("Waiting for signal. State is %d", global_lagent_state); g_cond_wait (stun_signal_ptr, stun_mutex_ptr); } g_mutex_unlock (stun_mutex_ptr); len = sendto (sock, buf, buf_len, 0, &addr.addr, addr_len); g_debug ("STUN response sent"); drop_stun_packets = TRUE; ret = (len < buf_len) ? -1 : 0; return ret; } static gpointer stun_thread_func (const gpointer user_data) { StunAgent oldagent; StunAgent newagent; int sock = GPOINTER_TO_INT (user_data); int exit_code = -1; g_mutex_lock (stun_thread_mutex_ptr); g_cond_signal (stun_thread_signal_ptr); g_mutex_unlock (stun_thread_mutex_ptr); stun_agent_init (&oldagent, known_attributes, STUN_COMPATIBILITY_RFC3489, 0); stun_agent_init (&newagent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT); while (!exit_stun_thread) { g_debug ("Ready to process next datagram"); dgram_process (sock, &oldagent, &newagent); } exit_code = close (sock); g_thread_exit (GINT_TO_POINTER (exit_code)); return NULL; } static void set_credentials (NiceAgent *lagent, guint lstream, NiceAgent *ragent, guint rstream) { gchar *ufrag = NULL, *password = NULL; nice_agent_get_local_credentials (lagent, lstream, &ufrag, &password); nice_agent_set_remote_credentials (ragent, rstream, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials (ragent, rstream, &ufrag, &password); nice_agent_set_remote_credentials (lagent, lstream, ufrag, password); g_free (ufrag); g_free (password); } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-dribblemode:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT(data) == 1) { g_debug ("lagent finished gathering candidates"); lagent_candidate_gathering_done = TRUE; } else if (GPOINTER_TO_UINT(data) == 2) { g_debug ("ragent finished gathering candidates"); ragent_candidate_gathering_done = TRUE; } g_cancellable_cancel (global_cancellable); } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { gint ret; g_debug ("test-dribblemode:%s: %p", G_STRFUNC, user_data); ret = strncmp ("0000", buf, 4); if (ret == 0) { ret = strncmp ("00001234567812345678", buf, 16); g_assert (ret == 0); g_debug ("test-dribblemode:%s: ragent recieved %d bytes : quit mainloop", G_STRFUNC, len); data_received = TRUE; g_cancellable_cancel (global_cancellable); } } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { gint ret; g_debug ("test-dribblemode:%s: %p", G_STRFUNC, data); if(GPOINTER_TO_UINT(data) == 1) { global_lagent_state = state; g_debug ("lagent state is %d", state); } else if (GPOINTER_TO_UINT(data) == 2) { g_debug ("ragent state is %d", state); global_ragent_state = state; } if (GPOINTER_TO_UINT(data) == 1 && state == NICE_COMPONENT_STATE_FAILED) { g_debug ("Signalling STUN response since connchecks failed"); g_mutex_lock (stun_mutex_ptr); send_stun = TRUE; g_cond_signal (stun_signal_ptr); g_mutex_unlock (stun_mutex_ptr); g_cancellable_cancel (global_cancellable); } if(GPOINTER_TO_UINT(data) == 1 && state == NICE_COMPONENT_STATE_READY) { /* note: test payload send and receive */ ret = nice_agent_send (agent, stream_id, component_id, 20, "00001234567812345678"); g_debug ("Sent %d bytes", ret); g_assert (ret == 20); } } static void swap_candidates(NiceAgent *local, guint local_id, NiceAgent *remote, guint remote_id, gboolean signal_stun_reply) { GSList *cands = NULL; g_debug ("test-dribblemode:%s", G_STRFUNC); cands = nice_agent_get_local_candidates(local, local_id, NICE_COMPONENT_TYPE_RTP); g_assert(nice_agent_set_remote_candidates(remote, remote_id, NICE_COMPONENT_TYPE_RTP, cands)); if (signal_stun_reply) { g_mutex_lock (stun_mutex_ptr); send_stun = TRUE; g_cond_signal (stun_signal_ptr); g_mutex_unlock (stun_mutex_ptr); } g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free); } static void cb_agent_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer user_data) { NiceAgent *other = g_object_get_data (G_OBJECT (agent), "other-agent"); GSList *cands = nice_agent_get_local_candidates (agent, stream_id, component_id); GSList *i = NULL; GSList *remote_cands = NULL; NiceCandidate* temp; gpointer tmp; guint id; g_debug ("test-dribblemode:%s: %p", G_STRFUNC, user_data); tmp = g_object_get_data (G_OBJECT (other), "id"); id = GPOINTER_TO_UINT (tmp); for (i = cands; i; i = i->next) { temp = (NiceCandidate*) i->data; if (g_strcmp0(temp->foundation, foundation) == 0) { g_debug ("Adding new local candidate to other agent's connchecks"); remote_cands = g_slist_prepend (remote_cands, nice_candidate_copy(temp)); g_assert (nice_agent_set_remote_candidates (other, id, NICE_COMPONENT_TYPE_RTP, remote_cands)); } } g_slist_free_full (remote_cands, (GDestroyNotify) nice_candidate_free); g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free); } static void add_bad_candidate (NiceAgent *agent, guint stream_id, NiceCandidate *cand) { NiceAddress bad_addr; GSList *cand_list = NULL; g_assert (nice_address_set_from_string (&bad_addr, "172.1.0.1")); cand = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST); cand->stream_id = stream_id; cand->component_id = NICE_COMPONENT_TYPE_RTP; cand->addr = bad_addr; nice_agent_get_local_credentials (agent, stream_id, &cand->username, &cand->password); cand_list = g_slist_prepend (cand_list, cand); g_debug ("Adding buggy candidate to the agent %p", agent); g_assert (nice_agent_set_remote_candidates (agent, stream_id, NICE_COMPONENT_TYPE_RTP, cand_list)); g_slist_free_full (cand_list, (GDestroyNotify) nice_candidate_free); } static void init_test(NiceAgent *lagent, NiceAgent *ragent, gboolean connect_new_candidate_signal) { global_lagent_state = NICE_COMPONENT_STATE_DISCONNECTED; global_ragent_state = NICE_COMPONENT_STATE_DISCONNECTED; lagent_candidate_gathering_done = FALSE; ragent_candidate_gathering_done = FALSE; global_ls_id = nice_agent_add_stream (lagent, 1); global_rs_id = nice_agent_add_stream (ragent, 1); g_assert (global_ls_id > 0); g_assert (global_rs_id > 0); g_debug ("lagent stream is : %d and ragent stream is %d", global_ls_id, global_rs_id); g_object_set_data (G_OBJECT (lagent), "id", GUINT_TO_POINTER (global_ls_id)); g_object_set_data (G_OBJECT (ragent), "id", GUINT_TO_POINTER (global_rs_id)); if (connect_new_candidate_signal) { g_signal_connect (G_OBJECT(lagent), "new-candidate", G_CALLBACK(cb_agent_new_candidate), LEFT_AGENT); g_signal_connect (G_OBJECT(ragent), "new-candidate", G_CALLBACK(cb_agent_new_candidate), RIGHT_AGENT); } else { g_signal_handlers_disconnect_by_func (G_OBJECT(lagent), cb_agent_new_candidate, LEFT_AGENT); g_signal_handlers_disconnect_by_func (G_OBJECT(ragent), cb_agent_new_candidate, RIGHT_AGENT); } data_received = FALSE; got_stun_packet = FALSE; send_stun = FALSE; nice_agent_attach_recv (lagent, global_ls_id, NICE_COMPONENT_TYPE_RTP, g_main_context_default (), cb_nice_recv, LEFT_AGENT); nice_agent_attach_recv (ragent, global_rs_id, NICE_COMPONENT_TYPE_RTP, g_main_context_default (), cb_nice_recv, RIGHT_AGENT); } static void cleanup(NiceAgent *lagent, NiceAgent *ragent) { g_debug ("Cleaning up"); drop_stun_packets = FALSE; nice_agent_remove_stream (lagent, global_ls_id); nice_agent_remove_stream (ragent, global_rs_id); } static void standard_test(NiceAgent *lagent, NiceAgent *ragent) { g_debug ("test-dribblemode:%s", G_STRFUNC); got_stun_packet = FALSE; init_test (lagent, ragent, FALSE); nice_agent_gather_candidates (lagent, global_ls_id); while (!got_stun_packet) g_main_context_iteration (NULL, TRUE); g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING && !lagent_candidate_gathering_done); nice_agent_gather_candidates (ragent, global_rs_id); while (!ragent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (ragent_candidate_gathering_done); set_credentials (lagent, global_ls_id, ragent, global_rs_id); g_debug ("Setting local candidates of ragent as remote candidates of lagent"); swap_candidates (ragent, global_rs_id, lagent, global_ls_id, TRUE); while (!data_received) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (global_lagent_state >= NICE_COMPONENT_STATE_CONNECTED && data_received); g_debug ("Setting local candidates of lagent as remote candidates of ragent"); swap_candidates (lagent, global_ls_id, ragent, global_rs_id, FALSE); while (!lagent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (lagent_candidate_gathering_done); while (global_ragent_state < NICE_COMPONENT_STATE_CONNECTED) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED); cleanup (lagent, ragent); } static void bad_credentials_test(NiceAgent *lagent, NiceAgent *ragent) { g_debug ("test-dribblemode:%s", G_STRFUNC); init_test (lagent, ragent, FALSE); nice_agent_set_remote_credentials (lagent, global_ls_id, "wrong", "wrong"); nice_agent_set_remote_credentials (ragent, global_rs_id, "wrong2", "wrong2"); nice_agent_gather_candidates (lagent, global_ls_id); while (!got_stun_packet) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING && !lagent_candidate_gathering_done); nice_agent_gather_candidates (ragent, global_rs_id); while (!ragent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (ragent_candidate_gathering_done); swap_candidates (ragent, global_rs_id, lagent, global_ls_id, FALSE); while (global_lagent_state != NICE_COMPONENT_STATE_FAILED) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); // Set the correct credentials and swap candidates set_credentials (lagent, global_ls_id, ragent, global_rs_id); swap_candidates (ragent, global_rs_id, lagent, global_ls_id, FALSE); swap_candidates (lagent, global_ls_id, ragent, global_rs_id, FALSE); while (!data_received) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (data_received); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED); // Wait for lagent to finish gathering candidates while (!lagent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (lagent_candidate_gathering_done); cleanup (lagent, ragent); } static void bad_candidate_test(NiceAgent *lagent,NiceAgent *ragent) { NiceCandidate *cand = NULL; g_debug ("test-dribblemode:%s", G_STRFUNC); init_test (lagent, ragent, FALSE); nice_agent_gather_candidates (lagent, global_ls_id); while (!got_stun_packet) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING && !lagent_candidate_gathering_done); nice_agent_gather_candidates (ragent, global_rs_id); while (!ragent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (ragent_candidate_gathering_done); add_bad_candidate (lagent, global_ls_id, cand); // lagent will finish candidate gathering causing this mainloop to quit while (!lagent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); // connchecks will fail causing this mainloop to quit while (global_lagent_state != NICE_COMPONENT_STATE_FAILED) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (global_lagent_state == NICE_COMPONENT_STATE_FAILED && !data_received); set_credentials (lagent, global_ls_id, ragent, global_rs_id); swap_candidates (ragent, global_rs_id, lagent, global_ls_id, FALSE); swap_candidates (lagent, global_ls_id, ragent, global_rs_id, FALSE); while (!data_received) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (lagent_candidate_gathering_done); g_assert (global_lagent_state >= NICE_COMPONENT_STATE_CONNECTED); g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED); cleanup (lagent, ragent); } static void new_candidate_test(NiceAgent *lagent, NiceAgent *ragent) { g_debug ("test-dribblemode:%s", G_STRFUNC); init_test (lagent, ragent, TRUE); set_credentials (lagent, global_ls_id, ragent, global_rs_id); nice_agent_gather_candidates (lagent, global_ls_id); while (!got_stun_packet) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (global_lagent_state == NICE_COMPONENT_STATE_GATHERING && !lagent_candidate_gathering_done); nice_agent_gather_candidates (ragent, global_rs_id); while (!ragent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); // Wait for data while (!data_received) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (data_received); // Data arrived, signal STUN thread to send STUN response g_mutex_lock (stun_mutex_ptr); send_stun = TRUE; g_cond_signal (stun_signal_ptr); g_mutex_unlock (stun_mutex_ptr); // Wait for lagent to finish gathering candidates while (!lagent_candidate_gathering_done || !lagent_candidate_gathering_done) g_main_context_iteration (NULL, TRUE); g_cancellable_reset (global_cancellable); g_assert (lagent_candidate_gathering_done); g_assert (ragent_candidate_gathering_done); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state >= NICE_COMPONENT_STATE_CONNECTED); cleanup (lagent, ragent); } static void send_dummy_data(void) { int sockfd = listen_socket (NULL); union { struct sockaddr_in in; struct sockaddr addr; } addr; memset (&addr, 0, sizeof (addr)); addr.in.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &addr.in.sin_addr); addr.in.sin_port = htons (stun_port); g_debug ("Sending dummy data to close STUN thread"); sendto (sockfd, "close socket", 12, 0, &addr.addr, sizeof (addr)); } int main(void) { NiceAgent *lagent = NULL, *ragent = NULL; GThread *stun_thread = NULL; NiceAddress baseaddr; GSource *src; int sock; global_cancellable = g_cancellable_new (); src = g_cancellable_source_new (global_cancellable); g_source_set_dummy_callback (src); g_source_attach (src, NULL); sock = listen_socket (&stun_port); if (sock == -1) { g_assert_not_reached (); } stun_thread = g_thread_new ("listen for STUN requests", stun_thread_func, GINT_TO_POINTER (sock)); // Once the the thread is forked, we want to listen for a signal // that the socket was opened successfully g_mutex_lock (stun_thread_mutex_ptr); g_cond_wait (stun_thread_signal_ptr, stun_thread_mutex_ptr); lagent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); ragent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); g_object_set (G_OBJECT (lagent), "ice-tcp", FALSE, NULL); g_object_set (G_OBJECT (ragent), "ice-tcp", FALSE, NULL); g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); g_object_set (G_OBJECT (lagent), "upnp", USE_UPNP, NULL); g_object_set (G_OBJECT (ragent), "upnp", USE_UPNP, NULL); g_object_set (G_OBJECT (lagent), "stun-server", "127.0.0.1", NULL); g_object_set (G_OBJECT (lagent), "stun-server-port", stun_port, NULL); g_object_set_data (G_OBJECT (lagent), "other-agent", ragent); g_object_set_data (G_OBJECT (ragent), "other-agent", lagent); g_assert (nice_address_set_from_string (&baseaddr, "127.0.0.1")); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); g_signal_connect(G_OBJECT(lagent), "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), LEFT_AGENT); g_signal_connect(G_OBJECT(ragent), "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), RIGHT_AGENT); g_signal_connect(G_OBJECT(lagent), "component-state-changed", G_CALLBACK(cb_component_state_changed), LEFT_AGENT); g_signal_connect(G_OBJECT(ragent), "component-state-changed", G_CALLBACK(cb_component_state_changed), RIGHT_AGENT); standard_test (lagent, ragent); bad_credentials_test (lagent, ragent); bad_candidate_test (lagent, ragent); new_candidate_test (lagent, ragent); // Do this to make sure the STUN thread exits exit_stun_thread = TRUE; drop_stun_packets = TRUE; send_dummy_data (); g_object_add_weak_pointer (G_OBJECT (lagent), (gpointer *) &lagent); g_object_add_weak_pointer (G_OBJECT (ragent), (gpointer *) &ragent); g_object_unref (lagent); g_object_unref (ragent); g_thread_join (stun_thread); g_object_unref (global_cancellable); g_source_destroy (src); g_source_unref (src); WAIT_UNTIL_UNSET (lagent, NULL); WAIT_UNTIL_UNSET (ragent, NULL); return 0; } libnice-0.1.14/tests/check-test-fullmode-with-stun.sh0000775000076400007640000000102612725333757017452 00000000000000#! /bin/sh STUND=../stun/tools/stund echo "Starting ICE full-mode with STUN unit test." [ -e "$STUND" ] || { echo "STUN server not found: Cannot run unit test!" >&2 exit 77 } set -x pidfile=./stund.pid export NICE_STUN_SERVER=127.0.0.1 export NICE_STUN_SERVER_PORT=3800 echo "Launching stund on port ${NICE_STUN_SERVER_PORT}." rm -f -- "$pidfile" (sh -c "echo \$\$ > \"$pidfile\" && exec "$STUND" ${NICE_STUN_SERVER_PORT}") & sleep 1 ./test-fullmode error=$? kill "$(cat "$pidfile")" rm -f -- "$pidfile" wait exit ${error} libnice-0.1.14/tests/test-pseudotcp.c0000664000076400007640000001700112661700132014423 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include "pseudotcp.h" PseudoTcpSocket *left; PseudoTcpSocket *right; GMainLoop *mainloop = NULL; FILE *in = NULL; FILE *out = NULL; int total_read = 0; int total_wrote = 0; guint left_clock = 0; guint right_clock = 0; gboolean left_closed; gboolean right_closed; gboolean reading_done = FALSE; static void adjust_clock (PseudoTcpSocket *sock); static void write_to_sock (PseudoTcpSocket *sock) { gchar buf[1024]; gsize len; gint wlen; guint total = 0; while (TRUE) { len = fread (buf, 1, sizeof(buf), in); if (len == 0) { g_debug ("Done reading data from file"); g_assert (feof (in)); reading_done = TRUE; pseudo_tcp_socket_close (sock, FALSE); break; } else { wlen = pseudo_tcp_socket_send (sock, buf, len); g_debug ("Sending %" G_GSIZE_FORMAT " bytes : %d", len, wlen); total += wlen; total_read += wlen; if (wlen < (gint) len) { g_debug ("seeking %ld from %lu", wlen - len, ftell (in)); fseek (in, wlen - len, SEEK_CUR); g_assert (!feof (in)); g_debug ("Socket queue full after %d bytes written", total); break; } } } adjust_clock (sock); } static void opened (PseudoTcpSocket *sock, gpointer data) { g_debug ("Socket %p Opened", sock); if (sock == left) { if (in) write_to_sock (sock); else { pseudo_tcp_socket_send (sock, "abcdefghijklmnopqrstuvwxyz", 26); reading_done = TRUE; pseudo_tcp_socket_close (sock, FALSE); } } } static void readable (PseudoTcpSocket *sock, gpointer data) { gchar buf[1024]; gint len; g_debug ("Socket %p Readable", sock); do { len = pseudo_tcp_socket_recv (sock, buf, sizeof(buf)); if (len > 0) { g_debug ("Read %d bytes", len); if (out) { if (fwrite (buf, len, 1, out) == 0) g_debug ("Error writing to output file"); else { total_wrote += len; g_assert (total_wrote <= total_read); g_debug ("Written %d bytes, need %d bytes", total_wrote, total_read); if (total_wrote == total_read && feof (in)) { g_assert (reading_done); pseudo_tcp_socket_close (sock, FALSE); } } } else { if (len == 26 && strncmp (buf, "abcdefghijklmnopqrstuvwxyz", len) == 0) { pseudo_tcp_socket_close (sock, FALSE); } else { g_debug ("Error reading data.. read %d bytes : %s", len, buf); exit (-1); } } } else if (len == 0) { pseudo_tcp_socket_close (sock, FALSE); } } while (len > 0); if (len == -1 && pseudo_tcp_socket_get_error (sock) != EWOULDBLOCK) { g_debug ("Error reading from socket %p: %s", sock, g_strerror (pseudo_tcp_socket_get_error (sock))); exit (-1); } } static void writable (PseudoTcpSocket *sock, gpointer data) { g_debug ("Socket %p Writable", sock); if (in && sock == left) write_to_sock (sock); } static void closed (PseudoTcpSocket *sock, guint32 err, gpointer data) { g_error ("Socket %p Closed : %d", sock, err); } struct notify_data { PseudoTcpSocket *sock; guint32 len; gchar buffer[]; }; static gboolean notify_packet (gpointer user_data) { struct notify_data *data = (struct notify_data*) user_data; pseudo_tcp_socket_notify_packet (data->sock, data->buffer, data->len); adjust_clock (data->sock); g_free (data); return FALSE; } static PseudoTcpWriteResult write_packet (PseudoTcpSocket *sock, const gchar *buffer, guint32 len, gpointer user_data) { struct notify_data *data; PseudoTcpState state; int drop_rate = rand () % 100; g_object_get (sock, "state", &state, NULL); if (drop_rate < 5) { g_debug ("*********************Dropping packet (%d) from %p", drop_rate, sock); return WR_SUCCESS; } data = g_malloc (sizeof(struct notify_data) + len); g_debug ("Socket %p(%d) Writing : %d bytes", sock, state, len); memcpy (data->buffer, buffer, len); data->len = len; if (sock == left) data->sock = right; else data->sock = left; g_idle_add (notify_packet, data); return WR_SUCCESS; } static gboolean notify_clock (gpointer data) { PseudoTcpSocket *sock = (PseudoTcpSocket *)data; //g_debug ("Socket %p: Notifying clock", sock); pseudo_tcp_socket_notify_clock (sock); adjust_clock (sock); return FALSE; } static void adjust_clock (PseudoTcpSocket *sock) { guint64 timeout = 0; if (pseudo_tcp_socket_get_next_clock (sock, &timeout)) { timeout -= g_get_monotonic_time () / 1000; g_debug ("Socket %p: Adjusting clock to %" G_GUINT64_FORMAT " ms", sock, timeout); if (sock == left) { if (left_clock != 0) g_source_remove (left_clock); left_clock = g_timeout_add (timeout, notify_clock, sock); } else { if (right_clock != 0) g_source_remove (right_clock); right_clock = g_timeout_add (timeout, notify_clock, sock); } } else { g_debug ("Socket %p should be destroyed, it's done", sock); if (sock == left) left_closed = TRUE; else right_closed = TRUE; if (left_closed && right_closed) g_main_loop_quit (mainloop); } } int main (int argc, char *argv[]) { PseudoTcpCallbacks cbs = { NULL, opened, readable, writable, closed, write_packet }; setlocale (LC_ALL, ""); mainloop = g_main_loop_new (NULL, FALSE); pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE); left_closed = right_closed = FALSE; left = pseudo_tcp_socket_new (0, &cbs); right = pseudo_tcp_socket_new (0, &cbs); g_debug ("Left: %p. Right: %p", left, right); pseudo_tcp_socket_notify_mtu (left, 1496); pseudo_tcp_socket_notify_mtu (right, 1496); pseudo_tcp_socket_connect (left); adjust_clock (left); adjust_clock (right); if (argc == 3) { in = fopen (argv[1], "r"); out = fopen (argv[2], "w"); } g_main_loop_run (mainloop); g_object_unref (left); g_object_unref (right); if (in) fclose (in); if (out) fclose (out); return 0; } libnice-0.1.14/tests/Makefile.in0000664000076400007640000017445313070512350013356 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ check_PROGRAMS = test-pseudotcp$(EXEEXT) test-pseudotcp-fin$(EXEEXT) \ test-pseudotcp-fuzzy$(EXEEXT) test-bsd$(EXEEXT) test$(EXEEXT) \ test-address$(EXEEXT) test-add-remove-stream$(EXEEXT) \ test-build-io-stream$(EXEEXT) test-io-stream-thread$(EXEEXT) \ test-io-stream-closing-write$(EXEEXT) \ test-io-stream-closing-read$(EXEEXT) \ test-io-stream-cancelling$(EXEEXT) \ test-io-stream-pollable$(EXEEXT) test-send-recv$(EXEEXT) \ test-socket-is-based-on$(EXEEXT) test-priority$(EXEEXT) \ test-mainloop$(EXEEXT) test-fullmode$(EXEEXT) \ test-restart$(EXEEXT) test-fallback$(EXEEXT) \ test-thread$(EXEEXT) test-dribble$(EXEEXT) \ test-new-dribble$(EXEEXT) test-tcp$(EXEEXT) \ test-icetcp$(EXEEXT) test-credentials$(EXEEXT) \ test-turn$(EXEEXT) $(am__EXEEXT_1) @HAVE_GST_CHECK_TRUE@am__append_1 = test-gstreamer subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ $(noinst_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @HAVE_GST_CHECK_TRUE@am__EXEEXT_1 = test-gstreamer$(EXEEXT) test_SOURCES = test.c test_OBJECTS = test.$(OBJEXT) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = $(top_builddir)/agent/libagent.la \ $(top_builddir)/socket/libsocket.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) test_DEPENDENCIES = $(am__DEPENDENCIES_2) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = test_add_remove_stream_SOURCES = test-add-remove-stream.c test_add_remove_stream_OBJECTS = test-add-remove-stream.$(OBJEXT) test_add_remove_stream_DEPENDENCIES = $(am__DEPENDENCIES_2) test_address_SOURCES = test-address.c test_address_OBJECTS = test-address.$(OBJEXT) test_address_DEPENDENCIES = $(am__DEPENDENCIES_2) test_bsd_SOURCES = test-bsd.c test_bsd_OBJECTS = test-bsd.$(OBJEXT) test_bsd_DEPENDENCIES = $(am__DEPENDENCIES_2) test_build_io_stream_SOURCES = test-build-io-stream.c test_build_io_stream_OBJECTS = test-build-io-stream.$(OBJEXT) test_build_io_stream_DEPENDENCIES = $(am__DEPENDENCIES_2) test_credentials_SOURCES = test-credentials.c test_credentials_OBJECTS = test-credentials.$(OBJEXT) test_credentials_DEPENDENCIES = $(am__DEPENDENCIES_2) test_dribble_SOURCES = test-dribble.c test_dribble_OBJECTS = test-dribble.$(OBJEXT) test_dribble_DEPENDENCIES = $(am__DEPENDENCIES_2) test_fallback_SOURCES = test-fallback.c test_fallback_OBJECTS = test-fallback.$(OBJEXT) test_fallback_DEPENDENCIES = $(am__DEPENDENCIES_2) test_fullmode_SOURCES = test-fullmode.c test_fullmode_OBJECTS = test-fullmode.$(OBJEXT) test_fullmode_DEPENDENCIES = $(am__DEPENDENCIES_2) test_gstreamer_SOURCES = test-gstreamer.c test_gstreamer_OBJECTS = test_gstreamer-test-gstreamer.$(OBJEXT) test_gstreamer_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) test_gstreamer_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_gstreamer_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ test_icetcp_SOURCES = test-icetcp.c test_icetcp_OBJECTS = test-icetcp.$(OBJEXT) test_icetcp_DEPENDENCIES = $(am__DEPENDENCIES_2) am_test_io_stream_cancelling_OBJECTS = \ test-io-stream-cancelling.$(OBJEXT) \ test-io-stream-common.$(OBJEXT) test_io_stream_cancelling_OBJECTS = \ $(am_test_io_stream_cancelling_OBJECTS) test_io_stream_cancelling_DEPENDENCIES = $(am__DEPENDENCIES_2) am_test_io_stream_closing_read_OBJECTS = \ test-io-stream-closing-read.$(OBJEXT) \ test-io-stream-common.$(OBJEXT) test_io_stream_closing_read_OBJECTS = \ $(am_test_io_stream_closing_read_OBJECTS) test_io_stream_closing_read_DEPENDENCIES = $(am__DEPENDENCIES_2) am_test_io_stream_closing_write_OBJECTS = \ test-io-stream-closing-write.$(OBJEXT) \ test-io-stream-common.$(OBJEXT) test_io_stream_closing_write_OBJECTS = \ $(am_test_io_stream_closing_write_OBJECTS) test_io_stream_closing_write_DEPENDENCIES = $(am__DEPENDENCIES_2) am_test_io_stream_pollable_OBJECTS = \ test-io-stream-pollable.$(OBJEXT) \ test-io-stream-common.$(OBJEXT) test_io_stream_pollable_OBJECTS = \ $(am_test_io_stream_pollable_OBJECTS) test_io_stream_pollable_DEPENDENCIES = $(am__DEPENDENCIES_2) am_test_io_stream_thread_OBJECTS = test-io-stream-thread.$(OBJEXT) \ test-io-stream-common.$(OBJEXT) test_io_stream_thread_OBJECTS = $(am_test_io_stream_thread_OBJECTS) test_io_stream_thread_DEPENDENCIES = $(am__DEPENDENCIES_2) test_mainloop_SOURCES = test-mainloop.c test_mainloop_OBJECTS = test-mainloop.$(OBJEXT) test_mainloop_DEPENDENCIES = $(am__DEPENDENCIES_2) test_new_dribble_SOURCES = test-new-dribble.c test_new_dribble_OBJECTS = test-new-dribble.$(OBJEXT) test_new_dribble_DEPENDENCIES = $(am__DEPENDENCIES_2) test_priority_SOURCES = test-priority.c test_priority_OBJECTS = test-priority.$(OBJEXT) test_priority_DEPENDENCIES = $(am__DEPENDENCIES_2) test_pseudotcp_SOURCES = test-pseudotcp.c test_pseudotcp_OBJECTS = test-pseudotcp.$(OBJEXT) test_pseudotcp_DEPENDENCIES = $(am__DEPENDENCIES_2) test_pseudotcp_fin_SOURCES = test-pseudotcp-fin.c test_pseudotcp_fin_OBJECTS = test-pseudotcp-fin.$(OBJEXT) test_pseudotcp_fin_DEPENDENCIES = $(am__DEPENDENCIES_2) test_pseudotcp_fuzzy_SOURCES = test-pseudotcp-fuzzy.c test_pseudotcp_fuzzy_OBJECTS = test-pseudotcp-fuzzy.$(OBJEXT) test_pseudotcp_fuzzy_DEPENDENCIES = $(am__DEPENDENCIES_2) test_restart_SOURCES = test-restart.c test_restart_OBJECTS = test-restart.$(OBJEXT) test_restart_DEPENDENCIES = $(am__DEPENDENCIES_2) am_test_send_recv_OBJECTS = test-send-recv.$(OBJEXT) \ test-io-stream-common.$(OBJEXT) test_send_recv_OBJECTS = $(am_test_send_recv_OBJECTS) test_send_recv_DEPENDENCIES = $(am__DEPENDENCIES_2) test_socket_is_based_on_SOURCES = test-socket-is-based-on.c test_socket_is_based_on_OBJECTS = test-socket-is-based-on.$(OBJEXT) test_socket_is_based_on_DEPENDENCIES = $(am__DEPENDENCIES_2) test_tcp_SOURCES = test-tcp.c test_tcp_OBJECTS = test-tcp.$(OBJEXT) test_tcp_DEPENDENCIES = $(am__DEPENDENCIES_2) test_thread_SOURCES = test-thread.c test_thread_OBJECTS = test-thread.$(OBJEXT) test_thread_DEPENDENCIES = $(am__DEPENDENCIES_2) test_turn_SOURCES = test-turn.c test_turn_OBJECTS = test-turn.$(OBJEXT) test_turn_DEPENDENCIES = $(am__DEPENDENCIES_2) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = test.c test-add-remove-stream.c test-address.c test-bsd.c \ test-build-io-stream.c test-credentials.c test-dribble.c \ test-fallback.c test-fullmode.c test-gstreamer.c test-icetcp.c \ $(test_io_stream_cancelling_SOURCES) \ $(test_io_stream_closing_read_SOURCES) \ $(test_io_stream_closing_write_SOURCES) \ $(test_io_stream_pollable_SOURCES) \ $(test_io_stream_thread_SOURCES) test-mainloop.c \ test-new-dribble.c test-priority.c test-pseudotcp.c \ test-pseudotcp-fin.c test-pseudotcp-fuzzy.c test-restart.c \ $(test_send_recv_SOURCES) test-socket-is-based-on.c test-tcp.c \ test-thread.c test-turn.c DIST_SOURCES = test.c test-add-remove-stream.c test-address.c \ test-bsd.c test-build-io-stream.c test-credentials.c \ test-dribble.c test-fallback.c test-fullmode.c \ test-gstreamer.c test-icetcp.c \ $(test_io_stream_cancelling_SOURCES) \ $(test_io_stream_closing_read_SOURCES) \ $(test_io_stream_closing_write_SOURCES) \ $(test_io_stream_pollable_SOURCES) \ $(test_io_stream_thread_SOURCES) test-mainloop.c \ test-new-dribble.c test-priority.c test-pseudotcp.c \ test-pseudotcp-fin.c test-pseudotcp-fuzzy.c test-restart.c \ $(test_send_recv_SOURCES) test-socket-is-based-on.c test-tcp.c \ test-thread.c test-turn.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda TESTS_ENVIRONMENT = \ GST_PLUGIN_PATH=${GST_PLUGIN_PATH}:$(top_builddir)/gst AM_CFLAGS = \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUPNP_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun AM_CPPFLAGS = -DG_LOG_DOMAIN=\"libnice-tests\" AM_TESTS_ENVIRONMENT = \ G_MESSAGES_DEBUG=all \ NICE_DEBUG=all; COMMON_LDADD = $(top_builddir)/agent/libagent.la $(top_builddir)/socket/libsocket.la $(GLIB_LIBS) $(GUPNP_LIBS) dist_check_SCRIPTS = \ check-test-fullmode-with-stun.sh \ test-pseudotcp-random.sh TESTS = $(check_PROGRAMS) $(dist_check_SCRIPTS) noinst_HEADERS = test-io-stream-common.h test_pseudotcp_LDADD = $(COMMON_LDADD) test_pseudotcp_fin_LDADD = $(COMMON_LDADD) test_pseudotcp_fuzzy_LDADD = $(COMMON_LDADD) -lm test_bsd_LDADD = $(COMMON_LDADD) test_LDADD = $(COMMON_LDADD) test_thread_LDADD = $(COMMON_LDADD) test_address_LDADD = $(COMMON_LDADD) test_add_remove_stream_LDADD = $(COMMON_LDADD) test_build_io_stream_LDADD = $(COMMON_LDADD) test_io_stream_thread_SOURCES = test-io-stream-thread.c test-io-stream-common.c test_io_stream_thread_LDADD = $(COMMON_LDADD) test_io_stream_closing_write_SOURCES = test-io-stream-closing-write.c test-io-stream-common.c test_io_stream_closing_write_LDADD = $(COMMON_LDADD) test_io_stream_closing_read_SOURCES = test-io-stream-closing-read.c test-io-stream-common.c test_io_stream_closing_read_LDADD = $(COMMON_LDADD) test_io_stream_cancelling_SOURCES = test-io-stream-cancelling.c test-io-stream-common.c test_io_stream_cancelling_LDADD = $(COMMON_LDADD) test_io_stream_pollable_SOURCES = test-io-stream-pollable.c test-io-stream-common.c test_io_stream_pollable_LDADD = $(COMMON_LDADD) test_send_recv_SOURCES = test-send-recv.c test-io-stream-common.c test_send_recv_LDADD = $(COMMON_LDADD) test_socket_is_based_on_LDADD = $(COMMON_LDADD) test_priority_LDADD = $(COMMON_LDADD) test_mainloop_LDADD = $(COMMON_LDADD) test_fullmode_LDADD = $(COMMON_LDADD) test_restart_LDADD = $(COMMON_LDADD) test_fallback_LDADD = $(COMMON_LDADD) test_dribble_LDADD = $(COMMON_LDADD) test_new_dribble_LDADD = $(COMMON_LDADD) test_tcp_LDADD = $(COMMON_LDADD) test_icetcp_LDADD = $(COMMON_LDADD) test_credentials_LDADD = $(COMMON_LDADD) test_turn_LDADD = $(COMMON_LDADD) test_gstreamer_CFLAGS = $(AM_CFLAGS) $(GST_CHECK_CFLAGS) test_gstreamer_LDADD = -lnice -L$(top_builddir)/nice/.libs $(GLIB_LIBS) $(GUPNP_LIBS) $(GST_CHECK_LIBS) $(GST_LIBS) EXTRA_DIST = libnice.supp all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) @rm -f test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) test-add-remove-stream$(EXEEXT): $(test_add_remove_stream_OBJECTS) $(test_add_remove_stream_DEPENDENCIES) $(EXTRA_test_add_remove_stream_DEPENDENCIES) @rm -f test-add-remove-stream$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_add_remove_stream_OBJECTS) $(test_add_remove_stream_LDADD) $(LIBS) test-address$(EXEEXT): $(test_address_OBJECTS) $(test_address_DEPENDENCIES) $(EXTRA_test_address_DEPENDENCIES) @rm -f test-address$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_address_OBJECTS) $(test_address_LDADD) $(LIBS) test-bsd$(EXEEXT): $(test_bsd_OBJECTS) $(test_bsd_DEPENDENCIES) $(EXTRA_test_bsd_DEPENDENCIES) @rm -f test-bsd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_bsd_OBJECTS) $(test_bsd_LDADD) $(LIBS) test-build-io-stream$(EXEEXT): $(test_build_io_stream_OBJECTS) $(test_build_io_stream_DEPENDENCIES) $(EXTRA_test_build_io_stream_DEPENDENCIES) @rm -f test-build-io-stream$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_build_io_stream_OBJECTS) $(test_build_io_stream_LDADD) $(LIBS) test-credentials$(EXEEXT): $(test_credentials_OBJECTS) $(test_credentials_DEPENDENCIES) $(EXTRA_test_credentials_DEPENDENCIES) @rm -f test-credentials$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_credentials_OBJECTS) $(test_credentials_LDADD) $(LIBS) test-dribble$(EXEEXT): $(test_dribble_OBJECTS) $(test_dribble_DEPENDENCIES) $(EXTRA_test_dribble_DEPENDENCIES) @rm -f test-dribble$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dribble_OBJECTS) $(test_dribble_LDADD) $(LIBS) test-fallback$(EXEEXT): $(test_fallback_OBJECTS) $(test_fallback_DEPENDENCIES) $(EXTRA_test_fallback_DEPENDENCIES) @rm -f test-fallback$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fallback_OBJECTS) $(test_fallback_LDADD) $(LIBS) test-fullmode$(EXEEXT): $(test_fullmode_OBJECTS) $(test_fullmode_DEPENDENCIES) $(EXTRA_test_fullmode_DEPENDENCIES) @rm -f test-fullmode$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fullmode_OBJECTS) $(test_fullmode_LDADD) $(LIBS) test-gstreamer$(EXEEXT): $(test_gstreamer_OBJECTS) $(test_gstreamer_DEPENDENCIES) $(EXTRA_test_gstreamer_DEPENDENCIES) @rm -f test-gstreamer$(EXEEXT) $(AM_V_CCLD)$(test_gstreamer_LINK) $(test_gstreamer_OBJECTS) $(test_gstreamer_LDADD) $(LIBS) test-icetcp$(EXEEXT): $(test_icetcp_OBJECTS) $(test_icetcp_DEPENDENCIES) $(EXTRA_test_icetcp_DEPENDENCIES) @rm -f test-icetcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_icetcp_OBJECTS) $(test_icetcp_LDADD) $(LIBS) test-io-stream-cancelling$(EXEEXT): $(test_io_stream_cancelling_OBJECTS) $(test_io_stream_cancelling_DEPENDENCIES) $(EXTRA_test_io_stream_cancelling_DEPENDENCIES) @rm -f test-io-stream-cancelling$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_io_stream_cancelling_OBJECTS) $(test_io_stream_cancelling_LDADD) $(LIBS) test-io-stream-closing-read$(EXEEXT): $(test_io_stream_closing_read_OBJECTS) $(test_io_stream_closing_read_DEPENDENCIES) $(EXTRA_test_io_stream_closing_read_DEPENDENCIES) @rm -f test-io-stream-closing-read$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_io_stream_closing_read_OBJECTS) $(test_io_stream_closing_read_LDADD) $(LIBS) test-io-stream-closing-write$(EXEEXT): $(test_io_stream_closing_write_OBJECTS) $(test_io_stream_closing_write_DEPENDENCIES) $(EXTRA_test_io_stream_closing_write_DEPENDENCIES) @rm -f test-io-stream-closing-write$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_io_stream_closing_write_OBJECTS) $(test_io_stream_closing_write_LDADD) $(LIBS) test-io-stream-pollable$(EXEEXT): $(test_io_stream_pollable_OBJECTS) $(test_io_stream_pollable_DEPENDENCIES) $(EXTRA_test_io_stream_pollable_DEPENDENCIES) @rm -f test-io-stream-pollable$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_io_stream_pollable_OBJECTS) $(test_io_stream_pollable_LDADD) $(LIBS) test-io-stream-thread$(EXEEXT): $(test_io_stream_thread_OBJECTS) $(test_io_stream_thread_DEPENDENCIES) $(EXTRA_test_io_stream_thread_DEPENDENCIES) @rm -f test-io-stream-thread$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_io_stream_thread_OBJECTS) $(test_io_stream_thread_LDADD) $(LIBS) test-mainloop$(EXEEXT): $(test_mainloop_OBJECTS) $(test_mainloop_DEPENDENCIES) $(EXTRA_test_mainloop_DEPENDENCIES) @rm -f test-mainloop$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_mainloop_OBJECTS) $(test_mainloop_LDADD) $(LIBS) test-new-dribble$(EXEEXT): $(test_new_dribble_OBJECTS) $(test_new_dribble_DEPENDENCIES) $(EXTRA_test_new_dribble_DEPENDENCIES) @rm -f test-new-dribble$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_new_dribble_OBJECTS) $(test_new_dribble_LDADD) $(LIBS) test-priority$(EXEEXT): $(test_priority_OBJECTS) $(test_priority_DEPENDENCIES) $(EXTRA_test_priority_DEPENDENCIES) @rm -f test-priority$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_priority_OBJECTS) $(test_priority_LDADD) $(LIBS) test-pseudotcp$(EXEEXT): $(test_pseudotcp_OBJECTS) $(test_pseudotcp_DEPENDENCIES) $(EXTRA_test_pseudotcp_DEPENDENCIES) @rm -f test-pseudotcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_pseudotcp_OBJECTS) $(test_pseudotcp_LDADD) $(LIBS) test-pseudotcp-fin$(EXEEXT): $(test_pseudotcp_fin_OBJECTS) $(test_pseudotcp_fin_DEPENDENCIES) $(EXTRA_test_pseudotcp_fin_DEPENDENCIES) @rm -f test-pseudotcp-fin$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_pseudotcp_fin_OBJECTS) $(test_pseudotcp_fin_LDADD) $(LIBS) test-pseudotcp-fuzzy$(EXEEXT): $(test_pseudotcp_fuzzy_OBJECTS) $(test_pseudotcp_fuzzy_DEPENDENCIES) $(EXTRA_test_pseudotcp_fuzzy_DEPENDENCIES) @rm -f test-pseudotcp-fuzzy$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_pseudotcp_fuzzy_OBJECTS) $(test_pseudotcp_fuzzy_LDADD) $(LIBS) test-restart$(EXEEXT): $(test_restart_OBJECTS) $(test_restart_DEPENDENCIES) $(EXTRA_test_restart_DEPENDENCIES) @rm -f test-restart$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_restart_OBJECTS) $(test_restart_LDADD) $(LIBS) test-send-recv$(EXEEXT): $(test_send_recv_OBJECTS) $(test_send_recv_DEPENDENCIES) $(EXTRA_test_send_recv_DEPENDENCIES) @rm -f test-send-recv$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_send_recv_OBJECTS) $(test_send_recv_LDADD) $(LIBS) test-socket-is-based-on$(EXEEXT): $(test_socket_is_based_on_OBJECTS) $(test_socket_is_based_on_DEPENDENCIES) $(EXTRA_test_socket_is_based_on_DEPENDENCIES) @rm -f test-socket-is-based-on$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_socket_is_based_on_OBJECTS) $(test_socket_is_based_on_LDADD) $(LIBS) test-tcp$(EXEEXT): $(test_tcp_OBJECTS) $(test_tcp_DEPENDENCIES) $(EXTRA_test_tcp_DEPENDENCIES) @rm -f test-tcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_tcp_OBJECTS) $(test_tcp_LDADD) $(LIBS) test-thread$(EXEEXT): $(test_thread_OBJECTS) $(test_thread_DEPENDENCIES) $(EXTRA_test_thread_DEPENDENCIES) @rm -f test-thread$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_thread_OBJECTS) $(test_thread_LDADD) $(LIBS) test-turn$(EXEEXT): $(test_turn_OBJECTS) $(test_turn_DEPENDENCIES) $(EXTRA_test_turn_DEPENDENCIES) @rm -f test-turn$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_turn_OBJECTS) $(test_turn_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-add-remove-stream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-address.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-bsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-build-io-stream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-credentials.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dribble.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fallback.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-fullmode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-icetcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-io-stream-cancelling.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-io-stream-closing-read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-io-stream-closing-write.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-io-stream-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-io-stream-pollable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-io-stream-thread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-mainloop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-new-dribble.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-priority.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-pseudotcp-fin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-pseudotcp-fuzzy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-pseudotcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-restart.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-send-recv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-socket-is-based-on.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-tcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-thread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-turn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gstreamer-test-gstreamer.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< test_gstreamer-test-gstreamer.o: test-gstreamer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gstreamer_CFLAGS) $(CFLAGS) -MT test_gstreamer-test-gstreamer.o -MD -MP -MF $(DEPDIR)/test_gstreamer-test-gstreamer.Tpo -c -o test_gstreamer-test-gstreamer.o `test -f 'test-gstreamer.c' || echo '$(srcdir)/'`test-gstreamer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_gstreamer-test-gstreamer.Tpo $(DEPDIR)/test_gstreamer-test-gstreamer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-gstreamer.c' object='test_gstreamer-test-gstreamer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gstreamer_CFLAGS) $(CFLAGS) -c -o test_gstreamer-test-gstreamer.o `test -f 'test-gstreamer.c' || echo '$(srcdir)/'`test-gstreamer.c test_gstreamer-test-gstreamer.obj: test-gstreamer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gstreamer_CFLAGS) $(CFLAGS) -MT test_gstreamer-test-gstreamer.obj -MD -MP -MF $(DEPDIR)/test_gstreamer-test-gstreamer.Tpo -c -o test_gstreamer-test-gstreamer.obj `if test -f 'test-gstreamer.c'; then $(CYGPATH_W) 'test-gstreamer.c'; else $(CYGPATH_W) '$(srcdir)/test-gstreamer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_gstreamer-test-gstreamer.Tpo $(DEPDIR)/test_gstreamer-test-gstreamer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-gstreamer.c' object='test_gstreamer-test-gstreamer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_gstreamer_CFLAGS) $(CFLAGS) -c -o test_gstreamer-test-gstreamer.obj `if test -f 'test-gstreamer.c'; then $(CYGPATH_W) 'test-gstreamer.c'; else $(CYGPATH_W) '$(srcdir)/test-gstreamer.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test-pseudotcp.log: test-pseudotcp$(EXEEXT) @p='test-pseudotcp$(EXEEXT)'; \ b='test-pseudotcp'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-pseudotcp-fin.log: test-pseudotcp-fin$(EXEEXT) @p='test-pseudotcp-fin$(EXEEXT)'; \ b='test-pseudotcp-fin'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-pseudotcp-fuzzy.log: test-pseudotcp-fuzzy$(EXEEXT) @p='test-pseudotcp-fuzzy$(EXEEXT)'; \ b='test-pseudotcp-fuzzy'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-bsd.log: test-bsd$(EXEEXT) @p='test-bsd$(EXEEXT)'; \ b='test-bsd'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test.log: test$(EXEEXT) @p='test$(EXEEXT)'; \ b='test'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-address.log: test-address$(EXEEXT) @p='test-address$(EXEEXT)'; \ b='test-address'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-add-remove-stream.log: test-add-remove-stream$(EXEEXT) @p='test-add-remove-stream$(EXEEXT)'; \ b='test-add-remove-stream'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-build-io-stream.log: test-build-io-stream$(EXEEXT) @p='test-build-io-stream$(EXEEXT)'; \ b='test-build-io-stream'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-io-stream-thread.log: test-io-stream-thread$(EXEEXT) @p='test-io-stream-thread$(EXEEXT)'; \ b='test-io-stream-thread'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-io-stream-closing-write.log: test-io-stream-closing-write$(EXEEXT) @p='test-io-stream-closing-write$(EXEEXT)'; \ b='test-io-stream-closing-write'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-io-stream-closing-read.log: test-io-stream-closing-read$(EXEEXT) @p='test-io-stream-closing-read$(EXEEXT)'; \ b='test-io-stream-closing-read'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-io-stream-cancelling.log: test-io-stream-cancelling$(EXEEXT) @p='test-io-stream-cancelling$(EXEEXT)'; \ b='test-io-stream-cancelling'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-io-stream-pollable.log: test-io-stream-pollable$(EXEEXT) @p='test-io-stream-pollable$(EXEEXT)'; \ b='test-io-stream-pollable'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-send-recv.log: test-send-recv$(EXEEXT) @p='test-send-recv$(EXEEXT)'; \ b='test-send-recv'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-socket-is-based-on.log: test-socket-is-based-on$(EXEEXT) @p='test-socket-is-based-on$(EXEEXT)'; \ b='test-socket-is-based-on'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-priority.log: test-priority$(EXEEXT) @p='test-priority$(EXEEXT)'; \ b='test-priority'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-mainloop.log: test-mainloop$(EXEEXT) @p='test-mainloop$(EXEEXT)'; \ b='test-mainloop'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-fullmode.log: test-fullmode$(EXEEXT) @p='test-fullmode$(EXEEXT)'; \ b='test-fullmode'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-restart.log: test-restart$(EXEEXT) @p='test-restart$(EXEEXT)'; \ b='test-restart'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-fallback.log: test-fallback$(EXEEXT) @p='test-fallback$(EXEEXT)'; \ b='test-fallback'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-thread.log: test-thread$(EXEEXT) @p='test-thread$(EXEEXT)'; \ b='test-thread'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-dribble.log: test-dribble$(EXEEXT) @p='test-dribble$(EXEEXT)'; \ b='test-dribble'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-new-dribble.log: test-new-dribble$(EXEEXT) @p='test-new-dribble$(EXEEXT)'; \ b='test-new-dribble'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-tcp.log: test-tcp$(EXEEXT) @p='test-tcp$(EXEEXT)'; \ b='test-tcp'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-icetcp.log: test-icetcp$(EXEEXT) @p='test-icetcp$(EXEEXT)'; \ b='test-icetcp'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-credentials.log: test-credentials$(EXEEXT) @p='test-credentials$(EXEEXT)'; \ b='test-credentials'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-turn.log: test-turn$(EXEEXT) @p='test-turn$(EXEEXT)'; \ b='test-turn'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-gstreamer.log: test-gstreamer$(EXEEXT) @p='test-gstreamer$(EXEEXT)'; \ b='test-gstreamer'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check-test-fullmode-with-stun.sh.log: check-test-fullmode-with-stun.sh @p='check-test-fullmode-with-stun.sh'; \ b='check-test-fullmode-with-stun.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-pseudotcp-random.sh.log: test-pseudotcp-random.sh @p='test-pseudotcp-random.sh'; \ b='test-pseudotcp-random.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \ $(dist_check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(HEADERS) all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am all-local check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind all-local: chmod a+x $(srcdir)/check-test-fullmode-with-stun.sh chmod a+x $(srcdir)/test-pseudotcp-random.sh # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/tests/Makefile.am0000664000076400007640000000661412733070261013343 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include $(top_srcdir)/common.mk TESTS_ENVIRONMENT=\ GST_PLUGIN_PATH=${GST_PLUGIN_PATH}:$(top_builddir)/gst AM_CFLAGS = \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUPNP_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun AM_CPPFLAGS = -DG_LOG_DOMAIN=\"libnice-tests\" AM_TESTS_ENVIRONMENT = \ G_MESSAGES_DEBUG=all \ NICE_DEBUG=all; COMMON_LDADD = $(top_builddir)/agent/libagent.la $(top_builddir)/socket/libsocket.la $(GLIB_LIBS) $(GUPNP_LIBS) check_PROGRAMS = \ test-pseudotcp \ test-pseudotcp-fin \ test-pseudotcp-fuzzy \ test-bsd \ test \ test-address \ test-add-remove-stream \ test-build-io-stream \ test-io-stream-thread \ test-io-stream-closing-write \ test-io-stream-closing-read \ test-io-stream-cancelling \ test-io-stream-pollable \ test-send-recv \ test-socket-is-based-on \ test-priority \ test-mainloop \ test-fullmode \ test-restart \ test-fallback \ test-thread \ test-dribble \ test-new-dribble \ test-tcp \ test-icetcp \ test-credentials \ test-turn dist_check_SCRIPTS = \ check-test-fullmode-with-stun.sh \ test-pseudotcp-random.sh if HAVE_GST_CHECK check_PROGRAMS += test-gstreamer endif TESTS = $(check_PROGRAMS) $(dist_check_SCRIPTS) noinst_HEADERS = test-io-stream-common.h test_pseudotcp_LDADD = $(COMMON_LDADD) test_pseudotcp_fin_LDADD = $(COMMON_LDADD) test_pseudotcp_fuzzy_LDADD = $(COMMON_LDADD) -lm test_bsd_LDADD = $(COMMON_LDADD) test_LDADD = $(COMMON_LDADD) test_thread_LDADD = $(COMMON_LDADD) test_address_LDADD = $(COMMON_LDADD) test_add_remove_stream_LDADD = $(COMMON_LDADD) test_build_io_stream_LDADD = $(COMMON_LDADD) test_io_stream_thread_SOURCES = test-io-stream-thread.c test-io-stream-common.c test_io_stream_thread_LDADD = $(COMMON_LDADD) test_io_stream_closing_write_SOURCES = test-io-stream-closing-write.c test-io-stream-common.c test_io_stream_closing_write_LDADD = $(COMMON_LDADD) test_io_stream_closing_read_SOURCES = test-io-stream-closing-read.c test-io-stream-common.c test_io_stream_closing_read_LDADD = $(COMMON_LDADD) test_io_stream_cancelling_SOURCES = test-io-stream-cancelling.c test-io-stream-common.c test_io_stream_cancelling_LDADD = $(COMMON_LDADD) test_io_stream_pollable_SOURCES = test-io-stream-pollable.c test-io-stream-common.c test_io_stream_pollable_LDADD = $(COMMON_LDADD) test_send_recv_SOURCES = test-send-recv.c test-io-stream-common.c test_send_recv_LDADD = $(COMMON_LDADD) test_socket_is_based_on_LDADD = $(COMMON_LDADD) test_priority_LDADD = $(COMMON_LDADD) test_mainloop_LDADD = $(COMMON_LDADD) test_fullmode_LDADD = $(COMMON_LDADD) test_restart_LDADD = $(COMMON_LDADD) test_fallback_LDADD = $(COMMON_LDADD) test_dribble_LDADD = $(COMMON_LDADD) test_new_dribble_LDADD = $(COMMON_LDADD) test_tcp_LDADD = $(COMMON_LDADD) test_icetcp_LDADD = $(COMMON_LDADD) test_credentials_LDADD = $(COMMON_LDADD) test_turn_LDADD = $(COMMON_LDADD) test_gstreamer_CFLAGS = $(AM_CFLAGS) $(GST_CHECK_CFLAGS) test_gstreamer_LDADD = -lnice -L$(top_builddir)/nice/.libs $(GLIB_LIBS) $(GUPNP_LIBS) $(GST_CHECK_LIBS) $(GST_LIBS) all-local: chmod a+x $(srcdir)/check-test-fullmode-with-stun.sh chmod a+x $(srcdir)/test-pseudotcp-random.sh EXTRA_DIST = libnice.supp libnice-0.1.14/tests/test-io-stream-closing-write.c0000664000076400007640000000703312661700132017105 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "test-io-stream-common.h" #include #include #ifndef G_OS_WIN32 #include #endif #define NUM_MESSAGES 10 guint count = 0; GMutex count_lock; GCond count_cond; static void read_thread_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { gpointer tmp; guint stream_id; GError *error = NULL; gssize len; guint8 buf[MESSAGE_SIZE]; /* Block on receiving some data. */ len = g_input_stream_read (input_stream, buf, sizeof (buf), NULL, &error); g_assert_cmpint (len, ==, sizeof(buf)); g_mutex_lock (&count_lock); count++; g_cond_broadcast (&count_cond); if (data->user_data) { g_mutex_unlock (&count_lock); return; } while (count != 4) g_cond_wait (&count_cond, &count_lock); g_mutex_unlock (&count_lock); /* Now we remove the stream, lets see how the writer handles that */ tmp = g_object_get_data (G_OBJECT (data->other->agent), "stream-id"); stream_id = GPOINTER_TO_UINT (tmp); nice_agent_remove_stream (data->other->agent, stream_id); } static void write_thread_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { gchar buf[MESSAGE_SIZE] = {0}; gssize ret; GError *error = NULL; g_mutex_lock (&count_lock); count++; g_cond_broadcast (&count_cond); g_mutex_unlock (&count_lock); do { g_assert_no_error (error); ret = g_output_stream_write (output_stream, buf, sizeof (buf), NULL, &error); if (!data->user_data) { g_assert_cmpint (ret, ==, sizeof (buf)); return; } } while (ret > 0); g_assert_cmpint (ret, ==, -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); g_clear_error (&error); stop_main_loop (data->error_loop); } int main (void) { const TestIOStreamCallbacks callbacks = { read_thread_cb, write_thread_cb, NULL, NULL, }; #ifdef G_OS_WIN32 WSADATA w; WSAStartup (0x0202, &w); #endif run_io_stream_test (30, TRUE, &callbacks, (gpointer) TRUE, NULL, NULL, NULL); #ifdef G_OS_WIN32 WSACleanup (); #endif return 0; } libnice-0.1.14/tests/test-build-io-stream.c0000664000076400007640000003511012661700132015413 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2013 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "agent.h" #include "iostream.h" static void test_invalid_stream (NiceAddress *addr) { NiceAgent *agent; GIOStream *io_stream; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Try building an I/O stream for an invalid stream. All its operations should * return G_IO_ERROR_BROKEN_PIPE. */ io_stream = nice_agent_get_io_stream (agent, 5, 5); g_assert (io_stream == NULL); g_object_unref (agent); } static void test_io_stream_properties (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Check various initial properties. */ g_assert (!g_io_stream_is_closed (G_IO_STREAM (io_stream))); g_assert (!g_io_stream_has_pending (G_IO_STREAM (io_stream))); /* Check the input stream’s properties. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_INPUT_STREAM (input_stream)); g_assert (NICE_IS_INPUT_STREAM (input_stream)); g_assert (!g_input_stream_is_closed (input_stream)); g_assert (!g_input_stream_has_pending (input_stream)); /* Check the output stream’s properties. */ output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_OUTPUT_STREAM (output_stream)); g_assert (NICE_IS_OUTPUT_STREAM (output_stream)); g_assert (!g_output_stream_is_closing (output_stream)); g_assert (!g_output_stream_is_closed (output_stream)); g_assert (!g_output_stream_has_pending (output_stream)); /* Remove the component and check that the I/O streams close. */ nice_agent_remove_stream (agent, stream_id); g_assert (g_io_stream_is_closed (G_IO_STREAM (io_stream))); g_assert (g_input_stream_is_closed (input_stream)); g_assert (g_output_stream_is_closed (output_stream)); g_object_unref (io_stream); g_object_unref (agent); } static void test_pollable_properties (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; guint8 buf[65536]; GError *error = NULL; GSource *stream_source; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Check the input stream’s properties. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); g_assert (g_pollable_input_stream_can_poll (pollable_input_stream)); g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream)); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_clear_error (&error); stream_source = g_pollable_input_stream_create_source (pollable_input_stream, NULL); g_assert (stream_source != NULL); g_source_unref (stream_source); /* Check the output stream’s properties. */ output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream)); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); g_assert (g_pollable_output_stream_can_poll (pollable_output_stream)); g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream)); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_clear_error (&error); stream_source = g_pollable_output_stream_create_source (pollable_output_stream, NULL); g_assert (stream_source != NULL); g_source_unref (stream_source); /* Remove the component and check that the I/O streams close. */ nice_agent_remove_stream (agent, stream_id); g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream)); g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream)); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); g_clear_error (&error); g_object_unref (io_stream); g_object_unref (agent); } static gboolean source_cancel_cb (gpointer user_data) { GCancellable *cancellable = user_data; g_cancellable_cancel (cancellable); return FALSE; } static gboolean source_cancelled_cb (GObject *pollable_stream, gpointer user_data) { GMainLoop *main_loop = user_data; /* Try and check that the callback was invoked due to cancellation rather than * a poll() event on the socket itself. */ if (G_IS_POLLABLE_INPUT_STREAM (pollable_stream)) { g_assert ( !g_pollable_input_stream_is_readable ( G_POLLABLE_INPUT_STREAM (pollable_stream))); } else { g_assert ( !g_pollable_output_stream_is_writable ( G_POLLABLE_OUTPUT_STREAM (pollable_stream))); } g_main_loop_quit (main_loop); return FALSE; } static gboolean source_timeout_cb (gpointer user_data) { g_error ("check_pollable_source_cancellation() took too long. Aborting."); return FALSE; } /* Check that cancelling a GCancellable which is associated with a pollable * stream’s GSource invokes a callback from that source in the main loop. This * uses a main context with three sources: the pollable source, an idle source * to trigger the cancellation, and a timeout source to fail the test if it * takes too long. */ static void check_pollable_source_cancellation (GSource *pollable_source, GCancellable *cancellable) { GMainContext *main_context; GMainLoop *main_loop; GSource *idle_source, *timeout_source; main_context = g_main_context_new (); main_loop = g_main_loop_new (main_context, FALSE); /* Set up the pollable source. */ g_source_set_callback (pollable_source, (GSourceFunc) source_cancelled_cb, main_loop, NULL); g_source_attach (pollable_source, main_context); /* Idle source to cancel the cancellable. */ idle_source = g_idle_source_new (); g_source_set_callback (idle_source, (GSourceFunc) source_cancel_cb, cancellable, NULL); g_source_attach (idle_source, main_context); g_source_unref (idle_source); /* Timeout. */ timeout_source = g_timeout_source_new (30000); g_source_set_callback (timeout_source, (GSourceFunc) source_timeout_cb, NULL, NULL); g_source_attach (timeout_source, main_context); g_source_unref (timeout_source); /* Run the main loop and expect to quit it immediately as the pollable source * is cancelled. */ g_main_loop_run (main_loop); g_assert (g_cancellable_is_cancelled (cancellable)); g_main_loop_unref (main_loop); g_main_context_unref (main_context); } static void test_pollable_cancellation (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; guint8 buf[65536]; GError *error = NULL; GSource *stream_source; GCancellable *cancellable; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Grab the input and output streams. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream)); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); /* Check the non-blocking read() and write() return immediately if called with * a cancelled cancellable. */ cancellable = g_cancellable_new (); g_cancellable_cancel (cancellable); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), cancellable, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), cancellable, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); g_object_unref (cancellable); /* Check the GSources invoke a callback when run with the cancellable * cancelled. */ cancellable = g_cancellable_new (); stream_source = g_pollable_input_stream_create_source (pollable_input_stream, cancellable); check_pollable_source_cancellation (stream_source, cancellable); g_source_unref (stream_source); g_object_unref (cancellable); /* And for the output stream. */ cancellable = g_cancellable_new (); stream_source = g_pollable_output_stream_create_source (pollable_output_stream, cancellable); check_pollable_source_cancellation (stream_source, cancellable); g_object_unref (io_stream); g_source_unref (stream_source); g_object_unref (cancellable); g_object_unref (agent); } static void test_zero_length_reads_writes (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; GError *error = NULL; guint8 buf[1]; /* should never be accessed */ agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); /* Check zero-length reads and writes complete immediately without error. */ g_assert (g_input_stream_read (input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert (g_output_stream_write (output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); /* Remove the component and check that zero-length reads and writes still * result in a 0 response, rather than any error. */ nice_agent_remove_stream (agent, stream_id); g_assert (g_io_stream_is_closed (G_IO_STREAM (io_stream))); g_assert (g_input_stream_read (input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert (g_output_stream_write (output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_object_unref (io_stream); g_object_unref (agent); } int main (void) { NiceAddress addr; #ifdef G_OS_WIN32 WSADATA w; WSAStartup (0x0202, &w); #endif nice_address_init (&addr); g_assert (nice_address_set_from_string (&addr, "127.0.0.1")); test_invalid_stream (&addr); test_io_stream_properties (&addr); test_pollable_properties (&addr); test_pollable_cancellation (&addr); test_zero_length_reads_writes (&addr); #ifdef G_OS_WIN32 WSACleanup (); #endif return 0; } libnice-0.1.14/tests/test-io-stream-pollable.c0000664000076400007640000001174612661700132016117 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "test-io-stream-common.h" #include #include #ifndef G_OS_WIN32 #include #endif typedef struct { GMainLoop *read_loop; /* unowned */ gsize recv_count; gsize *other_recv_count; gsize send_count; gsize *other_send_count; } ThreadData; static gboolean read_stream_cb (GObject *pollable_stream, gpointer _user_data) { TestIOStreamThreadData *data = _user_data; ThreadData *user_data = data->user_data; gchar expected_data[MESSAGE_SIZE]; GError *error = NULL; guint8 buf[MESSAGE_SIZE]; gssize len; /* Try to receive some data. */ len = g_pollable_input_stream_read_nonblocking ( G_POLLABLE_INPUT_STREAM (pollable_stream), buf, sizeof (buf), NULL, &error); if (len == -1) { g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_error_free (error); return TRUE; } g_assert_cmpint (len, ==, MESSAGE_SIZE); memset (expected_data, user_data->recv_count + '1', sizeof (expected_data)); g_assert (memcmp (buf, expected_data, sizeof (expected_data)) == 0); user_data->recv_count++; if (user_data->recv_count == 10) { g_main_loop_quit (user_data->read_loop); return FALSE; } return TRUE; } static void read_thread_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { GMainContext *main_context; GMainLoop *main_loop; GSource *stream_source; ThreadData *user_data = data->user_data; main_context = g_main_context_new (); main_loop = g_main_loop_new (main_context, FALSE); g_main_context_push_thread_default (main_context); stream_source = g_pollable_input_stream_create_source ( G_POLLABLE_INPUT_STREAM (input_stream), NULL); g_source_set_callback (stream_source, (GSourceFunc) read_stream_cb, data, NULL); g_source_attach (stream_source, main_context); g_source_unref (stream_source); /* Run the main loop. */ user_data->read_loop = main_loop; g_main_loop_run (main_loop); g_main_context_pop_thread_default (main_context); g_main_loop_unref (main_loop); g_main_context_unref (main_context); check_for_termination (data, &user_data->recv_count, user_data->other_recv_count, &user_data->send_count, 10); } static void write_thread_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { ThreadData *user_data = data->user_data; guint8 buf[MESSAGE_SIZE]; for (user_data->send_count = 0; user_data->send_count < 10; user_data->send_count++) { GError *error = NULL; memset (buf, user_data->send_count + '1', MESSAGE_SIZE); g_pollable_output_stream_write_nonblocking ( G_POLLABLE_OUTPUT_STREAM (output_stream), buf, sizeof (buf), NULL, &error); g_assert_no_error (error); } } int main (void) { ThreadData *l_data, *r_data; const TestIOStreamCallbacks callbacks = { read_thread_cb, write_thread_cb, NULL, NULL, }; #ifdef G_OS_WIN32 WSADATA w; WSAStartup (0x0202, &w); #endif l_data = g_malloc0 (sizeof (ThreadData)); r_data = g_malloc0 (sizeof (ThreadData)); l_data->recv_count = 0; l_data->send_count = 0; l_data->other_recv_count = &r_data->recv_count; l_data->other_send_count = &r_data->send_count; r_data->recv_count = 0; r_data->send_count = 0; r_data->other_recv_count = &l_data->recv_count; r_data->other_send_count = &l_data->send_count; run_io_stream_test (30, TRUE, &callbacks, l_data, NULL, r_data, NULL); g_free (r_data); g_free (l_data); #ifdef G_OS_WIN32 WSACleanup (); #endif return 0; } libnice-0.1.14/tests/test-restart.c0000664000076400007640000004171212661700132014107 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "agent-priv.h" /* for testing purposes */ #include #include #ifdef _WIN32 #include #endif static NiceComponentState global_lagent_state = NICE_COMPONENT_STATE_LAST; static NiceComponentState global_ragent_state = NICE_COMPONENT_STATE_LAST; static guint global_components_ready = 0; static guint global_components_ready_exit = 0; static guint global_components_failed = 0; static guint global_components_failed_exit = 0; static GMainLoop *global_mainloop = NULL; static gboolean global_lagent_gathering_done = FALSE; static gboolean global_ragent_gathering_done = FALSE; static gboolean global_lagent_ibr_received = FALSE; static gboolean global_ragent_ibr_received = FALSE; static int global_lagent_cands = 0; static int global_ragent_cands = 0; static gint global_ragent_read = 0; static gint global_ragent_read_exit = 0; static void priv_print_global_status (void) { g_debug ("\tgathering_done=%d", global_lagent_gathering_done && global_ragent_gathering_done); g_debug ("\tlstate=%d", global_lagent_state); g_debug ("\trstate=%d", global_ragent_state); } static gboolean timer_cb (gpointer pointer) { g_debug ("test-restart:%s: %p", G_STRFUNC, pointer); /* signal status via a global variable */ /* note: should not be reached, abort */ g_debug ("ERROR: test has got stuck, aborting..."); exit (-1); } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { g_debug ("test-restart:%s: %p", G_STRFUNC, user_data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)buf; if ((intptr_t)user_data == 2) { global_ragent_read += len; if (global_ragent_read == global_ragent_read_exit) g_main_loop_quit (global_mainloop); } } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-restart:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) global_lagent_gathering_done = TRUE; else if ((intptr_t)data == 2) global_ragent_gathering_done = TRUE; if (global_lagent_gathering_done && global_ragent_gathering_done) g_main_loop_quit (global_mainloop); /* XXX: dear compiler, these are for you: */ (void)agent; } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { g_debug ("test-restart:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) global_lagent_state = state; else if ((intptr_t)data == 2) global_ragent_state = state; if (state == NICE_COMPONENT_STATE_READY) global_components_ready++; if (state == NICE_COMPONENT_STATE_FAILED) global_components_failed++; g_debug ("test-restart: READY %u exit at %u.", global_components_ready, global_components_ready_exit); /* signal status via a global variable */ if (global_components_ready == global_components_ready_exit) { g_main_loop_quit (global_mainloop); return; } /* signal status via a global variable */ if (global_components_failed == global_components_failed_exit) { g_main_loop_quit (global_mainloop); return; } /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data) { g_debug ("test-restart:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) ++global_lagent_cands; else if ((intptr_t)data == 2) ++global_ragent_cands; /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)lfoundation; (void)rfoundation; } static void cb_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer data) { g_debug ("test-restart:%s: %p", G_STRFUNC, data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; (void)foundation; } static void cb_initial_binding_request_received(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-restart:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) global_lagent_ibr_received = TRUE; else if ((intptr_t)data == 2) global_ragent_ibr_received = TRUE; /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; } static void priv_get_local_addr (NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *dstaddr) { GSList *cands, *i; cands = nice_agent_get_local_candidates(agent, stream_id, component_id); for (i = cands; i; i = i->next) { NiceCandidate *cand = i->data; if (cand) { g_assert (dstaddr); *dstaddr = cand->addr; } } for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } static int run_restart_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr) { NiceAddress laddr, raddr, laddr_rtcp, raddr_rtcp; NiceCandidate cdes; GSList *cands; guint ls_id, rs_id; guint64 tie_breaker; /* XXX: dear compiler, these are for you: */ (void)baseaddr; memset (&cdes, 0, sizeof(NiceCandidate)); cdes.priority = 10000; strcpy (cdes.foundation, "1"); cdes.type = NICE_CANDIDATE_TYPE_HOST; cdes.transport = NICE_CANDIDATE_TRANSPORT_UDP; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = 4; global_components_failed = 0; global_components_failed_exit = 4; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_lagent_cands = global_ragent_cands = 0; global_ragent_read_exit = -1; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-restart: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } /* step: find out the local candidates of each agent */ priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, &raddr); g_debug ("test-restart: local RTP port R %u", nice_address_get_port (&raddr)); priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, &laddr); g_debug ("test-restart: local RTP port L %u", nice_address_get_port (&laddr)); priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, &raddr_rtcp); g_debug ("test-restart: local RTCP port R %u", nice_address_get_port (&raddr_rtcp)); priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, &laddr_rtcp); g_debug ("test-restart: local RTCP port L %u", nice_address_get_port (&laddr_rtcp)); /* step: pass the remote candidates to agents */ cands = g_slist_append (NULL, &cdes); { gchar *ufrag = NULL, *password = NULL; nice_agent_get_local_credentials(lagent, ls_id, &ufrag, &password); nice_agent_set_remote_credentials (ragent, rs_id, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials(ragent, rs_id, &ufrag, &password); nice_agent_set_remote_credentials (lagent, ls_id, ufrag, password); g_free (ufrag); g_free (password); } cdes.component_id = NICE_COMPONENT_TYPE_RTP; cdes.addr = raddr; nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands); cdes.addr = laddr; nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands); cdes.component_id = NICE_COMPONENT_TYPE_RTCP; cdes.addr = raddr_rtcp; nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, cands); cdes.addr = laddr_rtcp; nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, cands); g_debug ("test-restart: Set properties, next running mainloop until connectivity checks succeed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ g_main_loop_run (global_mainloop); /* note: verify that STUN binding requests were sent */ g_assert (global_lagent_ibr_received == TRUE); g_assert (global_ragent_ibr_received == TRUE); /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 2); g_assert (global_ragent_cands == 2); /* note: verify that agents are in correct state */ g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY); /* step: next send a packet (should work during restart) and * then request an ICE restart by resetting the remote * candidates for agent R */ g_debug ("-------------------------------------------\n" "test-restart: Requesting a RESTART..."); /* step: send a new test packet from L ot R */ global_ragent_read = 0; g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16); /* step: restart agents, exchange updated credentials */ tie_breaker = ragent->tie_breaker; nice_agent_restart (ragent); g_assert (tie_breaker != ragent->tie_breaker); nice_agent_restart (lagent); { gchar *ufrag = NULL, *password = NULL; nice_agent_get_local_credentials(lagent, ls_id, &ufrag, &password); nice_agent_set_remote_credentials (ragent, rs_id, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials(ragent, rs_id, &ufrag, &password); nice_agent_set_remote_credentials (lagent, ls_id, ufrag, password); g_free (ufrag); g_free (password); } /* send another packet after restart */ g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16); /* step: reset state variables */ global_lagent_ibr_received = FALSE; global_ragent_ibr_received = FALSE; global_components_ready = 0; /* step: exchange remote candidates */ cdes.component_id = NICE_COMPONENT_TYPE_RTP; cdes.addr = raddr; nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands); cdes.addr = laddr; nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands); cdes.component_id = NICE_COMPONENT_TYPE_RTCP; cdes.addr = raddr_rtcp; nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, cands); cdes.addr = laddr_rtcp; nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, cands); g_main_loop_run (global_mainloop); /* note: verify that payload was succesfully received */ g_assert (global_ragent_read == 32); /* note: verify binding requests were resent after restart */ g_assert (global_lagent_ibr_received == TRUE); g_assert (global_ragent_ibr_received == TRUE); g_debug ("test-restart: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ g_slist_free (cands); nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); return 0; } int main (void) { NiceAgent *lagent, *ragent; /* agent's L and R */ NiceAddress baseaddr; int result; guint timer_id; const char *stun_server = NULL, *stun_server_port = NULL; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif global_mainloop = g_main_loop_new (NULL, FALSE); /* Note: impl limits ... * - no multi-stream support * - no IPv6 support */ /* step: create the agents L and R */ lagent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_RFC5245); ragent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_RFC5245); g_object_set (G_OBJECT (lagent), "ice-tcp", FALSE, NULL); g_object_set (G_OBJECT (ragent), "ice-tcp", FALSE, NULL); /* step: add a timer to catch state changes triggered by signals */ timer_id = g_timeout_add (30000, timer_cb, NULL); /* step: specify which local interface to use */ if (!nice_address_set_from_string (&baseaddr, "127.0.0.1")) g_assert_not_reached (); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "new-candidate", G_CALLBACK (cb_new_candidate), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "new-candidate", G_CALLBACK (cb_new_candidate), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), (gpointer)2); stun_server = getenv ("NICE_STUN_SERVER"); stun_server_port = getenv ("NICE_STUN_SERVER_PORT"); if (stun_server) { g_object_set (G_OBJECT (lagent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (lagent), "stun-server-port", atoi (stun_server_port), NULL); g_object_set (G_OBJECT (ragent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (ragent), "stun-server-port", atoi (stun_server_port), NULL); } /* step: run test the first time */ g_debug ("test-restart: TEST STARTS / restart test"); result = run_restart_test (lagent, ragent, &baseaddr); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY); g_object_unref (lagent); g_object_unref (ragent); g_main_loop_unref (global_mainloop); global_mainloop = NULL; g_source_remove (timer_id); #ifdef G_OS_WIN32 WSACleanup(); #endif return result; } libnice-0.1.14/tests/test-thread.c0000664000076400007640000002615012661700132013671 00000000000000/* * This file is part of the Nice GLib ICE library. * * Unit test for ICE full-mode related features. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include #include #ifndef G_OS_WIN32 #include #endif GMainLoop *error_loop; volatile gint global_lagent_cands = 0; volatile gint global_ragent_cands = 0; volatile gint global_lagent_buffers = 0; volatile gint global_ragent_buffers = 0; /* Waits about 10 seconds for @var to be NULL/FALSE */ #define WAIT_UNTIL_UNSET(var, context) \ if (var) \ { \ int _i; \ \ for (_i = 0; _i < 13 && (var); _i++) \ { \ g_usleep (1000 * (1 << _i)); \ g_main_context_iteration (context, FALSE); \ } \ \ g_assert (!(var)); \ } static gboolean timer_cb (gpointer pointer) { g_debug ("test-thread:%s: %p", G_STRFUNC, pointer); /* note: should not be reached, abort */ g_debug ("ERROR: test has got stuck, aborting..."); exit (-1); } static gpointer mainloop_thread (gpointer data) { GMainLoop *loop = data; /* Synchronise thread starting. */ while (!g_main_loop_is_running (error_loop)); g_main_loop_run (loop); return NULL; } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data) { g_debug ("test-thread:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) g_atomic_int_inc (&global_lagent_cands); else if (GPOINTER_TO_UINT (data) == 2) g_atomic_int_inc (&global_ragent_cands); } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { NiceAgent *other = g_object_get_data (G_OBJECT (agent), "other-agent"); gchar *ufrag = NULL, *password = NULL; GSList *cands, *i; guint id, other_id; gpointer tmp; g_debug ("test-thread:%s", G_STRFUNC); tmp = g_object_get_data (G_OBJECT (agent), "id"); id = GPOINTER_TO_UINT (tmp); tmp = g_object_get_data (G_OBJECT (other), "id"); other_id = GPOINTER_TO_UINT (tmp); nice_agent_get_local_credentials(agent, id, &ufrag, &password); nice_agent_set_remote_credentials (other, other_id, ufrag, password); g_free (ufrag); g_free (password); cands = nice_agent_get_local_candidates(agent, id, 1); g_assert (cands != NULL); nice_agent_set_remote_candidates (other, other_id, 1, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { gchar data[10]; volatile gint *count = NULL; gint count_val; if (GPOINTER_TO_UINT (user_data) == 1) count = &global_lagent_buffers; else if (GPOINTER_TO_UINT (user_data) == 2) count = &global_ragent_buffers; else g_error ("Invalid agent ?"); count_val = g_atomic_int_get (count); if (count_val == 10) return; g_assert (len == 10); memset (data, count_val + '1', 10); g_assert (memcmp (buf, data, 10) == 0); g_atomic_int_inc (count); if (g_atomic_int_get (&global_ragent_buffers) == 10 && g_atomic_int_get (&global_lagent_buffers) == 10) g_main_loop_quit (error_loop); } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer user_data) { int i; gchar data[10]; if (state != NICE_COMPONENT_STATE_READY) return; for (i=0; i<10; i++) { memset (data, i+'1', 10); nice_agent_send (agent, stream_id, component_id, 10, data); } } int main (void) { NiceAgent *lagent, *ragent; /* agent's L and R */ NiceAddress baseaddr; const char *stun_server = NULL, *stun_server_port = NULL; GMainContext *lmainctx, *rmainctx; GMainLoop *lmainloop, *rmainloop; GThread *lthread, *rthread; guint ls_id, rs_id; GMainContext *ldmainctx, *rdmainctx; GMainLoop *ldmainloop, *rdmainloop; GThread *ldthread, *rdthread; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif lmainctx = g_main_context_new (); rmainctx = g_main_context_new (); lmainloop = g_main_loop_new (lmainctx, FALSE); rmainloop = g_main_loop_new (rmainctx, FALSE); ldmainctx = g_main_context_new (); rdmainctx = g_main_context_new (); ldmainloop = g_main_loop_new (ldmainctx, FALSE); rdmainloop = g_main_loop_new (rdmainctx, FALSE); error_loop = g_main_loop_new (NULL, FALSE); /* step: create the agents L and R */ lagent = nice_agent_new (lmainctx, NICE_COMPATIBILITY_MSN); ragent = nice_agent_new (rmainctx, NICE_COMPATIBILITY_MSN); g_object_set_data (G_OBJECT (lagent), "other-agent", ragent); g_object_set_data (G_OBJECT (ragent), "other-agent", lagent); g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); g_object_set (G_OBJECT (lagent), "upnp", FALSE, NULL); g_object_set (G_OBJECT (ragent), "upnp", FALSE, NULL); /* step: add a timer to catch state changes triggered by signals */ g_timeout_add (30000, timer_cb, NULL); /* step: specify which local interface to use */ if (!nice_address_set_from_string (&baseaddr, "127.0.0.1")) g_assert_not_reached (); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(2)); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER(2)); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(2)); stun_server = getenv ("NICE_STUN_SERVER"); stun_server_port = getenv ("NICE_STUN_SERVER_PORT"); if (stun_server) { g_object_set (G_OBJECT (lagent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (lagent), "stun-server-port", atoi (stun_server_port), NULL); g_object_set (G_OBJECT (ragent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (ragent), "stun-server-port", atoi (stun_server_port), NULL); } /* step: test setter/getter functions for properties */ { guint max_checks = 0; gchar *string = NULL; guint port = 0; gboolean mode = FALSE; g_object_get (G_OBJECT (lagent), "stun-server", &string, NULL); g_assert (stun_server == NULL || strcmp (string, stun_server) == 0); g_free (string); g_object_get (G_OBJECT (lagent), "stun-server-port", &port, NULL); g_assert (stun_server_port == NULL || port == (guint)atoi (stun_server_port)); g_object_get (G_OBJECT (lagent), "controlling-mode", &mode, NULL); g_assert (mode == TRUE); g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 300, NULL); g_object_get (G_OBJECT (lagent), "max-connectivity-checks", &max_checks, NULL); g_assert (max_checks == 300); } /* step: run test the first time */ g_debug ("test-thread: TEST STARTS / running test for the 1st time"); lthread = g_thread_new ("lthread libnice", mainloop_thread, lmainloop); rthread = g_thread_new ("rthread libnice", mainloop_thread, rmainloop); g_assert (lthread); g_assert (rthread); ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); g_object_set_data (G_OBJECT (lagent), "id", GUINT_TO_POINTER (ls_id)); g_object_set_data (G_OBJECT (ragent), "id", GUINT_TO_POINTER (rs_id)); nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); nice_agent_attach_recv (lagent, ls_id, 1, ldmainctx, cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, 1, rdmainctx, cb_nice_recv, GUINT_TO_POINTER (2)); ldthread = g_thread_new ("ldthread libnice", mainloop_thread, ldmainloop); rdthread = g_thread_new ("rdthread libnice", mainloop_thread, rdmainloop); g_assert (ldthread); g_assert (rdthread); /* Run loop for error timer */ g_main_loop_run (error_loop); while (!g_main_loop_is_running (ldmainloop)); while (g_main_loop_is_running (ldmainloop)) g_main_loop_quit (ldmainloop); while (!g_main_loop_is_running (rdmainloop)); while (g_main_loop_is_running (rdmainloop)) g_main_loop_quit (rdmainloop); while (!g_main_loop_is_running (lmainloop)); while (g_main_loop_is_running (lmainloop)) g_main_loop_quit (lmainloop); while (!g_main_loop_is_running (rmainloop)); while (g_main_loop_is_running (rmainloop)) g_main_loop_quit (rmainloop); g_thread_join (ldthread); g_thread_join (rdthread); g_thread_join (lthread); g_thread_join (rthread); /* note: verify that correct number of local candidates were reported */ g_assert (g_atomic_int_get (&global_lagent_cands) == 1); g_assert (g_atomic_int_get (&global_ragent_cands) == 1); g_object_add_weak_pointer (G_OBJECT (lagent), (gpointer *) &lagent); g_object_add_weak_pointer (G_OBJECT (ragent), (gpointer *) &ragent); g_object_unref (lagent); g_object_unref (ragent); WAIT_UNTIL_UNSET (lagent, lmainctx); WAIT_UNTIL_UNSET (ragent, rmainctx); g_main_loop_unref (lmainloop); g_main_loop_unref (rmainloop); g_main_loop_unref (ldmainloop); g_main_loop_unref (rdmainloop); g_main_loop_unref (error_loop); #ifdef G_OS_WIN32 WSACleanup(); #endif return 0; } libnice-0.1.14/tests/test-io-stream-common.h0000664000076400007640000000701512732066460015624 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include #include #ifndef G_OS_WIN32 #include #endif /* Make the message sufficiently large to not hit Nagle’s algorithm in the * pseudo-TCP implementation, and hence run really slowly. */ #define MESSAGE_SIZE 1284 /* bytes */ typedef struct _TestIOStreamThreadData TestIOStreamThreadData; typedef struct { void (*read_thread) (GInputStream *input_stream, TestIOStreamThreadData *data); void (*write_thread) (GOutputStream *output_stream, TestIOStreamThreadData *data); void (*reliable_transport_writable) (GOutputStream *output_stream, NiceAgent *agent, guint stream_id, guint component_id, TestIOStreamThreadData *data); void (*new_selected_pair) (NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar *rfoundation, TestIOStreamThreadData *data); } TestIOStreamCallbacks; struct _TestIOStreamThreadData { NiceAgent *agent; GIOStream *io_stream; gboolean reliable; GMainLoop *main_loop; GMainLoop *error_loop; GMainContext *main_context; GMainContext *write_context; GMainContext *read_context; gpointer user_data; GDestroyNotify user_data_free; TestIOStreamThreadData *other; /*< private >*/ const TestIOStreamCallbacks *callbacks; /* Condition signalling for the stream being open/writeable. */ gboolean stream_open; gboolean stream_ready; GCond write_cond; GMutex write_mutex; GMutex *start_mutex; GCond *start_cond; guint *start_count; }; GThread *spawn_thread (const gchar *thread_name, GThreadFunc thread_func, gpointer user_data); void run_io_stream_test (guint deadlock_timeout, gboolean reliable, const TestIOStreamCallbacks *callbacks, gpointer l_user_data, GDestroyNotify l_user_data_free, gpointer r_user_data, GDestroyNotify r_user_data_free); void check_for_termination (TestIOStreamThreadData *data, gsize *recv_count, gsize *other_recv_count, volatile gsize *send_count, gsize expected_recv_count); void stop_main_loop (GMainLoop *loop); libnice-0.1.14/tests/test-add-remove-stream.c0000664000076400007640000000470412661700132015737 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "agent-priv.h" #include int main (void) { NiceAgent *agent; NiceAddress addr; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif nice_address_init (&addr); if (!nice_address_set_from_string (&addr, "127.0.0.1")) g_assert_not_reached (); agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, &addr); g_assert (nice_agent_add_stream (agent, 1) == 1); g_assert (nice_agent_add_stream (agent, 10) == 2); g_assert (nice_agent_add_stream (agent, 2) == 3); g_assert (NULL != agent->streams); nice_agent_remove_stream (agent, 1); nice_agent_remove_stream (agent, 2); nice_agent_remove_stream (agent, 3); g_assert (NULL == agent->streams); g_object_unref (agent); #ifdef G_OS_WIN32 WSACleanup(); #endif return 0; } libnice-0.1.14/tests/test-io-stream-closing-read.c0000664000076400007640000000700112661700132016661 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "test-io-stream-common.h" #include #include #ifndef G_OS_WIN32 #include #endif #define NUM_MESSAGES 10 guint count = 0; GMutex count_lock; GCond count_cond; static void read_thread_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { GError *error = NULL; gssize len; guint8 buf[MESSAGE_SIZE]; g_mutex_lock (&count_lock); count++; g_cond_broadcast (&count_cond); g_mutex_unlock (&count_lock); /* Block on receiving some data. */ do { len = g_input_stream_read (input_stream, buf, sizeof (buf), NULL, &error); if (!data->user_data) { g_assert_cmpint (len, ==, sizeof(buf)); return; } } while (len > 0); g_assert_cmpint (len, ==, -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE); g_clear_error (&error); stop_main_loop (data->error_loop); } static void write_thread_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { gchar buf[MESSAGE_SIZE] = {0}; gssize ret; GError *error = NULL; gpointer tmp; guint stream_id; ret = g_output_stream_write (output_stream, buf, sizeof (buf), NULL, &error); g_mutex_lock (&count_lock); count++; g_cond_broadcast (&count_cond); if (data->user_data) { g_assert_cmpint (ret, ==, sizeof(buf)); g_mutex_unlock (&count_lock); return; } while (count != 4) g_cond_wait (&count_cond, &count_lock); g_mutex_unlock (&count_lock); /* Now we remove the stream, lets see how the writer handles that */ tmp = g_object_get_data (G_OBJECT (data->other->agent), "stream-id"); stream_id = GPOINTER_TO_UINT (tmp); nice_agent_remove_stream (data->other->agent, stream_id); } int main (void) { const TestIOStreamCallbacks callbacks = { read_thread_cb, write_thread_cb, NULL, NULL, }; #ifdef G_OS_WIN32 WSADATA w; WSAStartup (0x0202, &w); #endif run_io_stream_test (30, TRUE, &callbacks, (gpointer) TRUE, NULL, NULL, NULL); #ifdef G_OS_WIN32 WSACleanup (); #endif return 0; } libnice-0.1.14/tests/test-socket-is-based-on.c0000664000076400007640000000770412721651116016021 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2016 Jakub Adam * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "socket.h" static NiceSocket *udp_bsd; static NiceSocket *tcp_active; static NiceSocket *pseudossl; static NiceSocket *udp_turn_over_tcp; static void socket_base_udp_bsd (void) { g_assert (nice_socket_is_based_on (udp_bsd, udp_bsd)); g_assert (!nice_socket_is_based_on (udp_bsd, tcp_active)); g_assert (!nice_socket_is_based_on (udp_bsd, pseudossl)); g_assert (!nice_socket_is_based_on (udp_bsd, udp_turn_over_tcp)); } static void socket_base_tcp_active (void) { g_assert (!nice_socket_is_based_on (tcp_active, udp_bsd)); g_assert (nice_socket_is_based_on (tcp_active, tcp_active)); g_assert (!nice_socket_is_based_on (tcp_active, pseudossl)); g_assert (!nice_socket_is_based_on (tcp_active, udp_turn_over_tcp)); } static void socket_base_pseudossl (void) { g_assert (!nice_socket_is_based_on (pseudossl, udp_bsd)); g_assert (nice_socket_is_based_on (pseudossl, tcp_active)); g_assert (nice_socket_is_based_on (pseudossl, pseudossl)); g_assert (!nice_socket_is_based_on (pseudossl, udp_turn_over_tcp)); } static void socket_base_udp_turn_over_tcp (void) { g_assert (!nice_socket_is_based_on (udp_turn_over_tcp, udp_bsd)); g_assert (nice_socket_is_based_on (udp_turn_over_tcp, tcp_active)); g_assert (nice_socket_is_based_on (udp_turn_over_tcp, pseudossl)); g_assert (nice_socket_is_based_on (udp_turn_over_tcp, udp_turn_over_tcp)); } int main (int argc, char *argv[]) { GMainLoop *mainloop = NULL; NiceAddress addr; setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); mainloop = g_main_loop_new (NULL, TRUE); nice_address_set_from_string (&addr, "127.0.0.1"); /* Standalone socket */ udp_bsd = nice_udp_bsd_socket_new (&addr); /* tcp_passive -> pseudossl -> udp_turn_over_tcp */ tcp_active = nice_tcp_active_socket_new (g_main_loop_get_context (mainloop), &addr); pseudossl = nice_pseudossl_socket_new (tcp_active, NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE); udp_turn_over_tcp = nice_udp_turn_over_tcp_socket_new (pseudossl, NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE); g_test_add_func ("/socket/is-base-of/udp-bsd", socket_base_udp_bsd); g_test_add_func ("/socket/is-base-of/tcp-active", socket_base_tcp_active); g_test_add_func ("/socket/is-base-of/pseudossl", socket_base_pseudossl); g_test_add_func ("/socket/is-base-of/udp-turn-over-tcp", socket_base_udp_turn_over_tcp); g_test_run (); nice_socket_free (udp_bsd); nice_socket_free (udp_turn_over_tcp); g_main_loop_unref (mainloop); return 0; } libnice-0.1.14/tests/test-pseudotcp-random.sh0000775000076400007640000000020412725333757016111 00000000000000#!/bin/sh dd if=/dev/urandom of=rand count=1024 ibs=1024 ./test-pseudotcp rand rand-copy diff rand rand-copy rm -rf rand rand-copy libnice-0.1.14/tests/test-pseudotcp-fuzzy.c0000664000076400007640000003157712732064261015633 00000000000000/* vim: et ts=2 sw=2 tw=80: */ /* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "pseudotcp.h" /** * A fuzzing test for the pseudotcp socket. This connects two sockets in a * loopback arrangement, with the packet output from one being fed to the other, * and vice-versa. Fuzzing happens on the packet interface between the two, * mutating the packets slightly and seeing what happens. * * The input data to the left-most socket is read from a file. The output data * from the loopback is written to another file, although this probably isn’t * very useful. If no files are provided, a small amount of dummy data is sent * through the sockets instead. This almost certainly won’t catch any bugs, and * is just present to allow this test to be run as part of `make check` so it * doesn’t bit rot. * * A good command to generate an input file is: * dd if=/dev/urandom of=rand count=10000 ibs=1024 * * None of the data is validated, and the test results are effectively the 1-bit * value of ‘did it crash?’. In particular, the output file is not validated, * and the TCP packets emitted by both sockets are not checked for validity. * * It is suggested that this test is run under GDB and Valgrind. Any crashes or * errors which are detected can be reproduced by providing the same input file * and seed (using the --seed option). The seed is printed out at the beginning * of each test run. */ PseudoTcpSocket *left; PseudoTcpSocket *right; GMainLoop *main_loop = NULL; GRand *prng = NULL; gint retval = 0; FILE *in = NULL; FILE *out = NULL; int total_read = 0; int total_wrote = 0; guint left_clock = 0; guint right_clock = 0; gboolean left_closed = FALSE; gboolean right_closed = FALSE; gboolean reading_done = FALSE; /* Number of bytes of payload each socket has received so far. */ guint32 left_stream_pos = 0; guint32 right_stream_pos = 0; /* Configuration options. */ gint64 seed = 0; guint32 fuzz_start_pos = 1; /* bytes into stream payload; after the SYN-ACKs */ guint n_changes_lambda = 1; /* lambda parameter for a Poisson distribution * controlling the number of mutations made to each * packet */ static void adjust_clock (PseudoTcpSocket *sock); static void write_to_sock (PseudoTcpSocket *sock) { gchar buf[1024]; gsize len; gint wlen; guint total = 0; while (TRUE) { len = fread (buf, 1, sizeof(buf), in); if (len == 0) { g_debug ("Done reading data from file"); g_assert (feof (in)); reading_done = TRUE; pseudo_tcp_socket_close (sock, FALSE); break; } else { wlen = pseudo_tcp_socket_send (sock, buf, len); g_debug ("Sending %" G_GSIZE_FORMAT " bytes : %d", len, wlen); total += wlen; total_read += wlen; if (wlen < (gint) len) { g_debug ("seeking %ld from %lu", wlen - len, ftell (in)); fseek (in, wlen - len, SEEK_CUR); g_assert (!feof (in)); g_debug ("Socket queue full after %d bytes written", total); break; } } } adjust_clock (sock); } static void opened (PseudoTcpSocket *sock, gpointer data) { g_debug ("Socket %p Opened", sock); if (sock == left) { if (in) write_to_sock (sock); else { pseudo_tcp_socket_send (sock, "abcdefghijklmnopqrstuvwxyz", 26); reading_done = TRUE; pseudo_tcp_socket_close (sock, FALSE); } } } static void readable (PseudoTcpSocket *sock, gpointer data) { gchar buf[1024]; gint len; g_debug ("Socket %p Readable", sock); do { len = pseudo_tcp_socket_recv (sock, buf, sizeof(buf)); if (len > 0) { g_debug ("Read %d bytes", len); if (out) { if (fwrite (buf, len, 1, out) == 0) g_debug ("Error writing to output file"); else { total_wrote += len; g_assert (total_wrote <= total_read); g_debug ("Written %d bytes, need %d bytes", total_wrote, total_read); if (total_wrote == total_read && feof (in)) { g_assert (reading_done); pseudo_tcp_socket_close (sock, FALSE); } } } else { pseudo_tcp_socket_close (sock, FALSE); } } else if (len == 0) { pseudo_tcp_socket_close (sock, FALSE); } } while (len > 0); if (len == -1 && pseudo_tcp_socket_get_error (sock) != EWOULDBLOCK) { g_printerr ("Error reading from socket %p: %s.\n", sock, g_strerror (pseudo_tcp_socket_get_error (sock))); retval = -1; g_main_loop_quit (main_loop); return; } } static void writable (PseudoTcpSocket *sock, gpointer data) { g_debug ("Socket %p Writable", sock); if (in && sock == left) write_to_sock (sock); } static void closed (PseudoTcpSocket *sock, guint32 err, gpointer data) { /* Don’t treat this as an error, since we’re throwing rubbish into the * socket and can hardly expect it to complete successfully. */ g_debug ("Socket %p Closed: %s", sock, g_strerror (err)); retval = 0; g_main_loop_quit (main_loop); } struct notify_data { PseudoTcpSocket *sock; guint32 len; guint32 stream_pos; guint8 buffer[]; }; /** * random_int_poisson: * @lambda: Lambda parameter for the distribution function, which must be * non-zero * * Generate a random variable from a Poisson distribution with parameter * @lambda. This consumes one %gdouble’s worth of randomness from the global * @prng. * * This is implemented using the inverse transform of the Poisson CDF, and is * guaranteed to return in time linearly proportional to @lambda. * * Returns: Poisson-distributed pseudo-random variable */ static guint32 random_int_poisson (guint lambda) { gdouble U; guint32 i; gdouble p, F; g_return_val_if_fail (lambda > 0, 0); /* * Reference: http://www.cs.bgu.ac.il/~mps042/invtransnote.htm, * §Simulating a Poisson random variable. */ U = g_rand_double (prng); /* step 1 */ i = 0; p = exp (0.0 - (gdouble) lambda); F = p; /* step 2 */ while (U >= F) { /* step 3 */ p = (lambda * p) / (i + 1); F += p; i += 1; /* step 4 and 5 */ } return i; } static guint32 fuzz_packet (guint8 *buf, guint32 len, guint32 stream_pos) { guint32 i; guint n_changes; #define HEADER_LENGTH 24 /* bytes; or thereabouts (include some options) */ /* Do we want to fuzz this packet? */ if (stream_pos < fuzz_start_pos) { return len; } /* Get fuzzing. Only bother fuzzing the header; fuzzing the payload is * pointless. Weight the number of changes towards having only a few changes, * since that makes them less likely to be summarily rejected. */ n_changes = random_int_poisson (n_changes_lambda); g_debug ("Making %u changes for bytes at stream position %u:", n_changes, stream_pos); for (i = 0; i < n_changes; i++) { guint32 pos = g_rand_int_range (prng, 0, MIN (len, HEADER_LENGTH)); g_debug (" • Changing byte %u.", stream_pos + pos); buf[pos] = g_rand_int_range (prng, 0, G_MAXUINT8 + 1); } return len; } static gboolean notify_packet (gpointer user_data) { struct notify_data *data = (struct notify_data*) user_data; /* Fuzz the packet. */ data->len = fuzz_packet (data->buffer, data->len, data->stream_pos); pseudo_tcp_socket_notify_packet (data->sock, (gchar *) data->buffer, data->len); adjust_clock (data->sock); g_free (data); return FALSE; } static PseudoTcpWriteResult write_packet (PseudoTcpSocket *sock, const gchar *buffer, guint32 len, gpointer user_data) { struct notify_data *data; PseudoTcpState state; g_object_get (sock, "state", &state, NULL); data = g_malloc (sizeof(struct notify_data) + len); g_debug ("Socket %p(%d) Writing : %d bytes", sock, state, len); memcpy (data->buffer, buffer, len); data->len = len; if (sock == left) { data->stream_pos = left_stream_pos; left_stream_pos += len; data->sock = right; } else { data->stream_pos = right_stream_pos; right_stream_pos += len; data->sock = left; } g_idle_add (notify_packet, data); return WR_SUCCESS; } static gboolean notify_clock (gpointer data) { PseudoTcpSocket *sock = (PseudoTcpSocket *)data; //g_debug ("Socket %p: Notifying clock", sock); pseudo_tcp_socket_notify_clock (sock); adjust_clock (sock); return FALSE; } static void adjust_clock (PseudoTcpSocket *sock) { guint64 timeout = 0; if (pseudo_tcp_socket_get_next_clock (sock, &timeout)) { timeout -= g_get_monotonic_time () / 1000; g_debug ("Socket %p: Adjusting clock to %ld ms", sock, timeout); if (sock == left) { if (left_clock != 0) g_source_remove (left_clock); left_clock = g_timeout_add (timeout, notify_clock, sock); } else { if (right_clock != 0) g_source_remove (right_clock); right_clock = g_timeout_add (timeout, notify_clock, sock); } } else { g_debug ("Socket %p should be destroyed, it's done", sock); if (sock == left) left_closed = TRUE; else right_closed = TRUE; if (left_closed && right_closed) g_main_loop_quit (main_loop); } } static GOptionEntry entries[] = { { "seed", 's', 0, G_OPTION_ARG_INT64, &seed, "PRNG seed", "N" }, { "fuzz-start-position", 'p', 0, G_OPTION_ARG_INT, &fuzz_start_pos, "Number of bytes into the stream to start fuzzing after", "B" }, { "fuzz-n-changes-lambda", 'l', 0, G_OPTION_ARG_INT, &n_changes_lambda, "Lambda value for the Poisson distribution controlling the number of " "changes made to each packet", "λ" }, { NULL } }; int main (int argc, char *argv[]) { PseudoTcpCallbacks cbs = { NULL, opened, readable, writable, closed, write_packet }; GOptionContext *context; GError *error = NULL; setlocale (LC_ALL, ""); /* Configuration. */ context = g_option_context_new ("— fuzz-test the pseudotcp socket"); g_option_context_add_main_entries (context, entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("Option parsing failed: %s\n", error->message); goto context_error; } if (n_changes_lambda == 0) { g_printerr ("Option parsing failed: %s\n", "Lambda values must be positive."); goto context_error; } g_option_context_free (context); /* Tweak the configuration. */ if (seed == 0) { seed = g_get_real_time (); } /* Open the input and output files */ if (argc >= 3) { in = fopen (argv[1], "r"); out = fopen (argv[2], "w"); } /* Set up the main loop and sockets. */ main_loop = g_main_loop_new (NULL, FALSE); g_print ("Using seed: %" G_GINT64_FORMAT ", start position: %u, λ: %u\n", seed, fuzz_start_pos, n_changes_lambda); prng = g_rand_new_with_seed (seed); pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE); left = pseudo_tcp_socket_new (0, &cbs); right = pseudo_tcp_socket_new (0, &cbs); g_debug ("Left: %p. Right: %p", left, right); pseudo_tcp_socket_notify_mtu (left, 1496); pseudo_tcp_socket_notify_mtu (right, 1496); pseudo_tcp_socket_connect (left); adjust_clock (left); adjust_clock (right); /* Run the main loop. */ g_main_loop_run (main_loop); g_main_loop_unref (main_loop); g_object_unref (left); g_object_unref (right); g_rand_free (prng); if (in != NULL) fclose (in); if (out != NULL) fclose (out); return retval; context_error: g_printerr ("\n%s\n", g_option_context_get_help (context, TRUE, NULL)); g_option_context_free (context); return 1; } libnice-0.1.14/tests/test-io-stream-common.c0000664000076400007640000004010412732066460015613 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "test-io-stream-common.h" #include #include #ifndef G_OS_WIN32 #include #endif GMutex start_mutex; GCond start_cond; gboolean started; /* Waits about 10 seconds for @var to be NULL/FALSE */ #define WAIT_UNTIL_UNSET(var, context) \ if (var) \ { \ int i; \ \ for (i = 0; i < 13 && (var); i++) \ { \ g_usleep (1000 * (1 << i)); \ g_main_context_iteration (context, FALSE); \ } \ \ g_assert (!(var)); \ } static gboolean timer_cb (gpointer pointer) { g_debug ("test-thread:%s: %p", G_STRFUNC, pointer); /* note: should not be reached, abort */ g_debug ("ERROR: test has got stuck, aborting..."); exit (-1); } static void wait_for_start (TestIOStreamThreadData *data) { g_mutex_lock (data->start_mutex); (*data->start_count)--; g_cond_broadcast (data->start_cond); while (*data->start_count > 0) g_cond_wait (data->start_cond, data->start_mutex); g_mutex_unlock (data->start_mutex); } static gpointer write_thread_cb (gpointer user_data) { TestIOStreamThreadData *data = user_data; GMainContext *main_context; GOutputStream *output_stream = NULL; main_context = g_main_context_new (); g_main_context_push_thread_default (main_context); /* Synchronise thread starting. */ wait_for_start (data); /* Wait for the stream to be writeable. */ g_mutex_lock (&data->write_mutex); while (!(data->stream_open && data->stream_ready)) g_cond_wait (&data->write_cond, &data->write_mutex); g_mutex_unlock (&data->write_mutex); if (data->reliable) output_stream = g_io_stream_get_output_stream (data->io_stream); data->callbacks->write_thread (output_stream, data); g_main_context_pop_thread_default (main_context); g_main_context_unref (main_context); return NULL; } static gpointer read_thread_cb (gpointer user_data) { TestIOStreamThreadData *data = user_data; GMainContext *main_context; GInputStream *input_stream = NULL; main_context = g_main_context_new (); g_main_context_push_thread_default (main_context); /* Synchronise thread starting. */ wait_for_start (data); if (data->reliable) input_stream = g_io_stream_get_input_stream (data->io_stream); data->callbacks->read_thread (input_stream, data); g_main_context_pop_thread_default (main_context); g_main_context_unref (main_context); return NULL; } static gpointer main_thread_cb (gpointer user_data) { TestIOStreamThreadData *data = user_data; g_main_context_push_thread_default (data->main_context); /* Synchronise thread starting. */ wait_for_start (data); /* Run the main context. */ g_main_loop_run (data->main_loop); g_main_context_pop_thread_default (data->main_context); return NULL; } static void candidate_gathering_done_cb (NiceAgent *agent, guint stream_id, gpointer user_data) { NiceAgent *other = g_object_get_data (G_OBJECT (agent), "other-agent"); gchar *ufrag = NULL, *password = NULL; GSList *cands, *i; guint id, other_id; gpointer tmp; tmp = g_object_get_data (G_OBJECT (agent), "stream-id"); id = GPOINTER_TO_UINT (tmp); tmp = g_object_get_data (G_OBJECT (other), "stream-id"); other_id = GPOINTER_TO_UINT (tmp); nice_agent_get_local_credentials (agent, id, &ufrag, &password); nice_agent_set_remote_credentials (other, other_id, ufrag, password); g_free (ufrag); g_free (password); cands = nice_agent_get_local_candidates (agent, id, 1); g_assert (cands != NULL); nice_agent_set_remote_candidates (other, other_id, 1, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } static void reliable_transport_writable_cb (NiceAgent *agent, guint stream_id, guint component_id, gpointer user_data) { TestIOStreamThreadData *data = user_data; g_assert (data->reliable); /* Signal writeability. */ g_mutex_lock (&data->write_mutex); data->stream_open = TRUE; g_cond_broadcast (&data->write_cond); g_mutex_unlock (&data->write_mutex); if (data->callbacks->reliable_transport_writable != NULL) { GIOStream *io_stream; GOutputStream *output_stream; io_stream = g_object_get_data (G_OBJECT (agent), "io-stream"); g_assert (io_stream != NULL); output_stream = g_io_stream_get_output_stream (io_stream); data->callbacks->reliable_transport_writable (output_stream, agent, stream_id, component_id, data); } } static void component_state_changed_cb (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer user_data) { TestIOStreamThreadData *data = user_data; if (state != NICE_COMPONENT_STATE_READY) return; /* Signal stream state. */ g_mutex_lock (&data->write_mutex); data->stream_ready = TRUE; g_cond_broadcast (&data->write_cond); g_mutex_unlock (&data->write_mutex); } static void new_selected_pair_cb (NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar *rfoundation, gpointer user_data) { TestIOStreamThreadData *data = user_data; if (data->callbacks->new_selected_pair != NULL) { data->callbacks->new_selected_pair (agent, stream_id, component_id, lfoundation, rfoundation, data); } } static NiceAgent * create_agent (gboolean controlling_mode, TestIOStreamThreadData *data, GMainContext **main_context, GMainLoop **main_loop) { NiceAgent *agent; NiceAddress base_addr; const gchar *stun_server, *stun_server_port; /* Create main contexts. */ *main_context = g_main_context_new (); *main_loop = g_main_loop_new (*main_context, FALSE); /* Use Google compatibility to ignore credentials. */ if (data->reliable) agent = nice_agent_new_reliable (*main_context, NICE_COMPATIBILITY_GOOGLE); else agent = nice_agent_new (*main_context, NICE_COMPATIBILITY_GOOGLE); g_object_set (G_OBJECT (agent), "controlling-mode", controlling_mode, "upnp", FALSE, NULL); /* Specify which local interface to use. */ g_assert (nice_address_set_from_string (&base_addr, "127.0.0.1")); nice_agent_add_local_address (agent, &base_addr); /* Hook up signals. */ g_signal_connect (G_OBJECT (agent), "candidate-gathering-done", (GCallback) candidate_gathering_done_cb, GUINT_TO_POINTER (controlling_mode)); g_signal_connect (G_OBJECT (agent), "new-selected-pair", (GCallback) new_selected_pair_cb, data); g_signal_connect (G_OBJECT (agent), "component-state-changed", (GCallback) component_state_changed_cb, data); if (data->reliable) { g_signal_connect (G_OBJECT (agent), "reliable-transport-writable", (GCallback) reliable_transport_writable_cb, data); } else { data->stream_open = TRUE; } /* Configure the STUN server. */ stun_server = g_getenv ("NICE_STUN_SERVER"); stun_server_port = g_getenv ("NICE_STUN_SERVER_PORT"); if (stun_server != NULL) { g_object_set (G_OBJECT (agent), "stun-server", stun_server, "stun-server-port", atoi (stun_server_port), NULL); } return agent; } static void add_stream (NiceAgent *agent) { guint stream_id; stream_id = nice_agent_add_stream (agent, 2); g_assert (stream_id > 0); g_object_set_data (G_OBJECT (agent), "stream-id", GUINT_TO_POINTER (stream_id)); } static void run_agent (TestIOStreamThreadData *data, NiceAgent *agent) { guint stream_id; gpointer tmp; tmp = g_object_get_data (G_OBJECT (agent), "stream-id"); stream_id = GPOINTER_TO_UINT (tmp); nice_agent_gather_candidates (agent, stream_id); if (data->reliable) { data->io_stream = G_IO_STREAM (nice_agent_get_io_stream (agent, stream_id, 1)); g_object_set_data (G_OBJECT (agent), "io-stream", data->io_stream); } else { data->io_stream = NULL; } } GThread * spawn_thread (const gchar *thread_name, GThreadFunc thread_func, gpointer user_data) { GThread *thread; thread = g_thread_new (thread_name, thread_func, user_data); g_assert (thread); return thread; } void run_io_stream_test (guint deadlock_timeout, gboolean reliable, const TestIOStreamCallbacks *callbacks, gpointer l_user_data, GDestroyNotify l_user_data_free, gpointer r_user_data, GDestroyNotify r_user_data_free) { GMainLoop *error_loop; GThread *l_main_thread, *r_main_thread; GThread *l_write_thread, *l_read_thread, *r_write_thread, *r_read_thread; TestIOStreamThreadData l_data, r_data; GMutex mutex; GCond cond; guint start_count = 6; guint stream_id; g_mutex_init (&mutex); g_cond_init (&cond); error_loop = g_main_loop_new (NULL, FALSE); /* Set up data structures. */ l_data.reliable = reliable; l_data.error_loop = error_loop; l_data.callbacks = callbacks; l_data.user_data = l_user_data; l_data.user_data_free = l_user_data_free; g_cond_init (&l_data.write_cond); g_mutex_init (&l_data.write_mutex); l_data.stream_open = FALSE; l_data.stream_ready = FALSE; l_data.start_mutex = &mutex; l_data.start_cond = &cond; l_data.start_count = &start_count; r_data.reliable = reliable; r_data.error_loop = error_loop; r_data.callbacks = callbacks; r_data.user_data = r_user_data; r_data.user_data_free = r_user_data_free; g_cond_init (&r_data.write_cond); g_mutex_init (&r_data.write_mutex); r_data.stream_open = FALSE; r_data.stream_ready = FALSE; r_data.start_mutex = &mutex; r_data.start_cond = &cond; r_data.start_count = &start_count; l_data.other = &r_data; r_data.other = &l_data; /* Create the L and R agents. */ l_data.agent = create_agent (TRUE, &l_data, &l_data.main_context, &l_data.main_loop); r_data.agent = create_agent (FALSE, &r_data, &r_data.main_context, &r_data.main_loop); g_object_set_data (G_OBJECT (l_data.agent), "other-agent", r_data.agent); g_object_set_data (G_OBJECT (r_data.agent), "other-agent", l_data.agent); /* Add a timer to catch deadlocks. */ g_timeout_add_seconds (deadlock_timeout, timer_cb, NULL); l_main_thread = spawn_thread ("libnice L main", main_thread_cb, &l_data); r_main_thread = spawn_thread ("libnice R main", main_thread_cb, &r_data); add_stream (l_data.agent); add_stream (r_data.agent); run_agent (&l_data, l_data.agent); run_agent (&r_data, r_data.agent); l_read_thread = spawn_thread ("libnice L read", read_thread_cb, &l_data); r_read_thread = spawn_thread ("libnice R read", read_thread_cb, &r_data); if (callbacks->write_thread != NULL) { l_write_thread = spawn_thread ("libnice L write", write_thread_cb, &l_data); r_write_thread = spawn_thread ("libnice R write", write_thread_cb, &r_data); } else { g_mutex_lock (&mutex); start_count -= 2; g_cond_broadcast (&cond); g_mutex_unlock (&mutex); l_write_thread = NULL; r_write_thread = NULL; } /* Run loop for error timer */ g_main_loop_run (error_loop); /* Clean up the main loops and threads. */ stop_main_loop (l_data.main_loop); stop_main_loop (r_data.main_loop); g_thread_join (l_read_thread); g_thread_join (r_read_thread); if (l_write_thread != NULL) g_thread_join (l_write_thread); if (r_write_thread != NULL) g_thread_join (r_write_thread); g_thread_join (l_main_thread); g_thread_join (r_main_thread); /* Free things. */ if (r_data.user_data_free != NULL) r_data.user_data_free (r_data.user_data); if (l_data.user_data_free != NULL) l_data.user_data_free (l_data.user_data); g_cond_clear (&r_data.write_cond); g_mutex_clear (&r_data.write_mutex); g_cond_clear (&l_data.write_cond); g_mutex_clear (&l_data.write_mutex); if (r_data.io_stream != NULL) g_object_unref (r_data.io_stream); if (l_data.io_stream != NULL) g_object_unref (l_data.io_stream); stream_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (r_data.agent), "stream-id")); if (stream_id != 0) nice_agent_remove_stream (r_data.agent, stream_id); stream_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (l_data.agent), "stream-id")); if (stream_id != 0) nice_agent_remove_stream (l_data.agent, stream_id); g_object_add_weak_pointer (G_OBJECT (r_data.agent), (gpointer *) &r_data.agent); g_object_add_weak_pointer (G_OBJECT (l_data.agent), (gpointer *) &l_data.agent); g_object_unref (r_data.agent); g_object_unref (l_data.agent); WAIT_UNTIL_UNSET (r_data.agent, r_data.main_context); WAIT_UNTIL_UNSET (l_data.agent, l_data.main_context); g_main_loop_unref (r_data.main_loop); g_main_loop_unref (l_data.main_loop); g_main_context_unref (r_data.main_context); g_main_context_unref (l_data.main_context); g_main_loop_unref (error_loop); g_mutex_clear (&mutex); g_cond_clear (&cond); } /* Once we’ve received all the expected bytes, wait to finish sending all bytes, * then send and wait for the close message. Finally, remove the stream. * * This must only be called from the read thread implementation. */ void check_for_termination (TestIOStreamThreadData *data, gsize *recv_count, gsize *other_recv_count, volatile gsize *send_count, gsize expected_recv_count) { guint stream_id; gpointer tmp; /* Wait for transmission to complete. */ while (*send_count < expected_recv_count); /* Send a close message. */ tmp = g_object_get_data (G_OBJECT (data->agent), "stream-id"); stream_id = GPOINTER_TO_UINT (tmp); /* Can't be certain enough to test for termination on non-reliable streams. * There may be packet losses, etc */ if (data->reliable) { guint8 buf[65536]; gsize buf_len; gssize len; GError *error = NULL; g_assert_cmpuint (*recv_count, >=, expected_recv_count); buf_len = strlen ("Done"); memcpy (buf, "Done", buf_len); len = nice_agent_send (data->agent, stream_id, 1, buf_len, (gchar *) buf); g_assert_cmpint (len, ==, buf_len); /* Wait for a done packet. */ len = nice_agent_recv (data->agent, stream_id, 1, buf, buf_len, NULL, &error); g_assert_no_error (error); g_assert_cmpint (len, ==, strlen ("Done")); g_assert_cmpint (memcmp (buf, "Done", strlen ("Done")), ==, 0); *recv_count = *recv_count + 1; } /* Remove the stream and run away. */ nice_agent_remove_stream (data->agent, stream_id); g_object_set_data (G_OBJECT (data->agent), "stream-id", GUINT_TO_POINTER (0)); /* If both sides have finished, quit the test main loop. */ if (*recv_count > expected_recv_count && *other_recv_count > expected_recv_count) { g_main_loop_quit (data->error_loop); } } void stop_main_loop (GMainLoop *loop) { GSource *src = g_idle_source_new (); g_source_set_callback (src, (GSourceFunc) g_main_loop_quit, g_main_loop_ref (loop), (GDestroyNotify) g_main_loop_unref); g_source_attach (src, g_main_loop_get_context (loop)); g_source_unref (src); } libnice-0.1.14/tests/libnice.supp0000664000076400007640000001570112520743534013626 00000000000000{ gnutls-init-calloc Memcheck:Leak fun:calloc ... fun:gtls_gnutls_init } { gnutls-init-realloc Memcheck:Leak fun:realloc ... fun:gtls_gnutls_init } { g-tls-backend-gnutls-init Memcheck:Leak fun:g_once_impl fun:g_tls_backend_gnutls_init } { p11-tokens-init Memcheck:Leak fun:calloc ... fun:create_tokens_inlock fun:initialize_module_inlock_reentrant } { gobject-init-malloc Memcheck:Leak fun:malloc ... fun:gobject_init_ctor } { gobject-init-realloc Memcheck:Leak fun:realloc ... fun:gobject_init_ctor } { gobject-init-calloc Memcheck:Leak fun:calloc ... fun:gobject_init_ctor } { g-type-register-dynamic Memcheck:Leak fun:malloc ... fun:g_type_register_dynamic } { g-type-register-static Memcheck:Leak fun:malloc ... fun:g_type_register_static } { g-type-register-static-realloc Memcheck:Leak fun:realloc ... fun:g_type_register_static } { g-type-register-static-calloc Memcheck:Leak fun:calloc ... fun:g_type_register_static } { g-type-add-interface-dynamic Memcheck:Leak fun:malloc ... fun:g_type_add_interface_dynamic } { g-type-add-interface-static Memcheck:Leak fun:malloc ... fun:g_type_add_interface_static } { g-test-rand-init Memcheck:Leak fun:calloc ... fun:g_rand_new_with_seed_array fun:test_run_seed ... fun:g_test_run } { g-test-rand-init2 Memcheck:Leak fun:calloc ... fun:g_rand_new_with_seed_array ... fun:get_global_random ... fun:g_test_init } { g-quark-table-new Memcheck:Leak fun:g_hash_table_new ... fun:quark_new } { g-quark-table-resize Memcheck:Leak fun:g_hash_table_resize ... fun:quark_new } { g-type-interface-init Memcheck:Leak fun:malloc ... fun:type_iface_vtable_base_init_Wm } { g-type-class-init Memcheck:Leak fun:calloc ... fun:type_class_init_Wm } { g-io-module-default-singleton-malloc Memcheck:Leak fun:malloc ... fun:g_type_create_instance ... fun:_g_io_module_get_default } { g-io-module-default-singleton-module Memcheck:Leak fun:calloc ... fun:g_module_open ... fun:_g_io_module_get_default } { g-get-language-names Memcheck:Leak fun:malloc ... fun:g_get_language_names } { g-static-mutex Memcheck:Leak fun:malloc ... fun:g_static_mutex_get_mutex_impl } { g-system-thread-init Memcheck:Leak fun:calloc ... fun:g_system_thread_new } { g-io-module-default-proxy-resolver-gnome Memcheck:Leak fun:calloc ... fun:g_proxy_resolver_gnome_init ... fun:_g_io_module_get_default } { g-private-get drd:ConflictingAccess fun:g_private_get } { g-private-get-helgrind Helgrind:Race fun:g_private_get } { g-private-set drd:ConflictingAccess fun:g_private_set } { g-private-set-helgrind Helgrind:Race fun:g_private_set } { g-type-construct-free drd:ConflictingAccess fun:g_type_free_instance } { g-type-construct-free-helgrind Helgrind:Race fun:g_type_free_instance } { g-variant-unref drd:ConflictingAccess fun:g_variant_unref } { g-variant-unref-helgrind Helgrind:Race fun:g_variant_unref } # TODO: haven't checked these entirely rigorously { g-unix-signals-main drd:ConflictingAccess fun:_g_main_create_unix_signal_watch } { g-unix-signals-dispatch drd:ConflictingAccess ... fun:dispatch_unix_signals* } { g-unix-signals-dispatch-helgrind Helgrind:Race ... fun:dispatch_unix_signals* } { g-unix-signals-other drd:ConflictingAccess fun:g_unix_signal_watch* } { g-unix-signals-other-helgrind Helgrind:Race fun:g_unix_signal_watch* } { g-unix-signals-handler drd:ConflictingAccess fun:g_unix_signal_handler* } { g-unix-signals-handler-helgrind Helgrind:Race fun:g_unix_signal_handler* } { g-unix-signals-worker drd:ConflictingAccess fun:glib_worker_main } { g-unix-signals-worker-helgrind Helgrind:Race fun:glib_worker_main } # TODO: haven't checked this thoroughly either { g-wakeup-acknowledge drd:ConflictingAccess fun:read fun:g_wakeup_acknowledge } # TODO: or these { g-type-fundamental drd:ConflictingAccess fun:g_type_fundamental } { g-type-fundamental-helgrind Helgrind:Race fun:g_type_fundamental } { g-type-class-peek-static drd:ConflictingAccess fun:g_type_class_peek_static } { g-type-class-peek-static-helgrind Helgrind:Race fun:g_type_class_peek_static } { g-type-is-a drd:ConflictingAccess ... fun:g_type_is_a } { g-type-is-a-helgrind Helgrind:Race ... fun:g_type_is_a } # TODO: ???? { g-inet-address-get-type drd:ConflictingAccess fun:g_inet_address_get_type } { g-inet-address-get-type-helgrind Helgrind:Race fun:g_inet_address_get_type } { nice-get-type-helgrind Helgrind:Race fun:nice_*_get_type } # From: https://github.com/fredericgermain/valgrind/blob/master/glibc-2.X-drd.supp { drd-libc-stdio drd:ConflictingAccess obj:*/lib*/libc-* } { drd-libc-recv drd:ConflictingAccess fun:recv } { drd-libc-send drd:ConflictingAccess fun:send } # GSources do an opportunistic ref count check { g-source-set-ready-time drd:ConflictingAccess fun:g_source_set_ready_time } { g-source-set-ready-time-helgrind Helgrind:Race fun:g_source_set_ready_time } # TODO: Check this { g-source-iter-next Helgrind:Race fun:g_source_iter_next fun:g_main_context_* fun:g_main_context_iterate } { g-object-instance-private drd:ConflictingAccess fun:*_get_instance_private } { g-object-instance-private-helgrind Helgrind:Race fun:*_get_instance_private } # GLib legitimately calls pthread_cond_signal without a mutex held { g-task-thread-complete drd:CondErr ... fun:g_cond_signal fun:g_task_thread_complete } { g-task-thread-complete Helgrind:Misc ... fun:g_cond_signal fun:g_task_thread_complete } # False positive { nice-output-stream-cond Helgrind:Misc ... fun:g_cond_clear fun:write_data_unref } # False positive, but I can't explain how (FIXME) { g-task-cond Helgrind:Misc ... fun:g_cond_clear fun:g_task_finalize } # TODO FIXME: This is definitely a race. # https://bugzilla.gnome.org/show_bug.cgi?id=735754 { g-tls-base-stream-close Helgrind:Race ... fun:g_*_stream_close fun:streams_removed_cb } { g-tls-base-stream-close2 Helgrind:Race ... fun:g_*_stream_close fun:g_tls_connection_gnutls_close } # Real race, but is_cancelled() is an opportunistic function anyway { g-cancellable-is-cancelled Helgrind:Race fun:g_cancellable_is_cancelled } # False positive { g-main-context-cond Helgrind:Misc ... fun:g_cond_clear fun:g_main_context_unref } # False positives { g-source-unlocked Helgrind:Race fun:g_source_*_unlocked } { g-source-internal Helgrind:Race fun:g_source_*_internal } # FIXME: Probably actually a race { test-io-stream-common-termination Helgrind:Race fun:check_for_termination } { test-io-stream-common-wait Helgrind:Race fun:wait_for_start } { test-io-stream-common-main Helgrind:Race fun:main_thread_cb } { test-io-stream-common-read Helgrind:Race fun:read_thread_cb } { test-io-stream-common-write Helgrind:Race fun:write_thread_cb } # False positive { g_object_real_dispose Helgrind:Race fun:g_object_real_dispose } # False positive { g_object_new_valist Helgrind:Race ... fun:g_object_new_valist } libnice-0.1.14/tests/test-gstreamer.c0000664000076400007640000002330312520743534014417 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 1015 Kurento. * Contact: Jose Antonio Santos Cadenas * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Jose Antonio Santos Cadenas, Kurento. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #include #include #define RTP_HEADER_SIZE 12 #define RTP_PAYLOAD_SIZE 1024 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); GMainLoop *loop; gint ready = 0; static guint bytes_received; guint data_size; static gboolean count_bytes (GstBuffer ** buffer, guint idx, gpointer data) { gsize size = gst_buffer_get_size (*buffer); GST_DEBUG ("received %" G_GSIZE_FORMAT " bytes", size); bytes_received += size; return TRUE; } static GstFlowReturn sink_chain_list_function (GstPad * pad, GstObject * parent, GstBufferList * list) { gst_buffer_list_foreach (list, count_bytes, NULL); if (data_size <= bytes_received) { GST_DEBUG ("We received expected data size"); g_main_loop_quit (loop); } return GST_FLOW_OK; } static GstFlowReturn sink_chain_function (GstPad * pad, GstObject * parent, GstBuffer * buffer) { gsize size = gst_buffer_get_size (buffer); GST_DEBUG ("received %" G_GSIZE_FORMAT " bytes", size); bytes_received += size; if (data_size <= bytes_received) { GST_DEBUG ("We received expected data size"); g_main_loop_quit (loop); } return GST_FLOW_OK; } /* * This function is get from gst-plugins-good tests tests/check/elements/udpsink.c */ static GstBufferList * create_buffer_list (void) { GstBufferList *list; GstBuffer *rtp_buffer; GstBuffer *data_buffer; gint total_size = 0; list = gst_buffer_list_new (); /*** First group, i.e. first packet. **/ /* Create the RTP header buffer */ rtp_buffer = gst_buffer_new_allocate (NULL, RTP_HEADER_SIZE, NULL); gst_buffer_memset (rtp_buffer, 0, 0, RTP_HEADER_SIZE); /* Create the buffer that holds the payload */ data_buffer = gst_buffer_new_allocate (NULL, RTP_PAYLOAD_SIZE, NULL); gst_buffer_memset (data_buffer, 0, 0, RTP_PAYLOAD_SIZE); /* Create a new group to hold the rtp header and the payload */ gst_buffer_list_add (list, gst_buffer_append (rtp_buffer, data_buffer)); total_size += gst_buffer_get_size (rtp_buffer); /*** Second group, i.e. second packet. ***/ /* Create the RTP header buffer */ rtp_buffer = gst_buffer_new_allocate (NULL, RTP_HEADER_SIZE, NULL); gst_buffer_memset (rtp_buffer, 0, 0, RTP_HEADER_SIZE); /* Create the buffer that holds the payload */ data_buffer = gst_buffer_new_allocate (NULL, RTP_PAYLOAD_SIZE, NULL); gst_buffer_memset (data_buffer, 0, 0, RTP_PAYLOAD_SIZE); /* Create a new group to hold the rtp header and the payload */ gst_buffer_list_add (list, gst_buffer_append (rtp_buffer, data_buffer)); total_size += gst_buffer_get_size (rtp_buffer); /* Calculate the size of the data */ data_size = 2 * RTP_HEADER_SIZE + 2 * RTP_PAYLOAD_SIZE; return list; } static void recv_cb (NiceAgent * agent, guint stream_id, guint component_id, guint len, gchar * buf, gpointer data) { GST_INFO ("Received data on agent %" GST_PTR_FORMAT ", stream: %d, compoment: %d", agent, stream_id, component_id); } static void print_candidate (gpointer data, gpointer user_data) { NiceCandidate *cand = data; gchar str_addr[INET6_ADDRSTRLEN]; nice_address_to_string (&cand->addr, str_addr); GST_INFO ("Cadidate: %s:%d", str_addr, nice_address_get_port (&cand->addr)); } static void cb_candidate_gathering_done (NiceAgent * agent, guint stream_id, gpointer data) { GSList *candidates; GST_INFO ("Candidates gathered on agent %" GST_PTR_FORMAT ", stream: %d", agent, stream_id); candidates = nice_agent_get_local_candidates (agent, stream_id, 1); nice_agent_set_remote_candidates (NICE_AGENT (data), stream_id, 1, candidates); GST_INFO ("Got %d candidates", g_slist_length (candidates)); g_slist_foreach (candidates, print_candidate, NULL); g_slist_free_full (candidates, (GDestroyNotify) nice_candidate_free); } static void credentials_negotiation (NiceAgent * a_agent, NiceAgent * b_agent, guint a_stream, guint b_stream) { gchar *user = NULL; gchar *passwd = NULL; nice_agent_get_local_credentials (a_agent, a_stream, &user, &passwd); nice_agent_set_remote_credentials (b_agent, b_stream, user, passwd); GST_DEBUG_OBJECT (a_agent, "User: %s", user); GST_DEBUG_OBJECT (a_agent, "Passwd: %s", passwd); g_free (user); g_free (passwd); } static void cb_component_state_changed (NiceAgent * agent, guint stream_id, guint component_id, guint state, gpointer user_data) { GST_DEBUG ("State changed: %" GST_PTR_FORMAT " to %s", agent, nice_component_state_to_string (state)); if (state == NICE_COMPONENT_STATE_READY) { ready++; if (ready >= 2) { g_main_loop_quit (loop); } } } GST_START_TEST (buffer_list_test) { GstSegment segment; GstElement *nicesink, *nicesrc; GstPad *srcpad, *sinkpad; GstBufferList *list; NiceAgent *sink_agent, *src_agent; guint sink_stream, src_stream; NiceAddress *addr; loop = g_main_loop_new (NULL, TRUE); /* Initialize nice agents */ addr = nice_address_new (); nice_address_set_from_string (addr, "127.0.0.1"); sink_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); src_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (sink_agent, addr); nice_agent_add_local_address (src_agent, addr); sink_stream = nice_agent_add_stream (sink_agent, 1); src_stream = nice_agent_add_stream (src_agent, 1); nice_agent_attach_recv (sink_agent, sink_stream, NICE_COMPONENT_TYPE_RTP, NULL, recv_cb, NULL); nice_agent_attach_recv (src_agent, src_stream, NICE_COMPONENT_TYPE_RTP, NULL, recv_cb, NULL); g_signal_connect (G_OBJECT (sink_agent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), src_agent); g_signal_connect (G_OBJECT (src_agent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), sink_agent); g_signal_connect (G_OBJECT (sink_agent), "component-state-changed", G_CALLBACK (cb_component_state_changed), NULL); g_signal_connect (G_OBJECT (src_agent), "component-state-changed", G_CALLBACK (cb_component_state_changed), NULL); credentials_negotiation (sink_agent, src_agent, sink_stream, src_stream); credentials_negotiation (src_agent, sink_agent, src_stream, src_stream); nice_agent_gather_candidates (sink_agent, sink_stream); nice_agent_gather_candidates (src_agent, src_stream); /* Create gstreamer elements */ nicesink = gst_check_setup_element ("nicesink"); nicesrc = gst_check_setup_element ("nicesrc"); g_object_set (nicesink, "agent", sink_agent, "stream", sink_stream, "component", 1, NULL); g_object_set (nicesrc, "agent", src_agent, "stream", src_stream, "component", 1, NULL); srcpad = gst_check_setup_src_pad_by_name (nicesink, &srctemplate, "sink"); sinkpad = gst_check_setup_sink_pad_by_name (nicesrc, &sinktemplate, "src"); gst_pad_set_chain_list_function_full (sinkpad, sink_chain_list_function, NULL, NULL); gst_pad_set_chain_function_full (sinkpad, sink_chain_function, NULL, NULL); gst_element_set_state (nicesink, GST_STATE_PLAYING); gst_pad_set_active (srcpad, TRUE); gst_element_set_state (nicesrc, GST_STATE_PLAYING); gst_pad_set_active (sinkpad, TRUE); gst_pad_push_event (srcpad, gst_event_new_stream_start ("test")); gst_segment_init (&segment, GST_FORMAT_TIME); gst_pad_push_event (srcpad, gst_event_new_segment (&segment)); list = create_buffer_list (); GST_DEBUG ("Waiting for agents to be ready ready"); g_main_loop_run (loop); fail_unless_equals_int (gst_pad_push_list (srcpad, list), GST_FLOW_OK); GST_DEBUG ("Waiting for buffers"); g_main_loop_run (loop); fail_unless_equals_int (data_size, bytes_received); gst_check_teardown_pad_by_name (nicesink, "sink"); gst_check_teardown_element (nicesink); gst_check_teardown_pad_by_name (nicesrc, "src"); gst_check_teardown_element (nicesrc); nice_address_free (addr); g_main_loop_unref (loop); } GST_END_TEST; static Suite * udpsink_suite (void) { Suite *s = suite_create ("nice_gstreamer_test"); TCase *tc_chain = tcase_create ("nice"); suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, buffer_list_test); return s; } GST_CHECK_MAIN (udpsink) libnice-0.1.14/tests/test-fullmode.c0000664000076400007640000011736512724123177014252 00000000000000/* * This file is part of the Nice GLib ICE library. * * Unit test for ICE full-mode related features. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include #include #define USE_TURN 0 #define USE_LOOPBACK 1 #define USE_PROXY 0 #define USE_UPNP 0 #define USE_RELIABLE 0 #define TEST_GOOGLE 0 #define PROXY_IP "127.0.0.1" #define PROXY_PORT 1080 #define PROXY_USERNAME NULL #define PROXY_PASSWORD NULL #if USE_PROXY #define PROXY_TYPE NICE_PROXY_TYPE_SOCKS5 #else #define PROXY_TYPE NICE_PROXY_TYPE_NONE #endif #if TEST_GOOGLE #define NICE_COMPATIBILITY NICE_COMPATIBILITY_GOOGLE #if USE_TURN #undef USE_LOOPBACK #define USE_LOOPBACK 0 #define TURN_IP "209.85.163.126" #define TURN_PORT 443 #define TURN_USER "ih9ppiM0P6vN34DB" #define TURN_PASS "" #define TURN_USER2 TURN_USER #define TURN_PASS2 TURN_PASS #define TURN_TYPE NICE_RELAY_TYPE_TURN_TLS #endif #else #define NICE_COMPATIBILITY NICE_COMPATIBILITY_RFC5245 #if USE_LOOPBACK #define USE_TURN_SERVER_ORG 1 #else #define USE_TURN_SERVER_ORG 0 #endif #define NUMB_IP "64.251.22.149" #define NUMB_PORT 3478 #define NUMB_USER "youness.alaoui@collabora.co.uk" #define NUMB_PASS "badger" #define TSORG_IP "127.0.0.1" #define TSORG_PORT 3478 #define TSORG_USER "toto" #define TSORG_PASS "password" #if USE_TURN_SERVER_ORG #define TURN_IP TSORG_IP #define TURN_PORT TSORG_PORT #define TURN_USER TSORG_USER #define TURN_PASS TSORG_PASS #define TURN_USER2 TSORG_USER #define TURN_PASS2 TSORG_PASS #define TURN_TYPE NICE_RELAY_TYPE_TURN_TCP #else #define TURN_IP NUMB_IP #define TURN_PORT NUMB_PORT #define TURN_USER NUMB_USER #define TURN_PASS NUMB_PASS #define TURN_USER2 NUMB_USER #define TURN_PASS2 NUMB_PASS #define TURN_TYPE NICE_RELAY_TYPE_TURN_UDP #endif #endif static NiceComponentState global_lagent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST }; static NiceComponentState global_ragent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST }; static guint global_components_ready = 0; static guint global_components_ready_exit = 0; static guint global_components_failed = 0; static guint global_components_failed_exit = 0; static GMainLoop *global_mainloop = NULL; static gboolean global_lagent_gathering_done = FALSE; static gboolean global_ragent_gathering_done = FALSE; static gboolean global_lagent_ibr_received = FALSE; static gboolean global_ragent_ibr_received = FALSE; static int global_lagent_cands = 0; static int global_ragent_cands = 0; static gint global_ragent_read = 0; static guint global_exit_when_ibr_received = 0; static void priv_print_global_status (void) { g_debug ("\tgathering_done=%d", global_lagent_gathering_done && global_ragent_gathering_done); g_debug ("\tlstate[rtp]=%d [rtcp]=%d", global_lagent_state[0], global_lagent_state[1]); g_debug ("\trstate[rtp]=%d [rtcp]=%d", global_ragent_state[0], global_ragent_state[1]); g_debug ("\tL cands=%d R cands=%d", global_lagent_cands, global_ragent_cands); } static gboolean timer_cb (gpointer pointer) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, pointer); /* signal status via a global variable */ /* note: should not be reached, abort */ g_error ("ERROR: test has got stuck, aborting..."); return FALSE; } static void cb_writable (NiceAgent*agent, guint stream_id, guint component_id, gpointer user_data) { guint *ls_id = user_data; if (stream_id == *ls_id && component_id == 1) { g_debug ("Transport is now writable, stopping mainloop"); *ls_id = 0; } } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, user_data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)buf; /* * Lets ignore stun packets that got through */ if (len < 8) return; if (strncmp ("12345678", buf, 8)) return; if (component_id == 2) return; if (GPOINTER_TO_UINT (user_data) == 2) { g_debug ("right agent received %d bytes, stopping mainloop", len); global_ragent_read = len; g_main_loop_quit (global_mainloop); } } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) global_lagent_gathering_done = TRUE; else if (GPOINTER_TO_UINT (data) == 2) global_ragent_gathering_done = TRUE; if (global_lagent_gathering_done && global_ragent_gathering_done) g_main_loop_quit (global_mainloop); /* XXX: dear compiler, these are for you: */ (void)agent; } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { gboolean ready_to_connected = FALSE; g_debug ("test-fullmode:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) { if (global_lagent_state[component_id - 1] == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_lagent_state[component_id - 1] = state; } else if (GPOINTER_TO_UINT (data) == 2) { if (global_ragent_state[component_id - 1] == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_ragent_state[component_id - 1] = state; } if (state == NICE_COMPONENT_STATE_READY) global_components_ready++; else if (state == NICE_COMPONENT_STATE_CONNECTED && ready_to_connected) global_components_ready--; if (state == NICE_COMPONENT_STATE_FAILED) global_components_failed++; g_debug ("test-fullmode: checks READY/EXIT-AT %u/%u.", global_components_ready, global_components_ready_exit); g_debug ("test-fullmode: checks FAILED/EXIT-AT %u/%u.", global_components_failed, global_components_failed_exit); /* signal status via a global variable */ if (global_components_ready == global_components_ready_exit && global_components_failed == global_components_failed_exit) { g_debug ("Components ready/failed achieved. Stopping mailoop"); g_main_loop_quit (global_mainloop); return; } #if 0 /* signal status via a global variable */ if (global_components_failed == global_components_failed_exit) { g_main_loop_quit (global_mainloop); return; } #endif /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) ++global_lagent_cands; else if (GPOINTER_TO_UINT (data) == 2) ++global_ragent_cands; /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)lfoundation; (void)rfoundation; } static void cb_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer data) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; (void)foundation; } static void cb_initial_binding_request_received(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) global_lagent_ibr_received = TRUE; else if (GPOINTER_TO_UINT (data) == 2) global_ragent_ibr_received = TRUE; if (global_exit_when_ibr_received) { g_debug ("Received initial binding request. Stopping mailoop"); g_main_loop_quit (global_mainloop); } /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; } static void set_candidates (NiceAgent *from, guint from_stream, NiceAgent *to, guint to_stream, guint component, gboolean remove_non_relay) { GSList *cands = NULL, *i; cands = nice_agent_get_local_candidates (from, from_stream, component); if (remove_non_relay) { restart: for (i = cands; i; i = i->next) { NiceCandidate *cand = i->data; if (cand->type != NICE_CANDIDATE_TYPE_RELAYED) { cands = g_slist_remove (cands, cand); nice_candidate_free (cand); goto restart; } } } nice_agent_set_remote_candidates (to, to_stream, component, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } static void set_credentials (NiceAgent *lagent, guint lstream, NiceAgent *ragent, guint rstream) { gchar *ufrag = NULL, *password = NULL; nice_agent_get_local_credentials(lagent, lstream, &ufrag, &password); nice_agent_set_remote_credentials (ragent, rstream, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials(ragent, rstream, &ufrag, &password); nice_agent_set_remote_credentials (lagent, lstream, ufrag, password); g_free (ufrag); g_free (password); } static int run_full_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed) { guint ls_id, rs_id; gint ret; /* XXX: dear compiler, this is for you */ (void)baseaddr; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = ready; global_components_failed = 0; global_components_failed_exit = failed; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_lagent_cands = global_ragent_cands = 0; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); #if USE_TURN nice_agent_set_relay_info(lagent, ls_id, 1, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); nice_agent_set_relay_info(lagent, ls_id, 2, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); nice_agent_set_relay_info(ragent, rs_id, 1, TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE); nice_agent_set_relay_info(ragent, rs_id, 2, TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE); #endif /* Gather candidates and test nice_agent_set_port_range */ nice_agent_set_port_range (lagent, ls_id, 1, 10000, 10000); nice_agent_set_port_range (lagent, ls_id, 2, 10001, 10001); nice_agent_set_port_range (ragent, rs_id, 1, 12345, 12345); nice_agent_set_port_range (ragent, rs_id, 2, 10000, 10001); g_assert (nice_agent_gather_candidates (lagent, ls_id) == TRUE); g_assert (nice_agent_gather_candidates (ragent, rs_id) == FALSE); g_assert (nice_agent_get_local_candidates (ragent, rs_id, 1) == NULL); g_assert (nice_agent_get_local_candidates (ragent, rs_id, 2) == NULL); nice_agent_set_port_range (ragent, rs_id, 2, 10000, 10002); g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE); #if USE_LOOPBACK { GSList *cands = NULL, *i; NiceCandidate *cand = NULL; cands = nice_agent_get_local_candidates (lagent, ls_id, 1); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 10000); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); cands = nice_agent_get_local_candidates (lagent, ls_id, 2); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 10001); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); cands = nice_agent_get_local_candidates (ragent, rs_id, 1); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 12345); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); cands = nice_agent_get_local_candidates (ragent, rs_id, 2); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 10002); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } #endif /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } set_credentials (lagent, ls_id, ragent, rs_id); /* step: pass the remote candidates to agents */ set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, USE_TURN); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, USE_TURN); g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ g_main_loop_run (global_mainloop); /* note: verify that STUN binding requests were sent */ g_assert (global_lagent_ibr_received == TRUE); g_assert (global_ragent_ibr_received == TRUE); /* note: test payload send and receive */ global_ragent_read = 0; ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); if (ret == -1) { gboolean reliable = FALSE; g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL); g_debug ("Sending data returned -1 in %s mode", reliable?"Reliable":"Non-reliable"); if (reliable) { gulong signal_handler; guint ls_id_copy = ls_id; signal_handler = g_signal_connect (G_OBJECT (lagent), "reliable-transport-writable", G_CALLBACK (cb_writable), &ls_id_copy); g_debug ("Running mainloop until transport is writable"); while (ls_id_copy == ls_id) g_main_context_iteration (NULL, TRUE); g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler); ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); } } g_debug ("Sent %d bytes", ret); g_assert (ret == 16); while (global_ragent_read != 16) g_main_context_iteration (NULL, TRUE); g_assert (global_ragent_read == 16); g_debug ("test-fullmode: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); return 0; } /* * Simulate the case where answer to the offer is delayed and * some STUN connectivity checks reach the offering party * before it gets the remote SDP information. */ static int run_full_test_delayed_answer (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed) { guint ls_id, rs_id; gint ret; /* XXX: dear compiler, this is for you */ (void)baseaddr; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = ready; global_components_failed = 0; global_components_failed_exit = failed; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_exit_when_ibr_received = 1; global_lagent_cands = global_ragent_cands = 0; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); /* We don't try this with TURN because as long as both agents don't have the remote candidates, they won't be able to create the permission on the TURN server, so the connchecks will never go through */ nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } set_credentials (lagent, ls_id, ragent, rs_id); /* step: set remote candidates for agent R (answering party) */ /* We have to disable TURN for this test because with the delayed answer, we can't create turn permissions, so we won't receive any connchecks */ set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, FALSE); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, FALSE); g_debug ("test-fullmode: Set properties, next running mainloop until first check is received..."); /* step: run the mainloop until first connectivity check receveid */ g_main_loop_run (global_mainloop); global_exit_when_ibr_received = 0; /* note: verify that STUN binding requests were sent */ g_assert (global_lagent_ibr_received == TRUE); g_debug ("test-fullmode: Delayed answer received, continuing processing.."); /* step: pass remove candidates to agent L (offering party) */ set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, FALSE); set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, FALSE); g_debug ("test-fullmode: Running mainloop until connectivity checks succeeed."); g_main_loop_run (global_mainloop); g_assert (global_ragent_ibr_received == TRUE); g_assert (global_components_failed == 0); /* note: test payload send and receive */ global_ragent_read = 0; ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); if (ret == -1) { gboolean reliable = FALSE; g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL); if (reliable) { gulong signal_handler; guint ls_id_copy = ls_id; signal_handler = g_signal_connect (G_OBJECT (lagent), "reliable-transport-writable", G_CALLBACK (cb_writable), &ls_id_copy); g_debug ("Running mainloop until transport is writable"); while (ls_id_copy == ls_id) g_main_context_iteration (NULL, TRUE); g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler); ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); } } global_ragent_read = 0; g_assert (ret == 16); g_main_loop_run (global_mainloop); g_assert (global_ragent_read == 16); g_debug ("test-fullmode: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); return 0; } static int run_full_test_wrong_password (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr) { guint ls_id, rs_id; /* XXX: dear compiler, this is for you */ (void)baseaddr; global_components_ready = 0; global_components_ready_exit = 0; global_components_failed = 0; global_components_failed_exit = 2; global_lagent_state[0] = global_lagent_state[1] = global_ragent_state[0] = global_ragent_state[1] = NICE_COMPONENT_STATE_LAST; global_lagent_gathering_done = global_ragent_gathering_done = FALSE; global_lagent_cands = global_ragent_cands = 0; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with one component, to each agent */ ls_id = nice_agent_add_stream (lagent, 1); rs_id = nice_agent_add_stream (ragent, 1); g_assert (ls_id > 0); g_assert (rs_id > 0); #if USE_TURN nice_agent_set_relay_info(lagent, ls_id, 1, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); nice_agent_set_relay_info(ragent, rs_id, 1, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); #endif nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } g_debug ("test-fullmode: Got local candidates..."); set_credentials (lagent, ls_id, ragent, rs_id); nice_agent_set_remote_credentials (ragent, rs_id, "wrong", "password"); nice_agent_set_remote_credentials (lagent, ls_id, "wrong2", "password2"); /* step: pass the remote candidates to agents */ set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ g_main_loop_run (global_mainloop); /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 0); g_assert (global_ragent_cands == 0); g_debug ("test-fullmode: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); return 0; } static int run_full_test_control_conflict (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, gboolean role) { guint ls_id, rs_id; /* XXX: dear compiler, this is for you */ (void)baseaddr; global_components_ready = 0; global_components_ready_exit = 2; global_components_failed = 0; global_components_failed_exit = 0; global_lagent_gathering_done = global_ragent_gathering_done = FALSE; global_lagent_cands = global_ragent_cands = 0; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; g_object_set (G_OBJECT (lagent), "controlling-mode", role, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", role, NULL); /* step: add one stream, with one component, to each agent */ ls_id = nice_agent_add_stream (lagent, 1); rs_id = nice_agent_add_stream (ragent, 1); g_assert (ls_id > 0); g_assert (rs_id > 0); #if USE_TURN nice_agent_set_relay_info(lagent, ls_id, 1, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); nice_agent_set_relay_info(ragent, rs_id, 1, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); #endif nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } g_debug ("test-fullmode: Got local candidates..."); set_credentials (lagent, ls_id, ragent, rs_id); /* step: pass the remote candidates to agents */ set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ g_main_loop_run (global_mainloop); /* When using TURN, we get peer reflexive candidates for the host cands that we removed so we can get another new_selected_pair signal later depending on timing/racing, we could double (or not) the amount we expected */ #if !(USE_TURN) /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 1); g_assert (global_ragent_cands == 1); #endif g_debug ("test-fullmode: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); return 0; } int main (void) { NiceAgent *lagent, *ragent; /* agent's L and R */ NiceAddress baseaddr; int result; guint timer_id; const char *stun_server = NULL, *stun_server_port = NULL; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif global_mainloop = g_main_loop_new (NULL, FALSE); /* Note: impl limits ... * - no multi-stream support * - no IPv6 support */ /* step: create the agents L and R */ #if USE_RELIABLE lagent = nice_agent_new_reliable (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); ragent = nice_agent_new_reliable (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); #else lagent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); ragent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); #endif g_object_set (G_OBJECT (lagent), "ice-tcp", FALSE, NULL); g_object_set (G_OBJECT (ragent), "ice-tcp", FALSE, NULL); nice_agent_set_software (lagent, "Test-fullmode, Left Agent"); nice_agent_set_software (ragent, "Test-fullmode, Right Agent"); /* step: add a timer to catch state changes triggered by signals */ #if USE_TURN timer_id = g_timeout_add (300000, timer_cb, NULL); #else timer_id = g_timeout_add (30000, timer_cb, NULL); #endif /* step: specify which local interface to use */ #if USE_LOOPBACK if (!nice_address_set_from_string (&baseaddr, "127.0.0.1")) g_assert_not_reached (); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); #endif g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (2)); stun_server = getenv ("NICE_STUN_SERVER"); stun_server_port = getenv ("NICE_STUN_SERVER_PORT"); if (stun_server) { g_object_set (G_OBJECT (lagent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (lagent), "stun-server-port", atoi (stun_server_port), NULL); g_object_set (G_OBJECT (ragent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (ragent), "stun-server-port", atoi (stun_server_port), NULL); } g_object_set (G_OBJECT (lagent), "upnp", USE_UPNP, NULL); g_object_set (G_OBJECT (lagent), "proxy-ip", PROXY_IP, NULL); g_object_set (G_OBJECT (lagent), "proxy-port", PROXY_PORT, NULL); g_object_set (G_OBJECT (lagent), "proxy-type", PROXY_TYPE, NULL); g_object_set (G_OBJECT (lagent), "proxy-username", PROXY_USERNAME, NULL); g_object_set (G_OBJECT (lagent), "proxy-password", PROXY_PASSWORD, NULL); g_object_set (G_OBJECT (ragent), "upnp", USE_UPNP, NULL); g_object_set (G_OBJECT (ragent), "proxy-ip", PROXY_IP, NULL); g_object_set (G_OBJECT (ragent), "proxy-port", PROXY_PORT, NULL); g_object_set (G_OBJECT (ragent), "proxy-type", PROXY_TYPE, NULL); g_object_set (G_OBJECT (ragent), "proxy-username", PROXY_USERNAME, NULL); g_object_set (G_OBJECT (ragent), "proxy-password", PROXY_PASSWORD, NULL); /* step: test setter/getter functions for properties */ { guint max_checks = 0; gchar *string = NULL; guint port = 0; gboolean mode = FALSE; g_object_get (G_OBJECT (lagent), "stun-server", &string, NULL); g_assert (stun_server == NULL || strcmp (string, stun_server) == 0); g_free (string); g_object_get (G_OBJECT (lagent), "stun-server-port", &port, NULL); g_assert (stun_server_port == NULL || port == (guint)atoi (stun_server_port)); g_object_get (G_OBJECT (lagent), "proxy-ip", &string, NULL); g_assert (strcmp (string, PROXY_IP) == 0); g_free (string); g_object_get (G_OBJECT (lagent), "proxy-port", &port, NULL); g_assert (port == PROXY_PORT); g_object_get (G_OBJECT (lagent), "controlling-mode", &mode, NULL); g_assert (mode == TRUE); g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 300, NULL); g_object_get (G_OBJECT (lagent), "max-connectivity-checks", &max_checks, NULL); g_assert (max_checks == 300); } /* step: run test the first time */ g_debug ("test-fullmode: TEST STARTS / running test for the 1st time"); result = run_full_test (lagent, ragent, &baseaddr, 4 ,0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* When using TURN, we get peer reflexive candidates for the host cands that we removed so we can get another new_selected_pair signal later depending on timing/racing, we could double (or not) the amount we expected */ #if !(USE_TURN) /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 2); g_assert (global_ragent_cands == 2); #endif /* step: run test again without unref'ing agents */ g_debug ("test-fullmode: TEST STARTS / running test for the 2nd time"); result = run_full_test (lagent, ragent, &baseaddr, 4, 0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* When using TURN, we get peer reflexive candidates for the host cands that we removed so we can get another new_selected_pair signal later depending on timing/racing, we could double (or not) the amount we expected */ #if !(USE_TURN) /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 2); g_assert (global_ragent_cands == 2); #endif /* step: run test simulating delayed SDP answer */ g_debug ("test-fullmode: TEST STARTS / delayed SDP answer"); result = run_full_test_delayed_answer (lagent, ragent, &baseaddr, 4, 0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* note: verify that correct number of local candidates were reported */ /* When using TURN, we get peer reflexive candidates for the host cands that we removed so we can get another new_selected_pair signal later depending on timing/racing, we could double (or not) the amount we expected */ #if !(USE_TURN) g_assert (global_lagent_cands == 2); g_assert (global_ragent_cands == 2); #endif #if TEST_GOOGLE return result; #endif /* run test with incorrect credentials (make sure process fails) */ g_debug ("test-fullmode: TEST STARTS / incorrect credentials"); result = run_full_test_wrong_password (lagent, ragent, &baseaddr); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_LAST); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_FAILED); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_LAST); /* The max connectivity checks test can't be run with TURN because we'll have 3 local candidates instead of 1 and the checks will be random, so we can't predict how many will fail/succeed */ #if USE_TURN == 0 /* step: run test with a hard limit for connecitivity checks */ g_debug ("test-fullmode: TEST STARTS / max connectivity checks"); g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 1, NULL); g_object_set (G_OBJECT (ragent), "max-connectivity-checks", 1, NULL); result = run_full_test (lagent, ragent, &baseaddr, 2, 2); priv_print_global_status (); g_assert (result == 0); /* should FAIL as agent L can't send any checks: */ g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED || global_lagent_state[1] == NICE_COMPONENT_STATE_FAILED); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED || global_lagent_state[1] == NICE_COMPONENT_STATE_FAILED); #endif g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 100, NULL); g_object_set (G_OBJECT (ragent), "max-connectivity-checks", 100, NULL); result = run_full_test (lagent, ragent, &baseaddr, 4, 0); priv_print_global_status (); /* should SUCCEED as agent L can send the checks: */ g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_CONNECTED || global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_CONNECTED || global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_CONNECTED || global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_CONNECTED || global_ragent_state[1] == NICE_COMPONENT_STATE_READY); g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 100, NULL); /* run test with a conflict in controlling mode: controlling-controlling */ g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-1"); result = run_full_test_control_conflict (lagent, ragent, &baseaddr, TRUE); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* run test with a conflict in controlling mode: controlled-controlled */ g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-2"); result = run_full_test_control_conflict (lagent, ragent, &baseaddr, FALSE); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); g_object_unref (lagent); g_object_unref (ragent); g_main_loop_unref (global_mainloop); global_mainloop = NULL; g_source_remove (timer_id); #ifdef G_OS_WIN32 WSACleanup(); #endif return result; } libnice-0.1.14/tests/test-priority.c0000664000076400007640000000671413070472665014323 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "agent-priv.h" int main (void) { NiceCandidate *candidate; candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST); nice_address_set_from_string (&candidate->addr, "127.0.0.1"); nice_address_set_from_string (&candidate->base_addr, "127.0.0.1"); /* test 1 */ g_assert_cmpuint (nice_candidate_jingle_priority (candidate), ==, 1000); /* Host UDP */ candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; candidate->component_id = 1; g_assert_cmpuint (nice_candidate_ice_priority (candidate, FALSE, FALSE), ==, 0x780001FF); /* Host UDP reliable */ g_assert_cmpuint (nice_candidate_ice_priority (candidate, TRUE, FALSE), ==, 0x3C0001FF); /* Host tcp-active unreliable */ candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; g_assert_cmpuint (nice_candidate_ice_priority (candidate, FALSE, FALSE) & 0xFFE000FF, ==, 0x3C8000FF); /* Host tcp-active reliable */ candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; /* Host tcp-active reliable */ g_assert_cmpuint (nice_candidate_ice_priority (candidate, TRUE, FALSE) & 0xFFE000FF, ==, 0x788000FF); /* srv-reflexive tcp-active reliable */ candidate->type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; g_assert_cmpuint (nice_candidate_ice_priority (candidate, TRUE, FALSE) & 0xFFE000FF, ==, 0x648000FF); /* nat-assisted srv-reflexive tcp-active reliable */ g_assert_cmpuint (nice_candidate_ice_priority (candidate, TRUE, TRUE) & 0xFFE000FF, ==, 0x698000FF); nice_candidate_free (candidate); /* test 2 */ /* 2^32*MIN(O,A) + 2*MAX(O,A) + (O>A?1:0) = 2^32*1 + 2*5000 + 0 = 4294977296 */ g_assert_cmpuint (nice_candidate_pair_priority (1,5000), ==, 4294977296LL); /* 2^32*1 + 2*5000 + 1 = 4294977297 */ g_assert_cmpuint (nice_candidate_pair_priority (5000, 1), ==, 4294977297LL); return 0; } libnice-0.1.14/tests/test-pseudotcp-fin.c0000664000076400007640000011111512724403337015205 00000000000000/* * This file is part of the Nice GLib ICE library. * * © 2014, 2015 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include "pseudotcp.h" typedef struct { PseudoTcpSocket *left; /* owned */ PseudoTcpSocket *right; /* owned */ guint32 left_current_time; guint32 right_current_time; /* Data sent and received by each socket. */ GQueue/**/ *left_sent; /* owned */ GQueue/**/ *right_sent; /* owned */ } Data; /* NOTE: Must match the on-the-wire flag values from pseudotcp.c. */ typedef enum { FLAG_NONE = 0, FLAG_FIN = 1 << 0, FLAG_SYN = 1 << 1, FLAG_RST = 1 << 2, } SegmentFlags; typedef void (*TestFunc) (Data *data, const void *next_funcs); static void data_clear (Data *data) { if (data->left != NULL) g_object_unref (data->left); if (data->right != NULL) g_object_unref (data->right); if (data->left_sent != NULL) g_queue_free_full (data->left_sent, (GDestroyNotify) g_bytes_unref); if (data->right_sent != NULL) g_queue_free_full (data->right_sent, (GDestroyNotify) g_bytes_unref); } static gchar * segment_flags_to_string (SegmentFlags flags) { GString *str = g_string_new (NULL); if (flags & FLAG_SYN) g_string_append (str, "SYN,"); if (flags & FLAG_FIN) g_string_append (str, "FIN,"); if (flags & FLAG_RST) g_string_append (str, "RST,"); /* Strip the trailing comma. */ if (str->len > 0) g_string_truncate (str, str->len - 1); if (str->len == 0) g_string_append (str, "0"); return g_string_free (str, FALSE); } static gchar * segment_to_string (guint32 seq, guint32 ack, SegmentFlags flags) { gchar *ctl, *out; ctl = segment_flags_to_string (flags); out = g_strdup_printf ("", seq, ack, ctl); g_free (ctl); return out; } static gchar * segment_bytes_to_string (const guint8 *bytes) { union { const guint8 *u8; const guint32 *u32; } b; guint32 seq, ack; guint8 flags; b.u8 = bytes; seq = ntohl (b.u32[1]); ack = ntohl (b.u32[2]); flags = b.u8[13]; return segment_to_string (seq, ack, flags); } static void opened (PseudoTcpSocket *sock, gpointer data) { g_debug ("Socket %p opened", sock); } static void readable (PseudoTcpSocket *sock, gpointer data) { g_debug ("Socket %p readable", sock); } static void writable (PseudoTcpSocket *sock, gpointer data) { g_debug ("Socket %p writeable", sock); } static void closed (PseudoTcpSocket *sock, guint32 err, gpointer data) { g_debug ("Socket %p closed: %s", sock, strerror (err)); } static PseudoTcpWriteResult write_packet (PseudoTcpSocket *sock, const gchar *buffer, guint32 len, gpointer user_data) { Data *data = user_data; gchar *str; /* owned */ GQueue/**/ *queue; /* unowned */ GBytes *segment; /* owned */ /* Debug output. */ str = segment_bytes_to_string ((const guint8 *) buffer); g_debug ("%p sent: %s", sock, str); g_free (str); /* One of the sockets has outputted a packet. */ if (sock == data->left) queue = data->left_sent; else if (sock == data->right) queue = data->right_sent; else g_assert_not_reached (); segment = g_bytes_new (buffer, len); g_queue_push_tail (queue, segment); return WR_SUCCESS; } static void create_sockets (Data *data, gboolean support_fin_ack) { PseudoTcpCallbacks cbs = { data, opened, readable, writable, closed, write_packet }; data->left = g_object_new (PSEUDO_TCP_SOCKET_TYPE, "conversation", 0, "callbacks", &cbs, "support-fin-ack", support_fin_ack, NULL); data->right = g_object_new (PSEUDO_TCP_SOCKET_TYPE, "conversation", 0, "callbacks", &cbs, "support-fin-ack", support_fin_ack, NULL); g_debug ("Left: %p, right: %p", data->left, data->right); /* Control the socket clocks precisely. */ pseudo_tcp_socket_set_time (data->left, 1); pseudo_tcp_socket_set_time (data->right, 1); /* Sanity check the socket state. */ g_assert_cmpint (pseudo_tcp_socket_send (data->left, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data->left), ==, ENOTCONN); g_assert_cmpint (pseudo_tcp_socket_send (data->right, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data->right), ==, ENOTCONN); data->left_sent = g_queue_new (); data->right_sent = g_queue_new (); } static void expect_segment (PseudoTcpSocket *socket, GQueue/**/ *queue, guint32 seq, guint32 ack, guint32 len, SegmentFlags flags) { GBytes *bytes; /* unowned */ union { const guint8 *u8; const guint32 *u32; } b; gsize size; gchar *str; str = segment_to_string (seq, ack, flags); g_debug ("%p expect: %s", socket, str); g_free (str); /* Grab the segment. */ bytes = g_queue_peek_head (queue); g_assert (bytes != NULL); b.u8 = g_bytes_get_data (bytes, &size); g_assert_cmpuint (size, >=, 24); /* minimum packet size */ g_assert_cmpuint (size - 24, ==, len); /* Check the segment’s fields. */ g_assert_cmpuint (ntohl (b.u32[1]), ==, seq); g_assert_cmpuint (ntohl (b.u32[2]), ==, ack); g_assert_cmpuint (b.u8[13], ==, flags); } static void expect_syn_sent (Data *data) { expect_segment (data->left, data->left_sent, 0, 0, 7, FLAG_SYN); } static void expect_syn_received (Data *data) { expect_segment (data->right, data->right_sent, 0, 7, 7, FLAG_SYN); } static void assert_empty_queues (Data *data) { g_assert_cmpuint (g_queue_get_length (data->left_sent), ==, 0); g_assert_cmpuint (g_queue_get_length (data->right_sent), ==, 0); } /* Return whether the socket accepted the packet. */ static gboolean forward_segment (GQueue/**/ *from, PseudoTcpSocket *to) { GBytes *segment; /* owned */ const guint8 *b; gsize size; gboolean retval; segment = g_queue_pop_head (from); g_assert (segment != NULL); b = g_bytes_get_data (segment, &size); retval = pseudo_tcp_socket_notify_packet (to, (const gchar *) b, size); g_bytes_unref (segment); return retval; } static void forward_segment_ltr (Data *data) { g_assert (forward_segment (data->left_sent, data->right)); } static void forward_segment_rtl (Data *data) { g_assert (forward_segment (data->right_sent, data->left)); } static void duplicate_segment (GQueue/**/ *queue) { GBytes *segment; /* unowned */ segment = g_queue_peek_head (queue); g_assert (segment != NULL); g_queue_push_head (queue, g_bytes_ref (segment)); } static void drop_segment (PseudoTcpSocket *socket, GQueue/**/ *queue) { GBytes *segment; /* owned */ gchar *str; segment = g_queue_pop_head (queue); g_assert (segment != NULL); str = segment_bytes_to_string (g_bytes_get_data (segment, NULL)); g_debug ("%p drop: %s", socket, str); g_free (str); g_bytes_unref (segment); } /* Swap the order of the head-most two segments in the @queue. */ static void reorder_segments (PseudoTcpSocket *socket, GQueue/**/ *queue) { GBytes *segment1, *segment2; /* unowned */ gchar *str; segment1 = g_queue_pop_head (queue); g_assert (segment1 != NULL); segment2 = g_queue_pop_head (queue); g_assert (segment2 != NULL); str = segment_bytes_to_string (g_bytes_get_data (segment1, NULL)); g_debug ("%p reorder: %s", socket, str); g_free (str); str = segment_bytes_to_string (g_bytes_get_data (segment2, NULL)); g_debug ("%p after: %s", socket, str); g_free (str); g_queue_push_head (queue, segment1); g_queue_push_head (queue, segment2); } static void expect_socket_state (PseudoTcpSocket *socket, PseudoTcpState expected_state) { PseudoTcpState state; g_object_get (socket, "state", &state, NULL); g_assert_cmpuint (state, ==, expected_state); } static void expect_sockets_connected (Data *data) { expect_socket_state (data->left, TCP_ESTABLISHED); expect_socket_state (data->right, TCP_ESTABLISHED); } static void expect_sockets_closed (Data *data) { guint8 buf[100]; expect_socket_state (data->left, TCP_CLOSED); expect_socket_state (data->right, TCP_CLOSED); g_assert_cmpint (pseudo_tcp_socket_send (data->left, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data->left), ==, EPIPE); g_assert_cmpint (pseudo_tcp_socket_recv (data->left, (char *) buf, sizeof (buf)), ==, 0); g_assert_cmpint (pseudo_tcp_socket_send (data->right, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data->right), ==, EPIPE); g_assert_cmpint (pseudo_tcp_socket_recv (data->right, (char *) buf, sizeof (buf)), ==, 0); } static void increment_time (PseudoTcpSocket *socket, guint32 *counter, guint32 increment) { g_debug ("Incrementing %p time by %u from %u to %u", socket, increment, *counter, *counter + increment); *counter = *counter + increment; pseudo_tcp_socket_set_time (socket, *counter); pseudo_tcp_socket_notify_clock (socket); } static void increment_time_both (Data *data, guint32 increment) { increment_time (data->left, &data->left_current_time, increment); increment_time (data->right, &data->right_current_time, increment); } static void expect_fin (PseudoTcpSocket *socket, GQueue/**/ *queue, guint32 seq, guint32 ack) { expect_segment (socket, queue, seq, ack, 0, FLAG_FIN); } static void expect_rst (PseudoTcpSocket *socket, GQueue/**/ *queue, guint32 seq, guint32 ack) { expect_segment (socket, queue, seq, ack, 0, FLAG_RST); } static void expect_ack (PseudoTcpSocket *socket, GQueue/**/ *queue, guint32 seq, guint32 ack) { expect_segment (socket, queue, seq, ack, 0, FLAG_NONE); } static void expect_data (PseudoTcpSocket *socket, GQueue/**/ *queue, guint32 seq, guint32 ack, guint32 len) { expect_segment (socket, queue, seq, ack, len, FLAG_NONE); } static void close_socket (PseudoTcpSocket *socket) { guint8 buf[100]; pseudo_tcp_socket_close (socket, FALSE); g_assert_cmpint (pseudo_tcp_socket_send (socket, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (socket), ==, EPIPE); g_assert_cmpint (pseudo_tcp_socket_recv (socket, (char *) buf, sizeof (buf)), ==, 0); } /* Helper to create a socket pair and perform the SYN handshake. */ static void establish_connection (Data *data) { create_sockets (data, TRUE); pseudo_tcp_socket_connect (data->left); expect_syn_sent (data); forward_segment_ltr (data); expect_syn_received (data); forward_segment_rtl (data); increment_time_both (data, 110); expect_ack (data->left, data->left_sent, 7, 7); forward_segment_ltr (data); expect_sockets_connected (data); assert_empty_queues (data); } /* Helper to close the LHS of a socket pair which has not transmitted any * data (i.e. perform the first half of the FIN handshake). */ static void close_lhs (Data *data) { pseudo_tcp_socket_close (data->left, FALSE); expect_fin (data->left, data->left_sent, 7, 7); forward_segment_ltr (data); expect_ack (data->right, data->right_sent, 7, 8); forward_segment_rtl (data); } /* Helper to close the RHS of a socket pair which has not transmitted any * data (i.e. perform the second half of the FIN handshake). */ static void close_rhs (Data *data) { pseudo_tcp_socket_close (data->right, FALSE); expect_fin (data->right, data->right_sent, 7, 8); forward_segment_rtl (data); increment_time_both (data, 10); /* TIME-WAIT */ expect_ack (data->left, data->left_sent, 8, 8); forward_segment_ltr (data); } /* Check that establishing a connection then immediately closing it works, using * normal handshakes (FIN, ACK, FIN, ACK). See: RFC 793, Figure 13. */ static void pseudotcp_close_normal (void) { Data data = { 0, }; guint8 buf[100]; /* Establish a connection. */ establish_connection (&data); /* Close it. Verify that sending fails. */ close_socket (data.left); expect_fin (data.left, data.left_sent, 7, 7); forward_segment_ltr (&data); expect_ack (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); /* Check the RHS is closed. */ g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0); close_socket (data.right); expect_fin (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); increment_time_both (&data, 10); /* TIME-WAIT */ expect_ack (data.left, data.left_sent, 8, 8); forward_segment_ltr (&data); expect_sockets_closed (&data); data_clear (&data); } /* Check that establishing a connection then immediately closing it works, using * simultaneous handshakes (FIN, FIN, ACK, ACK). See: RFC 793, Figure 14. */ static void pseudotcp_close_simultaneous (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close both sides simultaneously. Verify that sending fails. */ close_socket (data.left); close_socket (data.right); expect_fin (data.left, data.left_sent, 7, 7); expect_fin (data.right, data.right_sent, 7, 7); forward_segment_ltr (&data); forward_segment_rtl (&data); expect_ack (data.left, data.left_sent, 8, 8); expect_ack (data.right, data.right_sent, 8, 8); forward_segment_ltr (&data); forward_segment_rtl (&data); increment_time_both (&data, 10); /* TIME-WAIT */ expect_sockets_closed (&data); data_clear (&data); } /* Check that establishing a connection then immediately closing it works, using * skewed handshakes. The segments are reordered so that the FIN and ACK from * the LHS arrive at the RHS in reverse order. The RHS sees the ACK has a higher * sequence number than the bytes it’s seen so far (as it hasn’t seen the LHS * FIN at that point) and thus emits two sequential ACKs: one from before * receiving the FIN (fast retransmit), and one from after. * See: RFC 793, Figure 14. */ static void pseudotcp_close_skew1 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close both sides simultaneously. Verify that sending fails. */ close_socket (data.left); close_socket (data.right); expect_fin (data.left, data.left_sent, 7, 7); expect_fin (data.right, data.right_sent, 7, 7); forward_segment_rtl (&data); reorder_segments (data.left, data.left_sent); expect_ack (data.left, data.left_sent, 8, 8); forward_segment_ltr (&data); forward_segment_ltr (&data); expect_ack (data.right, data.right_sent, 8, 7); forward_segment_rtl (&data); expect_ack (data.right, data.right_sent, 8, 8); forward_segment_rtl (&data); increment_time_both (&data, 10); /* TIME-WAIT */ expect_sockets_closed (&data); data_clear (&data); } /* Same as pseudotcp_close_skew1() but with the packets reordered in a * different way. */ static void pseudotcp_close_skew2 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close both sides simultaneously. Verify that sending fails. */ close_socket (data.left); close_socket (data.right); expect_fin (data.right, data.right_sent, 7, 7); expect_fin (data.left, data.left_sent, 7, 7); forward_segment_ltr (&data); reorder_segments (data.right, data.right_sent); expect_ack (data.right, data.right_sent, 8, 8); forward_segment_rtl (&data); forward_segment_rtl (&data); expect_ack (data.left, data.left_sent, 8, 7); forward_segment_ltr (&data); expect_ack (data.left, data.left_sent, 8, 8); forward_segment_ltr (&data); increment_time_both (&data, 10); /* TIME-WAIT */ expect_sockets_closed (&data); data_clear (&data); } /* Check that closing a connection recovers from the initial FIN segment being * dropped. Based on: RFC 793, Figure 13. */ static void pseudotcp_close_normal_recovery1 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close the LHS and drop the FIN segment. */ close_socket (data.left); expect_fin (data.left, data.left_sent, 7, 7); drop_segment (data.left, data.left_sent); increment_time_both (&data, 1100); /* retransmit timeout */ expect_fin (data.left, data.left_sent, 7, 7); forward_segment_ltr (&data); expect_ack (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); /* Close the RHS. */ close_rhs (&data); expect_sockets_closed (&data); data_clear (&data); } /* Check that closing a connection recovers from the initial ACK segment being * dropped. Based on: RFC 793, Figure 13. */ static void pseudotcp_close_normal_recovery2 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close the LHS and drop the ACK segment. The LHS should retransmit the * FIN. */ close_socket (data.left); expect_fin (data.left, data.left_sent, 7, 7); forward_segment_ltr (&data); expect_ack (data.right, data.right_sent, 7, 8); drop_segment (data.right, data.right_sent); increment_time_both (&data, 1100); /* retransmit timeout */ expect_fin (data.left, data.left_sent, 7, 7); forward_segment_ltr (&data); expect_ack (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); /* Close the RHS. */ close_rhs (&data); expect_sockets_closed (&data); data_clear (&data); } /* Check that closing a connection recovers from the second FIN segment being * dropped. Based on: RFC 793, Figure 13. */ static void pseudotcp_close_normal_recovery3 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close the LHS. */ close_lhs (&data); /* Close the RHS and drop the FIN segment. */ close_socket (data.right); expect_fin (data.right, data.right_sent, 7, 8); drop_segment (data.right, data.right_sent); increment_time_both (&data, 300); /* retransmit timeout */ expect_fin (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); increment_time_both (&data, 10); /* TIME-WAIT */ expect_ack (data.left, data.left_sent, 8, 8); forward_segment_ltr (&data); expect_sockets_closed (&data); data_clear (&data); } /* Check that closing a connection recovers from the second ACK segment being * dropped. Based on: RFC 793, Figure 13. */ static void pseudotcp_close_normal_recovery4 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close the LHS. */ close_lhs (&data); /* Close the RHS and drop the ACK segment. The RHS should retransmit the * FIN. The timers for the two peers are manipulated separately so the LHS * doesn’t exceed its TIME-WAIT while waiting for the retransmit. */ close_socket (data.right); expect_fin (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); expect_ack (data.left, data.left_sent, 8, 8); drop_segment (data.left, data.left_sent); increment_time (data.right, &data.right_current_time, 300); /* retransmit timeout */ expect_fin (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); increment_time (data.left, &data.left_current_time, 10); /* TIME-WAIT */ expect_ack (data.left, data.left_sent, 8, 8); forward_segment_ltr (&data); expect_sockets_closed (&data); data_clear (&data); } /* Check that closing a connection recovers from a data segment being dropped * immediately before the first FIN is sent. Based on: RFC 793, Figure 13. */ static void pseudotcp_close_normal_recovery_data (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Send some data from LHS to RHS, but drop the segment. */ g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, 3); expect_data (data.left, data.left_sent, 7, 7, 3); drop_segment (data.left, data.left_sent); assert_empty_queues(&data); /* Close the LHS. */ g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0); g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.right), ==, 0); close_socket (data.left); expect_socket_state (data.left, TCP_FIN_WAIT_1); expect_fin (data.left, data.left_sent, 10, 7); forward_segment_ltr (&data); expect_socket_state (data.right, TCP_ESTABLISHED); expect_ack (data.right, data.right_sent, 7, 7); forward_segment_rtl (&data); expect_socket_state (data.left, TCP_FIN_WAIT_1); assert_empty_queues(&data); /* Close the RHS. */ close_socket (data.right); expect_socket_state (data.right, TCP_FIN_WAIT_1); expect_fin (data.right, data.right_sent, 7, 7); forward_segment_rtl (&data); expect_socket_state (data.left, TCP_CLOSING); expect_ack (data.left, data.left_sent, 11, 8); forward_segment_ltr (&data); expect_socket_state (data.right, TCP_FIN_WAIT_2); expect_data (data.right, data.right_sent, 8, 7, 0); forward_segment_rtl (&data); expect_socket_state (data.left, TCP_CLOSING); expect_data (data.left, data.left_sent, 7, 8, 3); forward_segment_ltr (&data); expect_socket_state (data.right, TCP_TIME_WAIT); increment_time_both (&data, 100); /* Delayed ACK */ expect_ack (data.right, data.right_sent, 8, 11); forward_segment_rtl (&data); expect_socket_state (data.left, TCP_TIME_WAIT); increment_time_both (&data, 10); /* TIME-WAIT */ expect_sockets_closed (&data); data_clear (&data); } /* Check that if both FIN segments from a simultaneous FIN handshake are * dropped, the handshake recovers and completes successfully. * See: RFC 793, Figure 14. */ static void pseudotcp_close_simultaneous_recovery1 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close both sides simultaneously and drop the FINs. */ close_socket (data.left); close_socket (data.right); expect_fin (data.left, data.left_sent, 7, 7); expect_fin (data.right, data.right_sent, 7, 7); drop_segment (data.left, data.left_sent); drop_segment (data.right, data.right_sent); increment_time_both (&data, 1200); /* retransmit timeout */ expect_fin (data.left, data.left_sent, 7, 7); expect_fin (data.right, data.right_sent, 7, 7); forward_segment_ltr (&data); forward_segment_rtl (&data); expect_ack (data.left, data.left_sent, 8, 8); expect_ack (data.right, data.right_sent, 8, 8); forward_segment_ltr (&data); forward_segment_rtl (&data); increment_time_both (&data, 10); /* TIME-WAIT */ expect_sockets_closed (&data); data_clear (&data); } /* Check that if both ACK segments from a simultaneous FIN handshake are * dropped, the handshake recovers and completes successfully. * See: RFC 793, Figure 14. */ static void pseudotcp_close_simultaneous_recovery2 (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close both sides simultaneously and forward the FINs. */ close_socket (data.left); close_socket (data.right); expect_fin (data.left, data.left_sent, 7, 7); expect_fin (data.right, data.right_sent, 7, 7); forward_segment_ltr (&data); forward_segment_rtl (&data); /* Drop the ACKs. */ expect_ack (data.left, data.left_sent, 8, 8); expect_ack (data.right, data.right_sent, 8, 8); drop_segment (data.left, data.left_sent); drop_segment (data.right, data.right_sent); increment_time_both (&data, 1200); /* retransmit timeout */ expect_fin (data.left, data.left_sent, 7, 8); expect_fin (data.right, data.right_sent, 7, 8); forward_segment_ltr (&data); forward_segment_rtl (&data); expect_ack (data.left, data.left_sent, 8, 8); expect_ack (data.right, data.right_sent, 8, 8); forward_segment_ltr (&data); forward_segment_rtl (&data); increment_time_both (&data, 10); /* TIME-WAIT */ expect_sockets_closed (&data); data_clear (&data); } /* Check that closing a connection ignores a duplicate FIN segment. * Based on: RFC 793, Figure 13. */ static void pseudotcp_close_duplicate_fin (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close the LHS. */ close_lhs (&data); /* Close the RHS and duplicate the FIN segment. */ close_socket (data.right); expect_fin (data.right, data.right_sent, 7, 8); duplicate_segment (data.right_sent); forward_segment_rtl (&data); forward_segment_rtl (&data); increment_time (data.left, &data.left_current_time, 10); /* TIME-WAIT */ expect_ack (data.left, data.left_sent, 8, 8); forward_segment_ltr (&data); expect_sockets_closed (&data); data_clear (&data); } /* Check that closing a connection ignores a duplicate ACK segment. * Based on: RFC 793, Figure 13. */ static void pseudotcp_close_duplicate_ack (void) { Data data = { 0, }; /* Establish a connection. */ establish_connection (&data); /* Close the LHS. */ close_lhs (&data); /* Close the RHS and duplicate the ACK segment. The RHS should reject the * duplicate with a RST segment. The LHS should then reject the RST. */ close_socket (data.right); expect_fin (data.right, data.right_sent, 7, 8); forward_segment_rtl (&data); increment_time (data.left, &data.left_current_time, 10); /* TIME-WAIT */ expect_ack (data.left, data.left_sent, 8, 8); duplicate_segment (data.left_sent); forward_segment_ltr (&data); g_assert (!forward_segment (data.left_sent, data.right)); expect_rst (data.right, data.right_sent, 8, 8); g_assert (!forward_segment (data.right_sent, data.left)); expect_sockets_closed (&data); data_clear (&data); } /* Check that forcefully closing a connection by sending a RST segment works. * See: RFC 1122, §4.2.2.13. */ static void pseudotcp_close_rst (void) { Data data = { 0, }; guint8 buf[100]; /* Establish a connection. */ establish_connection (&data); /* Close the LHS. */ pseudo_tcp_socket_close (data.left, TRUE); g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data.left), ==, EPIPE); g_assert_cmpint (pseudo_tcp_socket_recv (data.left, (char *) buf, sizeof (buf)), ==, 0); expect_rst (data.left, data.left_sent, 7, 7); g_assert (!forward_segment (data.left_sent, data.right)); /* Check the RHS is closed. */ g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EPIPE); g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0); expect_sockets_closed (&data); data_clear (&data); } /* Check that an RST is sent if a connection is closed with pending data in the * local receive buffer. See: RFC 1122, §4.2.2.13. */ static void pseudotcp_close_pending_received (void) { Data data = { 0, }; guint8 buf[100]; /* Establish a connection. */ establish_connection (&data); /* Send some data from RHS to LHS. Do *not* read the data from the LHS receive * buffer. */ g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, 3); expect_data (data.right, data.right_sent, 7, 7, 3); forward_segment_rtl (&data); /* Close the LHS. */ g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 3); close_socket (data.left); expect_rst (data.left, data.left_sent, 7, 10); g_assert (!forward_segment (data.left_sent, data.right)); /* Check the RHS is closed. */ g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EPIPE); g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0); expect_sockets_closed (&data); data_clear (&data); } /* Check that an RST is sent if data is received on a socket after close() has * been called. See: RFC 1122, §4.2.2.13. */ static void pseudotcp_close_rst_afterwards (void) { Data data = { 0, }; guint8 buf[100]; /* Establish a connection. */ establish_connection (&data); /* Close the LHS. */ g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0); pseudo_tcp_socket_close (data.left, TRUE); close_socket (data.left); expect_rst (data.left, data.left_sent, 7, 7); drop_segment (data.left, data.left_sent); /* just to get it out of the way */ assert_empty_queues(&data); /* Send some data from RHS to LHS, which should result in an RST. */ g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, 3); expect_data (data.right, data.right_sent, 7, 7, 3); g_assert (!forward_segment (data.right_sent, data.left)); expect_rst (data.left, data.left_sent, 7, 7); g_assert (!forward_segment (data.left_sent, data.right)); /* Check the RHS is closed. */ g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EPIPE); g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0); expect_sockets_closed (&data); data_clear (&data); } /* Check that two pseudo-TCP sockets interact correctly even if FIN–ACK support * is disabled on one of them. */ static void pseudotcp_compatibility (void) { Data data = { 0, }; guint8 buf[100]; guint64 timeout; /* Establish a connection. Note the sequence numbers should start at 4 this * time, rather than the 7 in other tests, because the FIN–ACK option should * not be being sent. */ create_sockets (&data, FALSE); pseudo_tcp_socket_connect (data.left); expect_segment (data.left, data.left_sent, 0, 0, 4, FLAG_SYN); forward_segment_ltr (&data); expect_segment (data.right, data.right_sent, 0, 4, 4, FLAG_SYN); forward_segment_rtl (&data); increment_time_both (&data, 110); expect_ack (data.left, data.left_sent, 4, 4); forward_segment_ltr (&data); expect_sockets_connected (&data); /* Close it. Sending shouldn’t fail. */ pseudo_tcp_socket_close (data.left, FALSE); g_assert (!pseudo_tcp_socket_is_closed (data.left)); g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, 3); g_assert_cmpint (pseudo_tcp_socket_recv (data.left, (char *) buf, sizeof (buf)), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data.left), ==, EWOULDBLOCK); expect_data (data.left, data.left_sent, 4, 4, 3); forward_segment_ltr (&data); increment_time_both (&data, 100); expect_ack (data.right, data.right_sent, 4, 7); forward_segment_rtl (&data); /* Advance the timers; now the LHS should be closed, as the RHS has ACKed all * outstanding data. */ increment_time_both (&data, 50); g_assert (!pseudo_tcp_socket_get_next_clock (data.left, &timeout)); /* Check the RHS can be closed after receiving the data just sent. */ g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 3); g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, -1); g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EWOULDBLOCK); pseudo_tcp_socket_close (data.right, FALSE); g_assert (!pseudo_tcp_socket_get_next_clock (data.right, &timeout)); expect_sockets_closed (&data); data_clear (&data); } /* Check that after receiving a FIN, queued data can still be read */ static void pseudotcp_close_recv_queued (void) { Data data = { 0, }; guint8 buf[100]; /* Establish a connection. */ establish_connection (&data); g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0); g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.right), ==, 0); g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.right), >, 0); g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.left), >, 0); g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, 3); expect_data (data.left, data.left_sent, 7, 7, 3); forward_segment_ltr (&data); increment_time_both (&data, 100); /* Delayed ACK */ expect_ack (data.right, data.right_sent, 7, 10); forward_segment_rtl (&data); close_socket (data.left); expect_fin (data.left, data.left_sent, 10, 7); forward_segment_ltr (&data); expect_socket_state (data.left, TCP_FIN_WAIT_1); expect_socket_state (data.right, TCP_CLOSE_WAIT); g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0); g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.left), ==, 0); expect_ack (data.right, data.right_sent, 7, 11); forward_segment_rtl (&data); expect_socket_state (data.left, TCP_FIN_WAIT_2); g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.right), ==, 3); g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.right), >, 0); /* Check that the data can be read */ g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 3); /* Now the socket should be empty */ g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0); data_clear (&data); } int main (int argc, char *argv[]) { setlocale (LC_ALL, ""); g_test_init (&argc, &argv, NULL); pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE); /* There are four possible scenarios for the FIN handshake, if the possibility * of dropped or duplicated segments is ignored (but reordered segments are * allowed: normal, simultaneous, and two types of skew. * * These can be generated by considering the events happening at a single peer * during connection closure: sending the FIN (SF), receiving a FIN and * sending a FIN-ACK (RF), receiving a FIN-ACK (RA). These have the following * permutations: * • SF, RF, RA * • SF, RA, RF * • RF, SF, RA * Other permutations are disallowed because SF must come before RA. * * The permutations of one peer’s (1) behaviour with a second (2) can then be * considered: * • 1: SF, RF, RA; 2: SF, RF, RA (simultaneous) * • 1: SF, RF, RA; 2: SF, RA, RF (skew 1) * • 1: SF, RF, RA; 2: RF, SF, RA (skew 2) * • 1: SF, RA, RF; 2: RF, SF, RA (normal) * Other permutations are disallowed because SF on one peer must come before * RF on the other; similarly RF on one must come before RA on the other. * * Thus, the following unit tests provably cover all possible scenarios where * segments can be reordered but not dropped or duplicated. */ g_test_add_func ("/pseudotcp/close/normal", pseudotcp_close_normal); g_test_add_func ("/pseudotcp/close/simultaneous", pseudotcp_close_simultaneous); g_test_add_func ("/pseudotcp/close/skew1", pseudotcp_close_skew1); g_test_add_func ("/pseudotcp/close/skew2", pseudotcp_close_skew2); /* An arbitrary (less methodical) selection of unit tests for dropped and * duplicated packets. */ g_test_add_func ("/pseudotcp/close/normal/recovery1", pseudotcp_close_normal_recovery1); g_test_add_func ("/pseudotcp/close/normal/recovery2", pseudotcp_close_normal_recovery2); g_test_add_func ("/pseudotcp/close/normal/recovery3", pseudotcp_close_normal_recovery3); g_test_add_func ("/pseudotcp/close/normal/recovery4", pseudotcp_close_normal_recovery4); g_test_add_func ("/pseudotcp/close/normal/recovery-data", pseudotcp_close_normal_recovery_data); g_test_add_func ("/pseudotcp/close/simultaneous/recovery1", pseudotcp_close_simultaneous_recovery1); g_test_add_func ("/pseudotcp/close/simultaneous/recovery2", pseudotcp_close_simultaneous_recovery2); g_test_add_func ("/pseudotcp/close/duplicate-fin", pseudotcp_close_duplicate_fin); g_test_add_func ("/pseudotcp/close/duplicate-ack", pseudotcp_close_duplicate_ack); g_test_add_func ("/pseudotcp/close/rst", pseudotcp_close_rst); g_test_add_func ("/pseudotcp/close/pending-received", pseudotcp_close_pending_received); g_test_add_func ("/pseudotcp/close/rst-afterwards", pseudotcp_close_rst_afterwards); g_test_add_func ("/pseudotcp/close/recv-queued", pseudotcp_close_recv_queued); g_test_add_func ("/pseudotcp/compatibility", pseudotcp_compatibility); g_test_run (); return 0; } libnice-0.1.14/tests/test-fallback.c0000664000076400007640000005133112661700132014160 00000000000000/* * This file is part of the Nice GLib ICE library. * * Contains a unit test for functionality to fallback to non-ICE * operation if remote party does not support ICE. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "agent-priv.h" /* for testing purposes */ #include #include #ifdef _WIN32 #include #endif static NiceComponentState global_lagent_state = NICE_COMPONENT_STATE_LAST; static NiceComponentState global_ragent_state = NICE_COMPONENT_STATE_LAST; static guint global_components_ready = 0; static guint global_components_ready_exit = 0; static guint global_components_failed = 0; static guint global_components_failed_exit = 0; static GMainLoop *global_mainloop = NULL; static gboolean global_lagent_gathering_done = FALSE; static gboolean global_ragent_gathering_done = FALSE; static gboolean global_lagent_ibr_received = FALSE; static gboolean global_ragent_ibr_received = FALSE; static int global_lagent_cands = 0; static int global_ragent_cands = 0; static gint global_ragent_read = 0; static gint global_ragent_read_exit = 0; static gboolean global_accept_non_data = TRUE; static void priv_print_global_status (void) { g_debug ("\tgathering_done=%d", global_lagent_gathering_done && global_ragent_gathering_done); g_debug ("\tlstate=%d", global_lagent_state); g_debug ("\trstate=%d", global_ragent_state); } static gboolean timer_cb (gpointer pointer) { g_debug ("test-fallback:%s: %p", G_STRFUNC, pointer); /* signal status via a global variable */ /* note: should not be reached, abort */ g_error ("ERROR: test has got stuck, aborting..."); return FALSE; } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { g_debug ("test-fallback:%s: %p", G_STRFUNC, user_data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)buf; /* * Lets ignore stun packets that got through */ if (len != 16 || strncmp ("1234567812345678", buf, 16)) { if (global_accept_non_data) return; else g_error ("Got non-data packet of lenght %u", len); } if ((intptr_t)user_data == 2) { global_ragent_read += len; if (global_ragent_read == global_ragent_read_exit) g_main_loop_quit (global_mainloop); } } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-fallback:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) global_lagent_gathering_done = TRUE; else if ((intptr_t)data == 2) global_ragent_gathering_done = TRUE; if (global_lagent_gathering_done && global_ragent_gathering_done) g_main_loop_quit (global_mainloop); /* XXX: dear compiler, these are for you: */ (void)agent; } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { g_debug ("test-fallback:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) global_lagent_state = state; else if ((intptr_t)data == 2) global_ragent_state = state; if (state == NICE_COMPONENT_STATE_READY) global_components_ready++; if (state == NICE_COMPONENT_STATE_FAILED) global_components_failed++; g_debug ("test-fallback: READY %u exit at %u.", global_components_ready, global_components_ready_exit); /* signal status via a global variable */ if (global_components_ready == global_components_ready_exit) { g_main_loop_quit (global_mainloop); return; } /* signal status via a global variable */ if (global_components_failed == global_components_failed_exit) { g_main_loop_quit (global_mainloop); return; } /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data) { g_debug ("test-fallback:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) ++global_lagent_cands; else if ((intptr_t)data == 2) ++global_ragent_cands; /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)lfoundation; (void)rfoundation; } static void cb_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer data) { g_debug ("test-fallback:%s: %p", G_STRFUNC, data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; (void)foundation; } static void cb_initial_binding_request_received(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-fallback:%s: %p", G_STRFUNC, data); if ((intptr_t)data == 1) global_lagent_ibr_received = TRUE; else if ((intptr_t)data == 2) global_ragent_ibr_received = TRUE; /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; } static void priv_get_local_addr (NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *dstaddr) { GSList *cands, *i; cands = nice_agent_get_local_candidates(agent, stream_id, component_id); for (i = cands; i; i = i->next) { NiceCandidate *cand = i->data; if (cand) { g_assert (dstaddr); *dstaddr = cand->addr; break; } } for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } static int run_fallback_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr) { NiceAddress laddr, raddr, laddr_rtcp, raddr_rtcp; NiceCandidate cdes; GSList *cands; guint ls_id, rs_id; memset (&cdes, 0, sizeof(NiceCandidate)); cdes.priority = 100000; strcpy (cdes.foundation, "1"); cdes.type = NICE_CANDIDATE_TYPE_HOST; cdes.transport = NICE_CANDIDATE_TRANSPORT_UDP; cdes.base_addr = *baseaddr; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = 4; global_components_failed = 0; global_components_failed_exit = 4; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_lagent_cands = global_ragent_cands = 0; global_ragent_read_exit = -1; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-fallback: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } /* step: find out the local candidates of each agent */ priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, &raddr); g_debug ("test-fallback: local RTP port R %u", nice_address_get_port (&raddr)); priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, &laddr); g_debug ("test-fallback: local RTP port L %u", nice_address_get_port (&laddr)); priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, &raddr_rtcp); g_debug ("test-fallback: local RTCP port R %u", nice_address_get_port (&raddr_rtcp)); priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, &laddr_rtcp); g_debug ("test-fallback: local RTCP port L %u", nice_address_get_port (&laddr_rtcp)); /* step: exchange candidate information but not the credentials */ cands = g_slist_append (NULL, &cdes); cdes.component_id = NICE_COMPONENT_TYPE_RTP; cdes.addr = raddr; nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, cands); cdes.addr = laddr; nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, cands); cdes.component_id = NICE_COMPONENT_TYPE_RTCP; cdes.addr = raddr_rtcp; nice_agent_set_remote_candidates (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, cands); cdes.addr = laddr_rtcp; nice_agent_set_remote_candidates (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, cands); /* step: fall back to non-ICE mode on both sides */ g_assert (nice_agent_set_selected_pair (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, "1", "1") == TRUE); g_assert (nice_agent_set_selected_pair (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, "1", "1") == TRUE); g_assert (nice_agent_set_selected_pair (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, "1", "1") == TRUE); g_assert (nice_agent_set_selected_pair (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, "1", "1") == TRUE); g_debug ("test-fallback: Requested for fallback, running mainloop until component state change is completed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ if (global_components_ready < global_components_ready_exit) g_main_loop_run (global_mainloop); /* note: verify that agents are in correct state */ g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY); /* step: next send a packet -> should work even if no ICE processing * has been done */ g_debug ("test-fallback: Sent a payload packet, run mainloop until packet received."); /* step: send a new test packet from L ot R */ global_ragent_read = 0; g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16); global_ragent_read_exit = 16; g_main_loop_run (global_mainloop); /* note: verify that payload was succesfully received */ g_assert (global_ragent_read == 16); g_debug ("test-fallback: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ g_slist_free (cands); nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); g_debug ("test-fallback: test COMPLETED"); return 0; } static int run_safe_fallback_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr) { NiceAddress laddr, raddr, laddr_rtcp, raddr_rtcp; NiceCandidate cdes; guint ls_id, rs_id; memset (&cdes, 0, sizeof(NiceCandidate)); cdes.priority = 100000; strcpy (cdes.foundation, "1"); cdes.type = NICE_CANDIDATE_TYPE_HOST; cdes.transport = NICE_CANDIDATE_TRANSPORT_UDP; cdes.base_addr = *baseaddr; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = 4; global_components_failed = 0; global_components_failed_exit = 4; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_lagent_cands = global_ragent_cands = 0; global_ragent_read_exit = -1; global_accept_non_data = FALSE; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); nice_agent_gather_candidates (lagent, ls_id); nice_agent_gather_candidates (ragent, rs_id); /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)1); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, (gpointer)2); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-fallback: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } /* step: find out the local candidates of each agent */ priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, &raddr); g_debug ("test-fallback: local RTP port R %u", nice_address_get_port (&raddr)); priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, &laddr); g_debug ("test-fallback: local RTP port L %u", nice_address_get_port (&laddr)); priv_get_local_addr (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, &raddr_rtcp); g_debug ("test-fallback: local RTCP port R %u", nice_address_get_port (&raddr_rtcp)); priv_get_local_addr (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, &laddr_rtcp); g_debug ("test-fallback: local RTCP port L %u", nice_address_get_port (&laddr_rtcp)); /* step: exchange candidate information but not the credentials */ cdes.component_id = NICE_COMPONENT_TYPE_RTP; cdes.addr = raddr; g_assert (nice_agent_set_selected_remote_candidate (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, &cdes)); cdes.addr = laddr; g_assert (nice_agent_set_selected_remote_candidate (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, &cdes)); cdes.component_id = NICE_COMPONENT_TYPE_RTCP; cdes.addr = raddr_rtcp; g_assert (nice_agent_set_selected_remote_candidate (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, &cdes)); cdes.addr = laddr_rtcp; g_assert (nice_agent_set_selected_remote_candidate (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, &cdes)); g_debug ("test-fallback: Requested for fallback, running mainloop until component state change is completed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ if (global_components_ready < global_components_ready_exit) g_main_loop_run (global_mainloop); /* note: verify that agents are in correct state */ g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY); /* step: next send a packet -> should work even if no ICE processing * has been done */ g_debug ("test-fallback: Sent a payload packet, run mainloop until packet received."); /* step: send a new test packet from L ot R */ global_ragent_read = 0; g_assert (nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678") == 16); global_ragent_read_exit = 16; g_main_loop_run (global_mainloop); /* note: verify that payload was succesfully received */ g_assert (global_ragent_read == 16); g_debug ("test-fallback: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); g_debug ("test-fallback: test COMPLETED"); return 0; } int main (void) { NiceAgent *lagent, *ragent; /* agent's L and R */ NiceAddress baseaddr; int result; guint timer_id; const char *stun_server = NULL, *stun_server_port = NULL; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif global_mainloop = g_main_loop_new (NULL, FALSE); /* Note: impl limits ... * - no multi-stream support * - no IPv6 support */ /* step: create the agents L and R */ lagent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_RFC5245); ragent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_RFC5245); /* step: add a timer to catch state changes triggered by signals */ timer_id = g_timeout_add (30000, timer_cb, NULL); /* step: specify which local interface to use */ if (!nice_address_set_from_string (&baseaddr, "127.0.0.1")) g_assert_not_reached (); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "new-candidate", G_CALLBACK (cb_new_candidate), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "new-candidate", G_CALLBACK (cb_new_candidate), (gpointer)2); g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), (gpointer)1); g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), (gpointer)2); stun_server = getenv ("NICE_STUN_SERVER"); stun_server_port = getenv ("NICE_STUN_SERVER_PORT"); if (stun_server) { g_object_set (G_OBJECT (lagent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (lagent), "stun-server-port", atoi (stun_server_port), NULL); g_object_set (G_OBJECT (ragent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (ragent), "stun-server-port", atoi (stun_server_port), NULL); } /* step: run test the first time */ g_debug ("test-fallback: TEST STARTS / fallback test"); result = run_fallback_test (lagent, ragent, &baseaddr); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY); /* step: run the safe test without sending any stnu */ g_debug ("test-fallback: TEST STARTS / safe fallback test"); result = run_safe_fallback_test (lagent, ragent, &baseaddr); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state == NICE_COMPONENT_STATE_READY); g_object_unref (lagent); g_object_unref (ragent); g_main_loop_unref (global_mainloop); global_mainloop = NULL; g_source_remove (timer_id); #ifdef G_OS_WIN32 WSACleanup(); #endif return result; } libnice-0.1.14/tests/test-turn.c0000664000076400007640000002730412733101312013407 00000000000000#include #include #include #include #include static NiceComponentState global_lagent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST }; static NiceComponentState global_ragent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST }; static guint global_components_ready = 0; static gboolean global_lagent_gathering_done = FALSE; static gboolean global_ragent_gathering_done = FALSE; static int global_lagent_cands = 0; static int global_ragent_cands = 0; #define TURN_USER "toto" #define TURN_PASS "password" static gboolean timer_cb (gpointer pointer) { g_debug ("test-turn:%s: %p", G_STRFUNC, pointer); /* signal status via a global variable */ /* note: should not be reached, abort */ g_error ("ERROR: test has got stuck, aborting..."); return FALSE; } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, user_data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)buf; /* * Lets ignore stun packets that got through */ if (len < 8) return; if (strncmp ("12345678", buf, 8)) return; if (component_id != 1) return; #if 0 if (GPOINTER_TO_UINT (user_data) == 2) { global_ragent_read += len; } #endif } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-fullmode:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) global_lagent_gathering_done = TRUE; else if (GPOINTER_TO_UINT (data) == 2) global_ragent_gathering_done = TRUE; } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { gboolean ready_to_connected = FALSE; g_debug ("test-fullmode:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) { if (global_lagent_state[component_id - 1] == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_lagent_state[component_id - 1] = state; } else if (GPOINTER_TO_UINT (data) == 2) { if (global_ragent_state[component_id - 1] == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_ragent_state[component_id - 1] = state; } if (state == NICE_COMPONENT_STATE_READY) global_components_ready++; else if (state == NICE_COMPONENT_STATE_CONNECTED && ready_to_connected) global_components_ready--; g_assert (state != NICE_COMPONENT_STATE_FAILED); g_debug ("test-turn: checks READY %u.", global_components_ready); } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data) { g_debug ("test-turn:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) ++global_lagent_cands; else if (GPOINTER_TO_UINT (data) == 2) ++global_ragent_cands; } static void set_candidates (NiceAgent *from, guint from_stream, NiceAgent *to, guint to_stream, guint component, gboolean remove_non_relay, gboolean force_relay) { GSList *cands = NULL, *i; cands = nice_agent_get_local_candidates (from, from_stream, component); if (remove_non_relay) { restart: for (i = cands; i; i = i->next) { NiceCandidate *cand = i->data; if (force_relay) g_assert (cand->type == NICE_CANDIDATE_TYPE_RELAYED); if (cand->type != NICE_CANDIDATE_TYPE_RELAYED) { cands = g_slist_remove (cands, cand); nice_candidate_free (cand); goto restart; } } } nice_agent_set_remote_candidates (to, to_stream, component, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } static void set_credentials (NiceAgent *lagent, guint lstream, NiceAgent *ragent, guint rstream) { gchar *ufrag = NULL, *password = NULL; nice_agent_get_local_credentials(lagent, lstream, &ufrag, &password); nice_agent_set_remote_credentials (ragent, rstream, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials(ragent, rstream, &ufrag, &password); nice_agent_set_remote_credentials (lagent, lstream, ufrag, password); g_free (ufrag); g_free (password); } static void run_test(guint turn_port, gboolean is_ipv6, gboolean ice_udp, gboolean ice_tcp, gboolean force_relay, gboolean remove_non_relay, NiceRelayType turn_type) { NiceAgent *lagent, *ragent; /* agent's L and R */ const gchar *localhost; NiceAddress localaddr; guint ls_id, rs_id; gulong timer_id; if (is_ipv6) localhost = "::1"; else localhost = "127.0.0.1"; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_cands = global_ragent_cands = 0; lagent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); ragent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); g_object_set (G_OBJECT (lagent), "ice-tcp", ice_tcp, "ice-udp", ice_udp, "force-relay", force_relay, NULL); g_object_set (G_OBJECT (ragent), "ice-tcp", ice_tcp, "ice-udp", ice_udp, "force-relay", force_relay, NULL); g_object_set (G_OBJECT (lagent), "upnp", FALSE, NULL); g_object_set (G_OBJECT (ragent), "upnp", FALSE, NULL); nice_agent_set_software (lagent, "Test-turn, Left Agent"); nice_agent_set_software (ragent, "Test-turn, Right Agent"); timer_id = g_timeout_add (30000, timer_cb, NULL); if (!nice_address_set_from_string (&localaddr, localhost)) g_assert_not_reached (); nice_agent_add_local_address (lagent, &localaddr); nice_agent_add_local_address (ragent, &localaddr); g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2)); g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); ls_id = nice_agent_add_stream (lagent, 1); rs_id = nice_agent_add_stream (ragent, 1); g_assert (ls_id > 0); g_assert (rs_id > 0); nice_agent_set_relay_info(lagent, ls_id, 1, localhost, turn_port, TURN_USER, TURN_PASS, turn_type); nice_agent_set_relay_info(ragent, rs_id, 1, localhost, turn_port, TURN_USER, TURN_PASS, turn_type); /* Gather candidates and test nice_agent_set_port_range */ g_assert (nice_agent_gather_candidates (lagent, ls_id) == TRUE); g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_context_default (), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_context_default (), cb_nice_recv, GUINT_TO_POINTER (2)); g_assert (global_lagent_gathering_done == FALSE); g_assert (global_ragent_gathering_done == FALSE); g_debug ("test-turn: Added streams, running context until 'candidate-gathering-done'..."); while (!global_lagent_gathering_done) g_main_context_iteration (NULL, TRUE); g_assert (global_lagent_gathering_done == TRUE); while (!global_ragent_gathering_done) g_main_context_iteration (NULL, TRUE); g_assert (global_ragent_gathering_done == TRUE); set_credentials (lagent, ls_id, ragent, rs_id); set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, remove_non_relay, force_relay); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, remove_non_relay, force_relay); while (global_lagent_state[0] != NICE_COMPONENT_STATE_READY || global_ragent_state[0] != NICE_COMPONENT_STATE_READY) g_main_context_iteration (NULL, TRUE); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); g_source_remove (timer_id); g_clear_object(&lagent); g_clear_object(&ragent); } guint global_turn_port; static void udp_no_force_no_remove_udp (void) { run_test(global_turn_port, FALSE /* is_ipv6 */, TRUE /* ice_udp */, FALSE /* ice_tcp */, FALSE /* force_relay */, FALSE /* remove_non_relay */, NICE_RELAY_TYPE_TURN_UDP); } static void udp_no_force_remove_udp (void) { run_test(global_turn_port, FALSE /* is_ipv6 */, TRUE /* ice_udp */, FALSE /* ice_tcp */, FALSE /* force_relay */, TRUE /* remove_non_relay */, NICE_RELAY_TYPE_TURN_UDP); } static void udp_force_no_remove_udp (void) { run_test(global_turn_port, FALSE /* is_ipv6 */, TRUE /* ice_udp */, FALSE /* ice_tcp */, TRUE /* force_relay */, FALSE /* remove_non_relay */, NICE_RELAY_TYPE_TURN_UDP); } static void udp_no_force_no_remove_tcp (void) { run_test(global_turn_port, FALSE /* is_ipv6 */, TRUE /* ice_udp */, FALSE /* ice_tcp */, FALSE /* force_relay */, FALSE /* remove_non_relay */, NICE_RELAY_TYPE_TURN_TCP); } static void udp_no_force_remove_tcp (void) { run_test(global_turn_port, FALSE /* is_ipv6 */, TRUE /* ice_udp */, FALSE /* ice_tcp */, FALSE /* force_relay */, TRUE /* remove_non_relay */, NICE_RELAY_TYPE_TURN_TCP); } static void udp_force_no_remove_tcp (void) { run_test(global_turn_port, FALSE /* is_ipv6 */, TRUE /* ice_udp */, FALSE /* ice_tcp */, TRUE /* force_relay */, FALSE /* remove_non_relay */, NICE_RELAY_TYPE_TURN_TCP); } int main (int argc, char **argv) { GSubprocess *sp; GError *error = NULL; gchar portstr[10]; int ret; gchar *out_str = NULL; gchar *err_str = NULL; g_test_init (&argc, &argv, NULL); global_turn_port = g_random_int_range (10000, 60000); snprintf(portstr, 9, "%u", global_turn_port); if (g_spawn_command_line_sync ("turnserver --help", &out_str, &err_str, NULL, NULL) && err_str) { if (!strstr(err_str, "--user")) { g_print ("rfc5766-turn-server not installed, skipping turn test\n"); return 0; } } else { g_print ("rfc5766-turn-server not installed, skipping turn test\n"); return 0; } g_free (err_str); g_free (out_str); sp = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, &error, "turnserver", "--user", "toto:0xaae440b3348d50265b63703117c7bfd5", "--realm", "realm", "--listening-port", portstr, NULL); g_test_add_func ("/nice/turn/udp", udp_no_force_no_remove_udp); g_test_add_func ("/nice/turn/udp/remove_non_turn", udp_no_force_remove_udp); g_test_add_func ("/nice/turn/udp/force_relay", udp_force_no_remove_udp); g_test_add_func ("/nice/turn/udp/over-tcp", udp_no_force_no_remove_tcp); g_test_add_func ("/nice/turn/udp/over-tcp/remove_non_turn", udp_no_force_remove_tcp); g_test_add_func ("/nice/turn/udp/over-tcp/force_relay", udp_force_no_remove_tcp); ret = g_test_run (); g_subprocess_force_exit (sp); g_subprocess_wait (sp, NULL, NULL); g_clear_object (&sp); return ret; } libnice-0.1.14/tests/test-io-stream-thread.c0000664000076400007640000001064112661700132015565 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2013 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "test-io-stream-common.h" #include #include #ifndef G_OS_WIN32 #include #endif typedef struct { guint cand_count; guint *other_cand_count; gsize recv_count; gsize *other_recv_count; gsize send_count; gsize *other_send_count; } ThreadData; static void read_thread_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { ThreadData *user_data = data->user_data; for (user_data->recv_count = 0; user_data->recv_count < 10; user_data->recv_count++) { guint8 expected_data[MESSAGE_SIZE]; GError *error = NULL; guint8 buf[MESSAGE_SIZE]; gssize len; /* Block on receiving some data. */ len = g_input_stream_read (input_stream, buf, sizeof (buf), NULL, &error); g_assert_no_error (error); g_assert_cmpint (len, ==, sizeof (buf)); memset (expected_data, user_data->recv_count + '1', sizeof (expected_data)); g_assert (memcmp (buf, expected_data, sizeof (expected_data)) == 0); } check_for_termination (data, &user_data->recv_count, user_data->other_recv_count, &user_data->send_count, 10); } static void new_selected_pair_cb (NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar *rfoundation, TestIOStreamThreadData *data) { ThreadData *user_data = data->user_data; g_atomic_int_inc (&user_data->cand_count); } static void write_thread_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { ThreadData *user_data = data->user_data; guint8 buf[MESSAGE_SIZE]; for (user_data->send_count = 0; user_data->send_count < 10; user_data->send_count++) { GError *error = NULL; memset (buf, user_data->send_count + '1', MESSAGE_SIZE); g_output_stream_write (output_stream, buf, sizeof (buf), NULL, &error); g_assert_no_error (error); } } int main (void) { ThreadData *l_data, *r_data; const TestIOStreamCallbacks callbacks = { read_thread_cb, write_thread_cb, NULL, new_selected_pair_cb, }; #ifdef G_OS_WIN32 WSADATA w; WSAStartup (0x0202, &w); #endif l_data = g_malloc0 (sizeof (ThreadData)); r_data = g_malloc0 (sizeof (ThreadData)); l_data->cand_count = 0; l_data->other_cand_count = &r_data->cand_count; l_data->recv_count = 0; l_data->other_recv_count = &r_data->recv_count; l_data->send_count = 0; l_data->other_send_count = &r_data->send_count; r_data->cand_count = 0; r_data->other_cand_count = &l_data->cand_count; r_data->recv_count = 0; r_data->other_recv_count = &l_data->recv_count; r_data->send_count = 0; r_data->other_send_count = &l_data->send_count; run_io_stream_test (30, TRUE, &callbacks, l_data, NULL, r_data, NULL); /* Verify that correct number of local candidates were reported. */ g_assert (l_data->cand_count == 1); g_assert (r_data->cand_count == 1); g_free (r_data); g_free (l_data); #ifdef G_OS_WIN32 WSACleanup (); #endif return 0; } libnice-0.1.14/tests/test-credentials.c0000664000076400007640000001465212661700132014723 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2015 Rohan Garg * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "agent-priv.h" #include #include #define LEFT_AGENT GINT_TO_POINTER(1) #define RIGHT_AGENT GINT_TO_POINTER(2) #define USE_UPNP 0 static GMainLoop *loop = NULL; static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { g_debug ("test-credentials:%s: %p", G_STRFUNC, user_data); } static void set_credentials(NiceAgent *lagent, NiceAgent *ragent) { gchar *ufrag = NULL, *password = NULL; g_debug ("test-credentials:%s", G_STRFUNC); nice_agent_get_local_credentials (lagent, 1, &ufrag, &password); nice_agent_set_remote_credentials (ragent, 1, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials (ragent, 1, &ufrag, &password); nice_agent_set_remote_credentials (lagent, 1, ufrag, password); g_free (ufrag); g_free (password); } static void swap_candidates(NiceAgent *local, guint local_id, NiceAgent *remote, guint remote_id) { GSList *cands = NULL; g_debug ("test-credentials:%s", G_STRFUNC); cands = nice_agent_get_local_candidates(local, local_id, NICE_COMPONENT_TYPE_RTP); g_assert(nice_agent_set_remote_candidates(remote, remote_id, NICE_COMPONENT_TYPE_RTP, cands)); g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free); } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { static gboolean L_CAND_DONE = false, R_CAND_DONE = false; static NiceAgent *lagent = NULL, *ragent = NULL; g_debug ("test-credentials:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT(data) == 1) { g_debug ("lagent finished gathering candidates"); L_CAND_DONE = true; lagent = agent; } else if (GPOINTER_TO_UINT(data) == 2) { g_debug ("ragent finished gathering candidates"); R_CAND_DONE = true; ragent = agent; } if (L_CAND_DONE && R_CAND_DONE) { set_credentials (lagent, ragent); swap_candidates (lagent, 1, ragent, 1); swap_candidates (ragent, 1, lagent, 1); } } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { if (state == NICE_COMPONENT_STATE_READY) { g_main_loop_quit(loop); } } static void setup(NiceAgent *lagent, NiceAgent *ragent) { NiceAddress addr; g_assert (nice_agent_add_stream (lagent, 1) == 1); g_assert (nice_agent_add_stream (ragent, 1) == 1); g_assert (NULL != lagent->streams); g_assert (NULL != ragent->streams); nice_address_init (&addr); g_assert (nice_address_set_from_string (&addr, "127.0.0.1")); nice_agent_add_local_address (lagent, &addr); nice_agent_add_local_address (ragent, &addr); nice_agent_attach_recv (lagent, 1, NICE_COMPONENT_TYPE_RTP, g_main_context_default (), cb_nice_recv, LEFT_AGENT); nice_agent_attach_recv (ragent, 1, NICE_COMPONENT_TYPE_RTP, g_main_context_default (), cb_nice_recv, RIGHT_AGENT); g_signal_connect(G_OBJECT(lagent), "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), LEFT_AGENT); g_signal_connect(G_OBJECT(ragent), "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), RIGHT_AGENT); g_signal_connect(G_OBJECT(lagent), "component-state-changed", G_CALLBACK(cb_component_state_changed), LEFT_AGENT); g_object_set (G_OBJECT (lagent), "ice-tcp", FALSE, NULL); g_object_set (G_OBJECT (ragent), "ice-tcp", FALSE, NULL); g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); g_object_set (G_OBJECT (lagent), "upnp", USE_UPNP, NULL); g_object_set (G_OBJECT (ragent), "upnp", USE_UPNP, NULL); g_object_set_data (G_OBJECT (lagent), "other-agent", ragent); g_object_set_data (G_OBJECT (ragent), "other-agent", lagent); } static void teardown(NiceAgent *lagent, NiceAgent *ragent) { nice_agent_remove_stream (lagent, 1); nice_agent_remove_stream (ragent, 1); } int main (void) { NiceAgent *lagent = NULL, *ragent = NULL; gchar *ufrag = NULL, *password = NULL; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif loop = g_main_loop_new (NULL, FALSE); lagent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); ragent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); setup (lagent, ragent); nice_agent_set_local_credentials (lagent, 1, "unicorns", "awesome"); nice_agent_get_local_credentials (lagent, 1, &ufrag, &password); g_assert (g_strcmp0("unicorns", ufrag) == 0); g_assert (g_strcmp0("awesome", password) == 0); nice_agent_gather_candidates (lagent, 1); nice_agent_gather_candidates (ragent, 1); g_main_loop_run (loop); teardown (lagent, ragent); g_object_unref (lagent); g_object_unref (ragent); #ifdef G_OS_WIN32 WSACleanup(); #endif return 0; } libnice-0.1.14/tests/test-tcp.c0000664000076400007640000001171612661700132013212 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2012 Collabora Ltd. * Contact: George Kiagiadakis * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * George Kiagiadakis, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include "socket.h" GMainLoop *mainloop = NULL; NiceSocket *active_sock, *client; NiceSocket *passive_sock, *server; NiceAddress tmp; gchar buf[5]; static gboolean on_server_connection_available (gpointer user_data) { server = nice_tcp_passive_socket_accept (passive_sock); g_assert (server); nice_socket_free (passive_sock); passive_sock = NULL; g_main_loop_quit (mainloop); return FALSE; } static gboolean on_server_input_available (gpointer user_data) { g_assert (5 == nice_socket_recv (server, &tmp, 5, buf)); g_assert (nice_address_equal (&tmp, &client->addr)); g_main_loop_quit (mainloop); return FALSE; } static gboolean on_client_input_available (gpointer user_data) { g_assert (5 == nice_socket_recv (client, &tmp, 5, buf)); g_assert (nice_address_equal (&tmp, &server->addr)); g_main_loop_quit (mainloop); return FALSE; } int main (void) { NiceAddress active_bind_addr, passive_bind_addr; GSource *srv_listen_source, *srv_input_source, *cli_input_source; mainloop = g_main_loop_new (NULL, FALSE); nice_address_init (&active_bind_addr); g_assert (nice_address_set_from_string (&active_bind_addr, "::1")); nice_address_init (&passive_bind_addr); g_assert (nice_address_set_from_string (&passive_bind_addr, "::1")); nice_address_set_port (&passive_bind_addr, 23456); nice_address_init (&tmp); passive_sock = nice_tcp_passive_socket_new (g_main_loop_get_context (mainloop), &passive_bind_addr); g_assert (passive_sock); srv_listen_source = g_socket_create_source (passive_sock->fileno, G_IO_IN, NULL); g_source_set_callback (srv_listen_source, on_server_connection_available, NULL, NULL); g_source_attach (srv_listen_source, g_main_loop_get_context (mainloop)); active_sock = nice_tcp_active_socket_new (g_main_loop_get_context (mainloop), &active_bind_addr); g_assert (active_sock); client = nice_tcp_active_socket_connect (active_sock, &passive_bind_addr); g_assert (client); nice_socket_free (active_sock); active_sock = NULL; g_main_loop_run (mainloop); /* -> on_server_connection_available */ g_assert (server); srv_input_source = g_socket_create_source (server->fileno, G_IO_IN, NULL); g_source_set_callback (srv_input_source, on_server_input_available, NULL, NULL); g_source_attach (srv_input_source, g_main_loop_get_context (mainloop)); cli_input_source = g_socket_create_source (client->fileno, G_IO_IN, NULL); g_source_set_callback (cli_input_source, on_client_input_available, NULL, NULL); g_source_attach (cli_input_source, g_main_loop_get_context (mainloop)); g_assert (nice_address_get_port (&client->addr) != 0); g_assert (nice_address_get_port (&server->addr) == 23456); g_assert (nice_address_set_from_string (&tmp, "::1")); nice_address_set_port (&tmp, nice_address_get_port (&server->addr)); g_assert (nice_address_get_port (&tmp) != 0); g_assert (5 == nice_socket_send (client, &tmp, 5, "hello")); g_main_loop_run (mainloop); /* -> on_server_input_available */ g_assert (0 == strncmp (buf, "hello", 5)); g_assert (5 == nice_socket_send (server, &tmp, 5, "uryyb")); g_main_loop_run (mainloop); /* -> on_client_input_available */ g_assert (0 == strncmp (buf, "uryyb", 5)); nice_socket_free (client); nice_socket_free (server); g_source_unref (srv_listen_source); g_source_unref (srv_input_source); g_source_unref (cli_input_source); g_main_loop_unref (mainloop); return 0; } libnice-0.1.14/tests/test-io-stream-cancelling.c0000664000076400007640000001011312661700132016407 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "test-io-stream-common.h" #include #include #ifndef G_OS_WIN32 #include #endif typedef struct { GCancellable *cancellable; /* owned */ GCond cond; GMutex mutex; gboolean blocking; /* protected by @mutex */ } CancellationData; static gpointer cancellation_thread_cb (gpointer user_data) { CancellationData *data = user_data; /* Wait to be signalled from read_thread_cb(). */ g_mutex_lock (&data->mutex); while (!data->blocking) g_cond_wait (&data->cond, &data->mutex); g_mutex_unlock (&data->mutex); /* Try and ensure we cancel part-way through the read, rather than before the * read function is called. */ g_usleep (100000); g_cancellable_cancel (data->cancellable); return NULL; } static void read_thread_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { CancellationData *user_data = data->user_data; GError *error = NULL; guint8 buf[MESSAGE_SIZE]; gssize len; /* Block on receiving some data or cancellation. */ g_mutex_lock (&user_data->mutex); user_data->blocking = TRUE; g_cond_signal (&user_data->cond); g_mutex_unlock (&user_data->mutex); len = g_input_stream_read (input_stream, buf, sizeof (buf), user_data->cancellable, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_error_free (error); g_assert (len == -1); g_main_loop_quit (data->error_loop); } int main (void) { GThread *l_cancellation_thread, *r_cancellation_thread; CancellationData l_data, r_data; const TestIOStreamCallbacks callbacks = { read_thread_cb, NULL, NULL, NULL, }; #ifdef G_OS_WIN32 WSADATA w; WSAStartup (0x0202, &w); #endif l_data.cancellable = g_cancellable_new (); l_data.blocking = FALSE; g_cond_init (&l_data.cond); g_mutex_init (&l_data.mutex); r_data.cancellable = g_cancellable_new (); r_data.blocking = FALSE; g_cond_init (&r_data.cond); g_mutex_init (&r_data.mutex); l_cancellation_thread = spawn_thread ("libnice L cancel", cancellation_thread_cb, &l_data); r_cancellation_thread = spawn_thread ("libnice R cancel", cancellation_thread_cb, &r_data); run_io_stream_test (30, TRUE, &callbacks, &l_data, NULL, &r_data, NULL); g_thread_join (l_cancellation_thread); g_thread_join (r_cancellation_thread); /* Free things. */ g_object_unref (r_data.cancellable); g_object_unref (l_data.cancellable); g_cond_clear (&l_data.cond); g_cond_clear (&r_data.cond); g_mutex_clear (&l_data.mutex); g_mutex_clear (&r_data.mutex); #ifdef G_OS_WIN32 WSACleanup (); #endif return 0; } libnice-0.1.14/tests/test-send-recv.c0000664000076400007640000012542712732064343014325 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /** * This is a comprehensive unit test for send() and recv() behaviour in libnice, * covering all APIs except the old nice_agent_attach_recv() one. It aims to * test the correctness of reliable and non-reliable I/O through libnice, using * a variety of data and a variety of buffer sizes. * * Abnormal features like error handling, zero-length buffer handling, stream * closure and cancellation are not tested. * * This is *not* a performance test, and would require significant work to be * useful as one. It allocates all of its buffers dynamically, and walks over * them frequently to set and check data. * * Several of the strategies in the test make use of random numbers. The seed * values for these are deterministically set (in main()), but may be specified * on the command line to allow fuzzing. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include "test-io-stream-common.h" #include #include #ifndef G_OS_WIN32 #include #endif /* Maximum IP payload ((1 << 16) - 1), minus IP header, minus UDP header. */ #define MAX_MESSAGE_SIZE (65535 - 20 - 8) /* bytes */ typedef enum { STREAM_AGENT, /* nice_agent_[send|recv]() */ STREAM_AGENT_NONBLOCKING, /* nice_agent_[send|recv]_nonblocking() */ STREAM_GIO, /* Nice[Input|Output]Stream */ STREAM_GSOURCE, /* GPollable[Input|Output]Stream */ } StreamApi; #define STREAM_API_N_ELEMENTS (STREAM_GSOURCE + 1) typedef enum { BUFFER_SIZE_CONSTANT_LARGE, /* always 65535 bytes */ BUFFER_SIZE_CONSTANT_SMALL, /* always 4096 bytes */ BUFFER_SIZE_CONSTANT_TINY, /* always 1 byte */ BUFFER_SIZE_ASCENDING, /* ascending powers of 2 */ BUFFER_SIZE_RANDOM, /* random every time */ } BufferSizeStrategy; #define BUFFER_SIZE_STRATEGY_N_ELEMENTS (BUFFER_SIZE_RANDOM + 1) typedef enum { BUFFER_COUNT_CONSTANT_ONE, /* always a single buffer */ BUFFER_COUNT_CONSTANT_TWO, /* always two buffers */ BUFFER_COUNT_RANDOM, /* random every time */ } BufferCountStrategy; #define BUFFER_COUNT_STRATEGY_N_ELEMENTS (BUFFER_COUNT_RANDOM + 1) typedef enum { MESSAGE_COUNT_CONSTANT_ONE, /* always a single message */ MESSAGE_COUNT_CONSTANT_TWO, /* always two messages */ MESSAGE_COUNT_RANDOM, /* random every time */ } MessageCountStrategy; #define MESSAGE_COUNT_STRATEGY_N_ELEMENTS (MESSAGE_COUNT_RANDOM + 1) typedef enum { BUFFER_DATA_CONSTANT, /* fill with 0xfe */ BUFFER_DATA_ASCENDING, /* ascending values for each byte */ BUFFER_DATA_PSEUDO_RANDOM, /* every byte is pseudo-random */ } BufferDataStrategy; #define BUFFER_DATA_STRATEGY_N_ELEMENTS (BUFFER_DATA_PSEUDO_RANDOM + 1) typedef struct { /* Test configuration (immutable per test run). */ gboolean reliable; StreamApi stream_api; struct { BufferSizeStrategy buffer_size_strategy; BufferCountStrategy buffer_count_strategy; MessageCountStrategy message_count_strategy; } transmit; struct { BufferSizeStrategy buffer_size_strategy; BufferCountStrategy buffer_count_strategy; MessageCountStrategy message_count_strategy; } receive; BufferDataStrategy buffer_data_strategy; gsize n_bytes; guint n_messages; /* Test state. */ GRand *transmit_size_rand; GRand *receive_size_rand; gsize transmitted_bytes; gsize received_bytes; gsize *other_received_bytes; guint transmitted_messages; guint received_messages; guint *other_received_messages; } TestData; /* Whether @stream_api is blocking (vs. non-blocking). */ static gboolean stream_api_is_blocking (StreamApi stream_api) { switch (stream_api) { case STREAM_AGENT: case STREAM_GIO: return TRUE; case STREAM_AGENT_NONBLOCKING: case STREAM_GSOURCE: return FALSE; default: g_assert_not_reached (); } } /* Whether @stream_api only works for reliable NiceAgents. */ static gboolean stream_api_is_reliable_only (StreamApi stream_api) { switch (stream_api) { case STREAM_GSOURCE: case STREAM_GIO: return TRUE; case STREAM_AGENT: case STREAM_AGENT_NONBLOCKING: return FALSE; default: g_assert_not_reached (); } } /* Whether @stream_api supports vectored I/O (multiple buffers or messages). */ static gboolean stream_api_supports_vectored_io (StreamApi stream_api) { switch (stream_api) { case STREAM_AGENT: case STREAM_AGENT_NONBLOCKING: return TRUE; case STREAM_GSOURCE: case STREAM_GIO: return FALSE; default: g_assert_not_reached (); } } /* Generate a size for the buffer containing the @buffer_offset-th byte. * Guaranteed to be in the interval [1, 1 << 16). ((1 << 16) is the maximum * message size.) */ static gsize generate_buffer_size (BufferSizeStrategy strategy, GRand *grand, gsize buffer_offset) { switch (strategy) { case BUFFER_SIZE_CONSTANT_LARGE: return (1 << 16) - 1; case BUFFER_SIZE_CONSTANT_SMALL: return 4096; case BUFFER_SIZE_CONSTANT_TINY: return 1; case BUFFER_SIZE_ASCENDING: return CLAMP (1L << buffer_offset, 1, (1 << 16) - 1); case BUFFER_SIZE_RANDOM: return g_rand_int_range (grand, 1, 1 << 16); default: g_assert_not_reached (); } } /* Generate a number of buffers to allocate when receiving the @buffer_offset-th * byte. Guaranteed to be in the interval [1, 100], where 100 was chosen * arbitrarily.*/ static guint generate_buffer_count (BufferCountStrategy strategy, GRand *grand, gsize buffer_offset) { switch (strategy) { case BUFFER_COUNT_CONSTANT_ONE: return 1; case BUFFER_COUNT_CONSTANT_TWO: return 2; case BUFFER_COUNT_RANDOM: return g_rand_int_range (grand, 1, 100 + 1); default: g_assert_not_reached (); } } /* Generate a number of messages to allocate and receive into when receiving the * @buffer_offset-th byte. Guaranteed to be in the interval [1, 100], where 100 * was chosen arbitrarily.*/ static guint generate_message_count (MessageCountStrategy strategy, GRand *grand, guint buffer_index) { switch (strategy) { case MESSAGE_COUNT_CONSTANT_ONE: return 1; case MESSAGE_COUNT_CONSTANT_TWO: return 2; case MESSAGE_COUNT_RANDOM: return g_rand_int_range (grand, 1, 100 + 1); default: g_assert_not_reached (); } } /* Fill the given @buf with @buf_len bytes of generated data. The data is * deterministically generated, so that: * generate_buffer_data(_, I, buf, 2) * and * generate_buffer_data(_, I+1, buf+1, 1) * generate the same buf[I+1] byte, for all I. * * The generation strategies are generally chosen to produce data which makes * send/receive errors (insertions, swaps, elisions) obvious. */ static void generate_buffer_data (BufferDataStrategy strategy, gsize buffer_offset, guint8 *buf, gsize buf_len) { switch (strategy) { case BUFFER_DATA_CONSTANT: memset (buf, 0xfe, buf_len); break; case BUFFER_DATA_ASCENDING: { gsize i; for (i = 0; i < buf_len; i++) { buf[i] = (i + buffer_offset) & 0xff; } break; } case BUFFER_DATA_PSEUDO_RANDOM: { gsize i; /* This can’t use GRand, because then the number of calls to g_rand_*() * methods would affect its output, and the bytes generated here have to be * entirely deterministic on @buffer_offset. * * Instead, use something akin to a LCG, except without any feedback * (because that would make it non-deterministic). The objective is to * generate numbers which are sufficiently pseudo-random that it’s likely * transpositions, elisions and insertions will be detected. * * The constants come from ‘ANSI C’ in: * http://en.wikipedia.org/wiki/Linear_congruential_generator */ for (i = 0; i < buf_len; i++) { buf[i] = (1103515245 * (buffer_offset + i) + 12345) & 0xff; } break; } default: g_assert_not_reached (); } } /* Choose a size and allocate a receive buffer in @buf, ready to receive bytes * starting at @buffer_offset into the stream. Fill the buffer with poison * values to hopefully make incorrect writes/reads more obvious. * * @buf must be freed with g_free(). */ static void generate_buffer_to_receive (TestIOStreamThreadData *data, gsize buffer_offset, guint8 **buf, gsize *buf_len) { TestData *test_data = data->user_data; /* Allocate the buffer. */ *buf_len = generate_buffer_size (test_data->receive.buffer_size_strategy, test_data->receive_size_rand, buffer_offset); *buf = g_malloc (*buf_len); /* Fill it with poison to try and detect incorrect writes. */ memset (*buf, 0xaa, *buf_len); } /* Similar to generate_buffer_to_receive(), but generate an entire message array * with multiple buffers instead. * * @max_buffer_size may be used to limit the total size of all the buffers in * all the messages, for example to avoid blocking on receiving data which will * never be sent. This only applies for blocking, reliable stream APIs. * * @max_n_messages may be used to limit the number of messages generated, to * avoid blocking on receiving messages which will never be sent. This only * applies for blocking, non-reliable stream APIs. * * @messages must be freed with g_free(), as must all of the buffer arrays and * the buffers themselves. */ static void generate_messages_to_receive (TestIOStreamThreadData *data, gsize buffer_offset, NiceInputMessage **messages, guint *n_messages, gsize max_buffer_size, guint max_n_messages) { TestData *test_data = data->user_data; guint i; /* Allocate the messages. */ *n_messages = generate_message_count (test_data->receive.message_count_strategy, test_data->receive_size_rand, buffer_offset); if (!data->reliable) *n_messages = MIN (*n_messages, max_n_messages); *messages = g_malloc_n (*n_messages, sizeof (NiceInputMessage)); for (i = 0; i < *n_messages; i++) { NiceInputMessage *message = &((*messages)[i]); guint j; message->n_buffers = generate_buffer_count (test_data->receive.buffer_count_strategy, test_data->receive_size_rand, buffer_offset); message->buffers = g_malloc_n (message->n_buffers, sizeof (GInputVector)); message->from = NULL; message->length = 0; for (j = 0; j < (guint) message->n_buffers; j++) { GInputVector *buffer = &message->buffers[j]; gsize buf_len; buf_len = generate_buffer_size (test_data->receive.buffer_size_strategy, test_data->receive_size_rand, buffer_offset); /* Trim the buffer length if it would otherwise cause the API to block. */ if (data->reliable) { buf_len = MIN (buf_len, max_buffer_size); max_buffer_size -= buf_len; } buffer->size = buf_len; buffer->buffer = g_malloc (buffer->size); /* Fill it with poison to try and detect incorrect writes. */ memset (buffer->buffer, 0xaa, buffer->size); /* If we’ve hit the max_buffer_size, adjust the buffer and message counts * and run away. */ if (data->reliable && max_buffer_size == 0) { message->n_buffers = j + 1; *n_messages = i + 1; return; } } } } /* Validate the length and data of a received buffer of length @buf_len, filled * with @len valid bytes. Updates the internal state machine to mark the bytes * as received. This consumes @buf. */ static void validate_received_buffer (TestIOStreamThreadData *data, gsize buffer_offset, guint8 **buf, gsize buf_len, gssize len) { TestData *test_data = data->user_data; guint8 *expected_buf; g_assert_cmpint (len, <=, buf_len); g_assert_cmpint (len, >=, 0); if (stream_api_is_blocking (test_data->stream_api) && data->reliable) g_assert_cmpint (len, ==, buf_len); /* Validate the buffer contents. * * Note: Buffers can only be validated up to valid_len. The buffer may * have been re-used internally (e.g. by receiving a STUN message, then * overwriting it with a data packet), so we can’t guarantee that the * bytes beyond valid_len have been untouched. */ expected_buf = g_malloc (buf_len); memset (expected_buf, 0xaa, buf_len); generate_buffer_data (test_data->buffer_data_strategy, buffer_offset, expected_buf, len); g_assert (memcmp (*buf, expected_buf, len) == 0); g_free (expected_buf); test_data->received_bytes += len; g_free (*buf); } /* Similar to validate_received_buffer(), except it validates a message array * instead of a single buffer. This consumes @messages. */ static void validate_received_messages (TestIOStreamThreadData *data, gsize buffer_offset, NiceInputMessage *messages, guint n_messages, gint n_valid_messages) { TestData *test_data = data->user_data; guint i; gsize prev_message_len = G_MAXSIZE; g_assert_cmpint (n_valid_messages, <=, n_messages); g_assert_cmpint (n_valid_messages, >=, 0); if (stream_api_is_blocking (test_data->stream_api)) g_assert_cmpint (n_valid_messages, ==, n_messages); test_data->received_messages += n_valid_messages; /* Validate the message contents. */ for (i = 0; i < (guint) n_valid_messages; i++) { NiceInputMessage *message = &messages[i]; guint j; gsize total_buf_len = 0; gsize message_len_remaining = message->length; g_assert_cmpint (message->n_buffers, >, 0); for (j = 0; j < (guint) message->n_buffers; j++) { GInputVector *buffer = &message->buffers[j]; gsize valid_len; /* See note above about valid_len. */ total_buf_len += buffer->size; valid_len = MIN (message_len_remaining, buffer->size); /* Only validate buffer content for reliable mode, anything could * be received in UDP mode */ if (test_data->reliable) { guint8 *expected_buf; expected_buf = g_malloc (buffer->size); memset (expected_buf, 0xaa, buffer->size); generate_buffer_data (test_data->buffer_data_strategy, buffer_offset, expected_buf, valid_len); g_assert_cmpint (memcmp (buffer->buffer, expected_buf, valid_len), ==, 0); g_free (expected_buf); buffer_offset += valid_len; message_len_remaining -= valid_len; } test_data->received_bytes += valid_len; } g_assert_cmpuint (message->length, <=, total_buf_len); g_assert_cmpuint (message->length, >=, 0); /* No non-empty messages can follow an empty message. */ if (prev_message_len == 0) g_assert_cmpuint (message->length, ==, 0); prev_message_len = message->length; /* If the API was blocking, it should have completely filled the message. */ if (stream_api_is_blocking (test_data->stream_api) && data->reliable) g_assert_cmpuint (message->length, ==, total_buf_len); g_assert (message->from == NULL); } /* Free all messages. */ for (i = 0; i < (guint) n_messages; i++) { NiceInputMessage *message = &messages[i]; guint j; for (j = 0; j < (guint) message->n_buffers; j++) { GInputVector *buffer = &message->buffers[j]; g_free (buffer->buffer); } g_free (message->buffers); } g_free (messages); } /* Determine a size for the next transmit buffer, allocate it, and fill it with * data to be transmitted. */ static void generate_buffer_to_transmit (TestIOStreamThreadData *data, gsize buffer_offset, guint8 **buf, gsize *buf_len) { TestData *test_data = data->user_data; /* Allocate the buffer. */ *buf_len = generate_buffer_size (test_data->transmit.buffer_size_strategy, test_data->transmit_size_rand, buffer_offset); *buf_len = MIN (*buf_len, test_data->n_bytes - test_data->transmitted_bytes); *buf = g_malloc (*buf_len); /* Fill it with data. */ generate_buffer_data (test_data->buffer_data_strategy, buffer_offset, *buf, *buf_len); } /* Similar to generate_buffer_to_transmit(), except that it generates an array * of NiceOutputMessages rather than a single buffer. */ static void generate_messages_to_transmit (TestIOStreamThreadData *data, gsize buffer_offset, NiceOutputMessage **messages, guint *n_messages) { TestData *test_data = data->user_data; guint i; gsize total_buf_len = 0; /* Determine the number of messages to send. */ *n_messages = generate_message_count (test_data->transmit.message_count_strategy, test_data->transmit_size_rand, buffer_offset); *n_messages = MIN (*n_messages, test_data->n_messages - test_data->transmitted_messages); *messages = g_malloc_n (*n_messages, sizeof (NiceOutputMessage)); for (i = 0; i < *n_messages; i++) { NiceOutputMessage *message = &((*messages)[i]); guint j; gsize max_message_size; gsize message_len = 0; message->n_buffers = generate_buffer_count (test_data->transmit.buffer_count_strategy, test_data->transmit_size_rand, buffer_offset); message->buffers = g_malloc_n (message->n_buffers, sizeof (GOutputVector)); /* Limit the overall message size to the smaller of (n_bytes / n_messages) * and MAX_MESSAGE_SIZE, to ensure each message is non-empty. */ max_message_size = MIN ((test_data->n_bytes / test_data->n_messages), MAX_MESSAGE_SIZE); for (j = 0; j < (guint) message->n_buffers; j++) { GOutputVector *buffer = &message->buffers[j]; gsize buf_len; guint8 *buf; buf_len = generate_buffer_size (test_data->transmit.buffer_size_strategy, test_data->transmit_size_rand, buffer_offset); buf_len = MIN (buf_len, test_data->n_bytes - test_data->transmitted_bytes - total_buf_len); buf_len = MIN (buf_len, max_message_size - message_len); buffer->size = buf_len; buf = g_malloc (buffer->size); buffer->buffer = buf; message_len += buf_len; total_buf_len += buf_len; /* Fill it with data. */ generate_buffer_data (test_data->buffer_data_strategy, buffer_offset, buf, buf_len); buffer_offset += buf_len; /* Reached the maximum UDP payload size? */ if (message_len >= max_message_size) { message->n_buffers = j + 1; break; } } g_assert_cmpuint (message_len, <=, max_message_size); } } /* Validate the number of bytes transmitted, and update the test’s internal * state machine. Consumes @buf. */ static void notify_transmitted_buffer (TestIOStreamThreadData *data, gsize buffer_offset, guint8 **buf, gsize buf_len, gssize len) { TestData *test_data = data->user_data; g_assert_cmpint (len, <=, buf_len); g_assert_cmpint (len, >=, 0); test_data->transmitted_bytes += len; g_free (*buf); } static gsize output_message_get_size (const NiceOutputMessage *message) { guint i; gsize message_len = 0; /* Find the total size of the message */ for (i = 0; (message->n_buffers >= 0 && i < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[i].buffer != NULL); i++) message_len += message->buffers[i].size; return message_len; } /* Similar to notify_transmitted_buffer(), except it operates on an array of * messages from generate_messages_to_transmit(). */ static void notify_transmitted_messages (TestIOStreamThreadData *data, gsize buffer_offset, NiceOutputMessage **messages, guint n_messages, gint n_sent_messages) { TestData *test_data = data->user_data; guint i; g_assert_cmpint (n_sent_messages, <=, n_messages); g_assert_cmpint (n_sent_messages, >=, 0); test_data->transmitted_messages += n_sent_messages; for (i = 0; i < n_messages; i++) { NiceOutputMessage *message = &((*messages)[i]); guint j; if (i < (guint) n_sent_messages) test_data->transmitted_bytes += output_message_get_size (message); for (j = 0; j < (guint) message->n_buffers; j++) { GOutputVector *buffer = &message->buffers[j]; g_free ((guint8 *) buffer->buffer); } g_free (message->buffers); } g_free (*messages); } /* * Implementation using nice_agent_recv_messages() and nice_agent_send(). */ static void read_thread_agent_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { TestData *test_data = data->user_data; guint stream_id, component_id; gpointer tmp; tmp = g_object_get_data (G_OBJECT (data->agent), "stream-id"); stream_id = GPOINTER_TO_UINT (tmp); component_id = 1; while (test_data->received_bytes < test_data->n_bytes) { GError *error = NULL; NiceInputMessage *messages; guint n_messages; gint n_valid_messages; /* Initialise an array of messages to receive into. */ generate_messages_to_receive (data, test_data->received_bytes, &messages, &n_messages, test_data->n_bytes - test_data->received_bytes, test_data->n_messages - test_data->received_messages); /* Block on receiving some data. */ n_valid_messages = nice_agent_recv_messages (data->agent, stream_id, component_id, messages, n_messages, NULL, &error); g_assert_no_error (error); /* Check the messages and update the test’s state machine. */ validate_received_messages (data, test_data->received_bytes, messages, n_messages, n_valid_messages); } check_for_termination (data, &test_data->received_bytes, test_data->other_received_bytes, &test_data->transmitted_bytes, test_data->n_bytes); } static void write_thread_agent_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { TestData *test_data = data->user_data; guint stream_id, component_id; gpointer tmp; tmp = g_object_get_data (G_OBJECT (data->agent), "stream-id"); stream_id = GPOINTER_TO_UINT (tmp); component_id = 1; while (test_data->transmitted_bytes < test_data->n_bytes) { GError *error = NULL; NiceOutputMessage *messages; guint n_messages; gint n_sent_messages; /* Generate a buffer to transmit. */ generate_messages_to_transmit (data, test_data->transmitted_bytes, &messages, &n_messages); /* Busy loop on receiving some data. */ do { g_clear_error (&error); n_sent_messages = nice_agent_send_messages_nonblocking (data->agent, stream_id, component_id, messages, n_messages, NULL, &error); } while (n_sent_messages == -1 && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); g_assert_no_error (error); /* Update the test’s buffer generation state machine. */ notify_transmitted_messages (data, test_data->transmitted_bytes, &messages, n_messages, n_sent_messages); } } /* * Implementation using nice_agent_recv_nonblocking() and * nice_agent_send_nonblocking(). */ static void read_thread_agent_nonblocking_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { TestData *test_data = data->user_data; guint stream_id, component_id; gpointer tmp; tmp = g_object_get_data (G_OBJECT (data->agent), "stream-id"); stream_id = GPOINTER_TO_UINT (tmp); component_id = 1; while (test_data->received_bytes < test_data->n_bytes) { GError *error = NULL; NiceInputMessage *messages; guint n_messages; gint n_valid_messages; /* Initialise an array of messages to receive into. */ generate_messages_to_receive (data, test_data->received_bytes, &messages, &n_messages, test_data->n_bytes - test_data->received_bytes, test_data->n_messages - test_data->received_messages); /* Trim n_messages to avoid consuming the ‘done’ message. */ n_messages = MIN (n_messages, test_data->n_messages - test_data->received_messages); /* Busy loop on receiving some data. */ do { g_clear_error (&error); n_valid_messages = nice_agent_recv_messages_nonblocking (data->agent, stream_id, component_id, messages, n_messages, NULL, &error); } while (n_valid_messages == -1 && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); g_assert_no_error (error); /* Check the messages and update the test’s state machine. */ validate_received_messages (data, test_data->received_bytes, messages, n_messages, n_valid_messages); } check_for_termination (data, &test_data->received_bytes, test_data->other_received_bytes, &test_data->transmitted_bytes, test_data->n_bytes); } static void write_thread_agent_nonblocking_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { /* FIXME: There is no nice_agent_send_nonblocking(); nice_agent_send() is * non-blocking by default. */ write_thread_agent_cb (output_stream, data); } /* * Implementation using NiceInputStream and NiceOutputStream. */ static void read_thread_gio_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { TestData *test_data = data->user_data; while (test_data->received_bytes < test_data->n_bytes) { GError *error = NULL; guint8 *buf = NULL; gsize buf_len = 0; gssize len; /* Initialise a receive buffer. */ generate_buffer_to_receive (data, test_data->received_bytes, &buf, &buf_len); /* Trim the receive buffer to avoid blocking on bytes which will never * appear. */ buf_len = MIN (buf_len, test_data->n_bytes - test_data->received_bytes); /* Block on receiving some data. */ len = g_input_stream_read (input_stream, buf, buf_len, NULL, &error); g_assert_no_error (error); /* Check the buffer and update the test’s state machine. */ validate_received_buffer (data, test_data->received_bytes, &buf, buf_len, len); } check_for_termination (data, &test_data->received_bytes, test_data->other_received_bytes, &test_data->transmitted_bytes, test_data->n_bytes); } static void write_thread_gio_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { TestData *test_data = data->user_data; while (test_data->transmitted_bytes < test_data->n_bytes) { GError *error = NULL; guint8 *buf = NULL; gsize buf_len = 0; gssize len; gsize total_len = 0; /* Generate a buffer to transmit. */ generate_buffer_to_transmit (data, test_data->transmitted_bytes, &buf, &buf_len); /* Transmit it. */ do { len = g_output_stream_write (output_stream, buf + total_len, buf_len - total_len, NULL, &error); g_assert_no_error (error); total_len += len; } while (total_len < buf_len); /* Update the test’s buffer generation state machine. */ notify_transmitted_buffer (data, test_data->transmitted_bytes, &buf, buf_len, total_len); } } /* * Implementation using GPollableInputStream and GPollableOutputStream. * * GSourceData is effectively the closure for the ‘for’ loop in other stream API * implementations. */ typedef struct { TestIOStreamThreadData *data; GMainLoop *main_loop; } GSourceData; static gboolean read_stream_cb (GObject *pollable_stream, gpointer _user_data) { GSourceData *gsource_data = _user_data; TestIOStreamThreadData *data = gsource_data->data; TestData *test_data = data->user_data; GError *error = NULL; guint8 *buf = NULL; gsize buf_len = 0; gssize len; /* Initialise a receive buffer. */ generate_buffer_to_receive (data, test_data->received_bytes, &buf, &buf_len); /* Trim the receive buffer to avoid consuming the ‘done’ message. */ buf_len = MIN (buf_len, test_data->n_bytes - test_data->received_bytes); /* Try to receive some data. */ len = g_pollable_input_stream_read_nonblocking ( G_POLLABLE_INPUT_STREAM (pollable_stream), buf, buf_len, NULL, &error); if (len == -1) { g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_error_free (error); g_free (buf); return G_SOURCE_CONTINUE; } g_assert_no_error (error); /* Check the buffer and update the test’s state machine. */ validate_received_buffer (data, test_data->received_bytes, &buf, buf_len, len); /* Termination time? */ if (test_data->received_bytes == test_data->n_bytes) { g_main_loop_quit (gsource_data->main_loop); return G_SOURCE_REMOVE; } return G_SOURCE_CONTINUE; } static void read_thread_gsource_cb (GInputStream *input_stream, TestIOStreamThreadData *data) { TestData *test_data = data->user_data; GSourceData gsource_data; GMainContext *main_context; GMainLoop *main_loop; GSource *stream_source; main_context = g_main_context_ref_thread_default (); main_loop = g_main_loop_new (main_context, FALSE); gsource_data.data = data; gsource_data.main_loop = main_loop; stream_source = g_pollable_input_stream_create_source ( G_POLLABLE_INPUT_STREAM (input_stream), NULL); g_source_set_callback (stream_source, (GSourceFunc) read_stream_cb, &gsource_data, NULL); g_source_attach (stream_source, main_context); /* Run the main loop. */ g_main_loop_run (main_loop); g_source_destroy (stream_source); g_source_unref (stream_source); g_main_loop_unref (main_loop); g_main_context_unref (main_context); /* Termination? */ check_for_termination (data, &test_data->received_bytes, test_data->other_received_bytes, &test_data->transmitted_bytes, test_data->n_bytes); } static gboolean write_stream_cb (GObject *pollable_stream, gpointer _user_data) { GSourceData *gsource_data = _user_data; TestIOStreamThreadData *data = gsource_data->data; TestData *test_data = data->user_data; GError *error = NULL; guint8 *buf = NULL; gsize buf_len = 0; gssize len; /* Initialise a receive buffer. */ generate_buffer_to_transmit (data, test_data->transmitted_bytes, &buf, &buf_len); /* Try to transmit some data. */ len = g_pollable_output_stream_write_nonblocking ( G_POLLABLE_OUTPUT_STREAM (pollable_stream), buf, buf_len, NULL, &error); if (len == -1) { g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_free (buf); return G_SOURCE_CONTINUE; } g_assert_no_error (error); /* Update the test’s buffer generation state machine. */ notify_transmitted_buffer (data, test_data->transmitted_bytes, &buf, buf_len, len); /* Termination time? */ if (test_data->transmitted_bytes == test_data->n_bytes) { g_main_loop_quit (gsource_data->main_loop); return G_SOURCE_REMOVE; } return G_SOURCE_CONTINUE; } static void write_thread_gsource_cb (GOutputStream *output_stream, TestIOStreamThreadData *data) { GSourceData gsource_data; GMainContext *main_context; GMainLoop *main_loop; GSource *stream_source; main_context = g_main_context_ref_thread_default (); main_loop = g_main_loop_new (main_context, FALSE); gsource_data.data = data; gsource_data.main_loop = main_loop; stream_source = g_pollable_output_stream_create_source ( G_POLLABLE_OUTPUT_STREAM (output_stream), NULL); g_source_set_callback (stream_source, (GSourceFunc) write_stream_cb, &gsource_data, NULL); g_source_attach (stream_source, main_context); /* Run the main loop. */ g_main_loop_run (main_loop); g_source_destroy (stream_source); g_source_unref (stream_source); g_main_loop_unref (main_loop); g_main_context_unref (main_context); } static void test_data_init (TestData *data, gboolean reliable, StreamApi stream_api, gsize n_bytes, guint n_messages, BufferSizeStrategy transmit_buffer_size_strategy, BufferCountStrategy transmit_buffer_count_strategy, MessageCountStrategy transmit_message_count_strategy, BufferSizeStrategy receive_buffer_size_strategy, BufferCountStrategy receive_buffer_count_strategy, MessageCountStrategy receive_message_count_strategy, BufferDataStrategy buffer_data_strategy, guint32 transmit_seed, guint32 receive_seed, gsize *other_received_bytes, guint *other_received_messages) { data->reliable = reliable; data->stream_api = stream_api; data->n_bytes = n_bytes; data->n_messages = n_messages; data->transmit.buffer_size_strategy = transmit_buffer_size_strategy; data->transmit.buffer_count_strategy = transmit_buffer_count_strategy; data->transmit.message_count_strategy = transmit_message_count_strategy; data->receive.buffer_size_strategy = receive_buffer_size_strategy; data->receive.buffer_count_strategy = receive_buffer_count_strategy; data->receive.message_count_strategy = receive_message_count_strategy; data->buffer_data_strategy = buffer_data_strategy; data->transmit_size_rand = g_rand_new_with_seed (transmit_seed); data->receive_size_rand = g_rand_new_with_seed (receive_seed); data->transmitted_bytes = 0; data->received_bytes = 0; data->other_received_bytes = other_received_bytes; data->transmitted_messages = 0; data->received_messages = 0; data->other_received_messages = other_received_messages; } /* * Test closures. */ static void test_data_clear (TestData *data) { g_rand_free (data->receive_size_rand); g_rand_free (data->transmit_size_rand); } static void test (gboolean reliable, StreamApi stream_api, gsize n_bytes, guint n_messages, BufferSizeStrategy transmit_buffer_size_strategy, BufferCountStrategy transmit_buffer_count_strategy, MessageCountStrategy transmit_message_count_strategy, BufferSizeStrategy receive_buffer_size_strategy, BufferCountStrategy receive_buffer_count_strategy, MessageCountStrategy receive_message_count_strategy, BufferDataStrategy buffer_data_strategy, guint32 transmit_seed, guint32 receive_seed, guint deadlock_timeout) { TestData l_data, r_data; /* Indexed by StreamApi. */ const TestIOStreamCallbacks callbacks[] = { { read_thread_agent_cb, write_thread_agent_cb, NULL, NULL, }, /* STREAM_AGENT */ { read_thread_agent_nonblocking_cb, write_thread_agent_nonblocking_cb, NULL, NULL, }, /* STREAM_AGENT_NONBLOCKING */ { read_thread_gio_cb, write_thread_gio_cb, NULL, NULL, }, /* STREAM_GIO */ { read_thread_gsource_cb, write_thread_gsource_cb, NULL, NULL }, /* STREAM_GSOURCE */ }; test_data_init (&l_data, reliable, stream_api, n_bytes, n_messages, transmit_buffer_size_strategy, transmit_buffer_count_strategy, transmit_message_count_strategy, receive_buffer_size_strategy, receive_buffer_count_strategy, receive_message_count_strategy, buffer_data_strategy, transmit_seed, receive_seed, &r_data.received_bytes, &r_data.received_messages); test_data_init (&r_data, reliable, stream_api, n_bytes, n_messages, transmit_buffer_size_strategy, transmit_buffer_count_strategy, transmit_message_count_strategy, receive_buffer_size_strategy, receive_buffer_count_strategy, receive_message_count_strategy, buffer_data_strategy, transmit_seed, receive_seed, &l_data.received_bytes, &l_data.received_messages); run_io_stream_test (deadlock_timeout, reliable, &callbacks[stream_api], &l_data, NULL, &r_data, NULL); test_data_clear (&r_data); test_data_clear (&l_data); } /* Options with default values. */ guint32 option_transmit_seed = 0; guint32 option_receive_seed = 0; gsize option_n_bytes = 10000; guint option_n_messages = 50; guint option_timeout = 15; /* seconds */ gboolean option_long_mode = FALSE; static GOptionEntry entries[] = { { "transmit-seed", 0, 0, G_OPTION_ARG_INT, &option_transmit_seed, "Seed for transmission RNG", "S" }, { "receive-seed", 0, 0, G_OPTION_ARG_INT, &option_receive_seed, "Seed for reception RNG", "S" }, { "n-bytes", 'n', 0, G_OPTION_ARG_INT64, &option_n_bytes, "Number of bytes to send in each test (default 10000)", "N" }, { "n-messages", 'm', 0, G_OPTION_ARG_INT64, &option_n_messages, "Number of messages to send in each test (default 50)", "M" }, { "timeout", 't', 0, G_OPTION_ARG_INT, &option_timeout, "Deadlock detection timeout length, in seconds (default: 15)", "S" }, { "long-mode", 'l', 0, G_OPTION_ARG_NONE, &option_long_mode, "Enable all tests, rather than a fast subset", NULL }, { NULL }, }; int main (int argc, char *argv[]) { gboolean reliable; StreamApi stream_api; BufferSizeStrategy transmit_buffer_size_strategy; BufferCountStrategy transmit_buffer_count_strategy; MessageCountStrategy transmit_message_count_strategy; BufferSizeStrategy receive_buffer_size_strategy; BufferCountStrategy receive_buffer_count_strategy; MessageCountStrategy receive_message_count_strategy; BufferDataStrategy buffer_data_strategy; guint32 transmit_seed; guint32 receive_seed; gsize n_bytes; guint n_messages; guint deadlock_timeout; gboolean long_mode; GOptionContext *context; GError *error = NULL; /* Argument parsing. Allow some of the test parameters to be specified on the * command line. */ context = g_option_context_new ("— test send()/recv() correctness"); g_option_context_add_main_entries (context, entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("Option parsing failed: %s\n", error->message); g_error_free (error); g_option_context_free (context); exit (1); } /* Set up the defaults. */ transmit_seed = option_transmit_seed; receive_seed = option_receive_seed; n_bytes = option_n_bytes; n_messages = option_n_messages; deadlock_timeout = option_timeout; long_mode = option_long_mode; #ifdef G_OS_WIN32 WSADATA w; WSAStartup (0x0202, &w); #endif if (!long_mode) { /* Quick mode. Just test each of the stream APIs in reliable and * non-reliable mode, with a single pair of buffer strategies, and a single * data strategy. */ /* Reliability. */ for (reliable = 0; reliable < 2; reliable++) { /* Stream API. */ for (stream_api = 0; (guint) stream_api < STREAM_API_N_ELEMENTS; stream_api++) { /* GIO streams must always be reliable. */ if (!reliable && stream_api_is_reliable_only (stream_api)) continue; /* Non-reliable socket receives require large buffers. */ if (reliable) { receive_buffer_size_strategy = BUFFER_SIZE_RANDOM; } else { receive_buffer_size_strategy = BUFFER_SIZE_CONSTANT_LARGE; } transmit_buffer_size_strategy = BUFFER_SIZE_RANDOM; buffer_data_strategy = BUFFER_DATA_PSEUDO_RANDOM; if (stream_api_supports_vectored_io (stream_api)) { transmit_buffer_count_strategy = BUFFER_COUNT_RANDOM; transmit_message_count_strategy = MESSAGE_COUNT_RANDOM; receive_buffer_count_strategy = BUFFER_COUNT_RANDOM; receive_message_count_strategy = MESSAGE_COUNT_RANDOM; } else { transmit_buffer_count_strategy = BUFFER_COUNT_CONSTANT_ONE; transmit_message_count_strategy = MESSAGE_COUNT_CONSTANT_ONE; receive_buffer_count_strategy = BUFFER_COUNT_CONSTANT_ONE; receive_message_count_strategy = MESSAGE_COUNT_CONSTANT_ONE; } g_debug ("Running test (%u, %u, %" G_GSIZE_FORMAT ", %u, %u, " "%u, %u, %u, %u)…", reliable, stream_api, n_bytes, n_messages, transmit_buffer_size_strategy, receive_buffer_size_strategy, buffer_data_strategy, transmit_seed, receive_seed); test (reliable, stream_api, n_bytes, n_messages, transmit_buffer_size_strategy, transmit_buffer_count_strategy, transmit_message_count_strategy, receive_buffer_size_strategy, receive_buffer_count_strategy, receive_message_count_strategy, buffer_data_strategy, transmit_seed, receive_seed, deadlock_timeout); } } goto done; } #define STRATEGY_LOOP(V, L) for (V = 0; (guint) V < L##_N_ELEMENTS; V++) STRATEGY_LOOP(transmit_buffer_size_strategy, BUFFER_SIZE_STRATEGY) STRATEGY_LOOP(transmit_buffer_count_strategy, BUFFER_COUNT_STRATEGY) STRATEGY_LOOP(transmit_message_count_strategy, MESSAGE_COUNT_STRATEGY) STRATEGY_LOOP(receive_buffer_size_strategy, BUFFER_SIZE_STRATEGY) STRATEGY_LOOP(receive_buffer_count_strategy, BUFFER_COUNT_STRATEGY) STRATEGY_LOOP(receive_message_count_strategy, MESSAGE_COUNT_STRATEGY) STRATEGY_LOOP(buffer_data_strategy, BUFFER_DATA_STRATEGY) /* Reliability. */ for (reliable = 0; reliable < 2; reliable++) { /* Stream API. */ for (stream_api = 0; (guint) stream_api < STREAM_API_N_ELEMENTS; stream_api++) { /* GIO streams must always be reliable. */ if (!reliable && stream_api_is_reliable_only (stream_api)) continue; /* Non-reliable socket receives require large buffers. We don’t claim to * support using them with small (< 65536B) buffers, so don’t test * them. */ if (!reliable && receive_buffer_size_strategy != BUFFER_SIZE_CONSTANT_LARGE) continue; /* Non-reliable socket transmits will always block with huge buffers. */ if (!reliable && transmit_buffer_size_strategy == BUFFER_SIZE_CONSTANT_LARGE) continue; /* Stream APIs which don’t support vectored I/O must not be passed * I/O vectors. */ if (!stream_api_supports_vectored_io (stream_api) && (transmit_buffer_count_strategy != BUFFER_COUNT_CONSTANT_ONE || transmit_message_count_strategy != MESSAGE_COUNT_CONSTANT_ONE || receive_buffer_count_strategy != BUFFER_COUNT_CONSTANT_ONE || receive_message_count_strategy != MESSAGE_COUNT_CONSTANT_ONE)) continue; g_debug ("Running test (%u, %u, %" G_GSIZE_FORMAT ", %u, %u, " "%u, %u, %u, %u, %u, %u, %u, %u)…", reliable, stream_api, n_bytes, n_messages, transmit_buffer_size_strategy, transmit_buffer_count_strategy, transmit_message_count_strategy, receive_buffer_size_strategy, receive_buffer_count_strategy, receive_message_count_strategy, buffer_data_strategy, transmit_seed, receive_seed); test (reliable, stream_api, n_bytes, n_messages, transmit_buffer_size_strategy, transmit_buffer_count_strategy, transmit_message_count_strategy, receive_buffer_size_strategy, receive_buffer_count_strategy, receive_message_count_strategy, buffer_data_strategy, transmit_seed, receive_seed, deadlock_timeout); } } done: g_option_context_free (context); #ifdef G_OS_WIN32 WSACleanup (); #endif return 0; } libnice-0.1.14/tests/test-mainloop.c0000664000076400007640000000622612661700132014242 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "socket/socket.h" static GMainLoop *loop = NULL; static void recv_cb ( NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data) { g_assert (agent != NULL); g_assert (stream_id == 1); g_assert (component_id == 1); g_assert (len == 6); g_assert (0 == strncmp (buf, "\x80hello", len)); g_assert (42 == GPOINTER_TO_UINT (data)); g_main_loop_quit (loop); } int main (void) { NiceAgent *agent; NiceAddress addr; guint stream; nice_address_init (&addr); loop = g_main_loop_new (NULL, FALSE); agent = nice_agent_new (g_main_loop_get_context (loop), NICE_COMPATIBILITY_RFC5245); nice_address_set_ipv4 (&addr, 0x7f000001); nice_agent_add_local_address (agent, &addr); stream = nice_agent_add_stream (agent, 1); nice_agent_gather_candidates (agent, stream); // attach to default main context nice_agent_attach_recv (agent, stream, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (loop), recv_cb, GUINT_TO_POINTER (42)); { NiceCandidate *candidate; GSList *candidates, *i; candidates = nice_agent_get_local_candidates (agent, 1, 1); candidate = candidates->data; nice_socket_send (candidate->sockptr, &(candidate->addr), 6, "\x80hello"); for (i = candidates; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (candidates); } g_main_loop_run (loop); nice_agent_remove_stream (agent, stream); g_object_unref (agent); return 0; } libnice-0.1.14/tests/test-icetcp.c0000664000076400007640000004317112723575700013705 00000000000000/* * This file is part of the Nice GLib ICE library. * * Unit test for ICE full-mode related features. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "agent.h" #include #include static NiceComponentState global_lagent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST }; static NiceComponentState global_ragent_state[2] = { NICE_COMPONENT_STATE_LAST, NICE_COMPONENT_STATE_LAST }; static guint global_components_ready = 0; static guint global_components_ready_exit = 0; static guint global_components_failed = 0; static guint global_components_failed_exit = 0; static GMainLoop *global_mainloop = NULL; static gboolean global_lagent_gathering_done = FALSE; static gboolean global_ragent_gathering_done = FALSE; static gboolean global_lagent_ibr_received = FALSE; static gboolean global_ragent_ibr_received = FALSE; static gboolean global_ready_reached = FALSE; static int global_lagent_cands = 0; static int global_ragent_cands = 0; static gint global_ragent_read = 0; static guint global_exit_when_ibr_received = 0; static void priv_print_global_status (void) { g_debug ("\tgathering_done=%d", global_lagent_gathering_done && global_ragent_gathering_done); g_debug ("\tlstate[rtp]=%d [rtcp]=%d", global_lagent_state[0], global_lagent_state[1]); g_debug ("\trstate[rtp]=%d [rtcp]=%d", global_ragent_state[0], global_ragent_state[1]); g_debug ("\tL cands=%d R cands=%d", global_lagent_cands, global_ragent_cands); } static gboolean timer_cb (gpointer pointer) { g_debug ("test-icetcp:%s: %p", G_STRFUNC, pointer); /* signal status via a global variable */ /* note: should not be reached, abort */ g_error ("ERROR: test has got stuck, aborting..."); return FALSE; } static void cb_writable (NiceAgent*agent, guint stream_id, guint component_id) { g_debug ("Transport is now writable, stopping mainloop"); g_main_loop_quit (global_mainloop); } static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data) { g_debug ("test-icetcp:%s: %p", G_STRFUNC, user_data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)buf; /* * Lets ignore stun packets that got through */ if (len < 8) return; if (strncmp ("12345678", buf, 8)) return; if (GPOINTER_TO_UINT (user_data) == 2) { g_debug ("right agent received %d bytes, stopping mainloop", len); global_ragent_read = len; g_main_loop_quit (global_mainloop); } } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-icetcp:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) global_lagent_gathering_done = TRUE; else if (GPOINTER_TO_UINT (data) == 2) global_ragent_gathering_done = TRUE; if (global_lagent_gathering_done && global_ragent_gathering_done) g_main_loop_quit (global_mainloop); /* XXX: dear compiler, these are for you: */ (void)agent; } static void check_loop_quit_condition (void) { if (global_ready_reached && global_lagent_cands >= 2 && global_ragent_cands >= 2) { g_main_loop_quit (global_mainloop); } } static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { gboolean ready_to_connected = FALSE; g_debug ("test-icetcp:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) { if (global_lagent_state[component_id - 1] == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_lagent_state[component_id - 1] = state; } else if (GPOINTER_TO_UINT (data) == 2) { if (global_ragent_state[component_id - 1] == NICE_COMPONENT_STATE_READY && state == NICE_COMPONENT_STATE_CONNECTED) ready_to_connected = TRUE; global_ragent_state[component_id - 1] = state; } if (state == NICE_COMPONENT_STATE_READY) global_components_ready++; else if (state == NICE_COMPONENT_STATE_CONNECTED && ready_to_connected) global_components_ready--; if (state == NICE_COMPONENT_STATE_FAILED) global_components_failed++; g_debug ("test-icetcp: checks READY/EXIT-AT %u/%u.", global_components_ready, global_components_ready_exit); g_debug ("test-icetcp: checks FAILED/EXIT-AT %u/%u.", global_components_failed, global_components_failed_exit); /* signal status via a global variable */ if (global_components_ready == global_components_ready_exit && global_components_failed == global_components_failed_exit && global_ready_reached == FALSE) { g_debug ("Components ready/failed achieved. Stopping mailoop"); global_ready_reached = TRUE; } check_loop_quit_condition (); #if 0 /* signal status via a global variable */ if (global_components_failed == global_components_failed_exit) { g_main_loop_quit (global_mainloop); return; } #endif /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar* rfoundation, gpointer data) { g_debug ("test-icetcp:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) ++global_lagent_cands; else if (GPOINTER_TO_UINT (data) == 2) ++global_ragent_cands; check_loop_quit_condition (); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)component_id; (void)lfoundation; (void)rfoundation; } static void cb_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, gchar *foundation, gpointer data) { g_debug ("test-icetcp:%s: %p", G_STRFUNC, data); /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; (void)component_id; (void)foundation; } static void cb_initial_binding_request_received(NiceAgent *agent, guint stream_id, gpointer data) { g_debug ("test-icetcp:%s: %p", G_STRFUNC, data); if (GPOINTER_TO_UINT (data) == 1) global_lagent_ibr_received = TRUE; else if (GPOINTER_TO_UINT (data) == 2) global_ragent_ibr_received = TRUE; if (global_exit_when_ibr_received) { g_debug ("Received initial binding request. Stopping mailoop"); g_main_loop_quit (global_mainloop); } /* XXX: dear compiler, these are for you: */ (void)agent; (void)stream_id; (void)data; } static void set_candidates (NiceAgent *from, guint from_stream, NiceAgent *to, guint to_stream, guint component) { GSList *cands = NULL, *i; cands = nice_agent_get_local_candidates (from, from_stream, component); restart: for (i = cands; i; i = i->next) { NiceCandidate *cand = i->data; if (cand->transport == NICE_CANDIDATE_TRANSPORT_UDP) { cands = g_slist_remove (cands, cand); nice_candidate_free (cand); goto restart; } } nice_agent_set_remote_candidates (to, to_stream, component, cands); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } static void set_credentials (NiceAgent *lagent, guint lstream, NiceAgent *ragent, guint rstream) { gchar *ufrag = NULL, *password = NULL; nice_agent_get_local_credentials(lagent, lstream, &ufrag, &password); nice_agent_set_remote_credentials (ragent, rstream, ufrag, password); g_free (ufrag); g_free (password); nice_agent_get_local_credentials(ragent, rstream, &ufrag, &password); nice_agent_set_remote_credentials (lagent, lstream, ufrag, password); g_free (ufrag); g_free (password); } static int run_full_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed) { guint ls_id, rs_id; gint ret; /* XXX: dear compiler, this is for you */ (void)baseaddr; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = ready; global_components_failed = 0; global_components_failed_exit = failed; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_lagent_cands = global_ragent_cands = 0; global_ready_reached = FALSE; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); /* Gather candidates */ g_assert (nice_agent_gather_candidates (lagent, ls_id) == TRUE); g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE); { GSList *cands = NULL, *i; NiceCandidate *cand = NULL; cands = nice_agent_get_local_candidates (lagent, ls_id, 1); g_assert (g_slist_length (cands) == 2); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE || cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE); cand = cands->next->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE || cand->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-icetcp: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } set_credentials (lagent, ls_id, ragent, rs_id); /* step: pass the remote candidates to agents */ set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP); set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTCP); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTCP); g_debug ("test-icetcp: Set properties, next running mainloop until connectivity checks succeed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ g_main_loop_run (global_mainloop); /* note: verify that STUN binding requests were sent */ g_assert (global_lagent_ibr_received == TRUE); g_assert (global_ragent_ibr_received == TRUE); /* note: test payload send and receive */ global_ragent_read = 0; ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); if (ret == -1) { gboolean reliable = FALSE; g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL); g_debug ("Sending data returned -1 in %s mode", reliable?"Reliable":"Non-reliable"); if (reliable) { gulong signal_handler; signal_handler = g_signal_connect (G_OBJECT (lagent), "reliable-transport-writable", G_CALLBACK (cb_writable), NULL); g_debug ("Running mainloop until transport is writable"); g_main_loop_run (global_mainloop); g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler); ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); } } g_debug ("Sent %d bytes", ret); g_assert (ret == 16); g_main_loop_run (global_mainloop); g_assert (global_ragent_read == 16); g_debug ("test-icetcp: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); return 0; } int main (void) { NiceAgent *lagent, *ragent; /* agent's L and R */ NiceAddress baseaddr; int result; guint timer_id; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif global_mainloop = g_main_loop_new (NULL, FALSE); /* step: create the agents L and R */ lagent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_RFC5245); ragent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY_RFC5245); g_object_set (G_OBJECT (lagent), "ice-udp", FALSE, NULL); g_object_set (G_OBJECT (ragent), "ice-udp", FALSE, NULL); nice_agent_set_software (lagent, "Test-icetcp, Left Agent"); nice_agent_set_software (ragent, "Test-icetcp, Right Agent"); /* step: add a timer to catch state changes triggered by signals */ timer_id = g_timeout_add (30000, timer_cb, NULL); /* step: specify which local interface to use */ if (!nice_address_set_from_string (&baseaddr, "127.0.0.1")) g_assert_not_reached (); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (2)); /* step: run test the first time */ g_debug ("test-icetcp: TEST STARTS / running test for the 1st time"); result = run_full_test (lagent, ragent, &baseaddr, 4 ,0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands >= 2); g_assert (global_ragent_cands >= 2); /* step: run test again without unref'ing agents */ g_debug ("test-icetcp: TEST STARTS / running test for the 2nd time"); result = run_full_test (lagent, ragent, &baseaddr, 4, 0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands >= 2); g_assert (global_ragent_cands >= 2); g_object_unref (lagent); g_object_unref (ragent); g_main_loop_unref (global_mainloop); global_mainloop = NULL; g_source_remove (timer_id); #ifdef G_OS_WIN32 WSACleanup(); #endif return result; } libnice-0.1.14/tests/test-bsd.c0000664000076400007640000003171312661700132013173 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007, 2014 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "socket.h" static gssize socket_recv (NiceSocket *sock, NiceAddress *addr, gsize buf_len, gchar *buf) { GInputVector local_buf = { buf, buf_len }; NiceInputMessage local_message = { &local_buf, 1, addr, 0 }; gint ret; ret = nice_socket_recv_messages (sock, &local_message, 1); if (ret <= 0) return ret; return local_buf.size; } static void test_socket_initial_properties (void) { NiceSocket *sock; sock = nice_udp_bsd_socket_new (NULL); g_assert (sock != NULL); // not bound to a particular interface g_assert_cmpint (sock->addr.s.ip4.sin_addr.s_addr, ==, 0); // is bound to a particular port g_assert_cmpuint (nice_address_get_port (&sock->addr), !=, 0); nice_socket_free (sock); } static void test_socket_address_properties (void) { NiceSocket *sock; NiceAddress tmp; sock = nice_udp_bsd_socket_new (NULL); g_assert (sock != NULL); g_assert (nice_address_set_from_string (&tmp, "127.0.0.1")); g_assert_cmpuint (nice_address_get_port (&sock->addr), !=, 0); nice_address_set_port (&tmp, nice_address_get_port (&sock->addr)); g_assert_cmpuint (nice_address_get_port (&tmp), !=, 0); nice_socket_free (sock); } static void test_simple_send_recv (void) { NiceSocket *server; NiceSocket *client; NiceAddress tmp; gchar buf[5]; server = nice_udp_bsd_socket_new (NULL); g_assert (server != NULL); client = nice_udp_bsd_socket_new (NULL); g_assert (client != NULL); g_assert (nice_address_set_from_string (&tmp, "127.0.0.1")); nice_address_set_port (&tmp, nice_address_get_port (&server->addr)); /* Send and receive stuff. */ g_assert_cmpint (nice_socket_send (client, &tmp, 5, "hello"), ==, 5); g_assert_cmpint (socket_recv (server, &tmp, 5, buf), ==, 5); g_assert_cmpint (strncmp (buf, "hello", 5), ==, 0); g_assert_cmpint (nice_socket_send (server, &tmp, 5, "uryyb"), ==, 5); g_assert_cmpint (socket_recv (client, &tmp, 5, buf), ==, 5); g_assert_cmpint (strncmp (buf, "uryyb", 5), ==, 0); nice_socket_free (client); nice_socket_free (server); } /* Check that sending and receiving to/from zero-length buffers returns * immediately. */ static void test_zero_send_recv (void) { NiceSocket *sock; NiceAddress tmp; gchar buf[5]; NiceOutputMessage local_out_message; NiceInputMessage local_in_message; sock = nice_udp_bsd_socket_new (NULL); g_assert (sock != NULL); g_assert (nice_address_set_from_string (&tmp, "127.0.0.1")); g_assert_cmpuint (nice_address_get_port (&sock->addr), !=, 0); nice_address_set_port (&tmp, nice_address_get_port (&sock->addr)); g_assert_cmpuint (nice_address_get_port (&tmp), !=, 0); g_assert_cmpint (nice_socket_send (sock, &tmp, 0, "ignore-me"), ==, 0); g_assert_cmpint (nice_socket_send (sock, &tmp, 0, NULL), ==, 0); g_assert_cmpint (socket_recv (sock, &tmp, 0, buf), ==, 0); g_assert_cmpint (socket_recv (sock, &tmp, 0, NULL), ==, 0); /* And again with messages. */ g_assert_cmpint (nice_socket_send_messages (sock, &tmp, &local_out_message, 0), ==, 0); g_assert_cmpint (nice_socket_send_messages (sock, &tmp, NULL, 0), ==, 0); g_assert_cmpint (nice_socket_recv_messages (sock, &local_in_message, 0), ==, 0); g_assert_cmpint (nice_socket_recv_messages (sock, NULL, 0), ==, 0); nice_socket_free (sock); } /* Test receiving into multiple tiny buffers. */ static void test_multi_buffer_recv (void) { NiceSocket *server; NiceSocket *client; NiceAddress tmp; guint8 buf[20]; guint8 dummy_buf[9]; server = nice_udp_bsd_socket_new (NULL); g_assert (server != NULL); client = nice_udp_bsd_socket_new (NULL); g_assert (client != NULL); g_assert (nice_address_set_from_string (&tmp, "127.0.0.1")); nice_address_set_port (&tmp, nice_address_get_port (&server->addr)); /* Send and receive stuff. */ { GInputVector bufs[7] = { { &buf[0], 1 }, { &buf[1], 4 }, { &buf[1], 0 }, /* should be unused (zero-length) */ { &buf[5], 1 }, { &buf[6], 5 }, { &buf[11], 9 }, /* should be unused (message fits in prior buffers) */ { &buf[11], 0 }, /* should be unused (zero-length) */ }; NiceInputMessage message = { bufs, G_N_ELEMENTS (bufs), NULL, 0 }; /* Initialise the buffers so we can try and catch out-of-bounds accesses. */ memset (buf, 0xaa, sizeof (buf)); memset (dummy_buf, 0xaa, sizeof (dummy_buf)); /* Send and receive. */ g_assert_cmpint (nice_socket_send (client, &tmp, 11, "hello-world"), ==, 11); g_assert_cmpuint (nice_socket_recv_messages (server, &message, 1), ==, 1); g_assert_cmpuint (message.length, ==, 11); /* Check all of the things. The sizes should not have been modified. */ g_assert_cmpuint (bufs[0].size, ==, 1); g_assert_cmpuint (bufs[1].size, ==, 4); g_assert_cmpuint (bufs[2].size, ==, 0); g_assert_cmpuint (bufs[3].size, ==, 1); g_assert_cmpuint (bufs[4].size, ==, 5); g_assert_cmpuint (bufs[5].size, ==, 9); g_assert_cmpuint (bufs[6].size, ==, 0); g_assert_cmpint (strncmp ((gchar *) buf, "hello-world", 11), ==, 0); g_assert_cmpint (memcmp (buf + 11, dummy_buf, 9), ==, 0); } nice_socket_free (client); nice_socket_free (server); } /* Fill a buffer with deterministic but non-repeated data, so that transmission * and reception corruption is more likely to be detected. */ static void fill_send_buf (guint8 *buf, gsize buf_len, guint seed) { gsize i; for (i = 0; i < buf_len; i++) { buf[i] = '0' + (seed % 10); seed++; } } /* Test receiving multiple messages in a single call. */ static void test_multi_message_recv (guint n_sends, guint n_receives, guint n_bufs_per_message, gsize send_buf_size, gsize recv_buf_size, guint expected_n_received_messages, guint expected_n_sent_messages) { NiceSocket *server; NiceSocket *client; NiceAddress tmp; server = nice_udp_bsd_socket_new (NULL); g_assert (server != NULL); client = nice_udp_bsd_socket_new (NULL); g_assert (client != NULL); g_assert (nice_address_set_from_string (&tmp, "127.0.0.1")); nice_address_set_port (&tmp, nice_address_get_port (&server->addr)); /* Send and receive stuff. */ { GInputVector *recv_bufs; NiceInputMessage *recv_messages; GOutputVector *send_bufs; NiceOutputMessage *send_messages; guint i, j; guint8 *_expected_recv_buf; gsize expected_recv_buf_len; /* Set up the send buffers. */ send_bufs = g_malloc0_n (n_sends * n_bufs_per_message, sizeof (GOutputVector)); send_messages = g_malloc0_n (n_sends, sizeof (NiceOutputMessage)); for (i = 0; i < n_sends; i++) { for (j = 0; j < n_bufs_per_message; j++) { guint8 *buf = g_slice_alloc (send_buf_size); send_bufs[i * n_bufs_per_message + j].buffer = buf; send_bufs[i * n_bufs_per_message + j].size = send_buf_size; /* Set up the buffer data. */ fill_send_buf (buf, send_buf_size, i); } send_messages[i].buffers = send_bufs + i * n_bufs_per_message; send_messages[i].n_buffers = n_bufs_per_message; } /* Set up the receive buffers. Yay for dynamic tests! */ recv_bufs = g_malloc0_n (n_receives * n_bufs_per_message, sizeof (GInputVector)); recv_messages = g_malloc0_n (n_receives, sizeof (NiceInputMessage)); for (i = 0; i < n_receives; i++) { for (j = 0; j < n_bufs_per_message; j++) { recv_bufs[i * n_bufs_per_message + j].buffer = g_slice_alloc (recv_buf_size); recv_bufs[i * n_bufs_per_message + j].size = recv_buf_size; /* Initialise the buffer to try to catch out-of-bounds accesses. */ memset (recv_bufs[i * n_bufs_per_message + j].buffer, 0xaa, recv_buf_size); } recv_messages[i].buffers = recv_bufs + i * n_bufs_per_message; recv_messages[i].n_buffers = n_bufs_per_message; recv_messages[i].from = NULL; recv_messages[i].length = 0; } /* Send multiple packets. */ g_assert_cmpint ( nice_socket_send_messages (client, &tmp, send_messages, n_sends), ==, expected_n_sent_messages); /* Receive things. */ g_assert_cmpint ( nice_socket_recv_messages (server, recv_messages, n_receives), ==, expected_n_received_messages); /* Check all of the things. The sizes should not have been modified. */ expected_recv_buf_len = recv_buf_size * n_bufs_per_message; _expected_recv_buf = g_slice_alloc (expected_recv_buf_len); for (i = 0; i < expected_n_received_messages; i++) { NiceInputMessage *message = &recv_messages[i]; guint8 *expected_recv_buf = _expected_recv_buf; gsize expected_len; expected_len = MIN (send_buf_size * n_bufs_per_message, expected_recv_buf_len); g_assert_cmpuint (message->length, ==, expected_len); /* Build the expected buffer as a concatenation of the expected values of * all receive buffers in the message. */ memset (expected_recv_buf, 0xaa, expected_recv_buf_len); fill_send_buf (expected_recv_buf, expected_len, i); for (j = 0; j < n_bufs_per_message; j++) { g_assert_cmpuint (message->buffers[j].size, ==, recv_buf_size); g_assert_cmpint ( memcmp (message->buffers[j].buffer, expected_recv_buf, recv_buf_size), ==, 0); expected_recv_buf += recv_buf_size; } } g_slice_free1 (expected_recv_buf_len, _expected_recv_buf); for (i = 0; i < n_receives; i++) { for (j = 0; j < n_bufs_per_message; j++) { g_slice_free1 (recv_buf_size, recv_bufs[i * n_bufs_per_message + j].buffer); } } for (i = 0; i < n_sends; i++) { for (j = 0; j < n_bufs_per_message; j++) { g_slice_free1 (send_buf_size, (gpointer) send_bufs[i * n_bufs_per_message + j].buffer); } } g_free (recv_messages); g_free (recv_bufs); g_free (send_messages); g_free (send_bufs); } nice_socket_free (client); nice_socket_free (server); } int main (void) { test_socket_initial_properties (); test_socket_address_properties (); test_simple_send_recv (); test_zero_send_recv (); test_multi_buffer_recv (); /* Multi-message testing. Serious business. */ { guint i; struct { guint n_sends; /* messages */ guint expected_n_sent_messages; guint n_receives; /* messages */ guint expected_n_received_messages; guint n_bufs_per_message; gsize send_buf_size; gsize recv_buf_size; } test_cases[] = { /* same number of sends and receives */ { 2, 2, 2, 2, 1, 100, 100 }, /* send 200B, receive 200B */ /* more sends than receives */ { 4, 4, 2, 2, 2, 100, 77 }, /* send 800B, receive 308B */ /* more receives than sends */ { 1, 1, 4, 1, 4, 10, 100 }, /* send 40B, receive 1600B */ /* small receive buffer (data loss) */ { 100, 100, 100, 100, 1, 100, 64 }, /* send 10000B, receive 6400B */ /* small receive buffers (data loss) */ { 50, 50, 50, 50, 10, 100, 8 }, /* send 50000B, receive 4000B */ }; for (i = 0; i < G_N_ELEMENTS (test_cases); i++) { test_multi_message_recv (test_cases[i].n_sends, test_cases[i].n_receives, test_cases[i].n_bufs_per_message, test_cases[i].send_buf_size, test_cases[i].recv_buf_size, test_cases[i].expected_n_received_messages, test_cases[i].expected_n_sent_messages); } } return 0; } libnice-0.1.14/socket/0000775000076400007640000000000013070512356011507 500000000000000libnice-0.1.14/socket/socks5.c0000664000076400007640000003533512724137775013030 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See * http://en.wikipedia.org/wiki/Berkeley_sockets.) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "socks5.h" #include "agent-priv.h" #include "socket-priv.h" #include #ifndef G_OS_WIN32 #include #endif typedef enum { SOCKS_STATE_INIT, SOCKS_STATE_AUTH, SOCKS_STATE_CONNECT, SOCKS_STATE_CONNECTED, SOCKS_STATE_ERROR } SocksState; typedef struct { SocksState state; NiceSocket *base_socket; NiceAddress addr; gchar *username; gchar *password; GQueue send_queue; } Socks5Priv; static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other); NiceSocket * nice_socks5_socket_new (NiceSocket *base_socket, NiceAddress *addr, gchar *username, gchar *password) { Socks5Priv *priv; NiceSocket *sock = NULL; if (addr) { sock = g_slice_new0 (NiceSocket); sock->priv = priv = g_slice_new0 (Socks5Priv); priv->base_socket = base_socket; priv->addr = *addr; priv->username = g_strdup (username); priv->password = g_strdup (password); sock->type = NICE_SOCKET_TYPE_SOCKS5; sock->fileno = priv->base_socket->fileno; sock->addr = priv->base_socket->addr; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->is_based_on = socket_is_based_on; sock->close = socket_close; /* Send SOCKS5 handshake */ { gchar msg[4]; gint len = 3; msg[0] = 0x05; /* SOCKS version */ msg[1] = 0x01; /* number of methods supported */ msg[2] = 0x00; /* no authentication method*/ g_debug ("user/pass : %s - %s", username, password); /* add support for authentication method */ if (username || password) { msg[1] = 0x02; /* number of methods supported */ msg[3] = 0x02; /* authentication method */ len++; } /* We send 'to' NULL because it will always be to an already connected * TCP base socket, which ignores the destination */ nice_socket_send_reliable (priv->base_socket, NULL, len, msg); priv->state = SOCKS_STATE_INIT; } } return sock; } static void socket_close (NiceSocket *sock) { Socks5Priv *priv = sock->priv; if (priv->base_socket) nice_socket_free (priv->base_socket); if (priv->username) g_free (priv->username); if (priv->password) g_free (priv->password); nice_socket_free_send_queue (&priv->send_queue); g_slice_free(Socks5Priv, sock->priv); sock->priv = NULL; } static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { Socks5Priv *priv = sock->priv; guint i; gint ret = -1; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); switch (priv->state) { case SOCKS_STATE_CONNECTED: /* Common case: fast pass-through to the base socket once we’re * connected. */ if (priv->base_socket) { ret = nice_socket_recv_messages (priv->base_socket, recv_messages, n_recv_messages); } if (ret <= 0) return ret; /* After successfully receiving into at least one NiceInputMessage, * update the from address in each valid NiceInputMessage. */ for (i = 0; i < (guint) ret; i++) { if (recv_messages[i].from != NULL) *recv_messages[i].from = priv->addr; } return ret; case SOCKS_STATE_INIT: { guint8 data[2]; GInputVector local_recv_buf = { data, sizeof (data) }; NiceInputMessage local_recv_message = { &local_recv_buf, 1, NULL, 0 }; nice_debug ("Socks5 state Init"); if (priv->base_socket) { ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); } if (ret <= 0) { return ret; } else if (ret == 1 && local_recv_buf.size == sizeof(data)) { if (data[0] == 0x05) { if (data[1] == 0x02) { gchar msg[515]; gint len = 0; if (priv->username || priv->password) { gint ulen = 0; gint plen = 0; if (priv->username) ulen = strlen (priv->username); if (ulen > 255) { nice_debug ("Socks5 username length > 255"); goto error; } if (priv->password) plen = strlen (priv->password); if (plen > 255) { nice_debug ("Socks5 password length > 255"); goto error; } msg[len++] = 0x01; /* auth version */ msg[len++] = ulen; /* username length */ if (ulen > 0) memcpy (msg + len, priv->username, ulen); /* Username */ len += ulen; msg[len++] = plen; /* Password length */ if (plen > 0) memcpy (msg + len, priv->password, plen); /* Password */ len += plen; nice_socket_send_reliable (priv->base_socket, NULL, len, msg); priv->state = SOCKS_STATE_AUTH; } else { /* Authentication required but no auth info available */ goto error; } } else if (data[1] == 0x00) { goto send_connect; } else { /* method not supported by socks server */ goto error; } } else { /* invalid SOCKS server version */ goto error; } } else { /* read error */ goto error; } } break; case SOCKS_STATE_AUTH: { guint8 data[2]; GInputVector local_recv_buf = { data, sizeof (data) }; NiceInputMessage local_recv_message = { &local_recv_buf, 1, NULL, 0 }; nice_debug ("Socks5 state auth"); if (priv->base_socket) { ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); } if (ret <= 0) { return ret; } else if (ret == 1 && local_recv_buf.size == sizeof(data)) { if (data[0] == 0x01 && data[1] == 0x00) { /* Authenticated */ goto send_connect; } else { /* Authentication failed */ goto error; } } } break; case SOCKS_STATE_CONNECT: { guint8 data[22]; GInputVector local_recv_buf = { data, sizeof (data) }; NiceInputMessage local_recv_message = { &local_recv_buf, 1, NULL, 0 }; nice_debug ("Socks5 state connect"); if (priv->base_socket) { local_recv_buf.size = 4; ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); } if (ret <= 0) { return ret; } else if (ret == 1 && local_recv_buf.size == 4) { if (data[0] == 0x05) { switch (data[1]) { case 0x00: if (data[2] == 0x00) { switch (data[3]) { case 0x01: /* IPV4 bound address */ local_recv_buf.size = 6; ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); if (ret != 1 || local_recv_buf.size != 6) { /* Could not read server bound address */ goto error; } break; case 0x04: /* IPV6 bound address */ local_recv_buf.size = 18; ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); if (ret != 1 || local_recv_buf.size != 18) { /* Could not read server bound address */ goto error; } break; default: /* Unsupported address type */ goto error; } nice_socket_flush_send_queue (priv->base_socket, &priv->send_queue); priv->state = SOCKS_STATE_CONNECTED; } else { /* Wrong reserved value */ goto error; } break; case 0x01: /* general SOCKS server failure */ case 0x02: /* connection not allowed by ruleset */ case 0x03: /* Network unreachable */ case 0x04: /* Host unreachable */ case 0x05: /* Connection refused */ case 0x06: /* TTL expired */ case 0x07: /* Command not supported */ case 0x08: /* Address type not supported */ default: /* Unknown error */ goto error; break; } } else { /* Wrong server version */ goto error; } } else { /* Invalid data received */ goto error; } } break; case SOCKS_STATE_ERROR: default: /* Unknown status */ goto error; } return 0; send_connect: { gchar msg[22]; gint len = 0; union { struct sockaddr_storage storage; struct sockaddr addr; struct sockaddr_in in; struct sockaddr_in6 in6; } name; nice_address_copy_to_sockaddr(&priv->addr, &name.addr); msg[len++] = 0x05; /* SOCKS version */ msg[len++] = 0x01; /* connect command */ msg[len++] = 0x00; /* reserved */ if (name.storage.ss_family == AF_INET) { msg[len++] = 0x01; /* IPV4 address type */ /* Address */ memcpy (msg + len, &(&name.in)->sin_addr, 4); len += 4; /* Port */ memcpy (msg + len, &(&name.in)->sin_port, 2); len += 2; } else if (name.storage.ss_family == AF_INET6) { msg[len++] = 0x04; /* IPV6 address type */ /* Address */ memcpy (msg + len, &(&name.in6)->sin6_addr, 16); len += 16; /* Port */ memcpy (msg + len, &(&name.in6)->sin6_port, 2); len += 2; } nice_socket_send_reliable (priv->base_socket, NULL, len, msg); priv->state = SOCKS_STATE_CONNECT; return 0; } error: nice_debug ("Socks5 error"); if (priv->base_socket) nice_socket_free (priv->base_socket); priv->base_socket = NULL; priv->state = SOCKS_STATE_ERROR; return -1; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { Socks5Priv *priv = sock->priv; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); if (priv->state == SOCKS_STATE_CONNECTED) { /* Fast path: pass through to the base socket once connected. */ if (priv->base_socket == NULL) return -1; return nice_socket_send_messages (priv->base_socket, to, messages, n_messages); } else if (priv->state == SOCKS_STATE_ERROR) { return -1; } else { return 0; } } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { Socks5Priv *priv = sock->priv; if (priv->state == SOCKS_STATE_CONNECTED) { /* Fast path: pass through to the base socket once connected. */ if (priv->base_socket == NULL) return -1; return nice_socket_send_messages_reliable (priv->base_socket, to, messages, n_messages); } else if (priv->state == SOCKS_STATE_ERROR) { return -1; } else { nice_socket_queue_send (&priv->send_queue, to, messages, n_messages); } return n_messages; } static gboolean socket_is_reliable (NiceSocket *sock) { Socks5Priv *priv = sock->priv; return nice_socket_is_reliable (priv->base_socket); } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { Socks5Priv *priv = sock->priv; return nice_socket_can_send (priv->base_socket, addr); } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { Socks5Priv *priv = sock->priv; nice_socket_set_writable_callback (priv->base_socket, callback, user_data); } static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other) { Socks5Priv *priv = sock->priv; return (sock == other) || (priv && nice_socket_is_based_on (priv->base_socket, other)); } libnice-0.1.14/socket/tcp-bsd.h0000664000076400007640000000364412520743534013146 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _TCP_BSD_H #define _TCP_BSD_H #include "socket.h" G_BEGIN_DECLS NiceSocket * nice_tcp_bsd_socket_new (GMainContext *ctx, NiceAddress *remote_addr, NiceAddress *local_addr, gboolean reliable); NiceSocket * nice_tcp_bsd_socket_new_from_gsock (GMainContext *ctx, GSocket *gsock, NiceAddress *remote_addr, NiceAddress *local_addr, gboolean reliable); G_END_DECLS #endif /* _TCP_BSD_H */ libnice-0.1.14/socket/udp-bsd.c0000664000076400007640000002242313070461476013142 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Implementation of UDP socket interface using Berkeley sockets. (See * http://en.wikipedia.org/wiki/Berkeley_sockets.) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include "udp-bsd.h" #include "agent-priv.h" #ifndef G_OS_WIN32 #include #endif static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); struct UdpBsdSocketPrivate { NiceAddress niceaddr; GSocketAddress *gaddr; }; NiceSocket * nice_udp_bsd_socket_new (NiceAddress *addr) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; NiceSocket *sock = g_slice_new0 (NiceSocket); GSocket *gsock = NULL; gboolean gret = FALSE; GSocketAddress *gaddr; struct UdpBsdSocketPrivate *priv; if (addr != NULL) { nice_address_copy_to_sockaddr(addr, &name.addr); } else { memset (&name, 0, sizeof (name)); name.storage.ss_family = AF_UNSPEC; } if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in); #endif } else if (name.storage.ss_family == AF_INET6) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in6); #endif } if (gsock == NULL) { g_slice_free (NiceSocket, sock); return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr != NULL) { gret = g_socket_bind (gsock, gaddr, FALSE, NULL); g_object_unref (gaddr); } if (gret == FALSE) { g_slice_free (NiceSocket, sock); g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } gaddr = g_socket_get_local_address (gsock, NULL); if (gaddr == NULL || !g_socket_address_to_native (gaddr, &name.addr, sizeof(name), NULL)) { g_slice_free (NiceSocket, sock); g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_object_unref (gaddr); nice_address_set_from_sockaddr (&sock->addr, &name.addr); priv = sock->priv = g_slice_new0 (struct UdpBsdSocketPrivate); nice_address_init (&priv->niceaddr); sock->type = NICE_SOCKET_TYPE_UDP_BSD; sock->fileno = gsock; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->close = socket_close; return sock; } static void socket_close (NiceSocket *sock) { struct UdpBsdSocketPrivate *priv = sock->priv; if (priv->gaddr) g_object_unref (priv->gaddr); g_slice_free (struct UdpBsdSocketPrivate, sock->priv); sock->priv = NULL; if (sock->fileno) { g_socket_close (sock->fileno, NULL); g_object_unref (sock->fileno); sock->fileno = NULL; } } static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { guint i; gboolean error = FALSE; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); /* Read messages into recv_messages until one fails or would block, or we * reach the end. */ for (i = 0; i < n_recv_messages; i++) { NiceInputMessage *recv_message = &recv_messages[i]; GSocketAddress *gaddr = NULL; GError *gerr = NULL; gssize recvd; gint flags = G_SOCKET_MSG_NONE; recvd = g_socket_receive_message (sock->fileno, (recv_message->from != NULL) ? &gaddr : NULL, recv_message->buffers, recv_message->n_buffers, NULL, NULL, &flags, NULL, &gerr); recv_message->length = MAX (recvd, 0); if (recvd < 0) { /* Handle ECONNRESET here as if it were EWOULDBLOCK; see * https://phabricator.freedesktop.org/T121 */ if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) || g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED)) recvd = 0; else error = TRUE; g_error_free (gerr); } if (recvd > 0 && recv_message->from != NULL && gaddr != NULL) { union { struct sockaddr_storage storage; struct sockaddr addr; } sa; g_socket_address_to_native (gaddr, &sa.addr, sizeof (sa), NULL); nice_address_set_from_sockaddr (recv_message->from, &sa.addr); } if (gaddr != NULL) g_object_unref (gaddr); /* Return early on error or EWOULDBLOCK. */ if (recvd <= 0) break; } /* Was there an error processing the first message? */ if (error && i == 0) return -1; return i; } static gssize socket_send_message (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *message) { struct UdpBsdSocketPrivate *priv = sock->priv; GError *child_error = NULL; gssize len; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); if (!nice_address_is_valid (&priv->niceaddr) || !nice_address_equal (&priv->niceaddr, to)) { union { struct sockaddr_storage storage; struct sockaddr addr; } sa; GSocketAddress *gaddr; if (priv->gaddr) g_object_unref (priv->gaddr); nice_address_copy_to_sockaddr (to, &sa.addr); gaddr = g_socket_address_new_from_native (&sa.addr, sizeof(sa)); priv->gaddr = gaddr; if (gaddr == NULL) return -1; priv->niceaddr = *to; } len = g_socket_send_message (sock->fileno, priv->gaddr, message->buffers, message->n_buffers, NULL, 0, G_SOCKET_MSG_NONE, NULL, &child_error); if (len < 0) { if (g_error_matches (child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { len = 0; } else { nice_debug_verbose ("%s: udp-bsd socket %p: error: %s", G_STRFUNC, sock, child_error->message); } g_error_free (child_error); } return len; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { guint i; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; gssize len; len = socket_send_message (sock, to, message); if (len < 0) { /* Error. */ if (i > 0) break; return len; } else if (len == 0) { /* EWOULDBLOCK. */ break; } } return i; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { return -1; } static gboolean socket_is_reliable (NiceSocket *sock) { return FALSE; } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { return TRUE; } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { } libnice-0.1.14/socket/socket-priv.h0000664000076400007640000001043012520743534014047 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _SOCKET_PRIV_H #define _SOCKET_PRIV_H #include "socket.h" G_BEGIN_DECLS /** * nice_socket_queue_send: * @send_queue: The queue to add to * @to : Destination * @messages: Messages to queue * @n_messages: Number of messages to queue * * Queue messages to be sent later into the GQueue */ void nice_socket_queue_send (GQueue *send_queue, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); /** * nice_socket_queue_send_with_callback: * @send_queue: The queue to add to * @message: The message to queue * @message_offset: Number of bytes to skip in the message * @message_len: Total length of the message * @head: Whether to add the message to the head of the queue or the tail * @gsock: The #GSocket to create the callback on * @io_source: Pointer to #GSource pointer to store the created source * @context: #GMainContext to attach the @io_source to * @cb: Callback function to call when the @gsock is writable * @user_data: User data for @cb * * Queue (partial) message to be sent later and create a source to call @cb * when the @gsock becomes writable. * The @message_offset can be used if a partial write happened and some bytes * were already written, in which case @head should be set to TRUE to add the * message to the head of the queue. */ void nice_socket_queue_send_with_callback (GQueue *send_queue, const NiceOutputMessage *message, gsize message_offset, gsize message_len, gboolean head, GSocket *gsock, GSource **io_source, GMainContext *context, GSourceFunc cb, gpointer user_data); /** * nice_socket_flush_send_queue: * @base_socket: Base socket to send on * @send_queue: Queue to flush * * Send all the queued messages reliably to the base socket. We assume only * reliable messages were queued and the underlying socket will handle the * send. */ void nice_socket_flush_send_queue (NiceSocket *base_socket, GQueue *send_queue); /** * nice_socket_flush_send_queue_to_socket: * @gsock: GSocket to send on * @send_queue: Queue to flush * * Send all the queued messages to the socket. If any message fails to be sent * it will be readded to the queue and #FALSE will be returned, in which case * the IO source must be kept to allow flushing the next time the socket * is writable. * If the queue gets flushed, #TRUE will be returned, in which case, the IO * source should be destroyed. * * Returns: #TRUE if the queue was emptied, #FALSE if the socket would block. */ gboolean nice_socket_flush_send_queue_to_socket (GSocket *gsock, GQueue *send_queue); /** * nice_socket_free_send_queue: * @send_queue: The send queue * * Frees every item in the send queue without sending them and empties the queue */ void nice_socket_free_send_queue (GQueue *send_queue); G_END_DECLS #endif /* _SOCKET_PRIV_H */ libnice-0.1.14/socket/tcp-active.h0000664000076400007640000000336712520743534013653 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _TCP_ACTIVE_H #define _TCP_ACTIVE_H #include "socket.h" G_BEGIN_DECLS NiceSocket * nice_tcp_active_socket_new (GMainContext *ctx, NiceAddress *addr); NiceSocket * nice_tcp_active_socket_connect (NiceSocket *socket, NiceAddress *addr); G_END_DECLS #endif /* _TCP_ACTIVE_H */ libnice-0.1.14/socket/Makefile.in0000664000076400007640000005122213070512350013470 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = socket ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsocket_la_LIBADD = am_libsocket_la_OBJECTS = socket.lo udp-bsd.lo tcp-bsd.lo \ tcp-active.lo tcp-passive.lo pseudossl.lo socks5.lo http.lo \ udp-turn.lo udp-turn-over-tcp.lo libsocket_la_OBJECTS = $(am_libsocket_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libsocket_la_SOURCES) DIST_SOURCES = $(libsocket_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda AM_CFLAGS = \ -DG_LOG_DOMAIN=\"libnice-socket\" \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUPNP_CFLAGS) \ -I $(top_srcdir)/random \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/ noinst_LTLIBRARIES = libsocket.la libsocket_la_SOURCES = \ socket.h \ socket-priv.h \ socket.c \ udp-bsd.h \ udp-bsd.c \ tcp-bsd.h \ tcp-bsd.c \ tcp-active.h \ tcp-active.c \ tcp-passive.h \ tcp-passive.c \ pseudossl.h \ pseudossl.c \ socks5.h \ socks5.c \ http.h \ http.c \ udp-turn.h \ udp-turn.c \ udp-turn-over-tcp.h \ udp-turn-over-tcp.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu socket/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu socket/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libsocket.la: $(libsocket_la_OBJECTS) $(libsocket_la_DEPENDENCIES) $(EXTRA_libsocket_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsocket_la_OBJECTS) $(libsocket_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pseudossl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socks5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp-active.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp-bsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp-passive.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udp-bsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udp-turn-over-tcp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udp-turn.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/socket/Makefile.am0000664000076400007640000000140712520743534013470 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include $(top_srcdir)/common.mk AM_CFLAGS = \ -DG_LOG_DOMAIN=\"libnice-socket\" \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUPNP_CFLAGS) \ -I $(top_srcdir)/random \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/ noinst_LTLIBRARIES = libsocket.la libsocket_la_SOURCES = \ socket.h \ socket-priv.h \ socket.c \ udp-bsd.h \ udp-bsd.c \ tcp-bsd.h \ tcp-bsd.c \ tcp-active.h \ tcp-active.c \ tcp-passive.h \ tcp-passive.c \ pseudossl.h \ pseudossl.c \ socks5.h \ socks5.c \ http.h \ http.c \ udp-turn.h \ udp-turn.c \ udp-turn-over-tcp.h \ udp-turn-over-tcp.c libnice-0.1.14/socket/tcp-bsd.c0000664000076400007640000003054212724137775013150 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See * http://en.wikipedia.org/wiki/Berkeley_sockets.) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "tcp-bsd.h" #include "agent-priv.h" #include "socket-priv.h" #include #include #include #ifndef G_OS_WIN32 #include #endif /* FIXME: This should be defined in gio/gnetworking.h, which we should include; * but we cannot do that without refactoring. * (See: https://phabricator.freedesktop.org/D230). */ #define TCP_NODELAY 1 typedef struct { NiceAddress remote_addr; GQueue send_queue; GMainContext *context; GSource *io_source; gboolean error; gboolean reliable; NiceSocketWritableCb writable_cb; gpointer writable_data; } TcpPriv; #define MAX_QUEUE_LENGTH 20 static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); static gboolean socket_send_more (GSocket *gsocket, GIOCondition condition, gpointer data); NiceSocket * nice_tcp_bsd_socket_new_from_gsock (GMainContext *ctx, GSocket *gsock, NiceAddress *local_addr, NiceAddress *remote_addr, gboolean reliable) { NiceSocket *sock; TcpPriv *priv; g_return_val_if_fail (G_IS_SOCKET (gsock), NULL); sock = g_slice_new0 (NiceSocket); sock->priv = priv = g_slice_new0 (TcpPriv); if (ctx == NULL) ctx = g_main_context_default (); priv->context = g_main_context_ref (ctx); priv->remote_addr = *remote_addr; priv->error = FALSE; priv->reliable = reliable; priv->writable_cb = NULL; priv->writable_data = NULL; sock->type = NICE_SOCKET_TYPE_TCP_BSD; sock->fileno = g_object_ref (gsock); sock->addr = *local_addr; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->close = socket_close; return sock; } NiceSocket * nice_tcp_bsd_socket_new (GMainContext *ctx, NiceAddress *local_addr, NiceAddress *remote_addr, gboolean reliable) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; NiceSocket *sock; GSocket *gsock = NULL; GError *gerr = NULL; gboolean gret = FALSE; GSocketAddress *gaddr; if (remote_addr == NULL) { /* We can't connect a tcp socket with no destination address */ return NULL; } nice_address_copy_to_sockaddr (remote_addr, &name.addr); if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in); #endif } else if (name.storage.ss_family == AF_INET6) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in6); #endif } if (gsock == NULL) { return NULL; } gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_object_unref (gsock); return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); /* setting TCP_NODELAY to TRUE in order to avoid packet batching */ g_socket_set_option (gsock, IPPROTO_TCP, TCP_NODELAY, TRUE, NULL); gret = g_socket_connect (gsock, gaddr, NULL, &gerr); g_object_unref (gaddr); if (gret == FALSE) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) { g_error_free (gerr); g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_error_free (gerr); } nice_address_copy_to_sockaddr (local_addr, &name.addr); gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_socket_bind (gsock, gaddr, FALSE, NULL); g_object_unref (gaddr); sock = nice_tcp_bsd_socket_new_from_gsock (ctx, gsock, local_addr, remote_addr, reliable); g_object_unref (gsock); return sock; } static void socket_close (NiceSocket *sock) { TcpPriv *priv = sock->priv; if (sock->fileno) { g_socket_close (sock->fileno, NULL); g_object_unref (sock->fileno); sock->fileno = NULL; } if (priv->io_source) { g_source_destroy (priv->io_source); g_source_unref (priv->io_source); } nice_socket_free_send_queue (&priv->send_queue); if (priv->context) g_main_context_unref (priv->context); g_slice_free(TcpPriv, sock->priv); } static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { TcpPriv *priv = sock->priv; guint i; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); /* Don't try to access the socket if it had an error */ if (priv->error) return -1; for (i = 0; i < n_recv_messages; i++) { gint flags = G_SOCKET_MSG_NONE; GError *gerr = NULL; gssize len; len = g_socket_receive_message (sock->fileno, NULL, recv_messages[i].buffers, recv_messages[i].n_buffers, NULL, NULL, &flags, NULL, &gerr); recv_messages[i].length = MAX (len, 0); /* recv returns 0 when the peer performed a shutdown.. we must return -1 * here so that the agent destroys the g_source */ if (len == 0) { priv->error = TRUE; break; } if (len < 0) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) len = 0; g_error_free (gerr); return len; } if (recv_messages[i].from) *recv_messages[i].from = priv->remote_addr; } /* Was there an error processing the first message? */ if (priv->error && i == 0) return -1; return i; } static gssize socket_send_message (NiceSocket *sock, const NiceOutputMessage *message, gboolean reliable) { TcpPriv *priv = sock->priv; gssize ret; GError *gerr = NULL; gsize message_len; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); /* Don't try to access the socket if it had an error, otherwise we risk a * crash with SIGPIPE (Broken pipe) */ if (priv->error) return -1; message_len = output_message_get_size (message); /* First try to send the data, don't send it later if it can be sent now * this way we avoid allocating memory on every send */ if (g_queue_is_empty (&priv->send_queue)) { ret = g_socket_send_message (sock->fileno, NULL, message->buffers, message->n_buffers, NULL, 0, G_SOCKET_MSG_NONE, NULL, &gerr); if (ret < 0) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) || g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_FAILED)) { /* Queue the message and send it later. */ nice_socket_queue_send_with_callback (&priv->send_queue, message, 0, message_len, FALSE, sock->fileno, &priv->io_source, priv->context, (GSourceFunc) socket_send_more, sock); ret = message_len; } g_error_free (gerr); } else if ((gsize) ret < message_len) { /* Partial send. */ nice_socket_queue_send_with_callback (&priv->send_queue, message, ret, message_len, TRUE, sock->fileno, &priv->io_source, priv->context, (GSourceFunc) socket_send_more, sock); ret = message_len; } } else { /* Only queue if we're sending reliably */ if (reliable) { /* Queue the message and send it later. */ nice_socket_queue_send_with_callback (&priv->send_queue, message, 0, message_len, FALSE, sock->fileno, &priv->io_source, priv->context, (GSourceFunc) socket_send_more, sock); ret = message_len; } else { /* non reliable send, so we shouldn't queue the message */ ret = 0; } } return ret; } /* Data sent to this function must be a single entity because buffers can be * dropped if the bandwidth isn't fast enough. So do not send a message in * multiple chunks. */ static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { guint i; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; gssize len; len = socket_send_message (sock, message, FALSE); if (len < 0) { /* Error. */ if (i > 0) break; return len; } else if (len == 0) { /* EWOULDBLOCK. */ break; } } return i; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { guint i; for (i = 0; i < n_messages; i++) { if (socket_send_message (sock, &messages[i], TRUE) < 0) { /* Error. */ return -1; } } return i; } static gboolean socket_is_reliable (NiceSocket *sock) { TcpPriv *priv = sock->priv; return priv->reliable; } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { TcpPriv *priv = sock->priv; return g_queue_is_empty (&priv->send_queue); } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { TcpPriv *priv = sock->priv; priv->writable_cb = callback; priv->writable_data = user_data; } static gboolean socket_send_more ( GSocket *gsocket, GIOCondition condition, gpointer data) { NiceSocket *sock = (NiceSocket *) data; TcpPriv *priv = sock->priv; agent_lock (); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in tcp-bsd.c:socket_send_more"); agent_unlock (); return FALSE; } /* connection hangs up or queue was emptied */ if (condition & G_IO_HUP || nice_socket_flush_send_queue_to_socket (sock->fileno, &priv->send_queue)) { g_source_destroy (priv->io_source); g_source_unref (priv->io_source); priv->io_source = NULL; agent_unlock (); if (priv->writable_cb) priv->writable_cb (sock, priv->writable_data); return FALSE; } agent_unlock (); return TRUE; } libnice-0.1.14/socket/tcp-active.c0000664000076400007640000001665112724137775013660 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2012 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * George Kiagiadakis, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "socket.h" #include "tcp-active.h" #include #include #include #ifndef G_OS_WIN32 #include #endif /* FIXME: This should be defined in gio/gnetworking.h, which we should include; * but we cannot do that without refactoring. * (See: https://phabricator.freedesktop.org/D230). */ #define TCP_NODELAY 1 typedef struct { GSocketAddress *local_addr; GMainContext *context; } TcpActivePriv; static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); NiceSocket * nice_tcp_active_socket_new (GMainContext *ctx, NiceAddress *addr) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; NiceSocket *sock; TcpActivePriv *priv; GSocketAddress *gaddr; NiceAddress local_addr; if (addr != NULL) { local_addr = *addr; /* Make sure we don't bind to any local port */ nice_address_set_port (&local_addr, 0); nice_address_copy_to_sockaddr(&local_addr, &name.addr); } else { memset (&local_addr, 0, sizeof (local_addr)); memset (&name, 0, sizeof (name)); name.storage.ss_family = AF_UNSPEC; } gaddr = g_socket_address_new_from_native (&name, sizeof (name)); if (gaddr == NULL) { return NULL; } if (ctx == NULL) { ctx = g_main_context_default (); } sock = g_slice_new0 (NiceSocket); sock->priv = priv = g_slice_new0 (TcpActivePriv); priv->context = g_main_context_ref (ctx); priv->local_addr = gaddr; sock->type = NICE_SOCKET_TYPE_TCP_ACTIVE; sock->fileno = NULL; sock->addr = local_addr; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->close = socket_close; return sock; } static void socket_close (NiceSocket *sock) { TcpActivePriv *priv = sock->priv; if (priv->context) g_main_context_unref (priv->context); if (priv->local_addr) g_object_unref (priv->local_addr); g_slice_free(TcpActivePriv, sock->priv); } static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { return -1; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { return -1; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { return -1; } static gboolean socket_is_reliable (NiceSocket *sock) { return TRUE; } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { return FALSE; } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { } NiceSocket * nice_tcp_active_socket_connect (NiceSocket *sock, NiceAddress *addr) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; TcpActivePriv *priv = sock->priv; GSocket *gsock = NULL; GError *gerr = NULL; gboolean gret = FALSE; GSocketAddress *gaddr; NiceAddress local_addr; NiceSocket *new_socket = NULL; if (addr == NULL) { /* We can't connect a tcp socket with no destination address */ return NULL; } nice_address_copy_to_sockaddr (addr, &name.addr); if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in); #endif } else if (name.storage.ss_family == AF_INET6) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in6); #endif } if (gsock == NULL) { return NULL; } gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_object_unref (gsock); return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); /* setting TCP_NODELAY to TRUE in order to avoid packet batching */ g_socket_set_option (gsock, IPPROTO_TCP, TCP_NODELAY, TRUE, NULL); /* Allow g_socket_bind to fail */ g_socket_bind (gsock, priv->local_addr, FALSE, NULL); gret = g_socket_connect (gsock, gaddr, NULL, &gerr); g_object_unref (gaddr); if (gret == FALSE) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_PENDING) == FALSE) { g_error_free (gerr); g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_error_free (gerr); } gaddr = g_socket_get_local_address (gsock, NULL); if (gaddr == NULL || !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_object_unref (gaddr); nice_address_set_from_sockaddr (&local_addr, &name.addr); new_socket = nice_tcp_bsd_socket_new_from_gsock (priv->context, gsock, &local_addr, addr, TRUE); g_object_unref (gsock); return new_socket; } libnice-0.1.14/socket/pseudossl.h0000664000076400007640000000432412520743534013627 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _PSEUDOSSL_H #define _PSEUDOSSL_H #include "socket.h" G_BEGIN_DECLS /** * PseudosslCompatibility: * @NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE: Use google compatible pseudossl * @NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC: Use compatibility for Microsoft * Office Communicator and Lync servers * * An enum to specify which pseudo SSL compatibility mode the #NiceSocket should * use. */ typedef enum { NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE = 0, NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC, } NicePseudoSSLSocketCompatibility; NiceSocket * nice_pseudossl_socket_new (NiceSocket *base_socket, NicePseudoSSLSocketCompatibility compatibility); G_END_DECLS #endif /* _PSEUDOSSL_H */ libnice-0.1.14/socket/udp-turn.c0000664000076400007640000020066413070471330013355 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Implementation of TURN */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "udp-turn.h" #include "stun/stunagent.h" #include "stun/usages/timer.h" #include "agent-priv.h" #define STUN_END_TIMEOUT 8000 #define STUN_MAX_MS_REALM_LEN 128 // as defined in [MS-TURN] #define STUN_EXPIRE_TIMEOUT 60 /* Time we refresh before expiration */ #define STUN_PERMISSION_TIMEOUT (300 - STUN_EXPIRE_TIMEOUT) /* 240 s */ #define STUN_BINDING_TIMEOUT (600 - STUN_EXPIRE_TIMEOUT) /* 540 s */ typedef struct { StunMessage message; uint8_t buffer[STUN_MAX_MESSAGE_SIZE]; StunTimer timer; } TURNMessage; typedef struct { NiceAddress peer; uint16_t channel; gboolean renew; GSource *timeout_source; } ChannelBinding; typedef struct { GMainContext *ctx; StunAgent agent; GList *channels; GList *pending_bindings; ChannelBinding *current_binding; TURNMessage *current_binding_msg; GList *pending_permissions; GSource *tick_source_channel_bind; GSource *tick_source_create_permission; NiceSocket *base_socket; NiceAddress server_addr; uint8_t *username; gsize username_len; uint8_t *password; gsize password_len; NiceTurnSocketCompatibility compatibility; GQueue *send_requests; uint8_t ms_realm[STUN_MAX_MS_REALM_LEN + 1]; uint8_t ms_connection_id[20]; uint32_t ms_sequence_num; bool ms_connection_id_valid; GList *permissions; /* the peers (NiceAddress) for which there is an installed permission */ GList *sent_permissions; /* ongoing permission installed */ GHashTable *send_data_queues; /* stores a send data queue for per peer */ GSource *permission_timeout_source; /* timer used to invalidate permissions */ guint8 *cached_realm; uint16_t cached_realm_len; guint8 *cached_nonce; uint16_t cached_nonce_len; } UdpTurnPriv; typedef struct { StunTransactionId id; GSource *source; UdpTurnPriv *priv; } SendRequest; /* used to store data sent while obtaining a permission */ typedef struct { gchar *data; guint data_len; gboolean reliable; } SendData; static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other); static void priv_process_pending_bindings (UdpTurnPriv *priv); static gboolean priv_retransmissions_tick_unlocked (UdpTurnPriv *priv); static gboolean priv_retransmissions_tick (gpointer pointer); static void priv_schedule_tick (UdpTurnPriv *priv); static void priv_send_turn_message (UdpTurnPriv *priv, TURNMessage *msg); static gboolean priv_send_create_permission (UdpTurnPriv *priv, const NiceAddress *peer); static gboolean priv_send_channel_bind (UdpTurnPriv *priv, uint16_t channel, const NiceAddress *peer); static gboolean priv_add_channel_binding (UdpTurnPriv *priv, const NiceAddress *peer); static gboolean priv_forget_send_request (gpointer pointer); static void priv_clear_permissions (UdpTurnPriv *priv); static guint priv_nice_address_hash (gconstpointer data) { gchar address[NICE_ADDRESS_STRING_LEN]; nice_address_to_string ((NiceAddress *) data, address); return g_str_hash(address); } static void priv_send_data_queue_destroy (gpointer user_data) { GQueue *send_queue = (GQueue *) user_data; GList *i; for (i = g_queue_peek_head_link (send_queue); i; i = i->next) { SendData *data = (SendData *) i->data; g_free (data->data); g_slice_free (SendData, data); } g_queue_free (send_queue); } NiceSocket * nice_udp_turn_socket_new (GMainContext *ctx, NiceAddress *addr, NiceSocket *base_socket, NiceAddress *server_addr, gchar *username, gchar *password, NiceTurnSocketCompatibility compatibility) { UdpTurnPriv *priv; NiceSocket *sock = g_slice_new0 (NiceSocket); if (!sock) { return NULL; } priv = g_new0 (UdpTurnPriv, 1); if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS); } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN) { stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_NO_INDICATION_AUTH); } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_IGNORE_CREDENTIALS); } else if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { stun_agent_init (&priv->agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_OC2007, STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS | STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES); } priv->channels = NULL; priv->current_binding = NULL; priv->base_socket = base_socket; if (ctx) priv->ctx = g_main_context_ref (ctx); if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN || compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { priv->username = g_base64_decode (username, &priv->username_len); priv->password = g_base64_decode (password, &priv->password_len); } else { priv->username = (uint8_t *)g_strdup (username); priv->username_len = (gsize) strlen (username); if (compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { priv->password = NULL; priv->password_len = 0; } else { priv->password = (uint8_t *)g_strdup (password); priv->password_len = (gsize) strlen (password); } } priv->server_addr = *server_addr; priv->compatibility = compatibility; priv->send_requests = g_queue_new (); priv->send_data_queues = g_hash_table_new_full (priv_nice_address_hash, (GEqualFunc) nice_address_equal, (GDestroyNotify) nice_address_free, priv_send_data_queue_destroy); sock->type = NICE_SOCKET_TYPE_UDP_TURN; sock->fileno = NULL; sock->addr = *addr; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->is_based_on = socket_is_based_on; sock->close = socket_close; sock->priv = (void *) priv; return sock; } static void socket_close (NiceSocket *sock) { UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv; GList *i = NULL; for (i = priv->channels; i; i = i->next) { ChannelBinding *b = i->data; if (b->timeout_source) { g_source_destroy (b->timeout_source); g_source_unref (b->timeout_source); } g_free (b); } g_list_free (priv->channels); g_list_foreach (priv->pending_bindings, (GFunc) nice_address_free, NULL); g_list_free (priv->pending_bindings); if (priv->tick_source_channel_bind != NULL) { g_source_destroy (priv->tick_source_channel_bind); g_source_unref (priv->tick_source_channel_bind); priv->tick_source_channel_bind = NULL; } if (priv->tick_source_create_permission != NULL) { g_source_destroy (priv->tick_source_create_permission); g_source_unref (priv->tick_source_create_permission); priv->tick_source_create_permission = NULL; } for (i = g_queue_peek_head_link (priv->send_requests); i; i = i->next) { SendRequest *r = i->data; g_source_destroy (r->source); g_source_unref (r->source); r->source = NULL; stun_agent_forget_transaction (&priv->agent, r->id); g_slice_free (SendRequest, r); } g_queue_free (priv->send_requests); priv_clear_permissions (priv); g_list_foreach (priv->sent_permissions, (GFunc) nice_address_free, NULL); g_list_free (priv->sent_permissions); g_hash_table_destroy (priv->send_data_queues); if (priv->permission_timeout_source) { g_source_destroy (priv->permission_timeout_source); g_source_unref (priv->permission_timeout_source); priv->permission_timeout_source = NULL; } if (priv->ctx) g_main_context_unref (priv->ctx); g_free (priv->current_binding); g_free (priv->current_binding_msg); g_list_foreach (priv->pending_permissions, (GFunc) g_free, NULL); g_list_free(priv->pending_permissions); g_free (priv->username); g_free (priv->password); g_free (priv->cached_realm); g_free (priv->cached_nonce); g_free (priv); sock->priv = NULL; } static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv; gint n_messages; guint i; gboolean error = FALSE; guint n_valid_messages; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); nice_debug_verbose ("received message on TURN socket"); n_messages = nice_socket_recv_messages (priv->base_socket, recv_messages, n_recv_messages); if (n_messages < 0) return n_messages; /* Process all the messages. Those which fail parsing are re-used for the next * message. * * FIXME: This needs a fast path which avoids allocations or memcpy()s. * Implementing such a path means rewriting the TURN parser (and hence the * STUN message code) to operate on vectors of buffers, rather than a * monolithic buffer. */ for (i = 0; i < (guint) n_messages; i += n_valid_messages) { NiceInputMessage *message = &recv_messages[i]; NiceSocket *dummy; NiceAddress from; guint8 *buffer; gsize buffer_length; gint parsed_buffer_length; gboolean allocated_buffer = FALSE; n_valid_messages = 1; if (message->length == 0) continue; /* Compact the message’s buffers into a single one for parsing. Avoid this * in the (hopefully) common case of a single-element buffer vector. */ if (message->n_buffers == 1 || (message->n_buffers == -1 && message->buffers[0].buffer != NULL && message->buffers[1].buffer == NULL)) { buffer = message->buffers[0].buffer; buffer_length = message->length; } else { nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC); buffer = compact_input_message (message, &buffer_length); allocated_buffer = TRUE; } /* Parse in-place. */ parsed_buffer_length = nice_udp_turn_socket_parse_recv (sock, &dummy, &from, buffer_length, buffer, message->from, buffer, buffer_length); message->length = MAX (parsed_buffer_length, 0); if (parsed_buffer_length < 0) { error = TRUE; } else if (parsed_buffer_length == 0) { /* A TURN control message which needs ignoring. Re-use this * NiceInputMessage in the next loop iteration. */ n_valid_messages = 0; } else { *message->from = from; } /* Split up the monolithic buffer again into the caller-provided buffers. */ if (parsed_buffer_length > 0 && allocated_buffer) { parsed_buffer_length = memcpy_buffer_to_input_message (message, buffer, parsed_buffer_length); } if (allocated_buffer) g_free (buffer); if (error) break; } /* Was there an error processing the first message? */ if (error && i == 0) return -1; return i; } static GSource * priv_timeout_add_with_context (UdpTurnPriv *priv, guint interval, gboolean seconds, GSourceFunc function, gpointer data) { GSource *source; g_return_val_if_fail (function != NULL, NULL); if (seconds) source = g_timeout_source_new_seconds (interval); else source = g_timeout_source_new (interval); g_source_set_callback (source, function, data, NULL); g_source_attach (source, priv->ctx); return source; } static StunMessageReturn stun_message_append_ms_connection_id(StunMessage *msg, uint8_t *ms_connection_id, uint32_t ms_sequence_num) { union { uint8_t buf8[24]; uint32_t buf32[24/4]; } buf; memcpy(buf.buf8, ms_connection_id, 20); buf.buf32[5] = htonl(ms_sequence_num); return stun_message_append_bytes (msg, STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER, buf.buf8, 24); } static void stun_message_ensure_ms_realm(StunMessage *msg, uint8_t *realm) { /* With MS-TURN, original clients do not send REALM attribute in Send and Set * Active Destination requests, but use it to compute MESSAGE-INTEGRITY. We * simply append cached realm value to the message and use it in subsequent * stun_agent_finish_message() call. Messages with this additional attribute * are handled correctly on OCS Access Edge working as TURN server. */ if (stun_message_get_method(msg) == STUN_SEND || stun_message_get_method(msg) == STUN_OLD_SET_ACTIVE_DST) { stun_message_append_bytes (msg, STUN_ATTRIBUTE_REALM, realm, strlen((char *)realm)); } } static gboolean priv_is_peer_in_list (const GList *list, const NiceAddress *peer) { const GList *iter; for (iter = list ; iter ; iter = g_list_next (iter)) { NiceAddress *address = (NiceAddress *) iter->data; if (nice_address_equal (address, peer)) return TRUE; } return FALSE; } static gboolean priv_has_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer) { return priv_is_peer_in_list (priv->permissions, peer); } static gboolean priv_has_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer) { return priv_is_peer_in_list (priv->sent_permissions, peer); } static void priv_add_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer) { priv->permissions = g_list_append (priv->permissions, nice_address_dup (peer)); } static void priv_add_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer) { priv->sent_permissions = g_list_append (priv->sent_permissions, nice_address_dup (peer)); } static GList * priv_remove_peer_from_list (GList *list, const NiceAddress *peer) { GList *iter; for (iter = list ; iter ; iter = g_list_next (iter)) { NiceAddress *address = (NiceAddress *) iter->data; if (nice_address_equal (address, peer)) { GList *prev = iter->prev; nice_address_free (address); list = g_list_delete_link (list, iter); iter = prev; if (iter) iter = list; } } return list; } static void priv_remove_sent_permission_for_peer (UdpTurnPriv *priv, const NiceAddress *peer) { priv->sent_permissions = priv_remove_peer_from_list (priv->sent_permissions, peer); } static void priv_clear_permissions (UdpTurnPriv *priv) { g_list_foreach (priv->permissions, (GFunc) nice_address_free, NULL); g_list_free (priv->permissions); priv->permissions = NULL; } static gint _socket_send_messages_wrapped (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages, gboolean reliable) { if (!nice_socket_is_reliable (sock)) { if (reliable) return nice_socket_send_messages_reliable (sock, to, messages, n_messages); else return nice_socket_send_messages (sock, to, messages, n_messages); } else { GOutputVector *local_bufs; NiceOutputMessage local_message; const NiceOutputMessage *message; gsize message_len; guint n_bufs = 0; guint16 rfc4571_frame; guint i; gint ret; g_assert (n_messages == 1); message = &messages[0]; message_len = output_message_get_size (message); g_assert (message_len <= G_MAXUINT16); /* ICE-TCP requires that all packets be framed with RFC4571 */ /* Count the number of buffers. */ if (message->n_buffers == -1) { for (i = 0; message->buffers[i].buffer != NULL; i++) n_bufs++; } else { n_bufs = message->n_buffers; } local_bufs = g_alloca ((n_bufs + 1) * sizeof (GOutputVector)); local_message.buffers = local_bufs; local_message.n_buffers = n_bufs + 1; rfc4571_frame = htons (message_len); local_bufs[0].buffer = &rfc4571_frame; local_bufs[0].size = sizeof (guint16); for (i = 0; i < n_bufs; i++) { local_bufs[i + 1].buffer = message->buffers[i].buffer; local_bufs[i + 1].size = message->buffers[i].size; } if (reliable) ret = nice_socket_send_messages_reliable (sock, to, &local_message, 1); else ret = nice_socket_send_messages (sock, to, &local_message, 1); if (ret == 1) ret = message_len; return ret; } } static gssize _socket_send_wrapped (NiceSocket *sock, const NiceAddress *to, guint len, const gchar *buf, gboolean reliable) { gint ret; if (!nice_socket_is_reliable (sock)) { GOutputVector local_buf = { buf, len }; NiceOutputMessage local_message = { &local_buf, 1}; ret = _socket_send_messages_wrapped (sock, to, &local_message, 1, reliable); if (ret == 1) return len; return ret; } else { guint16 rfc4571_frame = htons (len); GOutputVector local_buf[2] = {{&rfc4571_frame, 2}, { buf, len }}; NiceOutputMessage local_message = { local_buf, 2}; if (reliable) ret = nice_socket_send_messages_reliable (sock, to, &local_message, 1); else ret = nice_socket_send_messages (sock, to, &local_message, 1); if (ret == 1) return len; return ret; } } static void socket_enqueue_data(UdpTurnPriv *priv, const NiceAddress *to, guint len, const gchar *buf, gboolean reliable) { SendData *data = g_slice_new0 (SendData); GQueue *queue = g_hash_table_lookup (priv->send_data_queues, to); if (queue == NULL) { queue = g_queue_new (); g_hash_table_insert (priv->send_data_queues, nice_address_dup (to), queue); } data->data = g_memdup(buf, len); data->data_len = len; data->reliable = reliable; g_queue_push_tail (queue, data); } static void socket_dequeue_all_data (UdpTurnPriv *priv, const NiceAddress *to) { GQueue *send_queue = g_hash_table_lookup (priv->send_data_queues, to); if (send_queue) { while (!g_queue_is_empty (send_queue)) { SendData *data = (SendData *) g_queue_pop_head(send_queue); nice_debug_verbose ("dequeuing data"); _socket_send_wrapped (priv->base_socket, &priv->server_addr, data->data_len, data->data, data->reliable); g_free (data->data); g_slice_free (SendData, data); } /* remove queue from table */ g_hash_table_remove (priv->send_data_queues, to); } } static gssize socket_send_message (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *message, gboolean reliable) { UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv; StunMessage msg; uint8_t buffer[STUN_MAX_MESSAGE_SIZE]; size_t msg_len; union { struct sockaddr_storage storage; struct sockaddr addr; } sa; GList *i; ChannelBinding *binding = NULL; gint ret; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); for (i = priv->channels; i; i = i->next) { ChannelBinding *b = i->data; if (nice_address_equal (&b->peer, to)) { binding = b; break; } } nice_address_copy_to_sockaddr (to, &sa.addr); if (binding) { if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { gsize message_len = output_message_get_size (message); if (message_len + sizeof(uint32_t) <= sizeof(buffer)) { guint j; uint16_t len16, channel16; gsize message_offset = 0; len16 = htons ((uint16_t) message_len); channel16 = htons (binding->channel); memcpy (buffer, &channel16, sizeof(uint16_t)); memcpy (buffer + sizeof(uint16_t), &len16, sizeof(uint16_t)); /* FIXME: Slow path! This should be replaced by code which manipulates * the GOutputVector array, rather than the buffer contents * themselves. */ for (j = 0; (message->n_buffers >= 0 && j < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[j].buffer != NULL); j++) { const GOutputVector *out_buf = &message->buffers[j]; gsize out_len; out_len = MIN (message_len - message_offset, out_buf->size); memcpy (buffer + sizeof (uint32_t) + message_offset, out_buf->buffer, out_len); message_offset += out_len; } msg_len = message_len + sizeof(uint32_t); } else { goto error; } } else { ret = _socket_send_messages_wrapped (priv->base_socket, &priv->server_addr, message, 1, reliable); if (ret == 1) return output_message_get_size (message); return ret; } } else { guint8 *compacted_buf; gsize compacted_buf_len; if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { if (!stun_agent_init_indication (&priv->agent, &msg, buffer, sizeof(buffer), STUN_IND_SEND)) goto error; if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_PEER_ADDRESS, &sa.storage, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) goto error; } else { if (!stun_agent_init_request (&priv->agent, &msg, buffer, sizeof(buffer), STUN_SEND)) goto error; if (stun_message_append32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE, TURN_MAGIC_COOKIE) != STUN_MESSAGE_RETURN_SUCCESS) goto error; if (priv->username != NULL && priv->username_len > 0) { if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_USERNAME, priv->username, priv->username_len) != STUN_MESSAGE_RETURN_SUCCESS) goto error; } if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_DESTINATION_ADDRESS, &sa.addr, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) goto error; if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE && priv->current_binding && nice_address_equal (&priv->current_binding->peer, to)) { stun_message_append32 (&msg, STUN_ATTRIBUTE_OPTIONS, 1); } } if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { stun_message_append32(&msg, STUN_ATTRIBUTE_MS_VERSION, 1); if (priv->ms_connection_id_valid) stun_message_append_ms_connection_id(&msg, priv->ms_connection_id, ++priv->ms_sequence_num); stun_message_ensure_ms_realm(&msg, priv->ms_realm); } /* Slow path! We have to compact the buffers to append them to the message. * FIXME: This could be improved by adding vectored I/O support to * stun_message_append_bytes(). */ compacted_buf = compact_output_message (message, &compacted_buf_len); if (stun_message_append_bytes (&msg, STUN_ATTRIBUTE_DATA, compacted_buf, compacted_buf_len) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (compacted_buf); goto error; } g_free (compacted_buf); /* Finish the message. */ msg_len = stun_agent_finish_message (&priv->agent, &msg, priv->password, priv->password_len); if (msg_len > 0 && stun_message_get_class (&msg) == STUN_REQUEST && priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { SendRequest *req = g_slice_new0 (SendRequest); req->priv = priv; stun_message_id (&msg, req->id); req->source = priv_timeout_add_with_context (priv, STUN_END_TIMEOUT, FALSE, priv_forget_send_request, req); g_queue_push_tail (priv->send_requests, req); } } if (msg_len > 0) { if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766 && !priv_has_permission_for_peer (priv, to)) { if (!priv_has_sent_permission_for_peer (priv, to)) { priv_send_create_permission (priv, to); } /* enque data */ nice_debug_verbose ("enqueuing data"); socket_enqueue_data(priv, to, msg_len, (gchar *)buffer, reliable); return msg_len; } else { GOutputVector local_buf = { buffer, msg_len }; NiceOutputMessage local_message = {&local_buf, 1}; ret = _socket_send_messages_wrapped (priv->base_socket, &priv->server_addr, &local_message, 1, reliable); if (ret == 1) return msg_len; return ret; } } /* Error condition pass through to the base socket. */ ret = _socket_send_messages_wrapped (priv->base_socket, to, message, 1, reliable); if (ret == 1) return output_message_get_size (message); return ret; error: return -1; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { guint i; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; gssize len; len = socket_send_message (sock, to, message, FALSE); if (len < 0) { /* Error. */ if (i > 0) break; return len; } else if (len == 0) { /* EWOULDBLOCK. */ break; } } return i; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv; guint i; /* TURN can depend either on tcp-turn or udp-bsd as a base socket * if we allow reliable send and need to create permissions and we queue the * data, then we must be sure that the reliable send will succeed later, so * we check for udp-bsd here as the base socket and don't allow it. */ if (priv->base_socket->type == NICE_SOCKET_TYPE_UDP_BSD) return -1; for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; gssize len; len = socket_send_message (sock, to, message, TRUE); if (len < 0) { /* Error. */ return len; } else if (len == 0) { /* EWOULDBLOCK. */ break; } } return i; } static gboolean socket_is_reliable (NiceSocket *sock) { UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv; return nice_socket_is_reliable (priv->base_socket); } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { UdpTurnPriv *priv = sock->priv; return nice_socket_can_send (priv->base_socket, addr); } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { UdpTurnPriv *priv = sock->priv; nice_socket_set_writable_callback (priv->base_socket, callback, user_data); } static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other) { UdpTurnPriv *priv = sock->priv; return (sock == other) || (priv && nice_socket_is_based_on (priv->base_socket, other)); } static gboolean priv_forget_send_request (gpointer pointer) { SendRequest *req = pointer; agent_lock (); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in turn.c:priv_forget_send_request"); agent_unlock (); return FALSE; } stun_agent_forget_transaction (&req->priv->agent, req->id); g_queue_remove (req->priv->send_requests, req); g_source_destroy (req->source); g_source_unref (req->source); req->source = NULL; agent_unlock (); g_slice_free (SendRequest, req); return FALSE; } static gboolean priv_permission_timeout (gpointer data) { UdpTurnPriv *priv = (UdpTurnPriv *) data; nice_debug ("Permission is about to timeout, schedule renewal"); agent_lock (); /* remove all permissions for this agent (the permission for the peer we are sending to will be renewed) */ priv_clear_permissions (priv); agent_unlock (); return TRUE; } static gboolean priv_binding_expired_timeout (gpointer data) { UdpTurnPriv *priv = (UdpTurnPriv *) data; GList *i; GSource *source = NULL; nice_debug ("Permission expired, refresh failed"); agent_lock (); source = g_main_current_source (); if (g_source_is_destroyed (source)) { nice_debug ("Source was destroyed. " "Avoided race condition in turn.c:priv_binding_expired_timeout"); agent_unlock (); return FALSE; } /* find current binding and destroy it */ for (i = priv->channels ; i; i = i->next) { ChannelBinding *b = i->data; if (b->timeout_source == source) { priv->channels = g_list_remove (priv->channels, b); /* Make sure we don't free a currently being-refreshed binding */ if (priv->current_binding_msg && !priv->current_binding) { union { struct sockaddr_storage storage; struct sockaddr addr; } sa; socklen_t sa_len = sizeof(sa); NiceAddress to; /* look up binding associated with peer */ stun_message_find_xor_addr ( &priv->current_binding_msg->message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.storage, &sa_len); nice_address_set_from_sockaddr (&to, &sa.addr); /* If the binding is being refreshed, then move it to priv->current_binding so it counts as a 'new' binding and will get readded to the list if it succeeds */ if (nice_address_equal (&b->peer, &to)) { priv->current_binding = b; break; } } /* In case the binding timed out before it could be processed, add it to the pending list */ priv_add_channel_binding (priv, &b->peer); g_free (b); break; } } agent_unlock (); return FALSE; } static gboolean priv_binding_timeout (gpointer data) { UdpTurnPriv *priv = (UdpTurnPriv *) data; GList *i; GSource *source = NULL; nice_debug ("Permission is about to timeout, sending binding renewal"); agent_lock (); source = g_main_current_source (); if (g_source_is_destroyed (source)) { nice_debug ("Source was destroyed. " "Avoided race condition in turn.c:priv_binding_timeout"); agent_unlock (); return FALSE; } /* find current binding and mark it for renewal */ for (i = priv->channels ; i; i = i->next) { ChannelBinding *b = i->data; if (b->timeout_source == source) { b->renew = TRUE; /* Remove any existing timer */ if (b->timeout_source) { g_source_destroy (b->timeout_source); g_source_unref (b->timeout_source); } /* Install timer to expire the permission */ b->timeout_source = priv_timeout_add_with_context (priv, STUN_EXPIRE_TIMEOUT, TRUE, priv_binding_expired_timeout, priv); /* Send renewal */ if (!priv->current_binding_msg) priv_send_channel_bind (priv, b->channel, &b->peer); break; } } agent_unlock (); return FALSE; } void nice_udp_turn_socket_cache_realm_nonce (NiceSocket *sock, StunMessage *msg) { UdpTurnPriv *priv = sock->priv; gconstpointer tmp; g_assert (sock->type == NICE_SOCKET_TYPE_UDP_TURN); g_free (priv->cached_realm); priv->cached_realm = NULL; priv->cached_realm_len = 0; g_free (priv->cached_nonce); priv->cached_nonce = NULL; priv->cached_nonce_len = 0; tmp = stun_message_find (msg, STUN_ATTRIBUTE_REALM, &priv->cached_realm_len); if (tmp && priv->cached_realm_len < 764) priv->cached_realm = g_memdup (tmp, priv->cached_realm_len); tmp = stun_message_find (msg, STUN_ATTRIBUTE_NONCE, &priv->cached_nonce_len); if (tmp && priv->cached_nonce_len < 764) priv->cached_nonce = g_memdup (tmp, priv->cached_nonce_len); } guint nice_udp_turn_socket_parse_recv_message (NiceSocket *sock, NiceSocket **from_sock, NiceInputMessage *message) { /* TODO: Speed this up in the common reliable case of having a 24-byte header * buffer to begin with, followed by one or more massive buffers. */ guint8 *buf; gsize buf_len, len; if (message->n_buffers == 1 || (message->n_buffers == -1 && message->buffers[0].buffer != NULL && message->buffers[1].buffer == NULL)) { /* Fast path. Single massive buffer. */ len = nice_udp_turn_socket_parse_recv (sock, from_sock, message->from, message->length, message->buffers[0].buffer, message->from, message->buffers[0].buffer, message->length); g_assert_cmpuint (len, <=, message->length); message->length = len; return (len > 0) ? 1 : 0; } /* Slow path. */ nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC); buf = compact_input_message (message, &buf_len); len = nice_udp_turn_socket_parse_recv (sock, from_sock, message->from, buf_len, buf, message->from, buf, buf_len); len = memcpy_buffer_to_input_message (message, buf, len); g_free (buf); return (len > 0) ? 1 : 0; } gsize nice_udp_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, NiceAddress *from, gsize len, guint8 *buf, NiceAddress *recv_from, guint8 *_recv_buf, gsize recv_len) { UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv; StunValidationStatus valid; StunMessage msg; GList *l; ChannelBinding *binding = NULL; union { guint8 *u8; guint16 *u16; } recv_buf; /* In the case of a reliable UDP-TURN-OVER-TCP (which means MS-TURN) * we must use RFC4571 framing */ if (nice_socket_is_reliable (sock)) { recv_buf.u8 = _recv_buf + sizeof(guint16); recv_len -= sizeof(guint16); } else { recv_buf.u8 = _recv_buf; } if (nice_address_equal (&priv->server_addr, recv_from)) { valid = stun_agent_validate (&priv->agent, &msg, recv_buf.u8, recv_len, NULL, NULL); if (valid == STUN_VALIDATION_SUCCESS) { if (priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 && priv->compatibility != NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { uint32_t cookie; if (stun_message_find32 (&msg, STUN_ATTRIBUTE_MAGIC_COOKIE, &cookie) != STUN_MESSAGE_RETURN_SUCCESS) goto recv; if (cookie != TURN_MAGIC_COOKIE) goto recv; } if (stun_message_get_method (&msg) == STUN_SEND) { if (stun_message_get_class (&msg) == STUN_RESPONSE) { SendRequest *req = NULL; GList *i = g_queue_peek_head_link (priv->send_requests); StunTransactionId msg_id; stun_message_id (&msg, msg_id); for (; i; i = i->next) { SendRequest *r = i->data; if (memcmp (&r->id, msg_id, sizeof(StunTransactionId)) == 0) { req = r; break; } } if (req) { g_source_destroy (req->source); g_source_unref (req->source); req->source = NULL; g_queue_remove (priv->send_requests, req); g_slice_free (SendRequest, req); } if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { uint32_t opts = 0; if (stun_message_find32 (&msg, STUN_ATTRIBUTE_OPTIONS, &opts) == STUN_MESSAGE_RETURN_SUCCESS && opts & 0x1) goto msn_google_lock; } } return 0; } else if (stun_message_get_method (&msg) == STUN_OLD_SET_ACTIVE_DST) { StunTransactionId request_id; StunTransactionId response_id; if (priv->current_binding && priv->current_binding_msg) { stun_message_id (&msg, response_id); stun_message_id (&priv->current_binding_msg->message, request_id); if (memcmp (request_id, response_id, sizeof(StunTransactionId)) == 0) { g_free (priv->current_binding_msg); priv->current_binding_msg = NULL; if (stun_message_get_class (&msg) == STUN_RESPONSE && (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN)) { goto msn_google_lock; } else { g_free (priv->current_binding); priv->current_binding = NULL; } } } return 0; } else if (stun_message_get_method (&msg) == STUN_CHANNELBIND) { StunTransactionId request_id; StunTransactionId response_id; if (priv->current_binding_msg) { stun_message_id (&msg, response_id); stun_message_id (&priv->current_binding_msg->message, request_id); if (memcmp (request_id, response_id, sizeof(StunTransactionId)) == 0) { if (priv->current_binding) { /* New channel binding */ binding = priv->current_binding; } else { /* Existing binding refresh */ GList *i; union { struct sockaddr_storage storage; struct sockaddr addr; } sa; socklen_t sa_len = sizeof(sa); NiceAddress to; /* look up binding associated with peer */ stun_message_find_xor_addr ( &priv->current_binding_msg->message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &sa.storage, &sa_len); nice_address_set_from_sockaddr (&to, &sa.addr); for (i = priv->channels; i; i = i->next) { ChannelBinding *b = i->data; if (nice_address_equal (&b->peer, &to)) { binding = b; break; } } } if (stun_message_get_class (&msg) == STUN_ERROR) { int code = -1; uint8_t *sent_realm = NULL; uint8_t *recv_realm = NULL; uint16_t sent_realm_len = 0; uint16_t recv_realm_len = 0; sent_realm = (uint8_t *) stun_message_find ( &priv->current_binding_msg->message, STUN_ATTRIBUTE_REALM, &sent_realm_len); recv_realm = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_REALM, &recv_realm_len); /* check for unauthorized error response */ if (stun_message_find_error (&msg, &code) == STUN_MESSAGE_RETURN_SUCCESS && (code == 438 || (code == 401 && !(recv_realm != NULL && recv_realm_len > 0 && recv_realm_len == sent_realm_len && sent_realm != NULL && memcmp (sent_realm, recv_realm, sent_realm_len) == 0)))) { g_free (priv->current_binding_msg); priv->current_binding_msg = NULL; nice_udp_turn_socket_cache_realm_nonce (sock, &msg); if (binding) priv_send_channel_bind (priv, binding->channel, &binding->peer); } else { g_free (priv->current_binding); priv->current_binding = NULL; g_free (priv->current_binding_msg); priv->current_binding_msg = NULL; priv_process_pending_bindings (priv); } } else if (stun_message_get_class (&msg) == STUN_RESPONSE) { g_free (priv->current_binding_msg); priv->current_binding_msg = NULL; /* If it's a new channel binding, then add it to the list */ if (priv->current_binding) priv->channels = g_list_append (priv->channels, priv->current_binding); priv->current_binding = NULL; if (binding) { binding->renew = FALSE; /* Remove any existing timer */ if (binding->timeout_source) { g_source_destroy (binding->timeout_source); g_source_unref (binding->timeout_source); } /* Install timer to schedule refresh of the permission */ binding->timeout_source = priv_timeout_add_with_context (priv, STUN_BINDING_TIMEOUT, TRUE, priv_binding_timeout, priv); } priv_process_pending_bindings (priv); } } } return 0; } else if (stun_message_get_method (&msg) == STUN_CREATEPERMISSION) { StunTransactionId request_id; StunTransactionId response_id; GList *i, *next; TURNMessage *current_create_permission_msg; for (i = priv->pending_permissions; i; i = next) { current_create_permission_msg = (TURNMessage *) i->data; next = i->next; stun_message_id (&msg, response_id); stun_message_id (¤t_create_permission_msg->message, request_id); if (memcmp (request_id, response_id, sizeof(StunTransactionId)) == 0) { union { struct sockaddr_storage storage; struct sockaddr addr; } peer; socklen_t peer_len = sizeof(peer); NiceAddress to; gchar tmpbuf[INET6_ADDRSTRLEN]; stun_message_find_xor_addr ( ¤t_create_permission_msg->message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &peer.storage, &peer_len); nice_address_set_from_sockaddr (&to, &peer.addr); nice_address_to_string (&to, tmpbuf); nice_debug ("TURN: got response for CreatePermission " "with XOR_PEER_ADDRESS=[%s]:%u : %s", tmpbuf, nice_address_get_port (&to), stun_message_get_class (&msg) == STUN_ERROR ? "unauthorized" : "ok"); /* unathorized => resend with realm and nonce */ if (stun_message_get_class (&msg) == STUN_ERROR) { int code = -1; uint8_t *sent_realm = NULL; uint8_t *recv_realm = NULL; uint16_t sent_realm_len = 0; uint16_t recv_realm_len = 0; sent_realm = (uint8_t *) stun_message_find ( ¤t_create_permission_msg->message, STUN_ATTRIBUTE_REALM, &sent_realm_len); recv_realm = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_REALM, &recv_realm_len); /* check for unauthorized error response */ if (stun_message_find_error (&msg, &code) == STUN_MESSAGE_RETURN_SUCCESS && (code == 438 || (code == 401 && !(recv_realm != NULL && recv_realm_len > 0 && recv_realm_len == sent_realm_len && sent_realm != NULL && memcmp (sent_realm, recv_realm, sent_realm_len) == 0)))) { priv->pending_permissions = g_list_delete_link ( priv->pending_permissions, i); g_free (current_create_permission_msg); current_create_permission_msg = NULL; nice_udp_turn_socket_cache_realm_nonce (sock, &msg); /* resend CreatePermission */ priv_send_create_permission (priv, &to); return 0; } } /* If we get an error, we just assume the server somehow doesn't support permissions and we ignore the error and fake a successful completion. If the server needs a permission but it failed to create it, then the connchecks will fail. */ priv_remove_sent_permission_for_peer (priv, &to); priv_add_permission_for_peer (priv, &to); /* install timer to schedule refresh of the permission */ /* (will not schedule refresh if we got an error) */ if (stun_message_get_class (&msg) == STUN_RESPONSE && !priv->permission_timeout_source) { priv->permission_timeout_source = priv_timeout_add_with_context (priv, STUN_PERMISSION_TIMEOUT, TRUE, priv_permission_timeout, priv); } /* send enqued data */ socket_dequeue_all_data (priv, &to); priv->pending_permissions = g_list_delete_link ( priv->pending_permissions, i); g_free (current_create_permission_msg); current_create_permission_msg = NULL; break; } } return 0; } else if (stun_message_get_class (&msg) == STUN_INDICATION && stun_message_get_method (&msg) == STUN_IND_DATA) { uint16_t data_len; uint8_t *data; union { struct sockaddr_storage storage; struct sockaddr addr; } sa; socklen_t from_len = sizeof (sa); if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS, &sa.storage, &from_len) != STUN_MESSAGE_RETURN_SUCCESS) goto recv; } else { if (stun_message_find_addr (&msg, STUN_ATTRIBUTE_REMOTE_ADDRESS, &sa.storage, &from_len) != STUN_MESSAGE_RETURN_SUCCESS) goto recv; } data = (uint8_t *) stun_message_find (&msg, STUN_ATTRIBUTE_DATA, &data_len); if (data == NULL) goto recv; nice_address_set_from_sockaddr (from, &sa.addr); if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766 && !priv_has_permission_for_peer (priv, from)) { if (!priv_has_sent_permission_for_peer (priv, from)) { priv_send_create_permission (priv, from); } } *from_sock = sock; memmove (buf, data, len > data_len ? data_len : len); return len > data_len ? data_len : len; } else { goto recv; } } } recv: for (l = priv->channels; l; l = l->next) { ChannelBinding *b = l->data; if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { if (b->channel == ntohs(recv_buf.u16[0])) { recv_len = ntohs (recv_buf.u16[1]); recv_buf.u8 += sizeof(uint32_t); binding = b; break; } } else { binding = b; break; } } if (binding) { *from = binding->peer; *from_sock = sock; } else { *from = *recv_from; } memmove (buf, recv_buf.u8, len > recv_len ? recv_len : len); return len > recv_len ? recv_len : len; msn_google_lock: if (priv->current_binding) { GList *i = priv->channels; for (; i; i = i->next) { ChannelBinding *b = i->data; g_free (b); } g_list_free (priv->channels); priv->channels = g_list_append (NULL, priv->current_binding); priv->current_binding = NULL; priv_process_pending_bindings (priv); } return 0; } gboolean nice_udp_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer) { UdpTurnPriv *priv = (UdpTurnPriv *) sock->priv; return priv_add_channel_binding (priv, peer); } static void priv_process_pending_bindings (UdpTurnPriv *priv) { gboolean ret = FALSE; while (priv->pending_bindings != NULL && ret == FALSE) { NiceAddress *peer = priv->pending_bindings->data; ret = priv_add_channel_binding (priv, peer); priv->pending_bindings = g_list_remove (priv->pending_bindings, peer); nice_address_free (peer); } /* If no new channel bindings are in progress and there are no pending bindings, then renew the soon to be expired bindings */ if (priv->pending_bindings == NULL && priv->current_binding_msg == NULL) { GList *i = NULL; /* find binding to renew */ for (i = priv->channels ; i; i = i->next) { ChannelBinding *b = i->data; if (b->renew) { priv_send_channel_bind (priv, b->channel, &b->peer); break; } } } } static gboolean priv_retransmissions_tick_unlocked (UdpTurnPriv *priv) { gboolean ret = FALSE; if (priv->current_binding_msg) { switch (stun_timer_refresh (&priv->current_binding_msg->timer)) { case STUN_USAGE_TIMER_RETURN_TIMEOUT: { /* Time out */ StunTransactionId id; stun_message_id (&priv->current_binding_msg->message, id); stun_agent_forget_transaction (&priv->agent, id); g_free (priv->current_binding); priv->current_binding = NULL; g_free (priv->current_binding_msg); priv->current_binding_msg = NULL; priv_process_pending_bindings (priv); break; } case STUN_USAGE_TIMER_RETURN_RETRANSMIT: /* Retransmit */ _socket_send_wrapped (priv->base_socket, &priv->server_addr, stun_message_length (&priv->current_binding_msg->message), (gchar *)priv->current_binding_msg->buffer, FALSE); ret = TRUE; break; case STUN_USAGE_TIMER_RETURN_SUCCESS: ret = TRUE; break; default: /* Nothing to do. */ break; } } if (ret) priv_schedule_tick (priv); return ret; } static gboolean priv_retransmissions_create_permission_tick_unlocked (UdpTurnPriv *priv, GList *list_element) { gboolean ret = FALSE; TURNMessage *current_create_permission_msg; current_create_permission_msg = (TURNMessage *)list_element->data; if (current_create_permission_msg) { switch (stun_timer_refresh (¤t_create_permission_msg->timer)) { case STUN_USAGE_TIMER_RETURN_TIMEOUT: { /* Time out */ StunTransactionId id; NiceAddress to; union { struct sockaddr_storage storage; struct sockaddr addr; } addr; socklen_t addr_len = sizeof(addr); stun_message_id (¤t_create_permission_msg->message, id); stun_agent_forget_transaction (&priv->agent, id); stun_message_find_xor_addr ( ¤t_create_permission_msg->message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &addr.storage, &addr_len); nice_address_set_from_sockaddr (&to, &addr.addr); priv_remove_sent_permission_for_peer (priv, &to); priv->pending_permissions = g_list_delete_link ( priv->pending_permissions, list_element); g_free (current_create_permission_msg); current_create_permission_msg = NULL; /* we got a timeout when retransmitting a CreatePermission message, assume we can just send the data, the server might not support RFC TURN, or connectivity check will fail eventually anyway */ priv_add_permission_for_peer (priv, &to); socket_dequeue_all_data (priv, &to); break; } case STUN_USAGE_TIMER_RETURN_RETRANSMIT: /* Retransmit */ _socket_send_wrapped (priv->base_socket, &priv->server_addr, stun_message_length (¤t_create_permission_msg->message), (gchar *)current_create_permission_msg->buffer, FALSE); ret = TRUE; break; case STUN_USAGE_TIMER_RETURN_SUCCESS: ret = TRUE; break; default: /* Nothing to do. */ break; } } return ret; } static gboolean priv_retransmissions_tick (gpointer pointer) { UdpTurnPriv *priv = pointer; agent_lock (); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in turn.c:priv_retransmissions_tick"); agent_unlock (); return FALSE; } if (priv_retransmissions_tick_unlocked (priv) == FALSE) { if (priv->tick_source_channel_bind != NULL) { g_source_destroy (priv->tick_source_channel_bind); g_source_unref (priv->tick_source_channel_bind); priv->tick_source_channel_bind = NULL; } } agent_unlock (); return FALSE; } static gboolean priv_retransmissions_create_permission_tick (gpointer pointer) { UdpTurnPriv *priv = pointer; agent_lock (); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. Avoided race condition in " "turn.c:priv_retransmissions_create_permission_tick"); agent_unlock (); return FALSE; } /* This will call priv_retransmissions_create_permission_tick_unlocked() for * every pending permission with an expired timer and will create a new timer * if there are pending permissions that require it */ priv_schedule_tick (priv); agent_unlock (); return FALSE; } static void priv_schedule_tick (UdpTurnPriv *priv) { GList *i, *next, *prev; TURNMessage *current_create_permission_msg; guint min_timeout = G_MAXUINT; if (priv->tick_source_channel_bind != NULL) { g_source_destroy (priv->tick_source_channel_bind); g_source_unref (priv->tick_source_channel_bind); priv->tick_source_channel_bind = NULL; } if (priv->current_binding_msg) { guint timeout = stun_timer_remainder (&priv->current_binding_msg->timer); if (timeout > 0) { priv->tick_source_channel_bind = priv_timeout_add_with_context (priv, timeout, FALSE, priv_retransmissions_tick, priv); } else { priv_retransmissions_tick_unlocked (priv); } } if (priv->tick_source_create_permission != NULL) { g_source_destroy (priv->tick_source_create_permission); g_source_unref (priv->tick_source_create_permission); priv->tick_source_create_permission = NULL; } for (i = priv->pending_permissions, prev = NULL; i; i = next) { guint timeout; current_create_permission_msg = (TURNMessage *)i->data; next = i->next; timeout = stun_timer_remainder (¤t_create_permission_msg->timer); if (timeout > 0) { min_timeout = MIN (min_timeout, timeout); prev = i; } else { /* This could either delete the permission from the list, or it could * refresh it, changing its timeout value */ priv_retransmissions_create_permission_tick_unlocked (priv, i); if (prev == NULL) next = priv->pending_permissions; else next = prev->next; } } /* We create one timer for the minimal timeout we need */ if (min_timeout != G_MAXUINT) { priv->tick_source_create_permission = priv_timeout_add_with_context (priv, FALSE, min_timeout, priv_retransmissions_create_permission_tick, priv); } } static void priv_send_turn_message (UdpTurnPriv *priv, TURNMessage *msg) { size_t stun_len = stun_message_length (&msg->message); if (priv->current_binding_msg) { g_free (priv->current_binding_msg); priv->current_binding_msg = NULL; } if (nice_socket_is_reliable (priv->base_socket)) { _socket_send_wrapped (priv->base_socket, &priv->server_addr, stun_len, (gchar *)msg->buffer, TRUE); stun_timer_start_reliable (&msg->timer, STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT); } else { if (_socket_send_wrapped (priv->base_socket, &priv->server_addr, stun_len, (gchar *)msg->buffer, TRUE) < 0) _socket_send_wrapped (priv->base_socket, &priv->server_addr, stun_len, (gchar *)msg->buffer, FALSE); stun_timer_start (&msg->timer, STUN_TIMER_DEFAULT_TIMEOUT, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); } priv->current_binding_msg = msg; priv_schedule_tick (priv); } static gboolean priv_send_create_permission(UdpTurnPriv *priv, const NiceAddress *peer) { guint msg_buf_len; gboolean res = FALSE; TURNMessage *msg = g_new0 (TURNMessage, 1); union { struct sockaddr_storage storage; struct sockaddr addr; } addr; /* register this peer as being pening a permission (if not already pending) */ if (!priv_has_sent_permission_for_peer (priv, peer)) { priv_add_sent_permission_for_peer (priv, peer); } nice_address_copy_to_sockaddr (peer, &addr.addr); /* send CreatePermission */ msg_buf_len = stun_usage_turn_create_permission(&priv->agent, &msg->message, msg->buffer, sizeof(msg->buffer), priv->username, priv->username_len, priv->password, priv->password_len, priv->cached_realm, priv->cached_realm_len, priv->cached_nonce, priv->cached_nonce_len, &addr.storage, STUN_USAGE_TURN_COMPATIBILITY_RFC5766); if (msg_buf_len > 0) { if (nice_socket_is_reliable (priv->base_socket)) { res = _socket_send_wrapped (priv->base_socket, &priv->server_addr, msg_buf_len, (gchar *) msg->buffer, TRUE); } else { res = _socket_send_wrapped (priv->base_socket, &priv->server_addr, msg_buf_len, (gchar *) msg->buffer, TRUE); if (res < 0) res = _socket_send_wrapped (priv->base_socket, &priv->server_addr, msg_buf_len, (gchar *) msg->buffer, FALSE); } if (nice_socket_is_reliable (priv->base_socket)) { stun_timer_start_reliable (&msg->timer, STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT); } else { stun_timer_start (&msg->timer, STUN_TIMER_DEFAULT_TIMEOUT, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); } priv->pending_permissions = g_list_append (priv->pending_permissions, msg); priv_schedule_tick (priv); } else { g_free(msg); } return res; } static gboolean priv_send_channel_bind (UdpTurnPriv *priv, uint16_t channel, const NiceAddress *peer) { uint32_t channel_attr = channel << 16; size_t stun_len; union { struct sockaddr_storage storage; struct sockaddr addr; } sa; TURNMessage *msg = g_new0 (TURNMessage, 1); nice_address_copy_to_sockaddr (peer, &sa.addr); if (!stun_agent_init_request (&priv->agent, &msg->message, msg->buffer, sizeof(msg->buffer), STUN_CHANNELBIND)) { g_free (msg); return FALSE; } if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_CHANNEL_NUMBER, channel_attr) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return FALSE; } if (stun_message_append_xor_addr (&msg->message, STUN_ATTRIBUTE_PEER_ADDRESS, &sa.storage, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return FALSE; } if (priv->username != NULL && priv->username_len > 0 && priv->cached_realm != NULL && priv->cached_realm_len > 0 && priv->cached_nonce != NULL && priv->cached_nonce_len > 0) { if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME, priv->username, priv->username_len) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return FALSE; } if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_REALM, priv->cached_realm, priv->cached_realm_len) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return 0; } if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_NONCE, priv->cached_nonce, priv->cached_nonce_len) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return 0; } } stun_len = stun_agent_finish_message (&priv->agent, &msg->message, priv->password, priv->password_len); if (stun_len > 0) { priv_send_turn_message (priv, msg); return TRUE; } g_free (msg); return FALSE; } static gboolean priv_add_channel_binding (UdpTurnPriv *priv, const NiceAddress *peer) { size_t stun_len; union { struct sockaddr_storage storage; struct sockaddr addr; } sa; nice_address_copy_to_sockaddr (peer, &sa.addr); if (priv->current_binding) { NiceAddress * pending= nice_address_new (); *pending = *peer; priv->pending_bindings = g_list_append (priv->pending_bindings, pending); return FALSE; } if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { uint16_t channel = 0x4000; GList *i = priv->channels; for (; i; i = i->next) { ChannelBinding *b = i->data; if (channel == b->channel) { i = priv->channels; channel++; continue; } } if (channel >= 0x4000 && channel < 0xffff) { gboolean ret = priv_send_channel_bind (priv, channel, peer); if (ret) { priv->current_binding = g_new0 (ChannelBinding, 1); priv->current_binding->channel = channel; priv->current_binding->peer = *peer; } return ret; } return FALSE; } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_MSN || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { TURNMessage *msg = g_new0 (TURNMessage, 1); if (!stun_agent_init_request (&priv->agent, &msg->message, msg->buffer, sizeof(msg->buffer), STUN_OLD_SET_ACTIVE_DST)) { g_free (msg); return FALSE; } if (stun_message_append32 (&msg->message, STUN_ATTRIBUTE_MAGIC_COOKIE, TURN_MAGIC_COOKIE) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return FALSE; } if (priv->username != NULL && priv->username_len > 0) { if (stun_message_append_bytes (&msg->message, STUN_ATTRIBUTE_USERNAME, priv->username, priv->username_len) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return FALSE; } } if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { if (priv->ms_connection_id_valid) stun_message_append_ms_connection_id(&msg->message, priv->ms_connection_id, ++priv->ms_sequence_num); stun_message_ensure_ms_realm(&msg->message, priv->ms_realm); } if (stun_message_append_addr (&msg->message, STUN_ATTRIBUTE_DESTINATION_ADDRESS, &sa.addr, sizeof(sa)) != STUN_MESSAGE_RETURN_SUCCESS) { g_free (msg); return FALSE; } stun_len = stun_agent_finish_message (&priv->agent, &msg->message, priv->password, priv->password_len); if (stun_len > 0) { priv->current_binding = g_new0 (ChannelBinding, 1); priv->current_binding->channel = 0; priv->current_binding->peer = *peer; priv_send_turn_message (priv, msg); return TRUE; } g_free (msg); return FALSE; } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { priv->current_binding = g_new0 (ChannelBinding, 1); priv->current_binding->channel = 0; priv->current_binding->peer = *peer; return TRUE; } else { return FALSE; } return FALSE; } void nice_udp_turn_socket_set_ms_realm(NiceSocket *sock, StunMessage *msg) { UdpTurnPriv *priv = (UdpTurnPriv *)sock->priv; uint16_t alen; const uint8_t *realm = stun_message_find(msg, STUN_ATTRIBUTE_REALM, &alen); if (realm && alen <= STUN_MAX_MS_REALM_LEN) { memcpy(priv->ms_realm, realm, alen); priv->ms_realm[alen] = '\0'; } } void nice_udp_turn_socket_set_ms_connection_id (NiceSocket *sock, StunMessage *msg) { UdpTurnPriv *priv = (UdpTurnPriv *)sock->priv; uint16_t alen; const uint8_t *ms_seq_num = stun_message_find(msg, STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER, &alen); if (ms_seq_num && alen == 24) { memcpy (priv->ms_connection_id, ms_seq_num, 20); priv->ms_sequence_num = ntohl((uint32_t)*(ms_seq_num + 20)); priv->ms_connection_id_valid = TRUE; } } libnice-0.1.14/socket/pseudossl.c0000664000076400007640000002460612724137775013641 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See * http://en.wikipedia.org/wiki/Berkeley_sockets.) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "pseudossl.h" #include "agent-priv.h" #include "socket-priv.h" #include #ifndef G_OS_WIN32 #include #endif typedef struct { gboolean handshaken; NiceSocket *base_socket; GQueue send_queue; NicePseudoSSLSocketCompatibility compatibility; } PseudoSSLPriv; static const gchar SSL_SERVER_GOOGLE_HANDSHAKE[] = { 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0, 0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f, 0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1, 0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f, 0x20, 0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f, 0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b, 0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38, 0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c, 0x00, 0x04, 0x00}; static const gchar SSL_CLIENT_GOOGLE_HANDSHAKE[] = { 0x80, 0x46, 0x01, 0x03, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80, 0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc, 0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea}; static const gchar SSL_SERVER_MSOC_HANDSHAKE[] = { 0x16, 0x03, 0x01, 0x00, 0x4e, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00}; static const gchar SSL_CLIENT_MSOC_HANDSHAKE[] = { 0x16, 0x03, 0x01, 0x00, 0x2d, 0x01, 0x00, 0x00, 0x29, 0x03, 0x01, 0xc1, 0xfc, 0xd5, 0xa3, 0x6d, 0x93, 0xdd, 0x7e, 0x0b, 0x45, 0x67, 0x3f, 0xec, 0x79, 0x85, 0xfb, 0xbc, 0x3f, 0xd6, 0x60, 0xc2, 0xce, 0x84, 0x85, 0x08, 0x1b, 0x81, 0x21, 0xbc, 0xaa, 0x10, 0xfb, 0x00, 0x00, 0x02, 0x00, 0x18, 0x01, 0x00}; static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other); NiceSocket * nice_pseudossl_socket_new (NiceSocket *base_socket, NicePseudoSSLSocketCompatibility compatibility) { PseudoSSLPriv *priv; NiceSocket *sock; const gchar *buf; guint len; if (compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC) { buf = SSL_CLIENT_MSOC_HANDSHAKE; len = sizeof(SSL_CLIENT_MSOC_HANDSHAKE); } else if (compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE) { buf = SSL_CLIENT_GOOGLE_HANDSHAKE; len = sizeof(SSL_CLIENT_GOOGLE_HANDSHAKE); } else { return NULL; } sock = g_slice_new0 (NiceSocket); sock->priv = priv = g_slice_new0 (PseudoSSLPriv); priv->handshaken = FALSE; priv->base_socket = base_socket; priv->compatibility = compatibility; sock->type = NICE_SOCKET_TYPE_PSEUDOSSL; sock->fileno = priv->base_socket->fileno; sock->addr = priv->base_socket->addr; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->is_based_on = socket_is_based_on; sock->close = socket_close; /* We send 'to' NULL because it will always be to an already connected * TCP base socket, which ignores the destination */ nice_socket_send_reliable (priv->base_socket, NULL, len, buf); return sock; } static void socket_close (NiceSocket *sock) { PseudoSSLPriv *priv = sock->priv; if (priv->base_socket) nice_socket_free (priv->base_socket); nice_socket_free_send_queue (&priv->send_queue); g_slice_free(PseudoSSLPriv, sock->priv); sock->priv = NULL; } static gboolean server_handshake_valid(NiceSocket *sock, GInputVector *data, guint length) { PseudoSSLPriv *priv = sock->priv; if (priv->compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC) { if (length == sizeof(SSL_SERVER_MSOC_HANDSHAKE)) { guint8 *buf = data->buffer; memset(buf + 11, 0, 32); memset(buf + 44, 0, 32); return memcmp(SSL_SERVER_MSOC_HANDSHAKE, data->buffer, sizeof(SSL_SERVER_MSOC_HANDSHAKE)) == 0; } return FALSE; } else { return length == sizeof(SSL_SERVER_GOOGLE_HANDSHAKE) && memcmp(SSL_SERVER_GOOGLE_HANDSHAKE, data->buffer, sizeof(SSL_SERVER_GOOGLE_HANDSHAKE)) == 0; } } static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { PseudoSSLPriv *priv = sock->priv; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); if (priv->handshaken) { if (priv->base_socket) { /* Fast path: once we’ve done the handshake, pass straight through to the * base socket. */ return nice_socket_recv_messages (priv->base_socket, recv_messages, n_recv_messages); } } else { guint8 data[MAX(sizeof(SSL_SERVER_GOOGLE_HANDSHAKE), sizeof(SSL_SERVER_MSOC_HANDSHAKE))]; gint ret = -1; GInputVector local_recv_buf = { data, sizeof(data) }; NiceInputMessage local_recv_message = { &local_recv_buf, 1, NULL, 0 }; if (priv->compatibility == NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC) { local_recv_buf.size = sizeof(SSL_SERVER_MSOC_HANDSHAKE); } else { local_recv_buf.size = sizeof(SSL_SERVER_GOOGLE_HANDSHAKE); } if (priv->base_socket) { ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); } if (ret <= 0) { return ret; } else if (ret == 1 && server_handshake_valid(sock, &local_recv_buf, local_recv_message.length)) { priv->handshaken = TRUE; nice_socket_flush_send_queue (priv->base_socket, &priv->send_queue); } else { if (priv->base_socket) nice_socket_free (priv->base_socket); priv->base_socket = NULL; return -1; } } return 0; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { PseudoSSLPriv *priv = sock->priv; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); if (priv->handshaken) { /* Fast path: pass directly through to the base socket once the handshake is * complete. */ if (priv->base_socket == NULL) return -1; return nice_socket_send_messages (priv->base_socket, to, messages, n_messages); } else { return 0; } return n_messages; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { PseudoSSLPriv *priv = sock->priv; if (priv->handshaken) { /* Fast path: pass directly through to the base socket once the handshake is * complete. */ if (priv->base_socket == NULL) return -1; return nice_socket_send_messages_reliable (priv->base_socket, to, messages, n_messages); } else { nice_socket_queue_send (&priv->send_queue, to, messages, n_messages); } return n_messages; } static gboolean socket_is_reliable (NiceSocket *sock) { PseudoSSLPriv *priv = sock->priv; return nice_socket_is_reliable (priv->base_socket); } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { PseudoSSLPriv *priv = sock->priv; return nice_socket_can_send (priv->base_socket, addr); } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { PseudoSSLPriv *priv = sock->priv; nice_socket_set_writable_callback (priv->base_socket, callback, user_data); } static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other) { PseudoSSLPriv *priv = sock->priv; return (sock == other) || (priv && nice_socket_is_based_on (priv->base_socket, other)); } libnice-0.1.14/socket/udp-turn-over-tcp.c0000664000076400007640000003227612724137775015135 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See * http://en.wikipedia.org/wiki/Berkeley_sockets.) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "udp-turn-over-tcp.h" #include "agent-priv.h" #include #include #include #ifndef G_OS_WIN32 #include #endif typedef struct { NiceTurnSocketCompatibility compatibility; union { guint8 u8[65536]; guint16 u16[32768]; } recv_buf; gsize recv_buf_len; /* in bytes */ guint expecting_len; NiceSocket *base_socket; } TurnTcpPriv; typedef enum { MS_TURN_CONTROL_MESSAGE = 2, MS_TURN_END_TO_END_DATA = 3 } MsTurnPayloadType; #define MAX_UDP_MESSAGE_SIZE 65535 #define MAGIC_COOKIE_OFFSET \ STUN_MESSAGE_HEADER_LENGTH + STUN_MESSAGE_TYPE_LEN + \ STUN_MESSAGE_LENGTH_LEN + sizeof(guint16) static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other); NiceSocket * nice_udp_turn_over_tcp_socket_new (NiceSocket *base_socket, NiceTurnSocketCompatibility compatibility) { TurnTcpPriv *priv; NiceSocket *sock = g_slice_new0 (NiceSocket); sock->priv = priv = g_slice_new0 (TurnTcpPriv); priv->compatibility = compatibility; priv->base_socket = base_socket; sock->type = NICE_SOCKET_TYPE_UDP_TURN_OVER_TCP; sock->fileno = priv->base_socket->fileno; sock->addr = priv->base_socket->addr; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->is_based_on = socket_is_based_on; sock->close = socket_close; return sock; } static void socket_close (NiceSocket *sock) { TurnTcpPriv *priv = sock->priv; if (priv->base_socket) nice_socket_free (priv->base_socket); g_slice_free(TurnTcpPriv, sock->priv); sock->priv = NULL; } static gssize socket_recv_message (NiceSocket *sock, NiceInputMessage *recv_message) { TurnTcpPriv *priv = sock->priv; gssize ret; guint padlen; GInputVector local_recv_buf; NiceInputMessage local_recv_message; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); if (priv->expecting_len == 0) { guint headerlen = 0; if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) headerlen = 4; else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) headerlen = 2; else return -1; local_recv_buf.buffer = priv->recv_buf.u8 + priv->recv_buf_len; local_recv_buf.size = headerlen - priv->recv_buf_len; local_recv_message.buffers = &local_recv_buf; local_recv_message.n_buffers = 1; local_recv_message.from = recv_message->from; local_recv_message.length = 0; ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); if (ret < 0) return ret; priv->recv_buf_len += local_recv_message.length; if (priv->recv_buf_len < headerlen) return 0; if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { guint16 magic = ntohs (*priv->recv_buf.u16); guint16 packetlen = ntohs (*(priv->recv_buf.u16 + 1)); if (magic < 0x4000) { /* Its STUN */ priv->expecting_len = 20 + packetlen; } else { /* Channel data */ priv->expecting_len = 4 + packetlen; } } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { guint compat_len = ntohs (*priv->recv_buf.u16); priv->expecting_len = compat_len; priv->recv_buf_len = 0; } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { guint8 pt = *priv->recv_buf.u8; guint16 packetlen = ntohs (priv->recv_buf.u16[1]); if (pt != MS_TURN_CONTROL_MESSAGE && pt != MS_TURN_END_TO_END_DATA) { /* Unexpected data, error in stream */ return -1; } /* Keep the RFC4571 framing for the NiceAgent to unframe */ priv->expecting_len = packetlen + sizeof(guint16); priv->recv_buf_len = sizeof(guint16); priv->recv_buf.u16[0] = priv->recv_buf.u16[1]; } } if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) padlen = (priv->expecting_len % 4) ? 4 - (priv->expecting_len % 4) : 0; else padlen = 0; local_recv_buf.buffer = priv->recv_buf.u8 + priv->recv_buf_len; local_recv_buf.size = priv->expecting_len + padlen - priv->recv_buf_len; local_recv_message.buffers = &local_recv_buf; local_recv_message.n_buffers = 1; local_recv_message.from = recv_message->from; local_recv_message.length = 0; ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); if (ret < 0) return ret; priv->recv_buf_len += local_recv_message.length; if (priv->recv_buf_len == priv->expecting_len + padlen) { /* FIXME: Eliminate this memcpy(). */ ret = memcpy_buffer_to_input_message (recv_message, priv->recv_buf.u8, priv->recv_buf_len); priv->expecting_len = 0; priv->recv_buf_len = 0; return ret; } return 0; } static gint socket_recv_messages (NiceSocket *nicesock, NiceInputMessage *recv_messages, guint n_recv_messages) { guint i; gboolean error = FALSE; /* Make sure socket has not been freed: */ g_assert (nicesock->priv != NULL); for (i = 0; i < n_recv_messages; i++) { gssize len; len = socket_recv_message (nicesock, &recv_messages[i]); recv_messages[i].length = MAX (len, 0); if (len < 0) error = TRUE; if (len <= 0) break; } /* Was there an error processing the first message? */ if (error && i == 0) return -1; return i; } static gssize socket_send_message (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *message, gboolean reliable) { TurnTcpPriv *priv = sock->priv; guint8 padbuf[3] = {0, 0, 0}; GOutputVector *local_bufs; NiceOutputMessage local_message; guint j; gint ret; guint n_bufs; union { guint16 google_len; struct { guint8 pt; guint8 zero; } msoc; } header_buf; guint offset = 0; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); /* Count the number of buffers. */ if (message->n_buffers == -1) { n_bufs = 0; for (j = 0; message->buffers[j].buffer != NULL; j++) n_bufs++; } else { n_bufs = message->n_buffers; } /* Allocate a new array of buffers, covering all the buffers in the input * @message, but with an additional one for a header and one for a footer. */ local_bufs = g_alloca ((n_bufs + 1) * sizeof (GOutputVector)); local_message.buffers = local_bufs; local_message.n_buffers = n_bufs + 1; if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE) { header_buf.google_len = htons (output_message_get_size (message)); local_bufs[0].buffer = &header_buf; local_bufs[0].size = sizeof (guint16); offset = 1; } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9 || priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_RFC5766) { gsize message_len = output_message_get_size (message); gsize padlen = (message_len % 4) ? 4 - (message_len % 4) : 0; local_bufs[n_bufs].buffer = &padbuf; local_bufs[n_bufs].size = padlen; } else if (priv->compatibility == NICE_TURN_SOCKET_COMPATIBILITY_OC2007) { union { guint32 u32; guint8 u8[4]; } cookie; guint16 len = output_message_get_size (message); /* Copy the cookie from possibly split messages */ cookie.u32 = 0; if (len > sizeof (TURN_MAGIC_COOKIE) + MAGIC_COOKIE_OFFSET) { guint16 buf_offset = 0; guint i; for (i = 0; i < n_bufs; i++) { if (message->buffers[i].size > (gsize) (MAGIC_COOKIE_OFFSET - buf_offset)) { /* If the cookie is split, we assume it's data */ if (message->buffers[i].size > sizeof (TURN_MAGIC_COOKIE) + MAGIC_COOKIE_OFFSET - buf_offset) { const guint8 *buf = message->buffers[i].buffer; memcpy (&cookie.u8, buf + MAGIC_COOKIE_OFFSET - buf_offset, sizeof (TURN_MAGIC_COOKIE)); } break; } else { buf_offset += message->buffers[i].size; } } } cookie.u32 = ntohl(cookie.u32); header_buf.msoc.zero = 0; if (cookie.u32 == TURN_MAGIC_COOKIE) header_buf.msoc.pt = MS_TURN_CONTROL_MESSAGE; else header_buf.msoc.pt = MS_TURN_END_TO_END_DATA; local_bufs[0].buffer = &header_buf; local_bufs[0].size = sizeof(header_buf.msoc); offset = 1; } else { local_message.n_buffers = n_bufs; } /* Copy the existing buffers across. */ for (j = 0; j < n_bufs; j++) { local_bufs[j + offset].buffer = message->buffers[j].buffer; local_bufs[j + offset].size = message->buffers[j].size; } if (reliable) ret = nice_socket_send_messages_reliable (priv->base_socket, to, &local_message, 1); else ret = nice_socket_send_messages (priv->base_socket, to, &local_message, 1); if (ret == 1) ret = output_message_get_size (&local_message); return ret; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { guint i; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; gssize len; len = socket_send_message (sock, to, message, FALSE); if (len < 0) { /* Error. */ if (i > 0) break; return len; } else if (len == 0) { /* EWOULDBLOCK. */ break; } } return i; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { guint i; for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; gssize len; len = socket_send_message (sock, to, message, TRUE); if (len < 0) { /* Error. */ return len; } } return i; } static gboolean socket_is_reliable (NiceSocket *sock) { TurnTcpPriv *priv = sock->priv; return nice_socket_is_reliable (priv->base_socket); } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { TurnTcpPriv *priv = sock->priv; return nice_socket_can_send (priv->base_socket, addr); } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { TurnTcpPriv *priv = sock->priv; nice_socket_set_writable_callback (priv->base_socket, callback, user_data); } static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other) { TurnTcpPriv *priv = sock->priv; return (sock == other) || (priv && nice_socket_is_based_on (priv->base_socket, other)); } libnice-0.1.14/socket/http.h0000664000076400007640000000337011522161146012557 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _HTTP_H #define _HTTP_H #include "socket.h" #include "agent.h" G_BEGIN_DECLS NiceSocket * nice_http_socket_new (NiceSocket *base_socket, NiceAddress *addr, gchar *username, gchar *password); G_END_DECLS #endif /* _HTTP_H */ libnice-0.1.14/socket/tcp-passive.h0000664000076400007640000000351112520743534014041 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2012 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * George Kiagiadakis, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _TCP_PASSIVE_H #define _TCP_PASSIVE_H #include "socket.h" G_BEGIN_DECLS NiceSocket * nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr); NiceSocket * nice_tcp_passive_socket_accept (NiceSocket *socket); G_END_DECLS #endif /* _TCP_PASSIVE_H */ libnice-0.1.14/socket/http.c0000664000076400007640000004746112724137775012603 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Implementation of TCP relay socket interface using TCP Berkeley sockets. (See * http://en.wikipedia.org/wiki/Berkeley_sockets.) */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "http.h" #include "agent-priv.h" #include "socket-priv.h" #include #include #ifndef G_OS_WIN32 #include #endif #define HTTP_USER_AGENT "libnice" typedef enum { HTTP_STATE_INIT, HTTP_STATE_HEADERS, HTTP_STATE_BODY, HTTP_STATE_CONNECTED, HTTP_STATE_ERROR } HttpState; typedef struct { HttpState state; NiceSocket *base_socket; NiceAddress addr; gchar *username; gchar *password; GQueue send_queue; /* Ring buffer for receiving HTTP headers into before they’re parsed. */ guint8 *recv_buf; gsize recv_buf_length; /* allocation size of @recv_buf */ gsize recv_buf_pos; /* offset from @recv_buf of the 0th byte in the buffer */ gsize recv_buf_fill; /* number of bytes occupied in the buffer */ /* Parsed from the Content-Length header provided by the other endpoint. */ gsize content_length; } HttpPriv; static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other); NiceSocket * nice_http_socket_new (NiceSocket *base_socket, NiceAddress *addr, gchar *username, gchar *password) { HttpPriv *priv; NiceSocket *sock = NULL; if (addr) { sock = g_slice_new0 (NiceSocket); sock->priv = priv = g_slice_new0 (HttpPriv); priv->base_socket = base_socket; priv->addr = *addr; priv->username = g_strdup (username); priv->password = g_strdup (password); priv->recv_buf = NULL; priv->recv_buf_length = 0; priv->recv_buf_pos = 0; priv->recv_buf_fill = 0; priv->content_length = 0; sock->type = NICE_SOCKET_TYPE_HTTP; sock->fileno = priv->base_socket->fileno; sock->addr = priv->base_socket->addr; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->is_based_on = socket_is_based_on; sock->close = socket_close; /* Send HTTP CONNECT */ { gchar *msg = NULL; gchar *credential = NULL; gchar host[INET6_ADDRSTRLEN]; gint port = nice_address_get_port (&priv->addr); GOutputVector local_bufs; NiceOutputMessage local_messages; nice_address_to_string (&priv->addr, host); if (username) { gchar * userpass = g_strdup_printf ("%s:%s", username, password ? password : ""); gchar * auth = g_base64_encode ((guchar *)userpass, strlen (userpass)); credential = g_strdup_printf ("Proxy-Authorization: Basic %s\r\n", auth); g_free (auth); g_free (userpass); } msg = g_strdup_printf ("CONNECT %s:%d HTTP/1.0\r\n" "Host: %s\r\n" "User-Agent: %s\r\n" "Content-Length: 0\r\n" "Proxy-Connection: Keep-Alive\r\n" "Connection: Keep-Alive\r\n" "Cache-Control: no-cache\r\n" "Pragma: no-cache\r\n" "%s\r\n", host, port, host, HTTP_USER_AGENT, credential? credential : "" ); g_free (credential); local_bufs.buffer = msg; local_bufs.size = strlen (msg); local_messages.buffers = &local_bufs; local_messages.n_buffers = 1; nice_socket_send_messages_reliable (priv->base_socket, NULL, &local_messages, 1); priv->state = HTTP_STATE_INIT; g_free (msg); } } return sock; } static void socket_close (NiceSocket *sock) { HttpPriv *priv = sock->priv; if (priv->base_socket) nice_socket_free (priv->base_socket); if (priv->username) g_free (priv->username); if (priv->password) g_free (priv->password); if (priv->recv_buf) g_free (priv->recv_buf); nice_socket_free_send_queue (&priv->send_queue); g_slice_free(HttpPriv, sock->priv); sock->priv = NULL; } static void assert_ring_buffer_valid (HttpPriv *priv) { g_assert (priv->recv_buf_fill <= priv->recv_buf_length); g_assert (priv->recv_buf_pos == 0 || priv->recv_buf_pos < priv->recv_buf_length); g_assert (priv->recv_buf_length == 0 || priv->recv_buf != NULL); } /* Pops up to @buffer_length bytes off the ring buffer and copies them into * @buffer. Returns the number of bytes copied. */ static gsize memcpy_ring_buffer_to_buffer (HttpPriv *priv, guint8 *buffer, gsize buffer_length) { gsize len, consumed = 0; gboolean has_wrapped; has_wrapped = (priv->recv_buf_pos + priv->recv_buf_fill) > priv->recv_buf_length; if (has_wrapped) { len = MIN (priv->recv_buf_length - priv->recv_buf_pos, buffer_length); memcpy (buffer, priv->recv_buf + priv->recv_buf_pos, len); consumed += len; buffer += len; buffer_length -= len; len = MIN (priv->recv_buf_fill - len, buffer_length); memcpy (buffer, priv->recv_buf, len); consumed += len; } else { len = MIN (priv->recv_buf_fill, buffer_length); memcpy (buffer, priv->recv_buf + priv->recv_buf_pos, len); consumed += len; } priv->recv_buf_pos = (priv->recv_buf_pos + consumed) % priv->recv_buf_length; priv->recv_buf_fill -= consumed; return consumed; } /* Returns the number of messages touched. Silently drops any data from @buffer * which doesn’t fit in @messages. Updates the ring buffer to pop the copied * data off it. Treats all #GInputVectors in @messages the same; there is no * differentiation between different #NiceInputMessages. */ static gint memcpy_ring_buffer_to_input_messages (HttpPriv *priv, NiceInputMessage *messages, guint n_messages) { guint i, j; for (i = 0; priv->recv_buf_fill > 0 && i < n_messages; i++) { NiceInputMessage *message = &messages[i]; for (j = 0; priv->recv_buf_fill > 0 && ((message->n_buffers >= 0 && j < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[j].buffer != NULL)); j++) { message->buffers[j].size = memcpy_ring_buffer_to_buffer (priv, message->buffers[j].buffer, message->buffers[j].size); } } return i; } /* FIXME: The current implementation of socket_recv_message() is a fast * pass-through to nice_socket_recv_message() if the HTTP socket is connected, * but is a slow state machine otherwise, using multiple memcpy()s. Spruce it up * to better to use the recv_messages to avoid the memcpy()s. */ static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { HttpPriv *priv = sock->priv; gint ret = -1; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); if (priv->state == HTTP_STATE_CONNECTED) { guint i; /* Fast path: pass through to the base socket once we’re connected. */ if (priv->base_socket) { ret = nice_socket_recv_messages (priv->base_socket, recv_messages, n_recv_messages); } if (ret <= 0) return ret; /* After successfully receiving into at least one NiceInputMessage, * update the from address in each valid NiceInputMessage. */ for (i = 0; i < (guint) ret; i++) { if (recv_messages[i].from != NULL) *recv_messages[i].from = priv->addr; } return ret; } else { /* Slow path: read into a local ring buffer until we’re parsed enough of the * headers. Double the buffer in size every time it fills up. */ gboolean has_wrapped; GInputVector local_recv_bufs[2]; NiceInputMessage local_recv_message = { local_recv_bufs, 2, NULL, 0 }; /* Has the buffer filled up? Start with an initial buffer of 1KB, which * should cover the average size of HTTP response headers. Source: * http://dev.chromium.org/spdy/spdy-whitepaper */ if (priv->recv_buf_fill == priv->recv_buf_length) { priv->recv_buf_length = MAX (priv->recv_buf_length * 2, 1024); priv->recv_buf = g_realloc (priv->recv_buf, priv->recv_buf_length); } assert_ring_buffer_valid (priv); /* Read some data into the buffer. Use two GInputVectors: one for the tail * of the buffer and one for the head. */ has_wrapped = (priv->recv_buf_pos + priv->recv_buf_fill) > priv->recv_buf_length; if (has_wrapped) { local_recv_bufs[0].buffer = priv->recv_buf + (priv->recv_buf_pos + priv->recv_buf_fill) % priv->recv_buf_length; local_recv_bufs[0].size = priv->recv_buf_length - priv->recv_buf_fill; local_recv_bufs[1].buffer = NULL; local_recv_bufs[1].size = 0; } else { local_recv_bufs[0].buffer = priv->recv_buf + priv->recv_buf_pos + priv->recv_buf_fill; local_recv_bufs[0].size = priv->recv_buf_length - (priv->recv_buf_pos + priv->recv_buf_fill); local_recv_bufs[1].buffer = priv->recv_buf; local_recv_bufs[1].size = priv->recv_buf_pos; } if (priv->base_socket) { ret = nice_socket_recv_messages (priv->base_socket, &local_recv_message, 1); } if (ret <= 0) return ret; /* Update the buffer’s metadata. */ priv->recv_buf_fill += local_recv_message.length; assert_ring_buffer_valid (priv); /* Fall through and try parsing the newly received data. */ } #define GET_BYTE(pos) \ priv->recv_buf[(pos + priv->recv_buf_pos) % priv->recv_buf_length] #define EAT_WHITESPACE(pos) \ while (pos < priv->recv_buf_fill && GET_BYTE(pos) == ' ') \ pos++; \ if (pos >= priv->recv_buf_fill) \ goto not_enough_data; retry: nice_debug ("Receiving from HTTP proxy (state %d) : %" G_GSSIZE_FORMAT " \n" "'%s'", priv->state, priv->recv_buf_fill, priv->recv_buf + priv->recv_buf_pos); switch (priv->state) { case HTTP_STATE_INIT: { /* This is a logical position in the recv_buf; add * (priv->recv_buf + priv->recv_buf_pos) to get the actual byte in * memory. */ guint pos = 0; /* Eat leading whitespace and check we have enough data. */ EAT_WHITESPACE (pos); if (pos + 7 > priv->recv_buf_fill) goto not_enough_data; if (GET_BYTE (pos + 0) != 'H' || GET_BYTE (pos + 1) != 'T' || GET_BYTE (pos + 2) != 'T' || GET_BYTE (pos + 3) != 'P' || GET_BYTE (pos + 4) != '/' || GET_BYTE (pos + 5) != '1' || GET_BYTE (pos + 6) != '.') goto error; pos += 7; if (pos >= priv->recv_buf_fill) goto not_enough_data; if (GET_BYTE (pos) != '0' && GET_BYTE (pos) != '1') goto error; pos++; /* Make sure we have a space after the HTTP version */ if (pos >= priv->recv_buf_fill) goto not_enough_data; if (GET_BYTE (pos) != ' ') goto error; EAT_WHITESPACE (pos); /* Check for a successful 2xx code */ if (pos + 3 > priv->recv_buf_fill) goto not_enough_data; if (GET_BYTE (pos) != '2' || GET_BYTE (pos + 1) < '0' || GET_BYTE (pos + 1) > '9' || GET_BYTE (pos + 2) < '0' || GET_BYTE (pos + 2) > '9') goto error; /* Clear any trailing chars */ while (pos + 1 < priv->recv_buf_fill && GET_BYTE (pos) != '\r' && GET_BYTE (pos + 1) != '\n') pos++; if (pos + 1 >= priv->recv_buf_fill) goto not_enough_data; pos += 2; /* Consume the data we just parsed. */ priv->recv_buf_pos = (priv->recv_buf_pos + pos) % priv->recv_buf_length; priv->recv_buf_fill -= pos; priv->content_length = 0; priv->state = HTTP_STATE_HEADERS; goto retry; } break; case HTTP_STATE_HEADERS: { guint pos = 0; if (pos + 15 < priv->recv_buf_fill && (GET_BYTE (pos + 0) == 'C' || GET_BYTE (pos + 0) == 'c') && (GET_BYTE (pos + 1) == 'o' || GET_BYTE (pos + 1) == 'O') && (GET_BYTE (pos + 2) == 'n' || GET_BYTE (pos + 2) == 'N') && (GET_BYTE (pos + 3) == 't' || GET_BYTE (pos + 3) == 'T') && (GET_BYTE (pos + 4) == 'e' || GET_BYTE (pos + 4) == 'E') && (GET_BYTE (pos + 5) == 'n' || GET_BYTE (pos + 5) == 'N') && (GET_BYTE (pos + 6) == 't' || GET_BYTE (pos + 6) == 'T') && GET_BYTE (pos + 7) == '-' && (GET_BYTE (pos + 8) == 'L' || GET_BYTE (pos + 8) == 'l') && (GET_BYTE (pos + 9) == 'e' || GET_BYTE (pos + 9) == 'E') && (GET_BYTE (pos + 10) == 'n' || GET_BYTE (pos + 10) == 'N') && (GET_BYTE (pos + 11) == 'g' || GET_BYTE (pos + 11) == 'G') && (GET_BYTE (pos + 12) == 't' || GET_BYTE (pos + 12) == 'T') && (GET_BYTE (pos + 13) == 'h' || GET_BYTE (pos + 13) == 'H') && GET_BYTE (pos + 14) == ':') { /* Found a Content-Length header. Parse and store the value. Note that * the HTTP standard allows for arbitrarily-big content lengths. We * limit it to G_MAXSIZE for sanity’s sake. * * The code below is equivalent to strtoul(input, NULL, 10), but * operates on a ring buffer. */ pos += 15; EAT_WHITESPACE (pos); priv->content_length = 0; while (TRUE) { guint8 byte = GET_BYTE (pos); gint val = g_ascii_digit_value (byte); if (byte == '\r') { /* Reached the end of the value; fall out to the code below which * will grab the \n. */ break; } else if (val == -1) { priv->content_length = 0; goto error; } /* Check for overflow. Don’t flag it as an error; just fall through * to the code below which will skip to the \r\n. */ if (priv->content_length > G_MAXSIZE / 10 || priv->content_length * 10 > G_MAXSIZE - val) { priv->content_length = 0; break; } priv->content_length = (priv->content_length * 10) + val; if (pos + 1 > priv->recv_buf_fill) goto not_enough_data; pos++; } } /* Skip over the header. */ while (pos + 1 < priv->recv_buf_fill && GET_BYTE (pos) != '\r' && GET_BYTE (pos + 1) != '\n') pos++; nice_debug ("pos = %u, fill = %" G_GSSIZE_FORMAT, pos, priv->recv_buf_fill); if (pos + 1 >= priv->recv_buf_fill) goto not_enough_data; pos += 2; /* Consume the data we just parsed. */ priv->recv_buf_pos = (priv->recv_buf_pos + pos) % priv->recv_buf_length; priv->recv_buf_fill -= pos; if (pos == 2) priv->state = HTTP_STATE_BODY; goto retry; } break; case HTTP_STATE_BODY: { gsize consumed; if (priv->content_length == 0) { priv->state = HTTP_STATE_CONNECTED; goto retry; } if (priv->recv_buf_fill == 0) goto not_enough_data; consumed = MIN (priv->content_length, priv->recv_buf_fill); priv->recv_buf_pos = (priv->recv_buf_pos + consumed) % priv->recv_buf_length; priv->recv_buf_fill -= consumed; priv->content_length -= consumed; goto retry; } break; case HTTP_STATE_CONNECTED: { gsize len; len = memcpy_ring_buffer_to_input_messages (priv, recv_messages, n_recv_messages); /* Send the pending data */ nice_socket_flush_send_queue (priv->base_socket, &priv->send_queue); return len; } break; case HTTP_STATE_ERROR: default: /* Unknown status */ goto error; } not_enough_data: return 0; error: nice_debug ("http error"); if (priv->base_socket) nice_socket_free (priv->base_socket); priv->base_socket = NULL; priv->state = HTTP_STATE_ERROR; return -1; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { HttpPriv *priv = sock->priv; /* Make sure socket has not been freed: */ g_assert (sock->priv != NULL); if (priv->state == HTTP_STATE_CONNECTED) { /* Fast path. */ if (!priv->base_socket) return -1; return nice_socket_send_messages (priv->base_socket, to, messages, n_messages); } else if (priv->state == HTTP_STATE_ERROR) { return -1; } else { return 0; } return n_messages; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { HttpPriv *priv = sock->priv; if (priv->state == HTTP_STATE_CONNECTED) { /* Fast path. */ if (!priv->base_socket) return -1; return nice_socket_send_messages_reliable (priv->base_socket, to, messages, n_messages); } else if (priv->state == HTTP_STATE_ERROR) { return -1; } else { nice_socket_queue_send (&priv->send_queue, to, messages, n_messages); } return n_messages; } static gboolean socket_is_reliable (NiceSocket *sock) { HttpPriv *priv = sock->priv; return nice_socket_is_reliable (priv->base_socket); } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { HttpPriv *priv = sock->priv; return nice_socket_can_send (priv->base_socket, addr); } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { HttpPriv *priv = sock->priv; nice_socket_set_writable_callback (priv->base_socket, callback, user_data); } static gboolean socket_is_based_on (NiceSocket *sock, NiceSocket *other) { HttpPriv *priv = sock->priv; return (sock == other) || (priv && nice_socket_is_based_on (priv->base_socket, other)); } libnice-0.1.14/socket/udp-bsd.h0000664000076400007640000000337011522161146013136 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _UDP_BSD_H #define _UDP_BSD_H #include "socket.h" G_BEGIN_DECLS NiceSocket * nice_udp_bsd_socket_new (NiceAddress *addr); G_END_DECLS #endif /* _UDP_BSD_H */ libnice-0.1.14/socket/socket.c0000664000076400007640000003473212724137775013111 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "socket.h" #include "socket-priv.h" #include "agent-priv.h" #include #ifndef G_OS_WIN32 #include #endif typedef struct _NiceSocketQueuedSend NiceSocketQueuedSend; struct _NiceSocketQueuedSend { guint8 *buf; /* owned */ gsize length; NiceAddress to; }; /** * nice_socket_recv_messages: * @sock: a #NiceSocket * @recv_messages: (array length=n_recv_messages) (out caller-allocates): * array of #NiceInputMessages to return received messages in * @n_recv_messages: number of elements in the @recv_messages array * * Receive up to @n_recv_messages message on the socket, in a non-reliable, * non-blocking fashion. The total size of the buffers in each #NiceInputMessage * must be big enough to contain an entire message (65536 bytes), or excess * bytes will be silently dropped. * * On success, the number of messages received into @recv_messages is returned, * which may be less than @n_recv_messages if the call would have blocked * part-way through. If the socket would have blocked to begin with, or if * @n_recv_messages is zero, zero is returned. On failure, a negative value is * returned, but no further error information is available. Calling this * function on a socket which has closed is an error, and a negative value is * returned. * * If a positive N is returned, the first N messages in @recv_messages are * valid. Each valid message is guaranteed to have a non-zero * #NiceInputMessage::length, and its buffers are guaranteed to be filled * sequentially up to that number of bytes If #NiceInputMessage::from was * non-%NULL for a valid message, it may be set to the address of the sender of * that received message. * * If the return value is zero or negative, the from return address and length * in every #NiceInputMessage in @recv_messages are guaranteed to be unmodified. * The buffers may have been modified. * * The base addresses and sizes of the buffers in a #NiceInputMessage are never * modified. Neither is the base address of #NiceInputMessage::from, nor the * base address and length of the #NiceInputMessage::buffers array. * * Returns: number of valid messages returned in @recv_messages, or a negative * value on error * * Since: 0.1.5 */ gint nice_socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { g_return_val_if_fail (sock != NULL, -1); g_return_val_if_fail (n_recv_messages == 0 || recv_messages != NULL, -1); return sock->recv_messages (sock, recv_messages, n_recv_messages); } /** * nice_socket_send_messages: * @sock: a #NiceSocket * @messages: (array length=n_messages) (in caller-allocates): * array of #NiceOutputMessages containing the messages to send * @n_messages: number of elements in the @messages array * * Send up to @n_messages on the socket, in a non-reliable, non-blocking * fashion. The total size of the buffers in each #NiceOutputMessage * must be at most the maximum UDP payload size (65535 bytes), or excess * bytes will be silently dropped. * * On success, the number of messages transmitted from @messages is returned, * which may be less than @n_messages if the call would have blocked * part-way through. If the socket would have blocked to begin with, or if * @n_messages is zero, zero is returned. On failure, a negative value is * returned, but no further error information is available. Calling this * function on a socket which has closed is an error, and a negative value is * returned. * * If a positive N is returned, the first N messages in @messages have been * sent in full, and the remaining messages have not been sent at all. * * If #NiceOutputMessage::to is specified for a message, that will be used as * the destination address for the message. Otherwise, if %NULL, the default * destination for @sock will be used. * * Every field of every #NiceOutputMessage is guaranteed to be unmodified when * this function returns. * * Returns: number of messages successfully sent from @messages, or a negative * value on error * * Since: 0.1.5 */ gint nice_socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { g_return_val_if_fail (sock != NULL, -1); g_return_val_if_fail (n_messages == 0 || messages != NULL, -1); return sock->send_messages (sock, to, messages, n_messages); } /** * nice_socket_send_messages_reliable: * @sock: a #NiceSocket * @messages: (array length=n_messages) (in caller-allocates): * array of #NiceOutputMessages containing the messages to send * @n_messages: number of elements in the @messages array * * Send @n_messages on the socket, in a reliable, non-blocking fashion. * The total size of the buffers in each #NiceOutputMessage * must be at most the maximum UDP payload size (65535 bytes), or excess * bytes will be silently dropped. * * On success, the number of messages transmitted from @messages is returned, * which will be equal to @n_messages. If the call would have blocked part-way * though, the remaining bytes will be queued for sending later. * On failure, a negative value is returned, but no further error information * is available. Calling this function on a socket which has closed is an error, * and a negative value is returned. Calling this function on a socket which * is not TCP or does not have a TCP base socket, will result in an error. * * If #NiceOutputMessage::to is specified for a message, that will be used as * the destination address for the message. Otherwise, if %NULL, the default * destination for @sock will be used. * * Every field of every #NiceOutputMessage is guaranteed to be unmodified when * this function returns. * * Returns: number of messages successfully sent from @messages, or a negative * value on error * * Since: 0.1.5 */ gint nice_socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { g_return_val_if_fail (sock != NULL, -1); g_return_val_if_fail (n_messages == 0 || messages != NULL, -1); return sock->send_messages_reliable (sock, to, messages, n_messages); } /* Convenience wrapper around nice_socket_recv_messages(). Returns the number of * bytes received on success (which will be @len), zero if sending would block, or * -1 on error. */ gssize nice_socket_recv (NiceSocket *sock, NiceAddress *from, gsize len, gchar *buf) { GInputVector local_buf = { buf, len }; NiceInputMessage local_message = { &local_buf, 1, from, 0}; gint ret; ret = sock->recv_messages (sock, &local_message, 1); if (ret == 1) return local_message.length; return ret; } /* Convenience wrapper around nice_socket_send_messages(). Returns the number of * bytes sent on success (which will be @len), zero if sending would block, or * -1 on error. */ gssize nice_socket_send (NiceSocket *sock, const NiceAddress *to, gsize len, const gchar *buf) { GOutputVector local_buf = { buf, len }; NiceOutputMessage local_message = { &local_buf, 1}; gint ret; ret = sock->send_messages (sock, to, &local_message, 1); if (ret == 1) return len; return ret; } gssize nice_socket_send_reliable (NiceSocket *sock, const NiceAddress *to, gsize len, const gchar *buf) { GOutputVector local_buf = { buf, len }; NiceOutputMessage local_message = { &local_buf, 1}; gint ret; ret = sock->send_messages_reliable (sock, to, &local_message, 1); if (ret == 1) return len; return ret; } gboolean nice_socket_is_reliable (NiceSocket *sock) { return sock->is_reliable (sock); } gboolean nice_socket_can_send (NiceSocket *sock, NiceAddress *addr) { if (sock->can_send) return sock->can_send (sock, addr); return TRUE; } void nice_socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { if (sock->set_writable_callback) sock->set_writable_callback (sock, callback, user_data); } gboolean nice_socket_is_based_on (NiceSocket *sock, NiceSocket *other) { if (sock->is_based_on) return sock->is_based_on (sock, other); return (sock == other); } void nice_socket_free (NiceSocket *sock) { if (sock) { sock->close (sock); g_slice_free (NiceSocket,sock); } } static void nice_socket_free_queued_send (NiceSocketQueuedSend *tbs) { g_free (tbs->buf); g_slice_free (NiceSocketQueuedSend, tbs); } void nice_socket_queue_send (GQueue *send_queue, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { guint i; if (n_messages == 0) return; /* Compact the message’s buffers before queueing. */ for (i = 0; i < n_messages; i++) { NiceSocketQueuedSend *tbs; const NiceOutputMessage *message = &messages[i]; gsize message_len_remaining = output_message_get_size (message); guint j; gsize offset = 0; if (message_len_remaining == 0) continue; /* Compact the buffer. */ tbs = g_slice_new0 (NiceSocketQueuedSend); tbs->buf = g_malloc (message_len_remaining); tbs->length = message_len_remaining; if (to) tbs->to = *to; else memset (&tbs->to, 0, sizeof(NiceAddress)); g_queue_push_tail (send_queue, tbs); for (j = 0; (message->n_buffers >= 0 && j < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[j].buffer != NULL); j++) { const GOutputVector *buffer = &message->buffers[j]; gsize len; len = MIN (buffer->size, message_len_remaining); memcpy (tbs->buf + offset, buffer->buffer, len); message_len_remaining -= len; offset += len; } g_assert (offset == tbs->length); } } void nice_socket_queue_send_with_callback (GQueue *send_queue, const NiceOutputMessage *message, gsize message_offset, gsize message_len, gboolean head, GSocket *gsock, GSource **io_source, GMainContext *context, GSourceFunc cb, gpointer user_data) { NiceSocketQueuedSend *tbs; guint j; gsize offset = 0; if (message_offset >= message_len) return; tbs = g_slice_new0 (NiceSocketQueuedSend); tbs->length = message_len - message_offset; tbs->buf = g_malloc (tbs->length); if (head) g_queue_push_head (send_queue, tbs); else g_queue_push_tail (send_queue, tbs); if (io_source && gsock && context && cb && *io_source == NULL) { *io_source = g_socket_create_source(gsock, G_IO_OUT, NULL); g_source_set_callback (*io_source, (GSourceFunc) cb, user_data, NULL); g_source_attach (*io_source, context); } /* Move the data into the buffer. */ for (j = 0; (message->n_buffers >= 0 && j < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[j].buffer != NULL); j++) { const GOutputVector *buffer = &message->buffers[j]; gsize len; /* Skip this buffer if it’s within @message_offset. */ if (buffer->size <= message_offset) { message_offset -= buffer->size; continue; } len = MIN (tbs->length - offset, buffer->size - message_offset); memcpy (tbs->buf + offset, (guint8 *) buffer->buffer + message_offset, len); offset += len; if (message_offset >= len) message_offset -= len; else message_offset = 0; } } void nice_socket_flush_send_queue (NiceSocket *base_socket, GQueue *send_queue) { NiceSocketQueuedSend *tbs; while ((tbs = g_queue_pop_head (send_queue))) { NiceAddress *to = &tbs->to; if (!nice_address_is_valid (to)) to = NULL; /* We only queue reliable data */ nice_socket_send_reliable (base_socket, to, tbs->length, (const gchar *) tbs->buf); nice_socket_free_queued_send (tbs); } } gboolean nice_socket_flush_send_queue_to_socket (GSocket *gsock, GQueue *send_queue) { NiceSocketQueuedSend *tbs; GError *gerr = NULL; while ((tbs = g_queue_pop_head (send_queue)) != NULL) { int ret; GOutputVector local_bufs = { tbs->buf, tbs->length }; ret = g_socket_send_message (gsock, NULL, &local_bufs, 1, NULL, 0, G_SOCKET_MSG_NONE, NULL, &gerr); if (ret < 0) { if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { GOutputVector local_buf = { tbs->buf, tbs->length }; NiceOutputMessage local_message = {&local_buf, 1}; nice_socket_queue_send_with_callback (send_queue, &local_message, 0, local_buf.size, TRUE, NULL, NULL, NULL, NULL, NULL); nice_socket_free_queued_send (tbs); g_error_free (gerr); return FALSE; } g_clear_error (&gerr); } else if (ret < (int) tbs->length) { GOutputVector local_buf = { tbs->buf + ret, tbs->length - ret }; NiceOutputMessage local_message = {&local_buf, 1}; nice_socket_queue_send_with_callback (send_queue, &local_message, 0, local_buf.size, TRUE, NULL, NULL, NULL, NULL, NULL); nice_socket_free_queued_send (tbs); return FALSE; } nice_socket_free_queued_send (tbs); } return TRUE; } void nice_socket_free_send_queue (GQueue *send_queue) { g_queue_foreach (send_queue, (GFunc) nice_socket_free_queued_send, NULL); g_queue_clear (send_queue); } libnice-0.1.14/socket/udp-turn.h0000664000076400007640000000532312721653245013366 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _UDP_TURN_H #define _UDP_TURN_H typedef enum { NICE_TURN_SOCKET_COMPATIBILITY_DRAFT9, NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE, NICE_TURN_SOCKET_COMPATIBILITY_MSN, NICE_TURN_SOCKET_COMPATIBILITY_OC2007, NICE_TURN_SOCKET_COMPATIBILITY_RFC5766, } NiceTurnSocketCompatibility; #include "socket.h" #include "stun/stunmessage.h" G_BEGIN_DECLS guint nice_udp_turn_socket_parse_recv_message (NiceSocket *sock, NiceSocket **from_sock, NiceInputMessage *message); gsize nice_udp_turn_socket_parse_recv (NiceSocket *sock, NiceSocket **from_sock, NiceAddress *from, gsize len, guint8 *buf, NiceAddress *recv_from, guint8 *recv_buf, gsize recv_len); gboolean nice_udp_turn_socket_set_peer (NiceSocket *sock, NiceAddress *peer); NiceSocket * nice_udp_turn_socket_new (GMainContext *ctx, NiceAddress *addr, NiceSocket *base_socket, NiceAddress *server_addr, gchar *username, gchar *password, NiceTurnSocketCompatibility compatibility); void nice_udp_turn_socket_set_ms_realm(NiceSocket *sock, StunMessage *msg); void nice_udp_turn_socket_set_ms_connection_id (NiceSocket *sock, StunMessage *msg); void nice_udp_turn_socket_cache_realm_nonce (NiceSocket *sock, StunMessage *msg); G_END_DECLS #endif /* _UDP_TURN_H */ libnice-0.1.14/socket/socks5.h0000644000076400007640000000340011241364464013005 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _SOCKS5_H #define _SOCKS5_H #include "socket.h" #include "agent.h" G_BEGIN_DECLS NiceSocket * nice_socks5_socket_new (NiceSocket *base_socket, NiceAddress *addr, gchar *username, gchar *password); G_END_DECLS #endif /* _SOCKS5_H */ libnice-0.1.14/socket/tcp-passive.c0000664000076400007640000002233612724137775014054 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2012 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * George Kiagiadakis, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "tcp-passive.h" #include "agent-priv.h" #include #include #include #ifndef G_OS_WIN32 #include #endif /* FIXME: This should be defined in gio/gnetworking.h, which we should include; * but we cannot do that without refactoring. * (See: https://phabricator.freedesktop.org/D230). */ #define TCP_NODELAY 1 typedef struct { GMainContext *context; GHashTable *connections; NiceSocketWritableCb writable_cb; gpointer writable_data; } TcpPassivePriv; static void socket_close (NiceSocket *sock); static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); static gboolean socket_is_reliable (NiceSocket *sock); static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr); static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); static guint nice_address_hash (const NiceAddress * key); NiceSocket * nice_tcp_passive_socket_new (GMainContext *ctx, NiceAddress *addr) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; NiceSocket *sock; TcpPassivePriv *priv; GSocket *gsock = NULL; gboolean gret = FALSE; GSocketAddress *gaddr; if (addr != NULL) { nice_address_copy_to_sockaddr(addr, &name.addr); } else { memset (&name, 0, sizeof (name)); name.storage.ss_family = AF_UNSPEC; } if (name.storage.ss_family == AF_UNSPEC || name.storage.ss_family == AF_INET) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in); #endif } else if (name.storage.ss_family == AF_INET6) { gsock = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL); name.storage.ss_family = AF_INET6; #ifdef HAVE_SA_LEN name.storage.ss_len = sizeof (struct sockaddr_in6); #endif } if (gsock == NULL) { return NULL; } gaddr = g_socket_address_new_from_native (&name.addr, sizeof (name)); if (gaddr == NULL) { g_object_unref (gsock); return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); gret = g_socket_bind (gsock, gaddr, FALSE, NULL) && g_socket_listen (gsock, NULL); g_object_unref (gaddr); if (gret == FALSE) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } gaddr = g_socket_get_local_address (gsock, NULL); if (gaddr == NULL || !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_object_unref (gaddr); if (ctx == NULL) { ctx = g_main_context_default (); } sock = g_slice_new0 (NiceSocket); nice_address_set_from_sockaddr (&sock->addr, &name.addr); sock->priv = priv = g_slice_new0 (TcpPassivePriv); priv->context = g_main_context_ref (ctx); priv->connections = g_hash_table_new_full ((GHashFunc) nice_address_hash, (GEqualFunc) nice_address_equal, ( GDestroyNotify) nice_address_free, NULL); priv->writable_cb = NULL; priv->writable_data = NULL; sock->type = NICE_SOCKET_TYPE_TCP_PASSIVE; sock->fileno = gsock; sock->send_messages = socket_send_messages; sock->send_messages_reliable = socket_send_messages_reliable; sock->recv_messages = socket_recv_messages; sock->is_reliable = socket_is_reliable; sock->can_send = socket_can_send; sock->set_writable_callback = socket_set_writable_callback; sock->close = socket_close; return sock; } static void socket_close (NiceSocket *sock) { TcpPassivePriv *priv = sock->priv; if (sock->fileno != NULL) { g_socket_close (sock->fileno, NULL); g_object_unref (sock->fileno); sock->fileno = NULL; } if (priv->context) g_main_context_unref (priv->context); g_hash_table_unref (priv->connections); g_slice_free (TcpPassivePriv, sock->priv); } static gint socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages) { return -1; } static gint socket_send_messages (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { TcpPassivePriv *priv = sock->priv; if (to) { NiceSocket *peer_socket = g_hash_table_lookup (priv->connections, to); if (peer_socket) return nice_socket_send_messages (peer_socket, to, messages, n_messages); } return -1; } static gint socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages) { TcpPassivePriv *priv = sock->priv; if (to) { NiceSocket *peer_socket = g_hash_table_lookup (priv->connections, to); if (peer_socket) return nice_socket_send_messages_reliable (peer_socket, to, messages, n_messages); } return -1; } static gboolean socket_is_reliable (NiceSocket *sock) { return TRUE; } static gboolean socket_can_send (NiceSocket *sock, NiceAddress *addr) { TcpPassivePriv *priv = sock->priv; NiceSocket *peer_socket = NULL; /* FIXME: Danger if child socket was closed */ if (addr) peer_socket = g_hash_table_lookup (priv->connections, addr); if (peer_socket) return nice_socket_can_send (peer_socket, addr); return FALSE; } static void _child_writable_cb (NiceSocket *child, gpointer data) { NiceSocket *sock = data; TcpPassivePriv *priv = sock->priv; if (priv->writable_cb) priv->writable_cb (sock, priv->writable_data); } static void socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data) { TcpPassivePriv *priv = sock->priv; priv->writable_cb = callback; priv->writable_data = user_data; } NiceSocket * nice_tcp_passive_socket_accept (NiceSocket *sock) { union { struct sockaddr_storage storage; struct sockaddr addr; } name; TcpPassivePriv *priv = sock->priv; GSocket *gsock = NULL; GSocketAddress *gaddr; NiceAddress remote_addr; NiceSocket *new_socket = NULL; gsock = g_socket_accept (sock->fileno, NULL, NULL); if (gsock == NULL) { return NULL; } /* GSocket: All socket file descriptors are set to be close-on-exec. */ g_socket_set_blocking (gsock, false); /* setting TCP_NODELAY to TRUE in order to avoid packet batching */ g_socket_set_option (gsock, IPPROTO_TCP, TCP_NODELAY, TRUE, NULL); gaddr = g_socket_get_remote_address (gsock, NULL); if (gaddr == NULL || !g_socket_address_to_native (gaddr, &name.addr, sizeof (name), NULL)) { g_socket_close (gsock, NULL); g_object_unref (gsock); return NULL; } g_object_unref (gaddr); nice_address_set_from_sockaddr (&remote_addr, &name.addr); new_socket = nice_tcp_bsd_socket_new_from_gsock (priv->context, gsock, &sock->addr, &remote_addr, TRUE); g_object_unref (gsock); if (new_socket) { NiceAddress *key = nice_address_dup (&remote_addr); nice_socket_set_writable_callback (new_socket, _child_writable_cb, sock); g_hash_table_insert (priv->connections, key, new_socket); } return new_socket; } static guint nice_address_hash (const NiceAddress * key) { gchar ip[INET6_ADDRSTRLEN]; gchar *str; guint hash; nice_address_to_string (key, ip); str = g_strdup_printf ("%s:%u", ip, nice_address_get_port (key)); hash = g_str_hash (str); g_free (str); return hash; } libnice-0.1.14/socket/udp-turn-over-tcp.h0000664000076400007640000000345412520743534015124 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _UDP_TURN_OVER_TCP_H #define _UDP_TURN_OVER_TCP_H #include "socket.h" #include "agent.h" G_BEGIN_DECLS NiceSocket * nice_udp_turn_over_tcp_socket_new (NiceSocket *base_socket, NiceTurnSocketCompatibility compatibility); G_END_DECLS #endif /* _UDP_TURN_OVER_TCP_H */ libnice-0.1.14/socket/socket.h0000664000076400007640000001165113070507156013076 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _SOCKET_H #define _SOCKET_H #include "agent.h" #include "address.h" #include #ifdef G_OS_WIN32 #include #include #else #include #include #include #include #endif G_BEGIN_DECLS typedef struct _NiceSocket NiceSocket; typedef enum { NICE_SOCKET_TYPE_UDP_BSD, NICE_SOCKET_TYPE_TCP_BSD, NICE_SOCKET_TYPE_PSEUDOSSL, NICE_SOCKET_TYPE_HTTP, NICE_SOCKET_TYPE_SOCKS5, NICE_SOCKET_TYPE_UDP_TURN, NICE_SOCKET_TYPE_UDP_TURN_OVER_TCP, NICE_SOCKET_TYPE_TCP_ACTIVE, NICE_SOCKET_TYPE_TCP_PASSIVE, NICE_SOCKET_TYPE_TCP_SO } NiceSocketType; typedef void (*NiceSocketWritableCb) (NiceSocket *sock, gpointer user_data); struct _NiceSocket { NiceAddress addr; NiceSocketType type; GSocket *fileno; /* Implementations must handle any value of n_recv_messages, including 0. Iff * n_recv_messages is 0, recv_messages may be NULL. */ gint (*recv_messages) (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); /* As above, @n_messages may be zero. Iff so, @messages may be %NULL. */ gint (*send_messages) (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); gint (*send_messages_reliable) (NiceSocket *sock, const NiceAddress *to, const NiceOutputMessage *messages, guint n_messages); gboolean (*is_reliable) (NiceSocket *sock); gboolean (*can_send) (NiceSocket *sock, NiceAddress *addr); void (*set_writable_callback) (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); gboolean (*is_based_on) (NiceSocket *sock, NiceSocket *other); void (*close) (NiceSocket *sock); void *priv; }; G_GNUC_WARN_UNUSED_RESULT gint nice_socket_recv_messages (NiceSocket *sock, NiceInputMessage *recv_messages, guint n_recv_messages); gint nice_socket_send_messages (NiceSocket *sock, const NiceAddress *addr, const NiceOutputMessage *messages, guint n_messages); gint nice_socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *addr, const NiceOutputMessage *messages, guint n_messages); gssize nice_socket_recv (NiceSocket *sock, NiceAddress *from, gsize len, gchar *buf); gssize nice_socket_send (NiceSocket *sock, const NiceAddress *to, gsize len, const gchar *buf); gssize nice_socket_send_reliable (NiceSocket *sock, const NiceAddress *addr, gsize len, const gchar *buf); gboolean nice_socket_is_reliable (NiceSocket *sock); gboolean nice_socket_can_send (NiceSocket *sock, NiceAddress *addr); void nice_socket_set_writable_callback (NiceSocket *sock, NiceSocketWritableCb callback, gpointer user_data); /** * nice_socket_is_based_on: * @sock: a #NiceSocket * @other: another #NiceSocket * * Checks whether @sock wraps @other as a source and destination of its read and * write operations. The function traverses the whole chain of @sock's base * sockets until @other is found or the end is reached. * * Returns: %TRUE if @sock is based on @other or if @sock and @other are * the same socket, %FALSE otherwise. * * Since: 0.1.14 */ gboolean nice_socket_is_based_on (NiceSocket *sock, NiceSocket *other); void nice_socket_free (NiceSocket *sock); #include "udp-bsd.h" #include "tcp-bsd.h" #include "tcp-active.h" #include "tcp-passive.h" #include "pseudossl.h" #include "socks5.h" #include "http.h" #include "udp-turn.h" #include "udp-turn-over-tcp.h" G_END_DECLS #endif /* _SOCKET_H */ libnice-0.1.14/ltmain.sh0000644000076400007640000117077113067560503011776 00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION=2.4.6 package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname (GNU libtool) 2.4.6 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -stdlib=* select c++ std lib with clang -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: libnice-0.1.14/config.sub0000755000076400007640000010624613067560510012132 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libnice-0.1.14/stun/0000775000076400007640000000000013070512356011210 500000000000000libnice-0.1.14/stun/Makefile.in0000664000076400007640000007362513070512350013204 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @WINDOWS_TRUE@am__append_1 = -DWINVER=0x0501 # _WIN32_WINNT_WINXP subdir = stun ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(libstun_la_include_HEADERS) \ $(libstun_usage_include_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libstun_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__dirstamp = $(am__leading_dot)dirstamp am_libstun_la_OBJECTS = stunagent.lo stunmessage.lo stun5389.lo \ stuncrc32.lo rand.lo stunhmac.lo utils.lo debug.lo \ usages/ice.lo usages/bind.lo usages/turn.lo usages/timer.lo libstun_la_OBJECTS = $(am_libstun_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libstun_la_SOURCES) DIST_SOURCES = $(libstun_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libstun_la_includedir)" \ "$(DESTDIR)$(libstun_usage_includedir)" HEADERS = $(libstun_la_include_HEADERS) \ $(libstun_usage_include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = . tools tests CLEANFILES = *.gcno *.gcda AM_CFLAGS = -std=gnu99 -DG_LOG_DOMAIN=\"libnice-stun\" \ $(LIBNICE_CFLAGS) $(GNUTLS_CFLAGS) $(NULL) $(am__append_1) AM_CPPFLAGS = -I$(top_srcdir) noinst_LTLIBRARIES = libstun.la libstun_la_SOURCES = constants.h \ stunagent.c stunagent.h \ stunmessage.c stunmessage.h \ stun5389.c stun5389.h \ stuncrc32.c stuncrc32.h \ rand.c rand.h \ stunhmac.c stunhmac.h \ utils.c utils.h \ debug.c debug.h \ usages/ice.c usages/ice.h \ usages/bind.c usages/bind.h \ usages/turn.c usages/turn.h \ usages/timer.c usages/timer.h libstun_la_LIBADD = $(LIBRT) $(GNUTLS_LIBS) EXTRA_DIST = win32_common.h libstun_la_includedir = $(includedir)/stun libstun_la_include_HEADERS = stunagent.h stunmessage.h win32_common.h debug.h constants.h libstun_usage_includedir = $(includedir)/stun/usages libstun_usage_include_HEADERS = usages/bind.h usages/ice.h usages/turn.h usages/timer.h all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu stun/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu stun/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } usages/$(am__dirstamp): @$(MKDIR_P) usages @: > usages/$(am__dirstamp) usages/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) usages/$(DEPDIR) @: > usages/$(DEPDIR)/$(am__dirstamp) usages/ice.lo: usages/$(am__dirstamp) usages/$(DEPDIR)/$(am__dirstamp) usages/bind.lo: usages/$(am__dirstamp) \ usages/$(DEPDIR)/$(am__dirstamp) usages/turn.lo: usages/$(am__dirstamp) \ usages/$(DEPDIR)/$(am__dirstamp) usages/timer.lo: usages/$(am__dirstamp) \ usages/$(DEPDIR)/$(am__dirstamp) libstun.la: $(libstun_la_OBJECTS) $(libstun_la_DEPENDENCIES) $(EXTRA_libstun_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libstun_la_OBJECTS) $(libstun_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f usages/*.$(OBJEXT) -rm -f usages/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stun5389.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stunagent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stuncrc32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stunhmac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stunmessage.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@usages/$(DEPDIR)/bind.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@usages/$(DEPDIR)/ice.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@usages/$(DEPDIR)/timer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@usages/$(DEPDIR)/turn.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf usages/.libs usages/_libs install-libstun_la_includeHEADERS: $(libstun_la_include_HEADERS) @$(NORMAL_INSTALL) @list='$(libstun_la_include_HEADERS)'; test -n "$(libstun_la_includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(libstun_la_includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libstun_la_includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libstun_la_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libstun_la_includedir)" || exit $$?; \ done uninstall-libstun_la_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libstun_la_include_HEADERS)'; test -n "$(libstun_la_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libstun_la_includedir)'; $(am__uninstall_files_from_dir) install-libstun_usage_includeHEADERS: $(libstun_usage_include_HEADERS) @$(NORMAL_INSTALL) @list='$(libstun_usage_include_HEADERS)'; test -n "$(libstun_usage_includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(libstun_usage_includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libstun_usage_includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libstun_usage_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libstun_usage_includedir)" || exit $$?; \ done uninstall-libstun_usage_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libstun_usage_include_HEADERS)'; test -n "$(libstun_usage_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libstun_usage_includedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libstun_la_includedir)" "$(DESTDIR)$(libstun_usage_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f usages/$(DEPDIR)/$(am__dirstamp) -rm -f usages/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) usages/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-libstun_la_includeHEADERS \ install-libstun_usage_includeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) usages/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-libstun_la_includeHEADERS \ uninstall-libstun_usage_includeHEADERS .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libstun_la_includeHEADERS \ install-libstun_usage_includeHEADERS install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-libstun_la_includeHEADERS \ uninstall-libstun_usage_includeHEADERS .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/stun/Makefile.am0000664000076400007640000000225113070464720013165 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. SUBDIRS = . tools tests include $(top_srcdir)/common.mk AM_CFLAGS = \ -std=gnu99 \ -DG_LOG_DOMAIN=\"libnice-stun\" \ $(LIBNICE_CFLAGS) \ $(GNUTLS_CFLAGS) \ $(NULL) AM_CPPFLAGS = -I$(top_srcdir) if WINDOWS AM_CFLAGS += -DWINVER=0x0501 # _WIN32_WINNT_WINXP endif noinst_LTLIBRARIES = libstun.la libstun_la_SOURCES = constants.h \ stunagent.c stunagent.h \ stunmessage.c stunmessage.h \ stun5389.c stun5389.h \ stuncrc32.c stuncrc32.h \ rand.c rand.h \ stunhmac.c stunhmac.h \ utils.c utils.h \ debug.c debug.h \ usages/ice.c usages/ice.h \ usages/bind.c usages/bind.h \ usages/turn.c usages/turn.h \ usages/timer.c usages/timer.h libstun_la_LIBADD = $(LIBRT) $(GNUTLS_LIBS) EXTRA_DIST = win32_common.h libstun_la_includedir=$(includedir)/stun libstun_la_include_HEADERS = stunagent.h stunmessage.h win32_common.h debug.h constants.h libstun_usage_includedir=$(includedir)/stun/usages libstun_usage_include_HEADERS = usages/bind.h usages/ice.h usages/turn.h usages/timer.h libnice-0.1.14/stun/stuncrc32.h0000664000076400007640000000356211522161146013132 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2007 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _CRC32_H #define _CRC32_H #ifdef _WIN32 #include "win32_common.h" #else #include #include #endif #include typedef struct { uint8_t *buf; size_t len; } crc_data; uint32_t stun_crc32 (const crc_data *data, size_t n, bool wlm2009_stupid_crc32_typo); #endif /* _CRC32_H */ libnice-0.1.14/stun/constants.h0000664000076400007640000001212312520743534013317 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _STUN_CONSTANTS_H #define _STUN_CONSTANTS_H /** * SECTION:stunconstants * @short_description: STUN constants * @include: stun/constants.h * @stability: Stable * * Various constants defining parts of the STUN and TURN protocols and * on-the-wire packet formats. */ /** * STUN_ATTRIBUTE_LENGTH_LEN: * * Length of the length field of a STUN attribute (in bytes). */ /** * STUN_ATTRIBUTE_LENGTH_POS: * * Offset of the length field of a STUN attribute (in bytes). */ /** * STUN_ATTRIBUTE_TYPE_LEN: * * Length of the type field of a STUN attribute (in bytes). */ /** * STUN_ATTRIBUTE_TYPE_POS: * * Offset of the type field of a STUN attribute (in bytes). */ /** * STUN_ATTRIBUTE_VALUE_POS: * * Offset of the value field of a STUN attribute (in bytes). */ /** * STUN_ID_LEN: * * Length of the ID field of a STUN message (in bytes). */ /** * STUN_MAGIC_COOKIE: * * Magic cookie value used to identify STUN messages. */ /** * TURN_MAGIC_COOKIE: * * Magic cookie value used to identify TURN messages. */ /** * STUN_MAX_MESSAGE_SIZE_IPV4: * * Maximum size of a STUN message sent over IPv4 (in bytes). */ /** * STUN_MAX_MESSAGE_SIZE_IPV6: * * Maximum size of a STUN message sent over IPv6 (in bytes). */ /** * STUN_MESSAGE_ATTRIBUTES_POS: * * Offset of the attributes of a STUN message (in bytes). */ /** * STUN_MESSAGE_HEADER_LENGTH: * * Total length of a STUN message header (in bytes). */ /** * STUN_MESSAGE_LENGTH_LEN: * * Length of the length field of a STUN message (in bytes). */ /** * STUN_MESSAGE_LENGTH_POS: * * Offset of the length field of a STUN message (in bytes). */ /** * STUN_MESSAGE_TRANS_ID_LEN: * * Length of the transaction ID field of a STUN message (in bytes). */ /** * STUN_MESSAGE_TRANS_ID_POS: * * Offset of the transaction ID field of a STUN message (in bytes). */ /** * STUN_MESSAGE_TYPE_LEN: * * Length of the type field of a STUN message (in bytes). */ /** * STUN_MESSAGE_TYPE_POS: * * Offset of the type field of a STUN message (in bytes). */ #define STUN_MESSAGE_TYPE_POS 0 #define STUN_MESSAGE_TYPE_LEN 2 #define STUN_MESSAGE_LENGTH_POS \ (STUN_MESSAGE_TYPE_POS + STUN_MESSAGE_TYPE_LEN) #define STUN_MESSAGE_LENGTH_LEN 2 #define STUN_MESSAGE_TRANS_ID_POS \ (STUN_MESSAGE_LENGTH_POS + STUN_MESSAGE_LENGTH_LEN) #define STUN_MESSAGE_TRANS_ID_LEN 16 #define STUN_MESSAGE_ATTRIBUTES_POS \ (STUN_MESSAGE_TRANS_ID_POS + STUN_MESSAGE_TRANS_ID_LEN) #define STUN_MESSAGE_HEADER_LENGTH STUN_MESSAGE_ATTRIBUTES_POS #define STUN_ATTRIBUTE_TYPE_POS 0 #define STUN_ATTRIBUTE_TYPE_LEN 2 #define STUN_ATTRIBUTE_LENGTH_POS \ (STUN_ATTRIBUTE_TYPE_POS + STUN_ATTRIBUTE_TYPE_LEN) #define STUN_ATTRIBUTE_LENGTH_LEN 2 #define STUN_ATTRIBUTE_VALUE_POS \ (STUN_ATTRIBUTE_LENGTH_POS + STUN_ATTRIBUTE_LENGTH_LEN) /** * STUN_ATTRIBUTE_HEADER_LENGTH: * * Length of a single STUN attribute header (in bytes). */ #define STUN_ATTRIBUTE_HEADER_LENGTH STUN_ATTRIBUTE_VALUE_POS #define STUN_MAX_MESSAGE_SIZE_IPV4 576 #define STUN_MAX_MESSAGE_SIZE_IPV6 1280 /* #define STUN_MAX_MESSAGE_SIZE STUN_MAX_MESSAGE_SIZE_IPV4 */ #define STUN_ID_LEN 16 /** * STUN_AGENT_MAX_SAVED_IDS: * * Maximum number of simultaneously ongoing STUN transactions. */ #define STUN_AGENT_MAX_SAVED_IDS 200 /** * STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES: * * Maximum number of unknown attribute which can be handled in a single STUN * message. */ #define STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES 256 #define STUN_MAGIC_COOKIE 0x2112A442 #define TURN_MAGIC_COOKIE 0x72c64bc6 #ifndef TRUE #define TRUE (1 == 1) #endif #ifndef FALSE #define FALSE (0 == 1) #endif #endif /* _STUN_CONSTANTS_H */ libnice-0.1.14/stun/debug.h0000664000076400007640000000611012520743534012370 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef STUN_DEBUG_H #define STUN_DEBUG_H #include #include #ifdef __cplusplus extern "C" { #endif /** * stun_debug_enable: * * Enable debug messages to stderr */ void stun_debug_enable (void); /** * stun_debug_disable: * * Disable debug messages to stderr */ void stun_debug_disable (void); /** * StunDebugHandler: * @format: printf()-style debug message format string * @ap: Parameters to substitute into message placeholders * * Callback for a debug message from the STUN code. */ #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) typedef void (*StunDebugHandler) (const char *format, va_list ap) __attribute__((__format__ (__printf__, 1, 0))); #else typedef void (*StunDebugHandler) (const char *format, va_list ap); #endif /** * stun_set_debug_handler: * @handler: (nullable): Handler for STUN debug messages, or %NULL to use the * default * * Set a callback function to be invoked for each debug message from the STUN * code. The callback will only be invoked if STUN debugging is enabled using * stun_debug_enable(). * * The default callback prints the formatted debug message to stderr. */ void stun_set_debug_handler (StunDebugHandler handler); #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) void stun_debug (const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); #else void stun_debug (const char *fmt, ...); #endif void stun_debug_bytes (const char *prefix, const void *data, size_t len); # ifdef __cplusplus } # endif #endif /* STUN_DEBUG_H */ libnice-0.1.14/stun/tests/0000775000076400007640000000000013070512356012352 500000000000000libnice-0.1.14/stun/tests/Makefile.in0000664000076400007640000011074013070512350014334 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ check_PROGRAMS = test-parse$(EXEEXT) test-format$(EXEEXT) \ test-bind$(EXEEXT) test-conncheck$(EXEEXT) test-hmac$(EXEEXT) @WINDOWS_TRUE@am__append_1 = -DWINVER=0x0501 # _WIN32_WINNT_WINXP @WINDOWS_TRUE@am__append_2 = -lws2_32 subdir = stun/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = test_bind_SOURCES = test-bind.c test_bind_OBJECTS = test-bind.$(OBJEXT) test_bind_LDADD = $(LDADD) am__DEPENDENCIES_1 = test_bind_DEPENDENCIES = $(top_builddir)/stun/libstun.la \ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = test_conncheck_SOURCES = test-conncheck.c test_conncheck_OBJECTS = test-conncheck.$(OBJEXT) test_conncheck_LDADD = $(LDADD) test_conncheck_DEPENDENCIES = $(top_builddir)/stun/libstun.la \ $(am__DEPENDENCIES_1) test_format_SOURCES = test-format.c test_format_OBJECTS = test-format.$(OBJEXT) test_format_LDADD = $(LDADD) test_format_DEPENDENCIES = $(top_builddir)/stun/libstun.la \ $(am__DEPENDENCIES_1) test_hmac_SOURCES = test-hmac.c test_hmac_OBJECTS = test-hmac.$(OBJEXT) test_hmac_LDADD = $(LDADD) test_hmac_DEPENDENCIES = $(top_builddir)/stun/libstun.la \ $(am__DEPENDENCIES_1) test_parse_SOURCES = test-parse.c test_parse_OBJECTS = test-parse.$(OBJEXT) test_parse_LDADD = $(LDADD) test_parse_DEPENDENCIES = $(top_builddir)/stun/libstun.la \ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = test-bind.c test-conncheck.c test-format.c test-hmac.c \ test-parse.c DIST_SOURCES = test-bind.c test-conncheck.c test-format.c test-hmac.c \ test-parse.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda AM_CPPFLAGS = -I$(top_srcdir) AM_CFLAGS = -std=gnu99 $(am__append_1) LDADD = $(top_builddir)/stun/libstun.la $(am__append_2) dist_check_SCRIPTS = check-bind.sh TESTS = $(check_PROGRAMS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu stun/tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu stun/tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list test-bind$(EXEEXT): $(test_bind_OBJECTS) $(test_bind_DEPENDENCIES) $(EXTRA_test_bind_DEPENDENCIES) @rm -f test-bind$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_bind_OBJECTS) $(test_bind_LDADD) $(LIBS) test-conncheck$(EXEEXT): $(test_conncheck_OBJECTS) $(test_conncheck_DEPENDENCIES) $(EXTRA_test_conncheck_DEPENDENCIES) @rm -f test-conncheck$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_conncheck_OBJECTS) $(test_conncheck_LDADD) $(LIBS) test-format$(EXEEXT): $(test_format_OBJECTS) $(test_format_DEPENDENCIES) $(EXTRA_test_format_DEPENDENCIES) @rm -f test-format$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_format_OBJECTS) $(test_format_LDADD) $(LIBS) test-hmac$(EXEEXT): $(test_hmac_OBJECTS) $(test_hmac_DEPENDENCIES) $(EXTRA_test_hmac_DEPENDENCIES) @rm -f test-hmac$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_hmac_OBJECTS) $(test_hmac_LDADD) $(LIBS) test-parse$(EXEEXT): $(test_parse_OBJECTS) $(test_parse_DEPENDENCIES) $(EXTRA_test_parse_DEPENDENCIES) @rm -f test-parse$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_parse_OBJECTS) $(test_parse_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-bind.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-conncheck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-format.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-hmac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-parse.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test-parse.log: test-parse$(EXEEXT) @p='test-parse$(EXEEXT)'; \ b='test-parse'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-format.log: test-format$(EXEEXT) @p='test-format$(EXEEXT)'; \ b='test-format'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-bind.log: test-bind$(EXEEXT) @p='test-bind$(EXEEXT)'; \ b='test-bind'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-conncheck.log: test-conncheck$(EXEEXT) @p='test-conncheck$(EXEEXT)'; \ b='test-conncheck'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-hmac.log: test-hmac$(EXEEXT) @p='test-hmac$(EXEEXT)'; \ b='test-hmac'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \ $(dist_check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind #$(dist_check_SCRIPTS) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/stun/tests/Makefile.am0000664000076400007640000000104312316360533014324 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include $(top_srcdir)/common.mk AM_CPPFLAGS = -I$(top_srcdir) AM_CFLAGS = -std=gnu99 LDADD = $(top_builddir)/stun/libstun.la check_PROGRAMS = \ test-parse \ test-format \ test-bind \ test-conncheck \ test-hmac if WINDOWS AM_CFLAGS += -DWINVER=0x0501 # _WIN32_WINNT_WINXP LDADD += -lws2_32 endif dist_check_SCRIPTS = check-bind.sh TESTS = $(check_PROGRAMS) #$(dist_check_SCRIPTS) libnice-0.1.14/stun/tests/test-hmac.c0000664000076400007640000000535213067553443014340 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include static void print_bytes (const uint8_t *bytes, int len) { int i; printf ("0x"); for (i = 0; i < len; i++) printf ("%02x", bytes[i]); printf ("\n"); } static void test_hmac (const uint8_t *key, const uint8_t *str, const uint8_t *expected) { uint8_t hmac[20]; /* Arbitrary. */ size_t msg_len = 300; stun_sha1 (str, strlen ((const char *) str), msg_len, hmac, key, strlen ((const char *) key), TRUE /* padding */); printf ("HMAC of '%s' with key '%s' is : ", str, key); print_bytes (hmac, sizeof (hmac)); printf ("Expected : "); print_bytes (expected, sizeof (hmac)); if (memcmp (hmac, expected, sizeof (hmac))) exit (1); } int main (void) { const uint8_t hmac1[] = { 0x83, 0x5a, 0x9b, 0x05, 0xea, 0xd7, 0x68, 0x45, 0x48, 0x74, 0x6b, 0xa3, 0x37, 0xe0, 0xa9, 0x3f, 0x4d, 0xb3, 0x9c, 0xa1 }; test_hmac ((const uint8_t *) "key", (const uint8_t *) "some complicated input string which is over 44 bytes long", hmac1); return 0; } libnice-0.1.14/stun/tests/check-bind.sh0000755000076400007640000000203711241364464014623 00000000000000#! /bin/sh STUNC=../tools/stunbdc STUND=../tools/stund set -xe # Dummy command line parsing tests $STUNC -h $STUNC -V ! $STUNC server port dummy # Timeout tests ! $STUNC -4 127.0.0.1 1 ! $STUNC -6 ::1 1 # Allocate a likely unused port number PORT=$((32768+$$)) if test $PORT -le 1024; then PORT=$(($PORT+1024)) fi echo "Using local UDP port number $PORT ..." # Start the STUN test daemon if needed rm -f stund?.pid stund?.fail stunc?.log for v in 4 6; do (($SHELL -c "echo \$\$ > stund$v.pid ; exec $STUND -$v $PORT") || \ touch stund$v.fail) & done # Run the test client $STUNC -4 127.0.0.1 $PORT > stunc4.log || test -f stund4.fail $STUNC -6 ::1 $PORT > stunc6.log || test -f stund6.fail # Terminate the test daemon for v in 4 6; do kill -INT $(cat stund$v.pid) || true; done wait # Check client results if test -f stund4.fail; then exit 77; fi grep -e "^Mapped address: 127.0.0.1" stunc4.log || exit 4 if test -f stund6.fail; then exit 77; fi grep -e "^Mapped address: ::1" stunc6.log || exit 6 rm -f stund?.fail stund?.pid stunc?.log libnice-0.1.14/stun/tests/test-bind.c0000664000076400007640000003046313070473732014341 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "stun/stunagent.h" #include "stun/usages/bind.h" #include #include #include #ifdef _WIN32 #include #include #define MSG_DONTWAIT 0 #define MSG_NOSIGNAL 0 #define alarm(...) #define close closesocket #else #include #include #include #include #include #endif #undef NDEBUG /* ensure assertions are built-in */ #include static int listen_dgram (void) { struct addrinfo hints, *res; const struct addrinfo *ptr; int val = -1; memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_DGRAM; if (getaddrinfo (NULL, "0", &hints, &res)) return -1; for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { int fd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (fd == -1) continue; if (bind (fd, ptr->ai_addr, ptr->ai_addrlen)) { close (fd); continue; } val = fd; break; } freeaddrinfo (res); return val; } /** Incorrect socket family test */ static void bad_family (void) { struct sockaddr addr; struct sockaddr_storage dummy; int val; socklen_t dummylen = sizeof(dummy); memset (&addr, 0, sizeof (addr)); addr.sa_family = AF_UNSPEC; #ifdef HAVE_SA_LEN addr.sa_len = sizeof (addr); #endif val = stun_usage_bind_run (&addr, sizeof (addr), &dummy, &dummylen); assert (val != 0); } /** Too small socket address test */ static void small_srv_addr (void) { struct sockaddr addr; struct sockaddr_storage dummy; int val; socklen_t dummylen = sizeof(dummy); memset (&addr, 0, sizeof (addr)); addr.sa_family = AF_INET; #ifdef HAVE_SA_LEN addr.sa_len = sizeof (addr); #endif val = stun_usage_bind_run (&addr, 1, &dummy, &dummylen); assert (val == STUN_USAGE_BIND_RETURN_ERROR); } /** Too big socket address test */ static void big_srv_addr (void) { uint8_t buf[sizeof (struct sockaddr_storage) + 16]; struct sockaddr_storage dummy; int val; socklen_t dummylen = sizeof(dummy); memset (buf, 0, sizeof (buf)); val = stun_usage_bind_run ((struct sockaddr *)buf, sizeof (buf), &dummy, &dummylen); assert (val == STUN_USAGE_BIND_RETURN_ERROR); } /** Timeout test */ static void timeout (void) { struct sockaddr_storage srv, dummy; socklen_t srvlen = sizeof (srv); socklen_t dummylen = sizeof(dummy); int val; /* Allocate a local UDP port, so we are 100% sure nobody responds there */ int servfd = listen_dgram (); assert (servfd != -1); val = getsockname (servfd, (struct sockaddr *)&srv, &srvlen); assert (val == 0); val = stun_usage_bind_run ((struct sockaddr *)&srv, srvlen, &dummy, &dummylen); assert (val == STUN_USAGE_BIND_RETURN_TIMEOUT); close (servfd); } /** Malformed responses test */ static void bad_responses (void) { struct sockaddr_storage addr; socklen_t addrlen = sizeof (addr); ssize_t val, len; uint8_t buf[STUN_MAX_MESSAGE_SIZE]; uint8_t req[STUN_MAX_MESSAGE_SIZE]; size_t req_len; StunAgent agent; StunMessage msg; StunMessage req_msg; int servfd, fd; uint16_t known_attributes[] = { STUN_ATTRIBUTE_MAPPED_ADDRESS, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, STUN_ATTRIBUTE_PRIORITY, STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, 0}; stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, 0); /* Allocate a local UDP port */ servfd = listen_dgram (); assert (servfd != -1); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); fd = socket (addr.ss_family, SOCK_DGRAM, 0); assert (fd != -1); req_len = stun_usage_bind_create (&agent, &req_msg, req, sizeof(req)); assert (req_len > 0); val = sendto (fd, req, req_len, MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *)&addr, addrlen); assert (val >= 0); /* Send to/receive from our client instance only */ val = getsockname (fd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); /* Send request instead of response */ val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); len = recvfrom (servfd, buf, 1000, MSG_DONTWAIT, NULL, 0); assert (len >= 20); assert (stun_agent_validate (&agent, &msg, buf, len, NULL, NULL) == STUN_VALIDATION_SUCCESS); val = stun_usage_bind_process (&msg, (struct sockaddr *) &addr, &addrlen, (struct sockaddr *) &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_INVALID); /* Send response with wrong request type */ buf[0] |= 0x03; buf[0] ^= 0x02; /* Send error response without ERROR-CODE */ buf[1] |= 0x10; val = stun_usage_bind_process (&msg, (struct sockaddr *) &addr, &addrlen, (struct sockaddr *) &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_INVALID); close (fd); close (servfd); } /** Various responses test */ static void responses (void) { struct sockaddr_storage addr; socklen_t addrlen = sizeof (addr); ssize_t val; size_t len; int servfd, fd; uint8_t buf[STUN_MAX_MESSAGE_SIZE]; uint8_t req[STUN_MAX_MESSAGE_SIZE]; size_t req_len; StunAgent agent; StunMessage msg; StunMessage req_msg; uint16_t known_attributes[] = { STUN_ATTRIBUTE_MAPPED_ADDRESS, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, STUN_ATTRIBUTE_PRIORITY, STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, 0}; stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, 0); /* Allocate a local UDP port for server */ servfd = listen_dgram (); assert (servfd != -1); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); /* Allocate a client socket and connect to server */ fd = socket (addr.ss_family, SOCK_DGRAM, 0); assert (fd != -1); /* Send error response */ req_len = stun_usage_bind_create (&agent, &req_msg, req, sizeof(req)); assert (req_len > 0); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); val = sendto (fd, req, req_len, MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *)&addr, addrlen); assert (val >= 0); val = recvfrom (servfd, buf, 1000, MSG_DONTWAIT, NULL, 0); assert (val >= 0); assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL) == STUN_VALIDATION_SUCCESS); stun_agent_init_error (&agent, &msg, buf, sizeof (buf), &msg, STUN_ERROR_SERVER_ERROR); len = stun_agent_finish_message (&agent, &msg, NULL, 0); assert (len > 0); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); val = stun_usage_bind_process (&msg, (struct sockaddr *) &addr, &addrlen, (struct sockaddr *) &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_ERROR); /* Send response with a no mapped address at all */ req_len = stun_usage_bind_create (&agent, &req_msg, req, sizeof(req)); assert (req_len > 0); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); val = sendto (fd, req, req_len, MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *)&addr, addrlen); assert (val >= 0); val = recvfrom (servfd, buf, 1000, MSG_DONTWAIT, NULL, 0); assert (val >= 0); assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL) == STUN_VALIDATION_SUCCESS); stun_agent_init_response (&agent, &msg, buf, sizeof (buf), &msg); len = stun_agent_finish_message (&agent, &msg, NULL, 0); assert (len > 0); assert (stun_agent_validate (&agent, &msg, buf, len, NULL, NULL) == STUN_VALIDATION_SUCCESS); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); val = stun_usage_bind_process (&msg, (struct sockaddr *) &addr, &addrlen, (struct sockaddr *) &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_ERROR); /* Send old-style response */ req_len = stun_usage_bind_create (&agent, &req_msg, req, sizeof(req)); assert (req_len > 0); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); val = sendto (fd, req, req_len, MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *)&addr, addrlen); assert (val >= 0); val = recvfrom (servfd, buf, 1000, MSG_DONTWAIT, NULL, 0); assert (val >= 0); assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL) == STUN_VALIDATION_SUCCESS); stun_agent_init_response (&agent, &msg, buf, sizeof (buf), &msg); assert (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, (struct sockaddr *) &addr, addrlen) == STUN_MESSAGE_RETURN_SUCCESS); len = stun_agent_finish_message (&agent, &msg, NULL, 0); assert (len > 0); assert (stun_agent_validate (&agent, &msg, buf, len, NULL, NULL) == STUN_VALIDATION_SUCCESS); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); val = stun_usage_bind_process (&msg, (struct sockaddr *) &addr, &addrlen, (struct sockaddr *) &addr, &addrlen); assert (val == STUN_USAGE_BIND_RETURN_SUCCESS); /* End */ close (servfd); val = close (fd); assert (val == 0); } static void keepalive (void) { struct sockaddr_storage addr = {0}; socklen_t addrlen = sizeof (addr); int val, servfd, fd; uint8_t buf[STUN_MAX_MESSAGE_SIZE]; size_t len; StunAgent agent; StunMessage msg; uint16_t known_attributes[] = { STUN_ATTRIBUTE_MAPPED_ADDRESS, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, STUN_ATTRIBUTE_PRIORITY, STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, 0}; stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, 0); /* Allocate a local UDP port for server */ servfd = listen_dgram (); assert (servfd != -1); val = getsockname (servfd, (struct sockaddr *)&addr, &addrlen); assert (val == 0); /* Allocate a client socket and connect to server */ fd = socket (addr.ss_family, SOCK_DGRAM, 0); assert (fd != -1); /* Keep alive sending smoke test */ len = stun_usage_bind_keepalive (&agent, &msg, buf, sizeof(buf)); assert (len == 20); val = sendto (fd, buf, len, MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *)&addr, addrlen); assert (val >= 0); /* End */ close (servfd); val = close (fd); assert (val == 0); } static void test (void (*func) (void), const char *name) { alarm (30); printf ("%s test... ", name); func (); puts ("OK"); } int main (void) { #ifdef _WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif test (bad_family, "Bad socket family"); test (small_srv_addr, "Too small server address"); test (big_srv_addr, "Too big server address"); test (bad_responses, "Bad responses"); test (responses, "Error responses"); test (keepalive, "Keep alives"); #ifdef HAVE_POLL test (timeout, "Binding discovery timeout"); #endif #ifdef _WIN32 WSACleanup(); #endif return 0; } libnice-0.1.14/stun/tests/test-format.c0000664000076400007640000002115412415560725014713 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "stun/stunagent.h" #include #include #include #include #include #ifdef _WIN32 #include #else #include #include #include #include #endif static void fatal (const char *msg, ...) { va_list ap; va_start (ap, msg); vfprintf (stderr, msg, ap); va_end (ap); fputc ('\n', stderr); exit (1); } static const uint8_t usr[] = "admin"; static const uint8_t pwd[] = "s3kr3t"; static bool dynamic_check_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { if (username_len != strlen ((char *) usr) || memcmp (username, usr, strlen ((char *) usr)) != 0) fatal ("vector test : Validater received wrong username!"); *password = (uint8_t *) pwd; *password_len = strlen ((char *) pwd); return true; } static void dynamic_check (StunAgent *agent, StunMessage *msg, size_t len) { StunMessage msg2; if (stun_agent_validate (agent, &msg2, msg->buffer, len, dynamic_check_validater, NULL) != STUN_VALIDATION_SUCCESS) fatal ("Could not validate message"); printf ("Built message of %u bytes\n", (unsigned)len); } static size_t finish_check (StunAgent *agent, StunMessage *msg) { uint8_t buf[STUN_MAX_MESSAGE_SIZE + 8]; size_t len; uint16_t plen; StunMessage msg2 = {0}; msg2.agent = msg->agent; msg2.buffer = buf; msg2.buffer_len = sizeof(buf); memcpy (msg2.buffer, msg->buffer, sizeof(buf) > msg->buffer_len ? msg->buffer_len : sizeof(buf)); len = stun_agent_finish_message (agent, msg, NULL, 0); if (len <= 0) fatal ("Cannot finish message"); dynamic_check (agent, msg, len); if (stun_message_find (&msg2, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, &plen) != NULL) fatal ("Missing HMAC test failed"); stun_message_append_string (&msg2, STUN_ATTRIBUTE_USERNAME, (char *) usr); len = stun_agent_finish_message (agent, &msg2, pwd, strlen ((char *) pwd)); if (len <= 0) fatal ("Cannot finish message with short-term creds"); dynamic_check (agent, &msg2, len); return len; } static void check_af (const char *name, int family, socklen_t addrlen) { struct sockaddr_storage addr; uint8_t buf[100]; StunAgent agent; StunMessage msg; uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, 0}; stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT); assert (addrlen <= sizeof (addr)); memset (&addr, 0, sizeof (addr)); stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING); if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, (struct sockaddr *) &addr, addrlen) != STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS) fatal ("Unknown address family test failed"); if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr, addrlen) != STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS) fatal ("Unknown address family xor test failed"); addr.ss_family = family; if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, (struct sockaddr *) &addr, addrlen - 1) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too small %s sockaddr test failed", name); if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr, addrlen - 1) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too small %s sockaddr xor test failed", name); if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, (struct sockaddr *) &addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("%s sockaddr test failed", name); if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("%s sockaddr xor test failed", name); } int main (void) { uint8_t buf[100]; size_t len; union { struct sockaddr_storage storage; struct sockaddr addr; } addr; StunAgent agent; StunMessage msg; uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, 0}; stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT); /* Request formatting test */ stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING); finish_check (&agent, &msg); if (memcmp (buf, "\x00\x01", 2)) fatal ("Request formatting test failed"); /* Response formatting test */ stun_agent_init_response (&agent, &msg, buf, sizeof (buf), &msg); finish_check (&agent, &msg); if (memcmp (buf, "\x01\x01", 2)) fatal ("Response formatting test failed"); /* Error formatting test */ stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING); finish_check (&agent, &msg); if (!stun_agent_init_error (&agent, &msg, buf, sizeof (buf), &msg, 400)) fatal ("Error initialization test failed"); finish_check (&agent, &msg); if (memcmp (buf, "\x01\x11", 2)) fatal ("Error formatting test failed"); /* Unknown error formatting test */ stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING); finish_check (&agent, &msg); if (!stun_agent_init_error (&agent, &msg, buf, sizeof (buf), &msg, 666)) fatal ("Unknown error initialization test failed"); finish_check (&agent, &msg); if (memcmp (buf, "\x01\x11", 2)) fatal ("Unknown error formatting test failed"); /* Overflow tests */ stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING); for (len = 0; stun_message_append_flag (&msg, 0xffff) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE; len += 4) { if (len > 0xffff) fatal ("Overflow protection test failed"); } if (stun_message_append32 (&msg, 0xffff, 0x12345678) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE) fatal ("Double-word overflow test failed"); if (stun_message_append64 (&msg, 0xffff, 0x123456789abcdef0) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE) fatal ("Quad-word overflow test failed"); if (stun_message_append_string (&msg, 0xffff, "foobar") != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE) fatal ("String overflow test failed"); memset (&addr, 0, sizeof (addr)); addr.addr.sa_family = AF_INET; #ifdef HAVE_SS_LEN addr.addr.ss_len = sizeof (addr); #endif if (stun_message_append_xor_addr (&msg, 0xffff, &addr.storage, sizeof (addr)) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE) fatal ("Address overflow test failed"); len = sizeof (msg); if (stun_agent_finish_message (&agent, &msg, NULL, 0) != 0) fatal ("Fingerprint overflow test failed"); if (stun_agent_finish_message (&agent, &msg, pwd, strlen ((char *) pwd)) != 0) fatal ("Message integrity overflow test failed"); /* Address attributes tests */ check_af ("IPv4", AF_INET, sizeof (struct sockaddr_in)); #ifdef AF_INET6 check_af ("IPv6", AF_INET6, sizeof (struct sockaddr_in6)); #endif return 0; } libnice-0.1.14/stun/tests/test-conncheck.c0000664000076400007640000003002113070473267015351 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "stun/stunagent.h" #include "stun/usages/ice.h" #include #include #include #include #ifdef _WIN32 #include #include #define MSG_DONTWAIT 0 #define MSG_NOSIGNAL 0 #define alarm(...) #else #include #include #include #include #include #endif #undef NDEBUG /* ensure assertions are built-in */ #include int main (void) { union { struct sockaddr sa; struct sockaddr_storage storage; struct sockaddr_in ip4; } addr; uint8_t req_buf[STUN_MAX_MESSAGE_SIZE]; uint8_t resp_buf[STUN_MAX_MESSAGE_SIZE]; const uint64_t tie = 0x8000000000000000LL; StunMessageReturn val; StunUsageIceReturn val2; size_t len; size_t rlen; static char username[] = "L:R"; static uint8_t ufrag[] = "L", pass[] = "secret"; size_t ufrag_len = strlen ((char*) ufrag); size_t pass_len = strlen ((char*) pass); int code; bool control = false; StunAgent agent; StunMessage req; StunMessage resp; StunDefaultValidaterData validater_data[] = { {ufrag, ufrag_len, pass, pass_len}, {(uint8_t *) username, strlen (username), pass, pass_len}, {NULL, 0, NULL, 0}}; StunValidationStatus valid; stun_agent_init (&agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT | STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS); memset (&addr, 0, sizeof (addr)); addr.ip4.sin_family = AF_INET; #ifdef HAVE_SA_LEN addr.ip4.sin_len = sizeof (addr); #endif addr.ip4.sin_port = htons (12345); addr.ip4.sin_addr.s_addr = htonl (0x7f000001); /* Incorrect message class */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); assert (stun_agent_init_response (&agent, &req, req_buf, sizeof (req_buf), &req)); rlen = stun_agent_finish_message (&agent, &req, NULL, 0); assert (rlen > 0); len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_REQUEST); assert (len == 0); /* Incorrect message method */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), 0x666)); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_METHOD); assert (len > 0); /* Unknown attribute */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append_string (&req, 0x666, "The evil unknown attribute!"); assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, username); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); valid = stun_agent_validate (&agent, &req, req_buf, rlen, stun_agent_default_validater, validater_data); assert (valid == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE); /* Unauthenticated message */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); rlen = stun_agent_finish_message (&agent, &req, NULL, 0); assert (rlen > 0); valid = stun_agent_validate (&agent, &req, req_buf, rlen, stun_agent_default_validater, validater_data); assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST); /* No username */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); valid = stun_agent_validate (&agent, &req, req_buf, rlen, stun_agent_default_validater, validater_data); assert (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST); assert (stun_usage_ice_conncheck_priority (&req) == 0); assert (stun_usage_ice_conncheck_use_candidate (&req) == false); /* Good message */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append32 (&req, STUN_ATTRIBUTE_PRIORITY, 0x12345678); assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_flag (&req, STUN_ATTRIBUTE_USE_CANDIDATE); assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, (char*) ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_SUCCESS); assert (len > 0); assert (stun_agent_validate (&agent, &resp, resp_buf, len, stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS); assert (stun_message_get_class (&resp) == STUN_RESPONSE); assert (stun_usage_ice_conncheck_priority (&req) == 0x12345678); assert (stun_usage_ice_conncheck_use_candidate (&req) == true); /* Invalid socket address */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, (char *) ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); addr.ip4.sin_family = AF_UNSPEC; len = sizeof (resp_buf); val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_INVALID_ADDRESS); assert (len == 0); addr.ip4.sin_family = AF_INET; /* Role conflict, controlling + ICE-CONTROLLING, switching controlled */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLING, tie + 1); assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, (char *) ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); control = true; val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT); assert (len > 0); assert (control == false); assert (stun_agent_validate (&agent, &resp, resp_buf, len, stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS); assert (stun_message_get_class (&resp) == STUN_RESPONSE); /* Role conflict, controlled + ICE-CONTROLLED, switching controlling */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLED, tie - 1); assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, (char *) ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); control = false; val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT); assert (len > 0); assert (control == true); assert (stun_agent_validate (&agent, &resp, resp_buf, len, stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS); assert (stun_message_get_class (&resp) == STUN_RESPONSE); /* Role conflict, controlling + ICE-CONTROLLING, staying controlling */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLING, tie - 1); assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, (char *) ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); control = true; val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT); assert (len > 0); assert (control == true); assert (stun_agent_validate (&agent, &resp, resp_buf, len, stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS); assert (stun_message_get_class (&resp) == STUN_ERROR); stun_message_find_error (&resp, &code); assert (code == STUN_ERROR_ROLE_CONFLICT); /* Role conflict, controlled + ICE-CONTROLLED, staying controlling */ assert (stun_agent_init_request (&agent, &req, req_buf, sizeof(req_buf), STUN_BINDING)); val = stun_message_append64 (&req, STUN_ATTRIBUTE_ICE_CONTROLLED, tie + 1); assert (val == STUN_MESSAGE_RETURN_SUCCESS); val = stun_message_append_string (&req, STUN_ATTRIBUTE_USERNAME, (char *) ufrag); assert (val == STUN_MESSAGE_RETURN_SUCCESS); rlen = stun_agent_finish_message (&agent, &req, pass, pass_len); assert (rlen > 0); len = sizeof (resp_buf); control = false; val2 = stun_usage_ice_conncheck_create_reply (&agent, &req, &resp, resp_buf, &len, &addr.storage, sizeof (addr.ip4), &control, tie, STUN_USAGE_ICE_COMPATIBILITY_RFC5245); assert (val2 == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT); assert (len > 0); assert (control == false); assert (stun_agent_validate (&agent, &resp, resp_buf, len, stun_agent_default_validater, validater_data) == STUN_VALIDATION_SUCCESS); assert (stun_message_get_class (&resp) == STUN_ERROR); stun_message_find_error (&resp, &code); assert (code == STUN_ERROR_ROLE_CONFLICT); return 0; } libnice-0.1.14/stun/tests/test-parse.c0000664000076400007640000005776512520743534014554 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2007 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "stun/stunagent.h" #include "stun/stunhmac.h" #include #include #include #include #ifdef _WIN32 #include #include #else #include #include #include #include #endif # define STUN_MAX_STR (763u) # define STUN_MAX_CP (127u) static void fatal (const char *msg, ...) { va_list ap; va_start (ap, msg); vfprintf (stderr, msg, ap); va_end (ap); fputc ('\n', stderr); exit (1); } static void validate (const uint8_t *msg, unsigned len) { unsigned i = 1; do { size_t vlen = stun_message_validate_buffer_length (msg, i, TRUE); if ((vlen & 3) || (vlen != ((i >= len) * len))) fatal ("%u/%u short message test failed", i, len); } while (i++ < (len + 4)); } /* Tests for generic message validation routines */ static void test_message (void) { static const uint8_t extra_garbage[] = {0x15, 0x55, 0x00, 0x00, 0x21, 0x12, 0xA4, 0x42, // cookie 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xaa, 0xbb, 0xcc, 0xdd}; //extra garbage static const uint8_t simple_resp[] = {0x15, 0x55, 0x00, 0x00, 0x21, 0x12, 0xA4, 0x42, // cookie 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; static const uint8_t old_ind[] = {0x14, 0x55, 0x00, 0x00, 0xfe, 0xdc, 0xba, 0x98, // NO cookie 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; static const uint8_t fpr_resp[] = {0x15, 0x55, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, // cookie 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x06, 0x00, 0x04, // dummy USERNAME header 0x41, 0x42, 0x43, 0x44, 0x80, 0x28, 0x00, 0x04, // FINGERPRINT header 0xdc, 0x8d, 0xa7, 0x74}; // CRC32; static const uint8_t bad1[32] = {0x15, 0x55, 0x00, 0x08, 0x21, 0x12, 0xA4, 0x42, // cookie 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x06, 0x00, 0x05, // too big attribute for message 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; static const uint8_t bad2[24] = {0x15, 0x55, 0x00, 0x05, // invalid message length 0x21, 0x12, 0xA4, 0x42, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x06, 0x00, 0x01}; static const uint8_t bad3[27] = {0x15, 0x55, 0x00, 0x08, 0x21, 0x12, 0xA4, 0x42, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x06, 0x00, 0x03, 0x11, 0x22, 0x33}; // missing padding static const uint8_t bad_crc[] = {0x15, 0x55, 0x00, 0x08, 0x21, 0x12, 0xA4, 0x42, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x80, 0x28, 0x00, 0x04, // FINGERPRINT header 0x04, 0x91, 0xcd, 0x78}; // CRC32 static uint8_t bad_crc_offset[] = {0x15, 0x55, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x20, 0x67, 0xc4, 0x09, 0x80, 0x28, 0x00, 0x04, // FINGERPRINT header 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x41, 0x42, 0x43, 0x44}; static unsigned char req[] = {0x00, 0x01, 0x00, 0x00, 0x8b, 0x45, 0x9b, 0xc3, 0xe7, 0x7a, 0x05, 0xb3, 0xe4, 0xfe, 0x01, 0xf0, 0xaf, 0x83, 0xe1, 0x9e}; static uint8_t binding_error_resp[] = {0x01, 0x11, 0x00, 0x84, 0x8b, 0x45, 0x9b, 0xc3, 0xe7, 0x7a, 0x05, 0xb3, 0xe4, 0xfe, 0x01, 0xf0, 0xaf, 0x83, 0xe1, 0x9e, 0x00, 0x06, 0x00, 0x48, // USERNAME 0x92, 0x6b, 0x2b, 0x3e, 0x6a, 0xa5, 0x43, 0x58, 0xa8, 0x51, 0x25, 0xa6, 0xf7, 0x9c, 0x0a, 0xe7, 0xd8, 0x86, 0xf7, 0x76, 0xf9, 0xcd, 0x8a, 0x2e, 0x45, 0xd7, 0xcb, 0xbb, 0xae, 0xe5, 0x03, 0xc3, 0x3a, 0x32, 0x3a, 0xa9, 0x9e, 0xb7, 0x7b, 0x32, 0xe3, 0xf3, 0xa6, 0xc0, 0xe8, 0x54, 0x4b, 0xef, 0x52, 0xd2, 0xe2, 0xc0, 0x43, 0xc2, 0x4c, 0xbc, 0xaf, 0xd9, 0xf2, 0xfa, 0x48, 0x8b, 0x8c, 0xe6, 0x62, 0x14, 0x64, 0x3a, 0x32, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x1c, // ERROR-CODE 0x00, 0x00, 0x04, 0x1f, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY 0xf7, 0x46, 0x81, 0xc4, 0x6f, 0x4c, 0x21, 0x5c, 0xf6, 0x8e, 0xc0, 0x81, 0x0e, 0x20, 0x3f, 0xb1, 0xb1, 0xad, 0xa4, 0x8a}; StunAgent agent; StunAgent agent2; StunMessage msg; uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_ERROR_CODE, STUN_ATTRIBUTE_MESSAGE_INTEGRITY}; uint8_t username_v[] = {0x92, 0x6b, 0x2b, 0x3e, 0x6a, 0xa5, 0x43, 0x58, 0xa8, 0x51, 0x25, 0xa6, 0xf7, 0x9c, 0x0a, 0xe7, 0xd8, 0x86, 0xf7, 0x76, 0xf9, 0xcd, 0x8a, 0x2e, 0x45, 0xd7, 0xcb, 0xbb, 0xae, 0xe5, 0x03, 0xc3, 0x3a, 0x32, 0x3a, 0xa9, 0x9e, 0xb7, 0x7b, 0x32, 0xe3, 0xf3, 0xa6, 0xc0, 0xe8, 0x54, 0x4b, 0xef, 0x52, 0xd2, 0xe2, 0xc0, 0x43, 0xc2, 0x4c, 0xbc, 0xaf, 0xd9, 0xf2, 0xfa, 0x48, 0x8b, 0x8c, 0xe6, 0x62, 0x14, 0x64, 0x3a, 0x32, 0x00, 0x00, 0x00}; uint8_t password_v[] = {0x77, 0xd9, 0x7a, 0xe9, 0xcf, 0xe0, 0x3e, 0xa2, 0x28, 0xa0, 0x5d, 0xec, 0xcf, 0x36, 0xe8, 0x49}; StunDefaultValidaterData v = {username_v, 72, password_v, 16}; stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT); stun_agent_init (&agent2, known_attributes, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS); stun_agent_validate (&agent2, &msg, req, sizeof(req), NULL, NULL); stun_agent_finish_message (&agent2, &msg, NULL, 0); if (stun_agent_validate (&agent2, &msg, binding_error_resp, sizeof(binding_error_resp), stun_agent_default_validater, &v) != STUN_VALIDATION_SUCCESS) fatal ("Binding Error Response failed"); if (stun_message_validate_buffer_length (NULL, 0, TRUE) != STUN_MESSAGE_BUFFER_INVALID) fatal ("0 bytes test failed"); if (stun_message_validate_buffer_length ((uint8_t *)"\xf0", 1, TRUE) >= 0) fatal ("1 byte test failed"); if (stun_message_validate_buffer_length (bad1, sizeof (bad1), TRUE) >= 0) fatal ("Badness 1 test failed"); if (stun_message_validate_buffer_length (bad2, sizeof (bad2), TRUE) >= 0) fatal ("Badness 2 test failed"); if (stun_message_validate_buffer_length (bad3, sizeof (bad3), TRUE) != 0) fatal ("Badness 3 test failed"); validate (simple_resp, 20); validate (old_ind, 20); validate (fpr_resp, 36); if (stun_agent_validate (&agent, &msg, extra_garbage, sizeof(extra_garbage), NULL, NULL) != STUN_VALIDATION_NOT_STUN) fatal ("Extra garbage test failed"); if (stun_agent_validate (&agent, &msg, simple_resp, sizeof(simple_resp), NULL, NULL) != STUN_VALIDATION_BAD_REQUEST) fatal ("Missing CRC test failed"); if (stun_agent_validate (&agent, &msg, old_ind, sizeof(old_ind), NULL, NULL) != STUN_VALIDATION_BAD_REQUEST) fatal ("Missing cookie test failed"); if (stun_agent_validate (&agent, &msg, bad_crc, sizeof(bad_crc), NULL, NULL) != STUN_VALIDATION_BAD_REQUEST) fatal ("Bad CRC test failed"); if (stun_agent_validate (&agent, &msg, bad_crc_offset, sizeof(bad_crc_offset), NULL, NULL) != STUN_VALIDATION_BAD_REQUEST) fatal ("Bad CRC offset test failed"); if (stun_agent_validate (&agent, &msg, fpr_resp, sizeof(fpr_resp), NULL, NULL) != STUN_VALIDATION_UNMATCHED_RESPONSE) fatal ("Good CRC test failed"); if (stun_message_get_class (&msg) != 3) fatal ("Class test failed"); if (stun_message_get_method (&msg) != 0x525) fatal ("Method test failed"); } static bool test_attribute_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { uint8_t *pwd = user_data; if (username_len != 4 || memcmp (username, "ABCD", 4) != 0) return false; *password = pwd; *password_len = strlen ((char *) pwd); return true; } /* Tests for message attribute parsing */ static void test_attribute (void) { static const uint8_t acme[] = {0x04, 0x55, 0x00, 0x6C, // <-- update message length if needed!! 0x21, 0x12, 0xA4, 0x42, // cookie 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, /* FF01: empty */ 0xff, 0x01, 0x00, 0x00, /* FF02: address of unknown family, 32-bits */ 0xff, 0x02, 0x00, 0x04, 0x41, 0x42, 0x43, 0x44, /* FF03: too short IPv6 address */ 0xff, 0x03, 0x00, 0x06, 0x00, 0x02, 0x12, 0x34, 0x20, 0x01, 0x0d, 0xb8, /* FF04: valid IPv4 address, 64-bits */ 0xff, 0x04, 0x00, 0x08, 0x00, 0x01, 0x12, 0x34, 0xc0, 0x00, 0x02, 0x01, /* FF05: too long IPv4 address */ 0xff, 0x05, 0x00, 0x0A, 0x00, 0x01, 0x12, 0x34, 0xc0, 0x00, 0x02, 0x01, 0x66, 0x60, 0x00, 0x00, /* FF06: valid xor'd IPv6 address, 160-bits */ 0xff, 0x06, 0x00, 0x14, 0x00, 0x02, 0x12, 0x34, 0x01, 0x13, 0xa9, 0xfa, 0xa8, 0xf9, 0x8c, 0xff, 0x20, 0x26, 0x74, 0x48, 0x8c, 0x9a, 0xec, 0xfd, /* dummy USERNAME header */ 0x00, 0x06, 0x00, 0x04, 0x41, 0x42, 0x43, 0x44, /* MESSAGE-INTEGRITY attribute */ 0x00, 0x08, 0x00, 0x14, 0x0b, 0xc4, 0xb2, 0x0c, 0x94, 0x58, 0xbb, 0x25, 0xa3, 0x22, 0x1a, 0xc8, 0xe1, 0x87, 0x32, 0x36, 0x3a, 0xfc, 0xe2, 0xc3}; union { struct sockaddr_storage st; struct sockaddr_in6 s6; } addr; socklen_t addrlen; uint32_t dword; uint64_t qword; char str[STUN_MAX_STR]; StunAgent agent; StunMessage msg; uint16_t known_attributes[] = {STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_USERNAME, 0}; printf ("Attribute test message length: %zd\n", sizeof (acme)); stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS); if (stun_agent_validate (&agent, &msg, acme, sizeof(acme), NULL, NULL) != STUN_VALIDATION_UNAUTHORIZED) fatal ("Unauthorized validation failed"); if (stun_agent_validate (&agent, &msg, acme, sizeof(acme), test_attribute_validater, (void *) "bad__guy") != STUN_VALIDATION_UNAUTHORIZED) fatal ("invalid password validation failed"); if (stun_agent_validate (&agent, &msg, acme, sizeof(acme), test_attribute_validater, (void *) "good_guy") != STUN_VALIDATION_SUCCESS) fatal ("good password validation failed"); if (stun_message_has_attribute (&msg, 0xff00)) fatal ("Absent attribute test failed"); if (!stun_message_has_attribute (&msg, 0xff01)) fatal ("Present attribute test failed"); if (stun_message_find_flag (&msg, 0xff00) != STUN_MESSAGE_RETURN_NOT_FOUND) fatal ("Absent flag test failed"); if (stun_message_find_flag (&msg, 0xff01) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("Flag test failed"); if (stun_message_find_flag (&msg, 0xff02) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too big flag test failed"); if (stun_message_find32 (&msg, 0xff00, &dword) != STUN_MESSAGE_RETURN_NOT_FOUND) fatal ("Absent dword test failed"); if (stun_message_find32 (&msg, 0xff01, &dword) != STUN_MESSAGE_RETURN_INVALID) fatal ("Bad dword test failed"); if (stun_message_find32 (&msg, 0xff02, &dword) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("Double-word test failed"); if (stun_message_find64 (&msg, 0xff00, &qword) != STUN_MESSAGE_RETURN_NOT_FOUND) fatal ("Absent qword test failed"); if (stun_message_find64 (&msg, 0xff01, &qword) != STUN_MESSAGE_RETURN_INVALID) fatal ("Bad qword test failed"); if (stun_message_find64 (&msg, 0xff04, &qword) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("Quad-word test failed"); if (stun_message_find_string (&msg, 0xff00, str, STUN_MAX_CP) != STUN_MESSAGE_RETURN_NOT_FOUND) fatal ("Absent string test failed"); if ((stun_message_find_string (&msg, 0xff02, str, STUN_MAX_CP) != STUN_MESSAGE_RETURN_SUCCESS) || strcmp (str, "ABCD")) fatal ("String test failed"); addrlen = sizeof (addr); if (stun_message_find_addr (&msg, 0xff01, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too short addres test failed"); addrlen = sizeof (addr); if (stun_message_find_addr (&msg, 0xff02, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS) fatal ("Unknown address family test failed"); addrlen = sizeof (addr); if (stun_message_find_addr (&msg, 0xff03, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too short IPv6 address test failed"); addrlen = sizeof (addr); if (stun_message_find_addr (&msg, 0xff04, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("IPv4 address test failed"); addrlen = sizeof (addr); if (stun_message_find_addr (&msg, 0xff05, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_INVALID) fatal ("Too big IPv4 address test failed"); addrlen = sizeof (addr); if (stun_message_find_xor_addr (&msg, 0xff06, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS || memcmp (&addr.s6.sin6_addr, "\x20\x01\x0d\xb8""\xde\xad\xbe\xef" "\xde\xfa\xce\xd0""\xfa\xce\xde\xed", 16)) fatal ("IPv6 address test failed"); } static const char vector_username[] = "evtj:h6vY"; static uint8_t vector_password[] = "VOkJxbRl1RmTxUk/WvJxBt"; static bool test_vector_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { intptr_t callable = (intptr_t) user_data; if (!callable) fatal ("vector test : Validater should not be called!"); if (username_len != strlen (vector_username) || memcmp (username, vector_username, strlen (vector_username)) != 0) fatal ("vector test : Validater received wrong username!"); *password = vector_password; *password_len = strlen ((char *) vector_password); return true; } static void test_vectors (void) { /* Request message */ static unsigned char req[] = {0x00, 0x01, 0x00, 0x44, 0x21, 0x12, 0xa4, 0x42, 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae, 0x00, 0x24, 0x00, 0x04, // PRIORITY 0x6e, 0x00, 0x01, 0xff, 0x80, 0x29, 0x00, 0x08, // ICE_CONTROLLED 0x93, 0x2f, 0xf9, 0xb1, 0x51, 0x26, 0x3b, 0x36, 0x00, 0x06, 0x00, 0x09, // USERNAME 0x65, 0x76, 0x74, 0x6a, 0x3a, 0x68, 0x36, 0x76, 0x59, 0x20, 0x20, 0x20, 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY 0x62, 0x4e, 0xeb, 0xdc, 0x3c, 0xc9, 0x2d, 0xd8, 0x4b, 0x74, 0xbf, 0x85, 0xd1, 0xc0, 0xf5, 0xde, 0x36, 0x87, 0xbd, 0x33, 0x80, 0x28, 0x00, 0x04, // FINGERPRINT 0xad, 0x8a, 0x85, 0xff}; static const unsigned char req2[] = {0x00, 0x01, 0x00, 0x44, 0x21, 0x12, 0xa4, 0x42, 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae, 0x00, 0x24, 0x00, 0x04, // PRIORITY 0x6e, 0x00, 0x01, 0xff, 0x80, 0x29, 0x00, 0x08, // ICE_CONTROLLED 0x93, 0x2f, 0xf9, 0xb1, 0x51, 0x26, 0x3b, 0x36, 0x00, 0x06, 0x00, 0x09, // USERNAME 0x65, 0x76, 0x74, 0x6a, 0x3a, 0x68, 0x36, 0x76, 0x59, 0x20, 0x20, 0x20, 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY 0x62, 0x4e, 0xeb, 0xdc, 0x3c, 0xc9, 0x2d, 0xd8, 0x4b, 0x74, 0xbf, 0x85, 0xd1, 0xc0, 0xf5, 0xde, 0x36, 0x87, 0xbd, 0x33, 0x80, 0x28, 0x00, 0x04, // FINGERPRINT 0xad, 0x8a, 0x85, 0xff}; /* Response message */ static const unsigned char respv4[] = {0x01, 0x01, 0x00, 0x4c, 0x21, 0x12, 0xa4, 0x42, 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae, 0x80, 0x22, 0x00, 0x0b, // SERVER 0x74, 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x00, 0x20, 0x00, 0x08, // XOR_MAPPED_ADDRESS 0x00, 0x01, 0xa1, 0x47, 0xe1, 0x12, 0xa6, 0x43, 0x00, 0x06, 0x00, 0x09, // USERNAME 0x65, 0x76, 0x74, 0x6a, 0x3a, 0x68, 0x36, 0x76, 0x59, 0x20, 0x20, 0x20, 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY 0x7d, 0xb7, 0xfc, 0x52, 0x70, 0xc6, 0xdb, 0x1f, 0xc3, 0x26, 0x34, 0xbb, 0x4c, 0x64, 0x6e, 0xe7, 0x1d, 0xb3, 0x78, 0x4a, 0x80, 0x28, 0x00, 0x04, // FINGERPRINT 0xf0, 0x60, 0x66, 0xa9}; static const unsigned char respv6[] = {0x01, 0x01, 0x00, 0x58, 0x21, 0x12, 0xa4, 0x42, 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae, 0x80, 0x22, 0x00, 0x0b, // SERVER 0x74, 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x00, 0x20, 0x00, 0x14, // XOR_MAPPED_ADDRESS 0x00, 0x02, 0xa1, 0x47, 0x01, 0x13, 0xa9, 0xfa, 0xa5, 0xd3, 0xf1, 0x79, 0xbc, 0x25, 0xf4, 0xb5, 0xbe, 0xd2, 0xb9, 0xd9, 0x00, 0x06, 0x00, 0x09, // USERNAME 0x65, 0x76, 0x74, 0x6a, 0x3a, 0x68, 0x36, 0x76, 0x59, 0x20, 0x20, 0x20, 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY 0x21, 0xcb, 0xbd, 0x25, 0x1a, 0x8c, 0x4c, 0x38, 0x8c, 0xc5, 0xcd, 0xb3, 0x27, 0x6a, 0xf5, 0x61, 0xb2, 0x21, 0xc8, 0x2b, 0x80, 0x28, 0x00, 0x04, // FINGERPRINT 0xec, 0x27, 0xae, 0xb7}; union { struct sockaddr_storage st; struct sockaddr_in ip4; struct sockaddr_in6 ip6; } addr; socklen_t addrlen; StunAgent agent; StunMessage msg; StunMessage msg2; uint16_t known_attributes[] = { STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, STUN_ATTRIBUTE_PRIORITY, 0}; stun_agent_init (&agent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_USE_FINGERPRINT); memset (&addr, 0, sizeof (addr)); puts ("Checking test vectors..."); if (stun_agent_validate (&agent, &msg2, req2, sizeof(req2), test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS) fatal ("Request test vector authentication failed"); if (stun_agent_validate (&agent, &msg, req, sizeof(req), test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS) fatal ("Request test vector authentication failed"); /* Remove the message-integrity and fingerprint attributes */ req[3] = 0x24; if (stun_message_length (&msg) != sizeof(req) - 32) fatal ("vector test: removing attributes failed"); stun_agent_finish_message (&agent, &msg, vector_password, strlen ((char *) vector_password)); if (stun_message_length (&msg) != stun_message_length (&msg2) || memcmp (req, req2, sizeof(req)) != 0) fatal ("vector test : req and req2 are different"); if (stun_agent_validate (&agent, &msg, respv4, sizeof(respv4), test_vector_validater, (void *) 0) != STUN_VALIDATION_SUCCESS) fatal ("Response ipv4 test vector authentication failed"); if (stun_agent_validate (&agent, &msg, respv4, sizeof(respv4), test_vector_validater, (void *) 0) != STUN_VALIDATION_UNMATCHED_RESPONSE) fatal ("Response ipv4 test vector authentication failed"); addrlen = sizeof (addr.ip4); if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("Response test vector IPv4 extraction failed"); if (addr.ip4.sin_family != AF_INET) fatal ("Response test vector IPv4 family failed"); if (ntohl (addr.ip4.sin_addr.s_addr) != 0xC0000201) fatal ("Response test vector IPv4 address failed"); if (ntohs (addr.ip4.sin_port) != 32853) fatal ("Response test vector IPv6 port failed"); if (stun_agent_validate (&agent, &msg, req, sizeof(req), test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS) fatal ("Request test vector second authentication failed"); /* Remove the fingerprint attributes */ msg.key = NULL; msg.key_len = 0; req[3] = 0x3C; if (stun_message_length (&msg) != sizeof(req) - 8) fatal ("vector test: removing attributes failed"); stun_agent_finish_message (&agent, &msg, NULL, 0); if (stun_message_length (&msg) != stun_message_length (&msg2) || memcmp (req, req2, sizeof(req)) != 0) fatal ("vector test : req and req2 are different"); if (stun_agent_validate (&agent, &msg, respv6, sizeof(respv6), test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS) fatal ("Response ipv6 test vector authentication failed"); addrlen = sizeof (addr.ip6); if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS) fatal ("Response test vector IPv6 extraction failed"); if (addr.ip6.sin6_family != AF_INET6) fatal ("Response test vector IPv6 family failed"); if (memcmp (addr.ip6.sin6_addr.s6_addr, "\x20\x01\x0d\xb8\x12\x34\x56\x78" "\x00\x11\x22\x33\x44\x55\x66\x77", 16) != 0) fatal ("Response test vector IPv6 address failed"); if (ntohs (addr.ip6.sin6_port) != 32853) fatal ("Response test vector IPv6 port failed"); puts ("Done."); } static void test_hash_creds (void) { uint8_t md5[16]; uint8_t real_md5[] = { 0x84, 0x93, 0xfb, 0xc5, 0x3b, 0xa5, 0x82, 0xfb, 0x4c, 0x04, 0x4c, 0x45, 0x6b, 0xdc, 0x40, 0xeb}; puts ("Testing long term credentials hash algorithm..."); stun_hash_creds ((uint8_t *) "realm", strlen ("realm"), (uint8_t *) "user", strlen ("user"), (uint8_t *) "pass", strlen ("pass"), md5); stun_debug_bytes ("key for user:realm:pass is : ", md5, 16); stun_debug_bytes ("RFC key for user:realm:pass is : ", real_md5, 16); if(memcmp (md5, real_md5, sizeof(md5)) != 0) fatal ("MD5 hashes are different!"); puts ("Done!"); } int main (void) { test_message (); test_attribute (); test_vectors (); test_hash_creds (); return 0; } libnice-0.1.14/stun/stunmessage.h0000664000076400007640000010673113004222453013640 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _STUN_MESSAGE_H #define _STUN_MESSAGE_H /** * SECTION:stunmessage * @short_description: STUN messages parsing and formatting functions * @include: stun/stunmessage.h * @see_also: #StunAgent * @stability: Stable * * The STUN Messages API allows you to create STUN messages easily as well as to * parse existing messages. * */ #ifdef _WIN32 #include "win32_common.h" #else #include #include #endif #include #ifdef _WIN32 #include #include #else #include #include #endif #include "constants.h" typedef struct _StunMessage StunMessage; /** * StunClass: * @STUN_REQUEST: A STUN Request message * @STUN_INDICATION: A STUN indication message * @STUN_RESPONSE: A STUN Response message * @STUN_ERROR: A STUN Error message * * This enum is used to represent the class of * a STUN message, as defined in RFC5389 */ /* Message classes */ typedef enum { STUN_REQUEST=0, STUN_INDICATION=1, STUN_RESPONSE=2, STUN_ERROR=3 } StunClass; /** * StunMethod: * @STUN_BINDING: The Binding method as defined by the RFC5389 * @STUN_SHARED_SECRET: The Shared-Secret method as defined by the RFC3489 * @STUN_ALLOCATE: The Allocate method as defined by the TURN draft 12 * @STUN_SET_ACTIVE_DST: The Set-Active-Destination method as defined by * the TURN draft 4 * @STUN_REFRESH: The Refresh method as defined by the TURN draft 12 * @STUN_SEND: The Send method as defined by the TURN draft 00 * @STUN_CONNECT: The Connect method as defined by the TURN draft 4 * @STUN_OLD_SET_ACTIVE_DST: The older Set-Active-Destination method as * defined by the TURN draft 0 * @STUN_IND_SEND: The Send method used in indication messages as defined * by the TURN draft 12 * @STUN_IND_DATA: The Data method used in indication messages as defined * by the TURN draft 12 * @STUN_IND_CONNECT_STATUS: The Connect-Status method used in indication * messages as defined by the TURN draft 4 * @STUN_CREATEPERMISSION: The CreatePermission method as defined by * the TURN draft 12 * @STUN_CHANNELBIND: The ChannelBind method as defined by the TURN draft 12 * * This enum is used to represent the method of * a STUN message, as defined by various RFCs */ /* Message methods */ typedef enum { STUN_BINDING=0x001, /* RFC5389 */ STUN_SHARED_SECRET=0x002, /* old RFC3489 */ STUN_ALLOCATE=0x003, /* TURN-12 */ STUN_SET_ACTIVE_DST=0x004, /* TURN-04 */ STUN_REFRESH=0x004, /* TURN-12 */ STUN_SEND=0x004, /* TURN-00 */ STUN_CONNECT=0x005, /* TURN-04 */ STUN_OLD_SET_ACTIVE_DST=0x006, /* TURN-00 */ STUN_IND_SEND=0x006, /* TURN-12 */ STUN_IND_DATA=0x007, /* TURN-12 */ STUN_IND_CONNECT_STATUS=0x008, /* TURN-04 */ STUN_CREATEPERMISSION= 0x008, /* TURN-12 */ STUN_CHANNELBIND= 0x009 /* TURN-12 */ } StunMethod; /** * StunAttribute: * @STUN_ATTRIBUTE_MAPPED_ADDRESS: The MAPPED-ADDRESS attribute as defined * by RFC5389 * @STUN_ATTRIBUTE_RESPONSE_ADDRESS: The RESPONSE-ADDRESS attribute as defined * by RFC3489 * @STUN_ATTRIBUTE_CHANGE_REQUEST: The CHANGE-REQUEST attribute as defined by * RFC3489 * @STUN_ATTRIBUTE_SOURCE_ADDRESS: The SOURCE-ADDRESS attribute as defined by * RFC3489 * @STUN_ATTRIBUTE_CHANGED_ADDRESS: The CHANGED-ADDRESS attribute as defined * by RFC3489 * @STUN_ATTRIBUTE_USERNAME: The USERNAME attribute as defined by RFC5389 * @STUN_ATTRIBUTE_PASSWORD: The PASSWORD attribute as defined by RFC3489 * @STUN_ATTRIBUTE_MESSAGE_INTEGRITY: The MESSAGE-INTEGRITY attribute as defined * by RFC5389 * @STUN_ATTRIBUTE_ERROR_CODE: The ERROR-CODE attribute as defined by RFC5389 * @STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES: The UNKNOWN-ATTRIBUTES attribute as * defined by RFC5389 * @STUN_ATTRIBUTE_REFLECTED_FROM: The REFLECTED-FROM attribute as defined * by RFC3489 * @STUN_ATTRIBUTE_CHANNEL_NUMBER: The CHANNEL-NUMBER attribute as defined by * TURN draft 09 and 12 * @STUN_ATTRIBUTE_LIFETIME: The LIFETIME attribute as defined by TURN * draft 04, 09 and 12 * @STUN_ATTRIBUTE_MS_ALTERNATE_SERVER: The ALTERNATE-SERVER attribute as * defined by [MS-TURN] * @STUN_ATTRIBUTE_MAGIC_COOKIE: The MAGIC-COOKIE attribute as defined by * the rosenberg-midcom TURN draft 08 * @STUN_ATTRIBUTE_BANDWIDTH: The BANDWIDTH attribute as defined by TURN draft 04 * @STUN_ATTRIBUTE_DESTINATION_ADDRESS: The DESTINATION-ADDRESS attribute as * defined by the rosenberg-midcom TURN draft 08 * @STUN_ATTRIBUTE_REMOTE_ADDRESS: The REMOTE-ADDRESS attribute as defined by * TURN draft 04 * @STUN_ATTRIBUTE_PEER_ADDRESS: The PEER-ADDRESS attribute as defined by * TURN draft 09 * @STUN_ATTRIBUTE_XOR_PEER_ADDRESS: The XOR-PEER-ADDRESS attribute as defined * by TURN draft 12 * @STUN_ATTRIBUTE_DATA: The DATA attribute as defined by TURN draft 04, * 09 and 12 * @STUN_ATTRIBUTE_REALM: The REALM attribute as defined by RFC5389 * @STUN_ATTRIBUTE_NONCE: The NONCE attribute as defined by RFC5389 * @STUN_ATTRIBUTE_RELAY_ADDRESS: The RELAY-ADDRESS attribute as defined by * TURN draft 04 * @STUN_ATTRIBUTE_RELAYED_ADDRESS: The RELAYED-ADDRESS attribute as defined by * TURN draft 09 * @STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS: The XOR-RELAYED-ADDRESS attribute as * defined by TURN draft 12 * @STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE: The REQUESTED-ADDRESS-TYPE attribute * as defined by TURN-IPV6 draft 05 * @STUN_ATTRIBUTE_REQUESTED_PORT_PROPS: The REQUESTED-PORT-PROPS attribute * as defined by TURN draft 04 * @STUN_ATTRIBUTE_REQUESTED_PROPS: The REQUESTED-PROPS attribute as defined * by TURN draft 09 * @STUN_ATTRIBUTE_EVEN_PORT: The EVEN-PORT attribute as defined by TURN draft 12 * @STUN_ATTRIBUTE_REQUESTED_TRANSPORT: The REQUESTED-TRANSPORT attribute as * defined by TURN draft 12 * @STUN_ATTRIBUTE_DONT_FRAGMENT: The DONT-FRAGMENT attribute as defined * by TURN draft 12 * @STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS: The XOR-MAPPED-ADDRESS attribute as * defined by RFC5389 * @STUN_ATTRIBUTE_TIMER_VAL: The TIMER-VAL attribute as defined by TURN draft 04 * @STUN_ATTRIBUTE_REQUESTED_IP: The REQUESTED-IP attribute as defined by * TURN draft 04 * @STUN_ATTRIBUTE_RESERVATION_TOKEN: The RESERVATION-TOKEN attribute as defined * by TURN draft 09 and 12 * @STUN_ATTRIBUTE_CONNECT_STAT: The CONNECT-STAT attribute as defined by TURN * draft 04 * @STUN_ATTRIBUTE_PRIORITY: The PRIORITY attribute as defined by ICE draft 19 * @STUN_ATTRIBUTE_USE_CANDIDATE: The USE-CANDIDATE attribute as defined by * ICE draft 19 * @STUN_ATTRIBUTE_OPTIONS: The OPTIONS optional attribute as defined by * libjingle * @STUN_ATTRIBUTE_MS_VERSION: The MS-VERSION optional attribute as defined * by [MS-TURN] * @STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS: The XOR-MAPPED-ADDRESS optional * attribute as defined by [MS-TURN] * @STUN_ATTRIBUTE_SOFTWARE: The SOFTWARE optional attribute as defined by RFC5389 * @STUN_ATTRIBUTE_ALTERNATE_SERVER: The ALTERNATE-SERVER optional attribute as * defined by RFC5389 * @STUN_ATTRIBUTE_FINGERPRINT: The FINGERPRINT optional attribute as defined * by RFC5389 * @STUN_ATTRIBUTE_ICE_CONTROLLED: The ICE-CONTROLLED optional attribute as * defined by ICE draft 19 * @STUN_ATTRIBUTE_ICE_CONTROLLING: The ICE-CONTROLLING optional attribute as * defined by ICE draft 19 * @STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER: The MS-SEQUENCE NUMBER optional attribute * as defined by [MS-TURN] * @STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER: The CANDIDATE-IDENTIFIER optional * attribute as defined by [MS-ICE2] * @STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION: The IMPLEMENTATION-VERSION * optional attribute as defined by [MS-ICE2] * * Known STUN attribute types as defined by various RFCs and drafts */ /* Should be in sync with stun_is_unknown() */ typedef enum { /* Mandatory attributes */ /* 0x0000 */ /* reserved */ STUN_ATTRIBUTE_MAPPED_ADDRESS=0x0001, /* RFC5389 */ STUN_ATTRIBUTE_RESPONSE_ADDRESS=0x0002, /* old RFC3489 */ STUN_ATTRIBUTE_CHANGE_REQUEST=0x0003, /* old RFC3489 */ STUN_ATTRIBUTE_SOURCE_ADDRESS=0x0004, /* old RFC3489 */ STUN_ATTRIBUTE_CHANGED_ADDRESS=0x0005, /* old RFC3489 */ STUN_ATTRIBUTE_USERNAME=0x0006, /* RFC5389 */ STUN_ATTRIBUTE_PASSWORD=0x0007, /* old RFC3489 */ STUN_ATTRIBUTE_MESSAGE_INTEGRITY=0x0008, /* RFC5389 */ STUN_ATTRIBUTE_ERROR_CODE=0x0009, /* RFC5389 */ STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES=0x000A, /* RFC5389 */ STUN_ATTRIBUTE_REFLECTED_FROM=0x000B, /* old RFC3489 */ STUN_ATTRIBUTE_CHANNEL_NUMBER=0x000C, /* TURN-12 */ STUN_ATTRIBUTE_LIFETIME=0x000D, /* TURN-12 */ /* MS_ALTERNATE_SERVER is only used by Microsoft's dialect, probably should * not to be placed in STUN_ALL_KNOWN_ATTRIBUTES */ STUN_ATTRIBUTE_MS_ALTERNATE_SERVER=0x000E, /* MS-TURN */ STUN_ATTRIBUTE_MAGIC_COOKIE=0x000F, /* midcom-TURN 08 */ STUN_ATTRIBUTE_BANDWIDTH=0x0010, /* TURN-04 */ STUN_ATTRIBUTE_DESTINATION_ADDRESS=0x0011, /* midcom-TURN 08 */ STUN_ATTRIBUTE_REMOTE_ADDRESS=0x0012, /* TURN-04 */ STUN_ATTRIBUTE_PEER_ADDRESS=0x0012, /* TURN-09 */ STUN_ATTRIBUTE_XOR_PEER_ADDRESS=0x0012, /* TURN-12 */ STUN_ATTRIBUTE_DATA=0x0013, /* TURN-12 */ STUN_ATTRIBUTE_REALM=0x0014, /* RFC5389 */ STUN_ATTRIBUTE_NONCE=0x0015, /* RFC5389 */ STUN_ATTRIBUTE_RELAY_ADDRESS=0x0016, /* TURN-04 */ STUN_ATTRIBUTE_RELAYED_ADDRESS=0x0016, /* TURN-09 */ STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS=0x0016, /* TURN-12 */ STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE=0x0017, /* TURN-IPv6-05 */ STUN_ATTRIBUTE_REQUESTED_PORT_PROPS=0x0018, /* TURN-04 */ STUN_ATTRIBUTE_REQUESTED_PROPS=0x0018, /* TURN-09 */ STUN_ATTRIBUTE_EVEN_PORT=0x0018, /* TURN-12 */ STUN_ATTRIBUTE_REQUESTED_TRANSPORT=0x0019, /* TURN-12 */ STUN_ATTRIBUTE_DONT_FRAGMENT=0x001A, /* TURN-12 */ /* 0x001B */ /* reserved */ /* 0x001C */ /* reserved */ /* 0x001D */ /* reserved */ /* 0x001E */ /* reserved */ /* 0x001F */ /* reserved */ STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS=0x0020, /* RFC5389 */ STUN_ATTRIBUTE_TIMER_VAL=0x0021, /* TURN-04 */ STUN_ATTRIBUTE_REQUESTED_IP=0x0022, /* TURN-04 */ STUN_ATTRIBUTE_RESERVATION_TOKEN=0x0022, /* TURN-09 */ STUN_ATTRIBUTE_CONNECT_STAT=0x0023, /* TURN-04 */ STUN_ATTRIBUTE_PRIORITY=0x0024, /* ICE-19 */ STUN_ATTRIBUTE_USE_CANDIDATE=0x0025, /* ICE-19 */ /* 0x0026 */ /* reserved */ /* 0x0027 */ /* reserved */ /* 0x0028 */ /* reserved */ /* 0x0029 */ /* reserved */ /* 0x002A-0x7fff */ /* reserved */ /* Optional attributes */ /* 0x8000-0x8021 */ /* reserved */ STUN_ATTRIBUTE_OPTIONS=0x8001, /* libjingle */ STUN_ATTRIBUTE_MS_VERSION=0x8008, /* MS-TURN */ STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS=0x8020, /* MS-TURN */ STUN_ATTRIBUTE_SOFTWARE=0x8022, /* RFC5389 */ STUN_ATTRIBUTE_ALTERNATE_SERVER=0x8023, /* RFC5389 */ /* 0x8024 */ /* reserved */ /* 0x8025 */ /* reserved */ /* 0x8026 */ /* reserved */ /* 0x8027 */ /* reserved */ STUN_ATTRIBUTE_FINGERPRINT=0x8028, /* RFC5389 */ STUN_ATTRIBUTE_ICE_CONTROLLED=0x8029, /* ICE-19 */ STUN_ATTRIBUTE_ICE_CONTROLLING=0x802A, /* ICE-19 */ /* 0x802B-0x804F */ /* reserved */ STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER=0x8050, /* MS-TURN */ /* 0x8051-0x8053 */ /* reserved */ STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER=0x8054, /* MS-ICE2 */ /* 0x8055-0x806F */ /* reserved */ STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION=0x8070 /* MS-ICE2 */ /* 0x8071-0xFFFF */ /* reserved */ } StunAttribute; /** * STUN_ALL_KNOWN_ATTRIBUTES: * * An array containing all the currently known and defined mandatory attributes * from StunAttribute */ /* Should be in sync with StunAttribute */ static const uint16_t STUN_ALL_KNOWN_ATTRIBUTES[] = { STUN_ATTRIBUTE_MAPPED_ADDRESS, STUN_ATTRIBUTE_RESPONSE_ADDRESS, STUN_ATTRIBUTE_CHANGE_REQUEST, STUN_ATTRIBUTE_SOURCE_ADDRESS, STUN_ATTRIBUTE_CHANGED_ADDRESS, STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_PASSWORD, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, STUN_ATTRIBUTE_REFLECTED_FROM, STUN_ATTRIBUTE_CHANNEL_NUMBER, STUN_ATTRIBUTE_LIFETIME, STUN_ATTRIBUTE_MAGIC_COOKIE, STUN_ATTRIBUTE_BANDWIDTH, STUN_ATTRIBUTE_DESTINATION_ADDRESS, STUN_ATTRIBUTE_REMOTE_ADDRESS, STUN_ATTRIBUTE_PEER_ADDRESS, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, STUN_ATTRIBUTE_DATA, STUN_ATTRIBUTE_REALM, STUN_ATTRIBUTE_NONCE, STUN_ATTRIBUTE_RELAY_ADDRESS, STUN_ATTRIBUTE_RELAYED_ADDRESS, STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS, STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE, STUN_ATTRIBUTE_REQUESTED_PORT_PROPS, STUN_ATTRIBUTE_REQUESTED_PROPS, STUN_ATTRIBUTE_EVEN_PORT, STUN_ATTRIBUTE_REQUESTED_TRANSPORT, STUN_ATTRIBUTE_DONT_FRAGMENT, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, STUN_ATTRIBUTE_TIMER_VAL, STUN_ATTRIBUTE_REQUESTED_IP, STUN_ATTRIBUTE_RESERVATION_TOKEN, STUN_ATTRIBUTE_CONNECT_STAT, STUN_ATTRIBUTE_PRIORITY, STUN_ATTRIBUTE_USE_CANDIDATE, 0 }; /** * STUN_MSOC_KNOWN_ATTRIBUTES: * * An array containing all the currently known mandatory attributes used by * Microsoft Office Communicator as defined in [MS-TURN] */ static const uint16_t STUN_MSOC_KNOWN_ATTRIBUTES[] = { STUN_ATTRIBUTE_MAPPED_ADDRESS, STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, STUN_ATTRIBUTE_LIFETIME, STUN_ATTRIBUTE_MS_ALTERNATE_SERVER, STUN_ATTRIBUTE_MAGIC_COOKIE, STUN_ATTRIBUTE_BANDWIDTH, STUN_ATTRIBUTE_DESTINATION_ADDRESS, STUN_ATTRIBUTE_REMOTE_ADDRESS, STUN_ATTRIBUTE_DATA, /* REALM and NONCE have swapped hexadecimal IDs in [MS-TURN]. Libnice users * or developers can still use these enumeration values in their original * meanings from StunAttribute anywhere in the code, as stun_message_find() * and stun_message_append() will choose correct ID in MSOC compatibility * modes. */ STUN_ATTRIBUTE_NONCE, STUN_ATTRIBUTE_REALM, 0 }; /** * StunTransactionId: * * A type that holds a STUN transaction id. */ typedef uint8_t StunTransactionId[STUN_MESSAGE_TRANS_ID_LEN]; /** * StunError: * @STUN_ERROR_TRY_ALTERNATE: The ERROR-CODE value for the * "Try Alternate" error as defined in RFC5389 * @STUN_ERROR_BAD_REQUEST: The ERROR-CODE value for the * "Bad Request" error as defined in RFC5389 * @STUN_ERROR_UNAUTHORIZED: The ERROR-CODE value for the * "Unauthorized" error as defined in RFC5389 * @STUN_ERROR_UNKNOWN_ATTRIBUTE: The ERROR-CODE value for the * "Unknown Attribute" error as defined in RFC5389 * @STUN_ERROR_ALLOCATION_MISMATCH:The ERROR-CODE value for the * "Allocation Mismatch" error as defined in TURN draft 12. * Equivalent to the "No Binding" error defined in TURN draft 04. * @STUN_ERROR_STALE_NONCE: The ERROR-CODE value for the * "Stale Nonce" error as defined in RFC5389 * @STUN_ERROR_ACT_DST_ALREADY: The ERROR-CODE value for the * "Active Destination Already Set" error as defined in TURN draft 04. * @STUN_ERROR_UNSUPPORTED_FAMILY: The ERROR-CODE value for the * "Address Family not Supported" error as defined in TURN IPV6 Draft 05. * @STUN_ERROR_WRONG_CREDENTIALS: The ERROR-CODE value for the * "Wrong Credentials" error as defined in TURN Draft 12. * @STUN_ERROR_UNSUPPORTED_TRANSPORT:he ERROR-CODE value for the * "Unsupported Transport Protocol" error as defined in TURN Draft 12. * @STUN_ERROR_INVALID_IP: The ERROR-CODE value for the * "Invalid IP Address" error as defined in TURN draft 04. * @STUN_ERROR_INVALID_PORT: The ERROR-CODE value for the * "Invalid Port" error as defined in TURN draft 04. * @STUN_ERROR_OP_TCP_ONLY: The ERROR-CODE value for the * "Operation for TCP Only" error as defined in TURN draft 04. * @STUN_ERROR_CONN_ALREADY: The ERROR-CODE value for the * "Connection Already Exists" error as defined in TURN draft 04. * @STUN_ERROR_ALLOCATION_QUOTA_REACHED: The ERROR-CODE value for the * "Allocation Quota Reached" error as defined in TURN draft 12. * @STUN_ERROR_ROLE_CONFLICT:The ERROR-CODE value for the * "Role Conflict" error as defined in ICE draft 19. * @STUN_ERROR_SERVER_ERROR: The ERROR-CODE value for the * "Server Error" error as defined in RFC5389 * @STUN_ERROR_SERVER_CAPACITY: The ERROR-CODE value for the * "Insufficient Capacity" error as defined in TURN draft 04. * @STUN_ERROR_INSUFFICIENT_CAPACITY: The ERROR-CODE value for the * "Insufficient Capacity" error as defined in TURN draft 12. * @STUN_ERROR_MAX: The maximum possible ERROR-CODE value as defined by RFC 5389. * * STUN error codes as defined by various RFCs and drafts */ /* Should be in sync with stun_strerror() */ typedef enum { STUN_ERROR_TRY_ALTERNATE=300, /* RFC5389 */ STUN_ERROR_BAD_REQUEST=400, /* RFC5389 */ STUN_ERROR_UNAUTHORIZED=401, /* RFC5389 */ STUN_ERROR_UNKNOWN_ATTRIBUTE=420, /* RFC5389 */ STUN_ERROR_ALLOCATION_MISMATCH=437, /* TURN-12 */ STUN_ERROR_STALE_NONCE=438, /* RFC5389 */ STUN_ERROR_ACT_DST_ALREADY=439, /* TURN-04 */ STUN_ERROR_UNSUPPORTED_FAMILY=440, /* TURN-IPv6-05 */ STUN_ERROR_WRONG_CREDENTIALS=441, /* TURN-12 */ STUN_ERROR_UNSUPPORTED_TRANSPORT=442, /* TURN-12 */ STUN_ERROR_INVALID_IP=443, /* TURN-04 */ STUN_ERROR_INVALID_PORT=444, /* TURN-04 */ STUN_ERROR_OP_TCP_ONLY=445, /* TURN-04 */ STUN_ERROR_CONN_ALREADY=446, /* TURN-04 */ STUN_ERROR_ALLOCATION_QUOTA_REACHED=486, /* TURN-12 */ STUN_ERROR_ROLE_CONFLICT=487, /* ICE-19 */ STUN_ERROR_SERVER_ERROR=500, /* RFC5389 */ STUN_ERROR_SERVER_CAPACITY=507, /* TURN-04 */ STUN_ERROR_INSUFFICIENT_CAPACITY=508, /* TURN-12 */ STUN_ERROR_MAX=699 } StunError; /** * StunMessageReturn: * @STUN_MESSAGE_RETURN_SUCCESS: The operation was successful * @STUN_MESSAGE_RETURN_NOT_FOUND: The attribute was not found * @STUN_MESSAGE_RETURN_INVALID: The argument or data is invalid * @STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE: There is not enough space in the * message to append data to it, or not enough in an argument to fill it with * the data requested. * @STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS: The address in the arguments or in * the STUN message is not supported. * * The return value of most stun_message_* functions. * This enum will report on whether an operation was successful or not * and what error occured if any. */ typedef enum { STUN_MESSAGE_RETURN_SUCCESS, STUN_MESSAGE_RETURN_NOT_FOUND, STUN_MESSAGE_RETURN_INVALID, STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE, STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS } StunMessageReturn; #include "stunagent.h" /** * STUN_MAX_MESSAGE_SIZE: * * The Maximum size of a STUN message */ #define STUN_MAX_MESSAGE_SIZE 65552 /** * StunMessage: * @agent: The agent that created or validated this message * @buffer: The buffer containing the STUN message * @buffer_len: The length of the buffer (not the size of the message) * @key: The short term credentials key to use for authentication validation * or that was used to finalize this message * @key_len: The length of the associated key * @long_term_key: The long term credential key to use for authentication * validation or that was used to finalize this message * @long_term_valid: Whether or not the #long_term_key variable contains valid * data * * This structure represents a STUN message */ struct _StunMessage { StunAgent *agent; uint8_t *buffer; size_t buffer_len; uint8_t *key; size_t key_len; uint8_t long_term_key[16]; bool long_term_valid; }; /** * stun_message_init: * @msg: The #StunMessage to initialize * @c: STUN message class (host byte order) * @m: STUN message method (host byte order) * @id: 16-bytes transaction ID * * Initializes a STUN message buffer, with no attributes. * Returns: %TRUE if the initialization was successful */ bool stun_message_init (StunMessage *msg, StunClass c, StunMethod m, const StunTransactionId id); /** * stun_message_length: * @msg: The #StunMessage * * Get the length of the message (including the header) * * Returns: The length of the message */ uint16_t stun_message_length (const StunMessage *msg); /** * stun_message_find: * @msg: The #StunMessage * @type: The #StunAttribute to find * @palen: A pointer to store the length of the attribute * * Finds an attribute in a STUN message and fetches its content * * Returns: A pointer to the start of the attribute payload if found, * otherwise NULL. */ const void * stun_message_find (const StunMessage * msg, StunAttribute type, uint16_t *palen); /** * stun_message_find_flag: * @msg: The #StunMessage * @type: The #StunAttribute to find * * Looks for a flag attribute within a valid STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not zero. */ StunMessageReturn stun_message_find_flag (const StunMessage *msg, StunAttribute type); /** * stun_message_find32: * @msg: The #StunMessage * @type: The #StunAttribute to find * @pval: A pointer where to store the value (host byte order) * * Extracts a 32-bits attribute from a STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not * 4 bytes. */ StunMessageReturn stun_message_find32 (const StunMessage *msg, StunAttribute type, uint32_t *pval); /** * stun_message_find64: * @msg: The #StunMessage * @type: The #StunAttribute to find * @pval: A pointer where to store the value (host byte order) * * Extracts a 64-bits attribute from a STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not * 8 bytes. */ StunMessageReturn stun_message_find64 (const StunMessage *msg, StunAttribute type, uint64_t *pval); /** * stun_message_find_string: * @msg: The #StunMessage * @type: The #StunAttribute to find * @buf: A pointer where to store the data * @buflen: The length of the buffer * * Extracts an UTF-8 string from a valid STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute is improperly * encoded * %STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE is return if the buffer size is too * small to hold the string * The string will be nul-terminated. * */ StunMessageReturn stun_message_find_string (const StunMessage *msg, StunAttribute type, char *buf, size_t buflen); /** * stun_message_find_addr: * @msg: The #StunMessage * @type: The #StunAttribute to find * @addr: The #sockaddr to be filled * @addrlen: The size of the @addr variable. Must be set to the size of the * @addr socket address and will be set to the size of the extracted socket * address. * * Extracts a network address attribute from a STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is * wrong or if the @addrlen is too small * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_find_addr (const StunMessage *msg, StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen); /** * stun_message_find_xor_addr: * @msg: The #StunMessage * @type: The #StunAttribute to find * @addr: The #sockaddr to be filled * @addrlen: The size of the @addr variable. Must be set to the size of the * @addr socket address and will be set to the size of the * extracted socket address. * * Extracts an obfuscated network address attribute from a STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is * wrong or if the @addrlen is too small * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_find_xor_addr (const StunMessage *msg, StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen); /** * stun_message_find_xor_addr_full: * @msg: The #StunMessage * @type: The #StunAttribute to find * @addr: The #sockaddr to be filled * @addrlen: The size of the @addr variable. Must be set to the size of the * @addr socket address and will be set to the size of the * extracted socket address. * @magic_cookie: The magic cookie to use to XOR the address. * * Extracts an obfuscated network address attribute from a STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is * wrong or if the @addrlen is too small * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_find_xor_addr_full (const StunMessage *msg, StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen, uint32_t magic_cookie); /** * stun_message_find_error: * @msg: The #StunMessage * @code: A pointer where to store the value * * Extract the error response code from a STUN message * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the value is invalid */ StunMessageReturn stun_message_find_error (const StunMessage *msg, int *code); /** * stun_message_append: * @msg: The #StunMessage * @type: The #StunAttribute to append * @length: The length of the attribute * * Reserves room for appending an attribute to an unfinished STUN message. * * Returns: A pointer to an unitialized buffer of @length bytes to * where the attribute payload must be written, or NULL if there is not * enough room in the STUN message buffer. */ void *stun_message_append (StunMessage *msg, StunAttribute type, size_t length); /** * stun_message_append_bytes: * @msg: The #StunMessage * @type: The #StunAttribute to append * @data: The data to append * @len: The length of the attribute * * Appends a binary value to a STUN message * * Returns: A #StunMessageReturn value. */ StunMessageReturn stun_message_append_bytes (StunMessage *msg, StunAttribute type, const void *data, size_t len); /** * stun_message_append_flag: * @msg: The #StunMessage * @type: The #StunAttribute to append * * Appends an empty flag attribute to a STUN message * * Returns: A #StunMessageReturn value. */ StunMessageReturn stun_message_append_flag (StunMessage *msg, StunAttribute type); /** * stun_message_append32: * @msg: The #StunMessage * @type: The #StunAttribute to append * @value: The value to append (host byte order) * * Appends a 32-bits value attribute to a STUN message * * Returns: A #StunMessageReturn value. */ StunMessageReturn stun_message_append32 (StunMessage *msg, StunAttribute type, uint32_t value); /** * stun_message_append64: * @msg: The #StunMessage * @type: The #StunAttribute to append * @value: The value to append (host byte order) * * Appends a 64-bits value attribute to a STUN message * * Returns: A #StunMessageReturn value. */ StunMessageReturn stun_message_append64 (StunMessage *msg, StunAttribute type, uint64_t value); /** * stun_message_append_string: * @msg: The #StunMessage * @type: The #StunAttribute to append * @str: The string to append * * Adds an attribute from a nul-terminated string to a STUN message * * Returns: A #StunMessageReturn value. */ StunMessageReturn stun_message_append_string (StunMessage *msg, StunAttribute type, const char *str); /** * stun_message_append_addr: * @msg: The #StunMessage * @type: The #StunAttribute to append * @addr: The #sockaddr to be append * @addrlen: The size of the @addr variable. * * Append a network address attribute to a STUN message * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_append_addr (StunMessage * msg, StunAttribute type, const struct sockaddr *addr, socklen_t addrlen); /** * stun_message_append_xor_addr: * @msg: The #StunMessage * @type: The #StunAttribute to append * @addr: The #sockaddr to be append * @addrlen: The size of the @addr variable. * * Append an obfuscated network address attribute to a STUN message * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_append_xor_addr (StunMessage * msg, StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen); /** * stun_message_append_xor_addr_full: * @msg: The #StunMessage * @type: The #StunAttribute to append * @addr: The #sockaddr to be append * @addrlen: The size of the @addr variable. * @magic_cookie: The magic cookie to use to XOR the address. * * Append an obfuscated network address attribute from a STUN message. * * Returns: A #StunMessageReturn value. * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown. */ StunMessageReturn stun_message_append_xor_addr_full (StunMessage * msg, StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie); /** * stun_message_append_error: * @msg: The #StunMessage * @code: The error code value * * Appends the ERROR-CODE attribute to the STUN message and fills it according * to #code * * Returns: A #StunMessageReturn value. */ StunMessageReturn stun_message_append_error (StunMessage * msg, StunError code); /** * STUN_MESSAGE_BUFFER_INCOMPLETE: * * Convenience macro for stun_message_validate_buffer_length() meaning that the * data to validate does not hold a complete STUN message */ #define STUN_MESSAGE_BUFFER_INCOMPLETE 0 /** * STUN_MESSAGE_BUFFER_INVALID: * * Convenience macro for stun_message_validate_buffer_length() meaning that the * data to validate is not a valid STUN message */ #define STUN_MESSAGE_BUFFER_INVALID -1 /** * stun_message_validate_buffer_length: * @msg: The buffer to validate * @length: The length of the buffer * @has_padding: Set TRUE if attributes should be padded to multiple of 4 bytes * * This function will take a data buffer and will try to validate whether it is * a STUN message or if it's not or if it's an incomplete STUN message and will * provide us with the length of the STUN message. * * Returns: The length of the valid STUN message in the buffer. * See also: #STUN_MESSAGE_BUFFER_INCOMPLETE * See also: #STUN_MESSAGE_BUFFER_INVALID */ int stun_message_validate_buffer_length (const uint8_t *msg, size_t length, bool has_padding); /** * StunInputVector: * @buffer: a buffer containing already-received binary data * @size: length of @buffer, in bytes * * Container for a single buffer which also stores its length. This is designed * for vectored I/O: typically an array of #StunInputVectors is passed to * functions, providing multiple buffers which store logically contiguous * received data. * * This is guaranteed to be layed out identically in memory to #GInputVector. * * Since: 0.1.5 */ typedef struct { const uint8_t *buffer; size_t size; } StunInputVector; /** * stun_message_validate_buffer_length_fast: * @buffers: (array length=n_buffers) (in caller-allocated): array of contiguous * #StunInputVectors containing already-received message data * @n_buffers: number of entries in @buffers or if -1 , then buffers is * terminated by a #StunInputVector with the buffer pointer being %NULL. * @total_length: total number of valid bytes stored consecutively in @buffers * @has_padding: %TRUE if attributes should be padded to 4-byte boundaries * * Quickly validate whether the message in the given @buffers is potentially a * valid STUN message, an incomplete STUN message, or if it’s definitely not one * at all. * * This is designed as a first-pass validation only, and does not check the * message’s attributes for validity. If this function returns success, the * buffers can be compacted and a more thorough validation can be performed * using stun_message_validate_buffer_length(). If it fails, the buffers * definitely do not contain a complete, valid STUN message. * * Returns: The length of the valid STUN message in the buffer, or zero or -1 on * failure * See also: #STUN_MESSAGE_BUFFER_INCOMPLETE * See also: #STUN_MESSAGE_BUFFER_INVALID * * Since: 0.1.5 */ ssize_t stun_message_validate_buffer_length_fast (StunInputVector *buffers, int n_buffers, size_t total_length, bool has_padding); /** * stun_message_id: * @msg: The #StunMessage * @id: The #StunTransactionId to fill * * Retreive the STUN transaction id from a STUN message */ void stun_message_id (const StunMessage *msg, StunTransactionId id); /** * stun_message_get_class: * @msg: The #StunMessage * * Retreive the STUN class from a STUN message * * Returns: The #StunClass */ StunClass stun_message_get_class (const StunMessage *msg); /** * stun_message_get_method: * @msg: The #StunMessage * * Retreive the STUN method from a STUN message * * Returns: The #StunMethod */ StunMethod stun_message_get_method (const StunMessage *msg); /** * stun_message_has_attribute: * @msg: The #StunMessage * @type: The #StunAttribute to look for * * Checks if an attribute is present within a STUN message. * * Returns: %TRUE if the attribute is found, %FALSE otherwise */ bool stun_message_has_attribute (const StunMessage *msg, StunAttribute type); /* Defined in stun5389.c */ /** * stun_message_has_cookie: * @msg: The #StunMessage * * Checks if the STUN message has a RFC5389 compatible cookie * * Returns: %TRUE if the cookie is present, %FALSE otherwise */ bool stun_message_has_cookie (const StunMessage *msg); /** * stun_optional: * @t: An attribute type * * Helper function that checks whether a STUN attribute is a mandatory * or an optional attribute * * Returns: %TRUE if the attribute is an optional one */ bool stun_optional (uint16_t t); /** * stun_strerror: * @code: host-byte order error code * * Transforms a STUN error-code into a human readable string * * Returns: A static pointer to a nul-terminated error message string. */ const char *stun_strerror (StunError code); #endif /* _STUN_MESSAGE_H */ libnice-0.1.14/stun/stun5389.h0000644000076400007640000000434111345503277012630 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _STUN_5389_H #define _STUN_5389_H #ifdef _WIN32 #include "win32_common.h" #else # include # include #endif # include #include "stunmessage.h" /* * Computes the FINGERPRINT checksum of a STUN message. * @param msg pointer to the STUN message * @param len size of the message from header (inclusive) and up to * FINGERPRINT attribute (inclusive) * * @return fingerprint value in host byte order. */ uint32_t stun_fingerprint (const uint8_t *msg, size_t len, bool wlm2009_stupid_crc32_typo); StunMessageReturn stun_message_append_software (StunMessage *msg, const char *software); #endif /* _STUN_5389_H */ libnice-0.1.14/stun/usages/0000775000076400007640000000000013070512356012477 500000000000000libnice-0.1.14/stun/usages/ice.c0000664000076400007640000003007013004222453013314 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #ifdef _WIN32 #include #else #include #include #include #endif #include "stunagent.h" /** ICE connectivity checks **/ #include "ice.h" size_t stun_usage_ice_conncheck_create (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const uint8_t *username, const size_t username_len, const uint8_t *password, const size_t password_len, bool cand_use, bool controlling, uint32_t priority, uint64_t tie, const char *candidate_identifier, StunUsageIceCompatibility compatibility) { StunMessageReturn val; stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_BINDING); if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_RFC5245 || compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSICE2) { if (cand_use) { val = stun_message_append_flag (msg, STUN_ATTRIBUTE_USE_CANDIDATE); if (val != STUN_MESSAGE_RETURN_SUCCESS) return 0; } val = stun_message_append32 (msg, STUN_ATTRIBUTE_PRIORITY, priority); if (val != STUN_MESSAGE_RETURN_SUCCESS) return 0; if (controlling) val = stun_message_append64 (msg, STUN_ATTRIBUTE_ICE_CONTROLLING, tie); else val = stun_message_append64 (msg, STUN_ATTRIBUTE_ICE_CONTROLLED, tie); if (val != STUN_MESSAGE_RETURN_SUCCESS) return 0; } if (username && username_len > 0) { val = stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME, username, username_len); if (val != STUN_MESSAGE_RETURN_SUCCESS) return 0; } if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSICE2) { size_t identifier_len = strlen(candidate_identifier); size_t attribute_len = identifier_len; int modulo4 = identifier_len % 4; uint8_t* buf; if (modulo4) attribute_len += 4 - modulo4; // Avoid a coverify false positive assert (attribute_len >= identifier_len); buf = malloc(attribute_len); memset(buf, 0, attribute_len); memcpy(buf, candidate_identifier, identifier_len); val = stun_message_append_bytes (msg, STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER, buf, attribute_len); free(buf); if (val != STUN_MESSAGE_RETURN_SUCCESS) return 0; val = stun_message_append32 (msg, STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION, 2); if (val != STUN_MESSAGE_RETURN_SUCCESS) return 0; } return stun_agent_finish_message (agent, msg, password, password_len); } StunUsageIceReturn stun_usage_ice_conncheck_process (StunMessage *msg, struct sockaddr_storage *addr, socklen_t *addrlen, StunUsageIceCompatibility compatibility) { int code = -1; StunMessageReturn val; if (stun_message_get_method (msg) != STUN_BINDING) return STUN_USAGE_ICE_RETURN_INVALID; switch (stun_message_get_class (msg)) { case STUN_REQUEST: case STUN_INDICATION: return STUN_USAGE_ICE_RETURN_INVALID; case STUN_RESPONSE: break; case STUN_ERROR: default: if (stun_message_find_error (msg, &code) != STUN_MESSAGE_RETURN_SUCCESS) { /* missing ERROR-CODE: ignore message */ return STUN_USAGE_ICE_RETURN_INVALID; } if (code == STUN_ERROR_ROLE_CONFLICT) return STUN_USAGE_ICE_RETURN_ROLE_CONFLICT; /* NOTE: currently we ignore unauthenticated messages if the context * is authenticated, for security reasons. */ stun_debug (" STUN error message received (code: %d)", code); return STUN_USAGE_ICE_RETURN_ERROR; } stun_debug ("Received %u-bytes STUN message", stun_message_length (msg)); if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSN) { union { StunTransactionId u8; uint32_t u32[STUN_MESSAGE_TRANS_ID_LEN / 4]; } transid; uint32_t magic_cookie; stun_message_id (msg, transid.u8); magic_cookie = *(transid.u32); val = stun_message_find_xor_addr_full (msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, addr, addrlen, htonl (magic_cookie)); } else { val = stun_message_find_xor_addr (msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, addr, addrlen); } if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No XOR-MAPPED-ADDRESS: %d", val); val = stun_message_find_addr (msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, addr, addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No MAPPED-ADDRESS: %d", val); return STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS; } } stun_debug ("Mapped address found!"); return STUN_USAGE_ICE_RETURN_SUCCESS; } static int stun_bind_error (StunAgent *agent, StunMessage *msg, uint8_t *buf, size_t *plen, const StunMessage *req, StunError code) { size_t len = *plen; int val; *plen = 0; stun_debug ("STUN Error Reply (buffer size: %u)...", (unsigned)len); val = stun_agent_init_error (agent, msg, buf, len, req, code); if (!val) return val; len = stun_agent_finish_message (agent, msg, NULL, 0); if (len == 0) return 0; *plen = len; stun_debug (" Error response (%u) of %u bytes", (unsigned)code, (unsigned)*plen); return 1; } StunUsageIceReturn stun_usage_ice_conncheck_create_reply (StunAgent *agent, StunMessage *req, StunMessage *msg, uint8_t *buf, size_t *plen, const struct sockaddr_storage *src, socklen_t srclen, bool *control, uint64_t tie, StunUsageIceCompatibility compatibility) { const char *username = NULL; uint16_t username_len; size_t len = *plen; uint64_t q; StunMessageReturn val = STUN_MESSAGE_RETURN_SUCCESS; StunUsageIceReturn ret = STUN_USAGE_ICE_RETURN_SUCCESS; #define err( code ) \ stun_bind_error (agent, msg, buf, &len, req, code); \ *plen = len *plen = 0; stun_debug ("STUN Reply (buffer size = %u)...", (unsigned)len); if (stun_message_get_class (req) != STUN_REQUEST) { stun_debug (" Unhandled non-request (class %u) message.", stun_message_get_class (req)); return STUN_USAGE_ICE_RETURN_INVALID_REQUEST; } if (stun_message_get_method (req) != STUN_BINDING) { stun_debug (" Bad request (method %u) message.", stun_message_get_method (req)); err (STUN_ERROR_BAD_REQUEST); return STUN_USAGE_ICE_RETURN_INVALID_METHOD; } /* Role conflict handling */ assert (control != NULL); if (stun_message_find64 (req, *control ? STUN_ATTRIBUTE_ICE_CONTROLLING : STUN_ATTRIBUTE_ICE_CONTROLLED, &q) == STUN_MESSAGE_RETURN_SUCCESS) { /* we have the ice-controlling/controlled attribute, * and there's a role conflict */ stun_debug ("STUN Role Conflict detected:"); /* According to ICE RFC 5245, section 7.2.1.1, we consider the four * possible cases when a role conflict is detected: two cases are * resolved by switching role locally, and the two other cases are * handled by responding with a STUN error. */ if ((tie < q && *control) || (tie >= q && !*control)) { stun_debug (" switching role from \"controll%s\" to \"controll%s\"", *control ? "ing" : "ed", *control ? "ed" : "ing"); *control = !*control; ret = STUN_USAGE_ICE_RETURN_ROLE_CONFLICT; } else { stun_debug (" staying \"controll%s\" (sending error)", *control ? "ing" : "ed"); err (STUN_ERROR_ROLE_CONFLICT); return STUN_USAGE_ICE_RETURN_ROLE_CONFLICT; } } else { if (stun_message_find64 (req, *control ? STUN_ATTRIBUTE_ICE_CONTROLLED : STUN_ATTRIBUTE_ICE_CONTROLLING, &q) != STUN_MESSAGE_RETURN_SUCCESS) { /* we don't have the expected ice-controlling/controlled * attribute */ if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_RFC5245 || compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSICE2) { stun_debug ("STUN Role not specified by peer!"); } } } if (stun_agent_init_response (agent, msg, buf, len, req) == FALSE) { stun_debug ("Unable to create response"); goto failure; } if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSN) { union { StunTransactionId transid; uint32_t magic_cookie; } conv; stun_message_id (msg, conv.transid); val = stun_message_append_xor_addr_full (msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, src, srclen, htonl (conv.magic_cookie)); } else if (stun_message_has_cookie (msg) && compatibility != STUN_USAGE_ICE_COMPATIBILITY_GOOGLE) { val = stun_message_append_xor_addr (msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, src, srclen); } else { val = stun_message_append_addr (msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, (struct sockaddr *) src, srclen); } if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" Mapped address problem: %d", val); goto failure; } username = (const char *)stun_message_find (req, STUN_ATTRIBUTE_USERNAME, &username_len); if (username) { val = stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME, username, username_len); } if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug ("Error appending username: %d", val); goto failure; } if (compatibility == STUN_USAGE_ICE_COMPATIBILITY_MSICE2) { val = stun_message_append32 (msg, STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION, 2); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug ("Error appending implementation version: %d", val); goto failure; } } /* the stun agent will automatically use the password of the request */ len = stun_agent_finish_message (agent, msg, NULL, 0); if (len == 0) goto failure; *plen = len; stun_debug (" All done (response size: %u)", (unsigned)len); return ret; failure: assert (*plen == 0); stun_debug (" Fatal error formatting Response: %d", val); switch (val) { case STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE: return STUN_USAGE_ICE_RETURN_MEMORY_ERROR; case STUN_MESSAGE_RETURN_INVALID: case STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS: return STUN_USAGE_ICE_RETURN_INVALID_ADDRESS; case STUN_MESSAGE_RETURN_SUCCESS: assert (0); /* shouldn’t be reached */ case STUN_MESSAGE_RETURN_NOT_FOUND: default: return STUN_USAGE_ICE_RETURN_ERROR; } } #undef err uint32_t stun_usage_ice_conncheck_priority (const StunMessage *msg) { uint32_t value; if (stun_message_find32 (msg, STUN_ATTRIBUTE_PRIORITY, &value) != STUN_MESSAGE_RETURN_SUCCESS) return 0; return value; } bool stun_usage_ice_conncheck_use_candidate (const StunMessage *msg) { return (stun_message_find_flag (msg, STUN_ATTRIBUTE_USE_CANDIDATE) == STUN_MESSAGE_RETURN_SUCCESS); } libnice-0.1.14/stun/usages/timer.c0000664000076400007640000001014012733070261013676 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #else #include #endif #include "timer.h" #include /* div() */ /* * Clock used throughout the STUN code. * STUN requires a monotonic 1kHz clock to operate properly. */ static void stun_gettime (struct timeval *now) { #ifdef _WIN32 FILETIME ft; unsigned long long *time64 = (unsigned long long *) &ft; GetSystemTimeAsFileTime (&ft); /* Convert from 100s of nanoseconds since 1601-01-01 * to Unix epoch. Yes, this is Y2038 unsafe. */ *time64 -= (unsigned long long) 116444736000000000; *time64 /= 10; now->tv_sec = (long)(*time64 / 1000000); now->tv_usec = *time64 % 1000000; #else #if defined (_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK >= 0) struct timespec spec; if (!clock_gettime (CLOCK_MONOTONIC, &spec)) { now->tv_sec = spec.tv_sec; now->tv_usec = spec.tv_nsec / 1000; } else #endif { // fallback to wall clock gettimeofday (now, NULL); } #endif } static void add_delay (struct timeval *ts, unsigned delay) { /* Delay is in ms. */ ts->tv_sec += delay / 1000; ts->tv_usec += (delay % 1000) * 1000; while (ts->tv_usec > 1000000) { ts->tv_usec -= 1000000; ts->tv_sec++; } } void stun_timer_start (StunTimer *timer, unsigned int initial_timeout, unsigned int max_retransmissions) { stun_gettime (&timer->deadline); timer->retransmissions = 1; timer->delay = initial_timeout; timer->max_retransmissions = max_retransmissions; add_delay (&timer->deadline, timer->delay); } void stun_timer_start_reliable (StunTimer *timer, unsigned int initial_timeout) { stun_timer_start (timer, initial_timeout, 0); } unsigned stun_timer_remainder (const StunTimer *timer) { unsigned delay; struct timeval now; stun_gettime (&now); if (now.tv_sec > timer->deadline.tv_sec) return 0; delay = timer->deadline.tv_sec - now.tv_sec; if ((delay == 0) && (now.tv_usec >= timer->deadline.tv_usec)) return 0; delay *= 1000; delay += ((signed)(timer->deadline.tv_usec - now.tv_usec)) / 1000; return delay; } StunUsageTimerReturn stun_timer_refresh (StunTimer *timer) { unsigned delay = stun_timer_remainder (timer); if (delay == 0) { if (timer->retransmissions >= timer->max_retransmissions) return STUN_USAGE_TIMER_RETURN_TIMEOUT; add_delay (&timer->deadline, timer->delay *= 2); timer->retransmissions++; return STUN_USAGE_TIMER_RETURN_RETRANSMIT; } return STUN_USAGE_TIMER_RETURN_SUCCESS; } libnice-0.1.14/stun/usages/turn.c0000664000076400007640000003403512721653245013565 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef _WIN32 #include #else #include #include #endif #include "stun/stunagent.h" #include "turn.h" #include #include #include #define REQUESTED_PROPS_E 0x80000000 #define REQUESTED_PROPS_R 0x40000000 #define REQUESTED_PROPS_P 0x20000000 #define STUN_ATTRIBUTE_MSN_MAPPED_ADDRESS 0x8000 #define TURN_REQUESTED_TRANSPORT_UDP 0x11000000 /** Non-blocking mode STUN TURN usage */ size_t stun_usage_turn_create (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMessage *previous_response, StunUsageTurnRequestPorts request_props, int32_t bandwidth, int32_t lifetime, uint8_t *username, size_t username_len, uint8_t *password, size_t password_len, StunUsageTurnCompatibility compatibility) { stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_ALLOCATE); if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 || compatibility == STUN_USAGE_TURN_COMPATIBILITY_RFC5766) { if (stun_message_append32 (msg, STUN_ATTRIBUTE_REQUESTED_TRANSPORT, TURN_REQUESTED_TRANSPORT_UDP) != STUN_MESSAGE_RETURN_SUCCESS) return 0; if (bandwidth >= 0) { if (stun_message_append32 (msg, STUN_ATTRIBUTE_BANDWIDTH, bandwidth) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } } else { if (stun_message_append32 (msg, STUN_ATTRIBUTE_MAGIC_COOKIE, TURN_MAGIC_COOKIE) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { stun_message_append32(msg, STUN_ATTRIBUTE_MS_VERSION, 1); } if (lifetime >= 0) { if (stun_message_append32 (msg, STUN_ATTRIBUTE_LIFETIME, lifetime) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } if ((compatibility == STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 || compatibility == STUN_USAGE_TURN_COMPATIBILITY_RFC5766) && request_props != STUN_USAGE_TURN_REQUEST_PORT_NORMAL) { uint32_t req = 0; if (request_props & STUN_USAGE_TURN_REQUEST_PORT_EVEN_AND_RESERVE) { req |= REQUESTED_PROPS_R; req |= REQUESTED_PROPS_E; } else if (request_props & STUN_USAGE_TURN_REQUEST_PORT_EVEN) { req |= REQUESTED_PROPS_E; } if (stun_message_append32 (msg, STUN_ATTRIBUTE_REQUESTED_PORT_PROPS, req) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } if (previous_response) { uint8_t *realm; uint8_t *nonce; uint64_t reservation; uint16_t len; realm = (uint8_t *) stun_message_find (previous_response, STUN_ATTRIBUTE_REALM, &len); if (realm != NULL) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_REALM, realm, len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } nonce = (uint8_t *) stun_message_find (previous_response, STUN_ATTRIBUTE_NONCE, &len); if (nonce != NULL) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_NONCE, nonce, len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } if (stun_message_find64 (previous_response, STUN_ATTRIBUTE_RESERVATION_TOKEN, &reservation) == STUN_MESSAGE_RETURN_SUCCESS) { if (stun_message_append64 (msg, STUN_ATTRIBUTE_RESERVATION_TOKEN, reservation) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } } if (username != NULL && username_len > 0 && (agent->usage_flags & STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS || previous_response)) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME, username, username_len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } return stun_agent_finish_message (agent, msg, password, password_len); } size_t stun_usage_turn_create_refresh (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMessage *previous_response, int32_t lifetime, uint8_t *username, size_t username_len, uint8_t *password, size_t password_len, StunUsageTurnCompatibility compatibility) { if (compatibility != STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 && compatibility != STUN_USAGE_TURN_COMPATIBILITY_RFC5766) { return stun_usage_turn_create (agent, msg, buffer, buffer_len, previous_response, STUN_USAGE_TURN_REQUEST_PORT_NORMAL, 0, lifetime, username, username_len, password, password_len, compatibility); } stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_REFRESH); if (lifetime >= 0) { if (stun_message_append32 (msg, STUN_ATTRIBUTE_LIFETIME, lifetime) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } if (previous_response) { uint8_t *realm; uint8_t *nonce; uint16_t len; realm = (uint8_t *) stun_message_find (previous_response, STUN_ATTRIBUTE_REALM, &len); if (realm != NULL) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_REALM, realm, len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } nonce = (uint8_t *) stun_message_find (previous_response, STUN_ATTRIBUTE_NONCE, &len); if (nonce != NULL) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_NONCE, nonce, len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } } if (username != NULL && username_len > 0 && (agent->usage_flags & STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS || previous_response)) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME, username, username_len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } return stun_agent_finish_message (agent, msg, password, password_len); } size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, uint8_t *username, size_t username_len, uint8_t *password, size_t password_len, uint8_t *realm, size_t realm_len, uint8_t *nonce, size_t nonce_len, struct sockaddr_storage *peer, StunUsageTurnCompatibility compatibility) { if (!peer) return 0; stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_CREATEPERMISSION); /* PEER address */ if (stun_message_append_xor_addr (msg, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer, sizeof(*peer)) != STUN_MESSAGE_RETURN_SUCCESS) { return 0; } /* nonce */ if (nonce != NULL) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_NONCE, nonce, nonce_len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } /* realm */ if (realm != NULL) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_REALM, realm, realm_len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } /* username */ if (username != NULL && (agent->usage_flags & STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS || (nonce != NULL && realm != NULL))) { if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_USERNAME, username, username_len) != STUN_MESSAGE_RETURN_SUCCESS) return 0; } return stun_agent_finish_message (agent, msg, password, password_len); } StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg, struct sockaddr_storage *relay_addr, socklen_t *relay_addrlen, struct sockaddr_storage *addr, socklen_t *addrlen, struct sockaddr_storage *alternate_server, socklen_t *alternate_server_len, uint32_t *bandwidth, uint32_t *lifetime, StunUsageTurnCompatibility compatibility) { int val, code = -1; StunUsageTurnReturn ret = STUN_USAGE_TURN_RETURN_RELAY_SUCCESS; if (stun_message_get_method (msg) != STUN_ALLOCATE) return STUN_USAGE_TURN_RETURN_INVALID; switch (stun_message_get_class (msg)) { case STUN_REQUEST: case STUN_INDICATION: return STUN_USAGE_TURN_RETURN_INVALID; case STUN_RESPONSE: break; case STUN_ERROR: if (stun_message_find_error (msg, &code) != STUN_MESSAGE_RETURN_SUCCESS) { /* missing ERROR-CODE: ignore message */ return STUN_USAGE_TURN_RETURN_INVALID; } /* NOTE: currently we ignore unauthenticated messages if the context * is authenticated, for security reasons. */ stun_debug (" STUN error message received (code: %d)", code); /* ALTERNATE-SERVER mechanism */ if ((code / 100) == 3) { if (alternate_server && alternate_server_len) { if (stun_message_find_addr (msg, STUN_ATTRIBUTE_ALTERNATE_SERVER, alternate_server, alternate_server_len) != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" Unexpectedly missing ALTERNATE-SERVER attribute"); return STUN_USAGE_TURN_RETURN_ERROR; } } else { if (!stun_message_has_attribute (msg, STUN_ATTRIBUTE_ALTERNATE_SERVER)) { stun_debug (" Unexpectedly missing ALTERNATE-SERVER attribute"); return STUN_USAGE_TURN_RETURN_ERROR; } } stun_debug ("Found alternate server"); return STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER; } return STUN_USAGE_TURN_RETURN_ERROR; default: /* Fall through. */ break; } stun_debug ("Received %u-bytes STUN message", stun_message_length (msg)); if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 || compatibility == STUN_USAGE_TURN_COMPATIBILITY_RFC5766) { val = stun_message_find_xor_addr (msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, addr, addrlen); if (val == STUN_MESSAGE_RETURN_SUCCESS) ret = STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS; val = stun_message_find_xor_addr (msg, STUN_ATTRIBUTE_RELAY_ADDRESS, relay_addr, relay_addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No RELAYED-ADDRESS: %d", val); return STUN_USAGE_TURN_RETURN_ERROR; } } else if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_GOOGLE) { val = stun_message_find_addr (msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, relay_addr, relay_addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No MAPPED-ADDRESS: %d", val); return STUN_USAGE_TURN_RETURN_ERROR; } } else if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_MSN) { val = stun_message_find_addr (msg, STUN_ATTRIBUTE_MSN_MAPPED_ADDRESS, addr, addrlen); if (val == STUN_MESSAGE_RETURN_SUCCESS) ret = STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS; val = stun_message_find_addr (msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, relay_addr, relay_addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No MAPPED-ADDRESS: %d", val); return STUN_USAGE_TURN_RETURN_ERROR; } } else if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { union { StunTransactionId id; uint32_t u32[4]; } transid; uint32_t magic_cookie; stun_message_id (msg, transid.id); magic_cookie = transid.u32[0]; val = stun_message_find_xor_addr_full (msg, STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS, addr, addrlen, htonl (magic_cookie)); if (val == STUN_MESSAGE_RETURN_SUCCESS) ret = STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS; val = stun_message_find_addr (msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, relay_addr, relay_addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No MAPPED-ADDRESS: %d", val); return STUN_USAGE_TURN_RETURN_ERROR; } } stun_message_find32 (msg, STUN_ATTRIBUTE_LIFETIME, lifetime); stun_message_find32 (msg, STUN_ATTRIBUTE_BANDWIDTH, bandwidth); stun_debug (" Mapped address found!"); return ret; } StunUsageTurnReturn stun_usage_turn_refresh_process (StunMessage *msg, uint32_t *lifetime, StunUsageTurnCompatibility compatibility) { int code = -1; StunUsageTurnReturn ret = STUN_USAGE_TURN_RETURN_RELAY_SUCCESS; if (compatibility == STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 || compatibility == STUN_USAGE_TURN_COMPATIBILITY_RFC5766) { if (stun_message_get_method (msg) != STUN_REFRESH) return STUN_USAGE_TURN_RETURN_INVALID; } else { if (stun_message_get_method (msg) != STUN_ALLOCATE) return STUN_USAGE_TURN_RETURN_INVALID; } switch (stun_message_get_class (msg)) { case STUN_REQUEST: case STUN_INDICATION: return STUN_USAGE_TURN_RETURN_INVALID; case STUN_RESPONSE: break; case STUN_ERROR: if (stun_message_find_error (msg, &code) != STUN_MESSAGE_RETURN_SUCCESS) { /* missing ERROR-CODE: ignore message */ return STUN_USAGE_TURN_RETURN_INVALID; } return STUN_USAGE_TURN_RETURN_ERROR; default: /* Fall through. */ break; } stun_message_find32 (msg, STUN_ATTRIBUTE_LIFETIME, lifetime); stun_debug ("TURN Refresh successful!"); return ret; } libnice-0.1.14/stun/usages/bind.h0000664000076400007640000001406712363772107013522 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef STUN_BIND_H # define STUN_BIND_H 1 /** * SECTION:bind * @short_description: STUN Binding Usage * @include: stun/usages/bind.h * @stability: Stable * * The STUN Binding usage allows for easily creating and parsing STUN Binding * requests and responses. It offers both an asynchronous and a synchronous API * that uses the STUN timer usage. */ #ifdef _WIN32 # include "../win32_common.h" #else # include # include #endif # include "stun/stunagent.h" # ifdef __cplusplus extern "C" { # endif /** * StunUsageBindReturn: * @STUN_USAGE_BIND_RETURN_SUCCESS: The binding usage succeeded * @STUN_USAGE_BIND_RETURN_ERROR: There was an unknown error in the bind usage * @STUN_USAGE_BIND_RETURN_INVALID: The message is invalid and should be ignored * @STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER: The binding request has an * ALTERNATE-SERVER attribute * @STUN_USAGE_BIND_RETURN_TIMEOUT: The binding was unsuccessful because it has * timed out. * * Return value of stun_usage_bind_process() and stun_usage_bind_run() which * allows you to see what status the function call returned. */ typedef enum { STUN_USAGE_BIND_RETURN_SUCCESS, STUN_USAGE_BIND_RETURN_ERROR, STUN_USAGE_BIND_RETURN_INVALID, STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER, STUN_USAGE_BIND_RETURN_TIMEOUT, } StunUsageBindReturn; /** * stun_usage_bind_create: * @agent: The #StunAgent to use to create the binding request * @msg: The #StunMessage to build * @buffer: The buffer to use for creating the #StunMessage * @buffer_len: The size of the @buffer * * Create a new STUN binding request to use with a STUN server. * Returns: The length of the built message. */ size_t stun_usage_bind_create (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len); /** * stun_usage_bind_process: * @msg: The #StunMessage to process * @addr: A pointer to a #sockaddr structure to fill with the mapped address * that the STUN server gives us * @addrlen: The length of @add. rMust be set to the size of the @addr socket * address and will be set to the actual length of the socket address. * @alternate_server: A pointer to a #sockaddr structure to fill with the * address of an alternate server to which we should send our new STUN * binding request, in case the currently used STUN server is requesting the use * of an alternate server. This argument will only be filled if the return value * of the function is #STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER * @alternate_server_len: The length of @alternate_server. Must be set to * the size of the @alternate_server socket address and will be set to the * actual length of the socket address. * * Process a STUN binding response and extracts the mapped address from the STUN * message. Also checks for the ALTERNATE-SERVER attribute. * Returns: A #StunUsageBindReturn value. * Note that #STUN_USAGE_BIND_RETURN_TIMEOUT cannot be returned by this function */ StunUsageBindReturn stun_usage_bind_process (StunMessage *msg, struct sockaddr *addr, socklen_t *addrlen, struct sockaddr *alternate_server, socklen_t *alternate_server_len); /** * stun_usage_bind_keepalive: * @agent: The #StunAgent to use to build the message * @msg: The #StunMessage to build * @buf: The buffer to use for creating the #StunMessage * @len: The size of the @buf * * Creates a STUN binding indication that can be used for a keepalive. * Since this is an indication message, no STUN response will be generated * and it can only be used as a keepalive message. * Returns: The length of the message to send */ size_t stun_usage_bind_keepalive (StunAgent *agent, StunMessage *msg, uint8_t *buf, size_t len); /** * stun_usage_bind_run: * @srv: A pointer to the #sockaddr structure representing the STUN server's * address * @srvlen: The length of @srv * @addr: A pointer to a #sockaddr structure to fill with the mapped address * that the STUN server gives us * @addrlen: The length of @addr * * This is a convenience function that will do a synchronous Binding request to * a server and wait for its answer. It will create the socket transports and * use the #StunTimer usage to send the request and handle the response. * Returns: A #StunUsageBindReturn. * Possible return values are #STUN_USAGE_BIND_RETURN_SUCCESS, * #STUN_USAGE_BIND_RETURN_ERROR and #STUN_USAGE_BIND_RETURN_TIMEOUT */ StunUsageBindReturn stun_usage_bind_run (const struct sockaddr *srv, socklen_t srvlen, struct sockaddr_storage *addr, socklen_t *addrlen); # ifdef __cplusplus } # endif #endif libnice-0.1.14/stun/usages/bind.c0000664000076400007640000003423013070470656013507 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef _WIN32 #include #include #include "win32_common.h" #define close closesocket #else #include #include #include #include #include #include #include #include #include #endif #ifdef HAVE_POLL # include #endif #include "bind.h" #include "stun/stunagent.h" #include #include #include #include #include #include "timer.h" #ifndef SOL_IP # define SOL_IP IPPROTO_IP #endif #ifndef SOL_IPV6 # define SOL_IPV6 IPPROTO_IPV6 #endif /** Non-blocking mode STUN binding discovery */ size_t stun_usage_bind_create (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len) { stun_agent_init_request (agent, msg, buffer, buffer_len, STUN_BINDING); return stun_agent_finish_message (agent, msg, NULL, 0); } StunUsageBindReturn stun_usage_bind_process (StunMessage *msg, struct sockaddr *addr, socklen_t *addrlen, struct sockaddr *alternate_server, socklen_t *alternate_server_len) { int code = -1; StunMessageReturn val; union { struct sockaddr *sa; struct sockaddr_storage *sas; } sa; sa.sa = addr; if (stun_message_get_method (msg) != STUN_BINDING) return STUN_USAGE_BIND_RETURN_INVALID; switch (stun_message_get_class (msg)) { case STUN_REQUEST: case STUN_INDICATION: return STUN_USAGE_BIND_RETURN_INVALID; case STUN_RESPONSE: break; case STUN_ERROR: if (stun_message_find_error (msg, &code) != STUN_MESSAGE_RETURN_SUCCESS) { /* missing ERROR-CODE: ignore message */ return STUN_USAGE_BIND_RETURN_INVALID; } /* NOTE: currently we ignore unauthenticated messages if the context * is authenticated, for security reasons. */ stun_debug (" STUN error message received (code: %d)", code); /* ALTERNATE-SERVER mechanism */ if ((code / 100) == 3) { union { struct sockaddr *sa; struct sockaddr_storage *sas; } alternate_sa; alternate_sa.sa = alternate_server; if (alternate_server && alternate_server_len) { if (stun_message_find_addr (msg, STUN_ATTRIBUTE_ALTERNATE_SERVER, alternate_sa.sas, alternate_server_len) != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" Unexpectedly missing ALTERNATE-SERVER attribute"); return STUN_USAGE_BIND_RETURN_ERROR; } } else { if (!stun_message_has_attribute (msg, STUN_ATTRIBUTE_ALTERNATE_SERVER)) { stun_debug (" Unexpectedly missing ALTERNATE-SERVER attribute"); return STUN_USAGE_BIND_RETURN_ERROR; } } stun_debug ("Found alternate server"); return STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER; } return STUN_USAGE_BIND_RETURN_ERROR; default: /* Fall through. */ break; } stun_debug ("Received %u-bytes STUN message", stun_message_length (msg)); val = stun_message_find_xor_addr (msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, sa.sas, addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No XOR-MAPPED-ADDRESS: %d", val); val = stun_message_find_addr (msg, STUN_ATTRIBUTE_MAPPED_ADDRESS, sa.sas, addrlen); if (val != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug (" No MAPPED-ADDRESS: %d", val); return STUN_USAGE_BIND_RETURN_ERROR; } } stun_debug (" Mapped address found!"); return STUN_USAGE_BIND_RETURN_SUCCESS; } /** Binding keep-alive (Binding discovery indication!) */ size_t stun_usage_bind_keepalive (StunAgent *agent, StunMessage *msg, uint8_t *buf, size_t len) { stun_agent_init_indication (agent, msg, buf, len, STUN_BINDING); return stun_agent_finish_message (agent, msg, NULL, 0); } typedef struct stun_trans_s { int fd; int own_fd; socklen_t dstlen; struct sockaddr_storage dst; } StunTransport; typedef enum { STUN_USAGE_TRANS_RETURN_SUCCESS, STUN_USAGE_TRANS_RETURN_ERROR, STUN_USAGE_TRANS_RETURN_RETRY, STUN_USAGE_TRANS_RETURN_INVALID_ADDRESS, STUN_USAGE_TRANS_RETURN_UNSUPPORTED, } StunUsageTransReturn; static StunUsageTransReturn stun_trans_init (StunTransport *tr, int fd, const struct sockaddr *srv, socklen_t srvlen) { assert (fd != -1); if ((size_t) srvlen > sizeof (tr->dst)) return STUN_USAGE_TRANS_RETURN_INVALID_ADDRESS; tr->own_fd = -1; tr->fd = fd; tr->dstlen = srvlen; memcpy (&tr->dst, srv, srvlen); return STUN_USAGE_TRANS_RETURN_SUCCESS; } /* * Creates and connects a socket. This is useful when a socket is to be used * for multiple consecutive transactions (e.g. TURN). */ static int stun_socket (int family, int type, int proto) { #ifdef _WIN32 unsigned long set_nonblock=1; #endif int fd = socket (family, type, proto); if (fd == -1) return -1; #ifdef FD_CLOEXEC fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC); #endif #ifdef O_NONBLOCK fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK); #elif defined _WIN32 ioctlsocket(fd, FIONBIO, &set_nonblock); #endif #ifdef MSG_ERRQUEUE if (type == SOCK_DGRAM) { /* Linux specifics for ICMP errors on non-connected sockets */ int yes = 1; switch (family) { case AF_INET: setsockopt (fd, SOL_IP, IP_RECVERR, &yes, sizeof (yes)); break; case AF_INET6: setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &yes, sizeof (yes)); break; default: /* Nothing to do. */ break; } } #endif return fd; } static StunUsageTransReturn stun_trans_create (StunTransport *tr, int type, int proto, const struct sockaddr *srv, socklen_t srvlen) { StunUsageTransReturn val = STUN_USAGE_TRANS_RETURN_ERROR; int fd; if ((size_t) srvlen < sizeof(*srv)) return STUN_USAGE_TRANS_RETURN_INVALID_ADDRESS; fd = stun_socket (srv->sa_family, type, proto); if (fd == -1) return STUN_USAGE_TRANS_RETURN_ERROR; if (type != SOCK_DGRAM) { if (connect (fd, srv, srvlen) && #ifdef _WIN32 (WSAGetLastError () != WSAEINPROGRESS)) { #else (errno != EINPROGRESS)) { #endif goto error; } val = stun_trans_init (tr, fd, NULL, 0); } else { val = stun_trans_init (tr, fd, srv, srvlen); } if (val) goto error; tr->own_fd = tr->fd; return STUN_USAGE_TRANS_RETURN_SUCCESS; error: close (fd); return val; } static void stun_trans_deinit (StunTransport *tr) { int saved = errno; assert (tr->fd != -1); if (tr->own_fd != -1) close (tr->own_fd); tr->own_fd = -1; tr->fd = -1; errno = saved; } #ifndef MSG_DONTWAIT # define MSG_DONTWAIT 0 #endif #ifndef MSG_NOSIGNAL # define MSG_NOSIGNAL 0 #endif static int stun_err_dequeue (int fd) { #ifdef MSG_ERRQUEUE struct msghdr hdr; int saved_errno = errno, ret; memset (&hdr, 0, sizeof (hdr)); ret = (recvmsg (fd, &hdr, MSG_ERRQUEUE) >= 0); errno = saved_errno; return ret; #else (void) fd; return 0; #endif } static ssize_t stun_trans_sendto (StunTransport *tr, const uint8_t *buf, size_t len, const struct sockaddr *dst, socklen_t dstlen) { static const int flags = MSG_DONTWAIT | MSG_NOSIGNAL; ssize_t val; do { if (dstlen > 0) val = sendto (tr->fd, (void *)buf, len, flags, dst, dstlen); else val = send (tr->fd, (void *)buf, len, flags); } while ((val == -1) && stun_err_dequeue (tr->fd)); return val; } static ssize_t stun_trans_recvfrom (StunTransport *tr, uint8_t *buf, size_t maxlen, struct sockaddr_storage * dst, socklen_t * dstlen) { static const int flags = MSG_DONTWAIT | MSG_NOSIGNAL; ssize_t val; if (dstlen != NULL) val = recvfrom (tr->fd, (void *)buf, maxlen, flags, (struct sockaddr *) dst, dstlen); else val = recv (tr->fd, (void *)buf, maxlen, flags); if (val == -1) stun_err_dequeue (tr->fd); return val; } static ssize_t stun_trans_send (StunTransport *tr, const uint8_t *buf, size_t len) { struct sockaddr *conv; conv = (struct sockaddr *) &tr->dst; return stun_trans_sendto (tr, buf, len, conv, tr->dstlen); } static ssize_t stun_trans_recv (StunTransport *tr, uint8_t *buf, size_t maxlen) { return stun_trans_recvfrom (tr, buf, maxlen, NULL, NULL); } #ifdef HAVE_POLL static int stun_trans_fd (const StunTransport *tr) { assert (tr != NULL); return tr->fd; } #endif /* * Waits for a response or timeout to occur. * * @return ETIMEDOUT if the transaction has timed out, or 0 if an incoming * message needs to be processed. */ static StunUsageTransReturn stun_trans_poll (StunTransport *tr, unsigned int delay) { #ifdef HAVE_POLL struct pollfd ufd; memset (&ufd, 0, sizeof (ufd)); ufd.fd = stun_trans_fd (tr); ufd.events |= POLLIN; if (poll (&ufd, 1, delay) <= 0) { return STUN_USAGE_TRANS_RETURN_RETRY; } return STUN_USAGE_TRANS_RETURN_SUCCESS; #else (void)tr; return STUN_USAGE_TRANS_RETURN_UNSUPPORTED; #endif } /** Blocking mode STUN binding discovery */ StunUsageBindReturn stun_usage_bind_run (const struct sockaddr *srv, socklen_t srvlen, struct sockaddr_storage *addr, socklen_t *addrlen) { StunTimer timer; StunTransport trans; StunAgent agent; StunMessage req; uint8_t req_buf[STUN_MAX_MESSAGE_SIZE]; StunMessage msg; uint8_t buf[STUN_MAX_MESSAGE_SIZE]; StunValidationStatus valid; size_t len; StunUsageTransReturn ret; int val; struct sockaddr_storage alternate_server; socklen_t alternate_server_len = sizeof (alternate_server); StunUsageBindReturn bind_ret; stun_agent_init (&agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, 0); len = stun_usage_bind_create (&agent, &req, req_buf, sizeof(req_buf)); ret = stun_trans_create (&trans, SOCK_DGRAM, 0, srv, srvlen); if (ret != STUN_USAGE_TRANS_RETURN_SUCCESS) { stun_debug ("STUN transaction failed: couldn't create transport."); return STUN_USAGE_BIND_RETURN_ERROR; } val = stun_trans_send (&trans, req_buf, len); if (val < -1) { stun_debug ("STUN transaction failed: couldn't send request."); return STUN_USAGE_BIND_RETURN_ERROR; } stun_timer_start (&timer, STUN_TIMER_DEFAULT_TIMEOUT, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); stun_debug ("STUN transaction started (timeout %dms).", stun_timer_remainder (&timer)); do { for (;;) { unsigned delay = stun_timer_remainder (&timer); ret = stun_trans_poll (&trans, delay); if (ret == STUN_USAGE_TRANS_RETURN_RETRY) { switch (stun_timer_refresh (&timer)) { case STUN_USAGE_TIMER_RETURN_TIMEOUT: stun_debug ("STUN transaction failed: time out."); return STUN_USAGE_BIND_RETURN_TIMEOUT; // fatal error! case STUN_USAGE_TIMER_RETURN_RETRANSMIT: stun_debug ("STUN transaction retransmitted (timeout %dms).", stun_timer_remainder (&timer)); val = stun_trans_send (&trans, req_buf, len); if (val < -1) { stun_debug ("STUN transaction failed: couldn't resend request."); return STUN_USAGE_BIND_RETURN_ERROR; } continue; case STUN_USAGE_TIMER_RETURN_SUCCESS: default: /* Fall through. */ break; } } val = stun_trans_recv (&trans, buf, sizeof (buf)); if (val >= 0) { break; } } valid = stun_agent_validate (&agent, &msg, buf, val, NULL, NULL); if (valid == STUN_VALIDATION_UNKNOWN_ATTRIBUTE) return STUN_USAGE_BIND_RETURN_ERROR; if (valid != STUN_VALIDATION_SUCCESS) { ret = STUN_USAGE_TRANS_RETURN_RETRY; } else { bind_ret = stun_usage_bind_process (&msg, (struct sockaddr *) addr, addrlen, (struct sockaddr *) &alternate_server, &alternate_server_len); if (bind_ret == STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER) { stun_trans_deinit (&trans); ret = stun_trans_create (&trans, SOCK_DGRAM, 0, (struct sockaddr *) &alternate_server, alternate_server_len); if (ret != STUN_USAGE_TRANS_RETURN_SUCCESS) { return STUN_USAGE_BIND_RETURN_ERROR; } val = stun_trans_send (&trans, req_buf, len); if (val < -1) return STUN_USAGE_BIND_RETURN_ERROR; stun_timer_start (&timer, STUN_TIMER_DEFAULT_TIMEOUT, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); ret = STUN_USAGE_TRANS_RETURN_RETRY; } else if (bind_ret == STUN_USAGE_BIND_RETURN_INVALID) { ret = STUN_USAGE_TRANS_RETURN_RETRY; } else { break; } } } while (ret == STUN_USAGE_TRANS_RETURN_RETRY); return bind_ret; } libnice-0.1.14/stun/usages/turn.h0000664000076400007640000002720012520743534013564 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef STUN_TURN_H # define STUN_TURN_H 1 /** * SECTION:turn * @short_description: TURN Allocation Usage * @include: stun/usages/turn.h * @stability: Stable * * The STUN TURN usage allows for easily creating and parsing STUN Allocate * requests and responses used for TURN. The API allows you to create a new * allocation or refresh an existing one as well as to parse a response to * an allocate or refresh request. */ #ifdef _WIN32 # include "../win32_common.h" #else # include # include #endif #ifdef _WIN32 #include #else #include #include #endif # include "stun/stunagent.h" # ifdef __cplusplus extern "C" { # endif /** * StunUsageTurnRequestPorts: * @STUN_USAGE_TURN_REQUEST_PORT_NORMAL: Request a normal port * @STUN_USAGE_TURN_REQUEST_PORT_EVEN: Request an even port * @STUN_USAGE_TURN_REQUEST_PORT_EVEN_AND_RESERVE: Request an even port and * reserve the next higher port * * This enum is used to specify which port configuration you want when creating * a new Allocation */ typedef enum { STUN_USAGE_TURN_REQUEST_PORT_NORMAL = 0, STUN_USAGE_TURN_REQUEST_PORT_EVEN = 1, STUN_USAGE_TURN_REQUEST_PORT_EVEN_AND_RESERVE = 2 } StunUsageTurnRequestPorts; /** * StunUsageTurnCompatibility: * @STUN_USAGE_TURN_COMPATIBILITY_DRAFT9: Use the specification compatible with * TURN Draft 09 * @STUN_USAGE_TURN_COMPATIBILITY_GOOGLE: Use the specification compatible with * Google Talk's relay server * @STUN_USAGE_TURN_COMPATIBILITY_MSN: Use the specification compatible with * MSN TURN servers * @STUN_USAGE_TURN_COMPATIBILITY_OC2007: Use the specification compatible with * Microsoft Office Communicator 2007 * @STUN_USAGE_TURN_COMPATIBILITY_RFC5766: Use the specification compatible with * RFC 5766 (the final, canonical TURN standard) * * Specifies which TURN specification compatibility to use */ typedef enum { STUN_USAGE_TURN_COMPATIBILITY_DRAFT9, STUN_USAGE_TURN_COMPATIBILITY_GOOGLE, STUN_USAGE_TURN_COMPATIBILITY_MSN, STUN_USAGE_TURN_COMPATIBILITY_OC2007, STUN_USAGE_TURN_COMPATIBILITY_RFC5766, } StunUsageTurnCompatibility; /** * StunUsageTurnReturn: * @STUN_USAGE_TURN_RETURN_RELAY_SUCCESS: The response was successful and a relay * address is provided * @STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS: The response was successful and a * relay address as well as a mapped address are provided * @STUN_USAGE_TURN_RETURN_ERROR: The response resulted in an error * @STUN_USAGE_TURN_RETURN_INVALID: The response is not a valid response * @STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER: The server requests the message * to be sent to an alternate server * * Return value of stun_usage_turn_process() and * stun_usage_turn_refresh_process() which allows you to see what status the * function call returned. */ typedef enum { STUN_USAGE_TURN_RETURN_RELAY_SUCCESS, STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS, STUN_USAGE_TURN_RETURN_ERROR, STUN_USAGE_TURN_RETURN_INVALID, STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER, } StunUsageTurnReturn; /** * stun_usage_turn_create: * @agent: The #StunAgent to use to build the request * @msg: The #StunMessage to build * @buffer: The buffer to use for creating the #StunMessage * @buffer_len: The size of the @buffer * @previous_response: If this is the first request you are sending, set this * argument to NULL, if it's a subsequent request you are building, then set this * argument to the response you have received. This argument is used for building * long term credentials (using the REALM and NONCE attributes) as well as for * getting the RESERVATION-TOKEN attribute when you previously requested an * allocation which reserved two ports * @request_ports: Specify how you want to request the allocated port(s). * This is only used if the compatibility is set to * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 * See #StunUsageTurnRequestPorts * @bandwidth: The bandwidth to request from the server for the allocation. If * this value is negative, then no BANDWIDTH attribute is added to the request. * This is only used if the compatibility is set to * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 * @lifetime: The lifetime of the allocation to request from the server. If * this value is negative, then no LIFETIME attribute is added to the request. * This is only used if the compatibility is set to * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 * @username: The username to use in the request * @username_len: The length of @username * @password: The key to use for building the MESSAGE-INTEGRITY * @password_len: The length of @password * @compatibility: The compatibility mode to use for building the Allocation * request * * Create a new TURN Allocation request * Returns: The length of the message to send */ size_t stun_usage_turn_create (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMessage *previous_response, StunUsageTurnRequestPorts request_ports, int32_t bandwidth, int32_t lifetime, uint8_t *username, size_t username_len, uint8_t *password, size_t password_len, StunUsageTurnCompatibility compatibility); /** * stun_usage_turn_create_refresh: * @agent: The #StunAgent to use to build the request * @msg: The #StunMessage to build * @buffer: The buffer to use for creating the #StunMessage * @buffer_len: The size of the @buffer * @previous_response: If this is the first request you are sending, set this * argument to NULL, if it's a subsequent request you are building, then set this * argument to the response you have received. This argument is used for building * long term credentials (using the REALM and NONCE attributes) * @lifetime: The lifetime of the allocation to request from the server. If * this value is negative, then no LIFETIME attribute is added to the request. * This is only used if the compatibility is set to * #STUN_USAGE_TURN_COMPATIBILITY_DRAFT9 * @username: The username to use in the request * @username_len: The length of @username * @password: The key to use for building the MESSAGE-INTEGRITY * @password_len: The length of @password * @compatibility: The compatibility mode to use for building the Allocation * request * * Create a new TURN Refresh request * Returns: The length of the message to send */ size_t stun_usage_turn_create_refresh (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMessage *previous_response, int32_t lifetime, uint8_t *username, size_t username_len, uint8_t *password, size_t password_len, StunUsageTurnCompatibility compatibility); /** * stun_usage_turn_create_permission: * @agent: The #StunAgent to use to build the request * @msg: The #StunMessage to build * @buffer: The buffer to use for creating the #StunMessage * @buffer_len: The size of the @buffer * @username: The username to use in the request * @username_len: The length of @username * @password: The key to use for building the MESSAGE-INTEGRITY * @password_len: The length of @password * @realm: The realm identifier to use in the request * @realm_len: The length of @realm * @nonce: Unique and securely random nonce to use in the request * @nonce_len: The length of @nonce * @peer: Server-reflexive host address to request permission for * @compatibility: The compatibility mode to use for building the * CreatePermission request * * Create a new TURN CreatePermission request * * Returns: The length of the message to send */ size_t stun_usage_turn_create_permission (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, uint8_t *username, size_t username_len, uint8_t *password, size_t password_len, uint8_t *realm, size_t realm_len, uint8_t *nonce, size_t nonce_len, struct sockaddr_storage *peer, StunUsageTurnCompatibility compatibility); /** * stun_usage_turn_process: * @msg: The message containing the response * @relay_addr: A pointer to a #sockaddr structure to fill with the relay address * that the TURN server allocated for us * @relay_addrlen: The length of @relay_addr * @addr: A pointer to a #sockaddr structure to fill with the mapped address * that the STUN response contains. * This argument will only be filled if the return value * of the function is #STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS * @addrlen: The length of @addr * @alternate_server: A pointer to a #sockaddr structure to fill with the * address of an alternate server to which we should send our new STUN * Allocate request, in case the currently used TURN server is requesting the use * of an alternate server. This argument will only be filled if the return value * of the function is #STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER * @alternate_server_len: The length of @alternate_server * @bandwidth: A pointer to fill with the bandwidth the TURN server allocated us * @lifetime: A pointer to fill with the lifetime of the allocation * @compatibility: The compatibility mode to use for processing the Allocation * response * * Process a TURN Allocate response and extract the necessary information from * the message * Returns: A #StunUsageTurnReturn value */ StunUsageTurnReturn stun_usage_turn_process (StunMessage *msg, struct sockaddr_storage *relay_addr, socklen_t *relay_addrlen, struct sockaddr_storage *addr, socklen_t *addrlen, struct sockaddr_storage *alternate_server, socklen_t *alternate_server_len, uint32_t *bandwidth, uint32_t *lifetime, StunUsageTurnCompatibility compatibility); /** * stun_usage_turn_refresh_process: * @msg: The message containing the response * @lifetime: A pointer to fill with the lifetime of the allocation * @compatibility: The compatibility mode to use for processing the Refresh * response * * Process a TURN Refresh response and extract the necessary information from * the message * Returns: A #StunUsageTurnReturn value. A #STUN_USAGE_TURN_RETURN_RELAY_SUCCESS * means the Refresh was successful, but no relay address is given (kept the same * as for the original allocation) */ StunUsageTurnReturn stun_usage_turn_refresh_process (StunMessage *msg, uint32_t *lifetime, StunUsageTurnCompatibility compatibility); # ifdef __cplusplus } # endif #endif libnice-0.1.14/stun/usages/timer.h0000664000076400007640000001606712733070261013721 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef STUN_TIMER_H # define STUN_TIMER_H 1 /** * SECTION:timer * @short_description: STUN timer Usage * @include: stun/usages/timer.h * @stability: Stable * * The STUN timer usage is a set of helpful utility functions that allows you * to easily track when a STUN message should be retransmitted or considered * as timed out. * * Simple example on how to use the timer usage StunTimer timer; unsigned remainder; StunUsageTimerReturn ret; // Build the message, etc.. ... // Send the message and start the timer send(socket, request, sizeof(request)); stun_timer_start(&timer, STUN_TIMER_DEFAULT_TIMEOUT, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); // Loop until we get the response for (;;) { remainder = stun_timer_remainder(&timer); // Poll the socket until data is received or the timer expires if (poll (&pollfd, 1, delay) <= 0) { // Time out and no response was received ret = stun_timer_refresh (&timer); if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) { // Transaction timed out break; } else if (ret == STUN_USAGE_TIMER_RETURN_RETRANSMIT) { // A retransmission is necessary send(socket, request, sizeof(request)); continue; } else if (ret == STUN_USAGE_TIMER_RETURN_SUCCESS) { // The refresh succeeded and nothing has to be done, continue polling continue; } } else { // We received a response, read it recv(socket, response, sizeof(response)); break; } } // Check if the transaction timed out or not if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) { // do whatever needs to be done in that case } else { // Parse the response } */ #ifdef _WIN32 #include #else # include # include # include #endif /** * StunTimer: * * An opaque structure representing a STUN transaction retransmission timer */ typedef struct stun_timer_s StunTimer; struct stun_timer_s { struct timeval deadline; unsigned delay; unsigned retransmissions; unsigned max_retransmissions; }; /** * STUN_TIMER_DEFAULT_TIMEOUT: * * The default intial timeout to use for the timer * RFC recommendds 500, but it's ridiculous, 50ms is known to work in most * cases as it is also what is used by SIP style VoIP when sending A-Law and * mu-Law audio, so 200ms should be hyper safe. */ #define STUN_TIMER_DEFAULT_TIMEOUT 200 /** * STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS: * * The default maximum retransmissions allowed before a timer decides to timeout */ #define STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS 7 /** * STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT: * * The default intial timeout to use for a reliable timer */ #define STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT 7900 /** * StunUsageTimerReturn: * @STUN_USAGE_TIMER_RETURN_SUCCESS: The timer was refreshed successfully * and there is nothing to be done * @STUN_USAGE_TIMER_RETURN_RETRANSMIT: The timer expired and the message * should be retransmitted now. * @STUN_USAGE_TIMER_RETURN_TIMEOUT: The timer expired as well as all the * retransmissions, the transaction timed out * * Return value of stun_usage_timer_refresh() which provides you with status * information on the timer. */ typedef enum { STUN_USAGE_TIMER_RETURN_SUCCESS, STUN_USAGE_TIMER_RETURN_RETRANSMIT, STUN_USAGE_TIMER_RETURN_TIMEOUT } StunUsageTimerReturn; # ifdef __cplusplus extern "C" { # endif /** * stun_timer_start: * @timer: The #StunTimer to start * @initial_timeout: The initial timeout to use before the first retransmission * @max_retransmissions: The maximum number of transmissions before the * #StunTimer times out * * Starts a STUN transaction retransmission timer. * This should be called as soon as you send the message for the first time on * a UDP socket. * The timeout before the next retransmission is set to @initial_timeout, then * each time a packet is retransmited, that timeout will be doubled, until the * @max_retransmissions retransmissions limit is reached. * * To determine the total timeout value, one can use the following equation : total_timeout = initial_timeout * (2^(max_retransmissions + 1) - 1); * * * See also: #STUN_TIMER_DEFAULT_TIMEOUT * * See also: #STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS */ void stun_timer_start (StunTimer *timer, unsigned int initial_timeout, unsigned int max_retransmissions); /** * stun_timer_start_reliable: * @timer: The #StunTimer to start * @initial_timeout: The initial timeout to use before the first retransmission * * Starts a STUN transaction retransmission timer for a reliable transport. * This should be called as soon as you send the message for the first time on * a TCP socket */ void stun_timer_start_reliable (StunTimer *timer, unsigned int initial_timeout); /** * stun_timer_refresh: * @timer: The #StunTimer to refresh * * Updates a STUN transaction retransmission timer. * Returns: A #StunUsageTimerReturn telling you what to do next */ StunUsageTimerReturn stun_timer_refresh (StunTimer *timer); /** * stun_timer_remainder: * @timer: The #StunTimer to query * * Query the timer on the time left before the next refresh should be done * Returns: The time remaining for the timer to expire in milliseconds */ unsigned stun_timer_remainder (const StunTimer *timer); # ifdef __cplusplus } # endif #endif /* !STUN_TIMER_H */ libnice-0.1.14/stun/usages/ice.h0000664000076400007640000002231513004222453013324 00000000000000 /* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef STUN_CONNCHECK_H # define STUN_CONNCHECK_H 1 /** * SECTION:ice * @short_description: STUN ICE Usage * @include: stun/usages/ice.h * @stability: Stable * * The STUN ICE usage allows for easily creating and parsing STUN Binding * requests and responses used for ICE connectivity checks. The API allows you * to create a connectivity check message, parse a response or create a reply * to an incoming connectivity check request. */ # include "stun/stunagent.h" # ifdef __cplusplus extern "C" { # endif /** * StunUsageIceCompatibility: * @STUN_USAGE_ICE_COMPATIBILITY_RFC5245: The ICE compatibility with RFC 5245 * @STUN_USAGE_ICE_COMPATIBILITY_GOOGLE: The ICE compatibility with Google's * implementation of ICE * @STUN_USAGE_ICE_COMPATIBILITY_MSN: The ICE compatibility with MSN's * implementation of ICE * @STUN_USAGE_ICE_COMPATIBILITY_MSICE2: The ICE compatibility with [MS-ICE2] * specification * @STUN_USAGE_ICE_COMPATIBILITY_DRAFT19: The ICE compatibility with draft 19 * @STUN_USAGE_ICE_COMPATIBILITY_WLM2009: An alias * for @STUN_USAGE_ICE_COMPATIBILITY_MSICE2 * * This enum defines which compatibility modes this ICE usage can use * * @STUN_USAGE_ICE_COMPATIBILITY_DRAFT19 and * @STUN_USAGE_ICE_COMPATIBILITY_WLM2009 are deprecated and should not be used * in newly-written code. They are kept for compatibility reasons and represent * the same compatibilities as @STUN_USAGE_ICE_COMPATIBILITY_RFC5245 and * @STUN_USAGE_ICE_COMPATIBILITY_MSICE2 respectively. */ typedef enum { STUN_USAGE_ICE_COMPATIBILITY_RFC5245, STUN_USAGE_ICE_COMPATIBILITY_GOOGLE, STUN_USAGE_ICE_COMPATIBILITY_MSN, STUN_USAGE_ICE_COMPATIBILITY_MSICE2, STUN_USAGE_ICE_COMPATIBILITY_DRAFT19 = STUN_USAGE_ICE_COMPATIBILITY_RFC5245, STUN_USAGE_ICE_COMPATIBILITY_WLM2009 = STUN_USAGE_ICE_COMPATIBILITY_MSICE2, } StunUsageIceCompatibility; /** * StunUsageIceReturn: * @STUN_USAGE_ICE_RETURN_SUCCESS: The function succeeded * @STUN_USAGE_ICE_RETURN_ERROR: There was an unspecified error * @STUN_USAGE_ICE_RETURN_INVALID: The message is invalid for processing * @STUN_USAGE_ICE_RETURN_ROLE_CONFLICT: A role conflict was detected * @STUN_USAGE_ICE_RETURN_INVALID_REQUEST: The message is an not a request * @STUN_USAGE_ICE_RETURN_INVALID_METHOD: The method of the request is invalid * @STUN_USAGE_ICE_RETURN_MEMORY_ERROR: The buffer size is too small to hold * the STUN reply * @STUN_USAGE_ICE_RETURN_INVALID_ADDRESS: The mapped address argument has * an invalid address family * @STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS: The response is valid but no * MAPPED-ADDRESS or XOR-MAPPED-ADDRESS attribute was found * * Return value of stun_usage_ice_conncheck_process() and * stun_usage_ice_conncheck_create_reply() which allows you to see what * status the function call returned. */ typedef enum { STUN_USAGE_ICE_RETURN_SUCCESS, STUN_USAGE_ICE_RETURN_ERROR, STUN_USAGE_ICE_RETURN_INVALID, STUN_USAGE_ICE_RETURN_ROLE_CONFLICT, STUN_USAGE_ICE_RETURN_INVALID_REQUEST, STUN_USAGE_ICE_RETURN_INVALID_METHOD, STUN_USAGE_ICE_RETURN_MEMORY_ERROR, STUN_USAGE_ICE_RETURN_INVALID_ADDRESS, STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS, } StunUsageIceReturn; /** * stun_usage_ice_conncheck_create: * @agent: The #StunAgent to use to build the request * @msg: The #StunMessage to build * @buffer: The buffer to use for creating the #StunMessage * @buffer_len: The size of the @buffer * @username: The username to use in the request * @username_len: The length of @username * @password: The key to use for building the MESSAGE-INTEGRITY * @password_len: The length of @password * @cand_use: Set to %TRUE to append the USE-CANDIDATE flag to the request * @controlling: Set to %TRUE if you are the controlling agent or set to * %FALSE if you are the controlled agent. * @priority: The value of the PRIORITY attribute * @tie: The value of the tie-breaker to put in the ICE-CONTROLLED or * ICE-CONTROLLING attribute * @candidate_identifier: The foundation value to put in the * CANDIDATE-IDENTIFIER attribute * @compatibility: The compatibility mode to use for building the conncheck * request * * Builds an ICE connectivity check STUN message. * If the compatibility is not #STUN_USAGE_ICE_COMPATIBILITY_RFC5245, the * @cand_use, @controlling, @priority and @tie arguments are not used. * If the compatibility is not #STUN_USAGE_ICE_COMPATIBILITY_MSICE2, the * @candidate_identifier argument is not used. * Returns: The length of the message built. */ size_t stun_usage_ice_conncheck_create (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const uint8_t *username, const size_t username_len, const uint8_t *password, const size_t password_len, bool cand_use, bool controlling, uint32_t priority, uint64_t tie, const char *candidate_identifier, StunUsageIceCompatibility compatibility); /** * stun_usage_ice_conncheck_process: * @msg: The #StunMessage to process * @addr: A pointer to a #sockaddr structure to fill with the mapped address * that the STUN connectivity check response contains * @addrlen: The length of @addr * @compatibility: The compatibility mode to use for processing the conncheck * response * * Process an ICE connectivity check STUN message and retreive the * mapped address from the message * See also stun_usage_ice_conncheck_priority() and * stun_usage_ice_conncheck_use_candidate() * Returns: A #StunUsageIceReturn value */ StunUsageIceReturn stun_usage_ice_conncheck_process (StunMessage *msg, struct sockaddr_storage *addr, socklen_t *addrlen, StunUsageIceCompatibility compatibility); /** * stun_usage_ice_conncheck_create_reply: * @agent: The #StunAgent to use to build the response * @req: The original STUN request to reply to * @msg: The #StunMessage to build * @buf: The buffer to use for creating the #StunMessage * @plen: A pointer containing the size of the @buffer on input. * Will contain the length of the message built on output. * @src: A pointer to a #sockaddr structure containing the source address from * which the request was received. Will be used as the mapped address in the * response * @srclen: The length of @addr * @control: Set to %TRUE if you are the controlling agent or set to * %FALSE if you are the controlled agent. * @tie: The value of the tie-breaker to put in the ICE-CONTROLLED or * ICE-CONTROLLING attribute * @compatibility: The compatibility mode to use for building the conncheck * response * * Tries to parse a STUN connectivity check request and builds a * response accordingly. In case of error, the @msg is filled with the appropriate error response to be sent and the value of @plen is set to the size of that message. If @plen has a size of 0, then no error response should be sent. * Returns: A #StunUsageIceReturn value */ StunUsageIceReturn stun_usage_ice_conncheck_create_reply (StunAgent *agent, StunMessage *req, StunMessage *msg, uint8_t *buf, size_t *plen, const struct sockaddr_storage *src, socklen_t srclen, bool *control, uint64_t tie, StunUsageIceCompatibility compatibility); /** * stun_usage_ice_conncheck_priority: * @msg: The #StunMessage to parse * * Extracts the priority from a STUN message. * Returns: host byte order priority, or 0 if not specified. */ uint32_t stun_usage_ice_conncheck_priority (const StunMessage *msg); /** * stun_usage_ice_conncheck_use_candidate: * @msg: The #StunMessage to parse * * Extracts the USE-CANDIDATE attribute flag from a STUN message. * Returns: %TRUE if the flag is set, %FALSE if not. */ bool stun_usage_ice_conncheck_use_candidate (const StunMessage *msg); # ifdef __cplusplus } # endif #endif libnice-0.1.14/stun/utils.c0000664000076400007640000000672312363772107012452 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Olivier Crete, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "utils.h" size_t stun_padding (size_t l) { return (4 - (l & 3)) & 3; } size_t stun_align (size_t l) { return (l + 3) & ~3; } uint16_t stun_getw (const uint8_t *ptr) { return ((ptr)[0] << 8) | ptr[1]; } void *stun_setw (uint8_t *ptr, uint16_t value) { *ptr++ = value >> 8; *ptr++ = value & 0xff; return ptr; } void stun_set_type (uint8_t *h, StunClass c, StunMethod m) { /* assert (c < 4); */ /* assert (m < (1 << 12)); */ h[0] = (c >> 1) | ((m >> 6) & 0x3e); h[1] = ((c << 4) & 0x10) | ((m << 1) & 0xe0) | (m & 0x0f); /* assert (stun_getw (h) < (1 << 14)); */ /* assert (stun_get_class (h) == c); */ /* assert (stun_get_method (h) == m); */ } StunMessageReturn stun_xor_address (const StunMessage *msg, struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie) { union { struct sockaddr_storage *addr; struct sockaddr_in *in; struct sockaddr_in6 *in6; } addr_ptr; addr_ptr.addr = addr; switch (addr->ss_family) { case AF_INET: { struct sockaddr_in *ip4 = addr_ptr.in; if ((size_t) addrlen < sizeof (*ip4)) return STUN_MESSAGE_RETURN_INVALID; ip4->sin_port ^= htons (magic_cookie >> 16); ip4->sin_addr.s_addr ^= htonl (magic_cookie); return STUN_MESSAGE_RETURN_SUCCESS; } case AF_INET6: { struct sockaddr_in6 *ip6 = addr_ptr.in6; unsigned short i; if ((size_t) addrlen < sizeof (*ip6)) return STUN_MESSAGE_RETURN_INVALID; ip6->sin6_port ^= htons (magic_cookie >> 16); for (i = 0; i < 16; i++) ip6->sin6_addr.s6_addr[i] ^= msg->buffer[4 + i]; return STUN_MESSAGE_RETURN_SUCCESS; } default: return STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS; } } libnice-0.1.14/stun/tools/0000775000076400007640000000000013070512356012350 500000000000000libnice-0.1.14/stun/tools/Makefile.in0000664000076400007640000005457313070512350014345 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = stunbdc$(EXEEXT) stund$(EXEEXT) check_PROGRAMS = stund$(EXEEXT) @WINDOWS_TRUE@am__append_1 = -DWINVER=0x0501 # _WIN32_WINNT_WINXP @WINDOWS_TRUE@am__append_2 = -lws2_32 subdir = stun/tools ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_stunbdc_OBJECTS = stunbdc.$(OBJEXT) stunbdc_OBJECTS = $(am_stunbdc_OBJECTS) am__DEPENDENCIES_1 = stunbdc_DEPENDENCIES = $(top_builddir)/stun/libstun.la \ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_stund_OBJECTS = stund.$(OBJEXT) stund_OBJECTS = $(am_stund_OBJECTS) stund_DEPENDENCIES = $(top_builddir)/stun/libstun.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(stunbdc_SOURCES) $(stund_SOURCES) DIST_SOURCES = $(stunbdc_SOURCES) $(stund_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda AM_CFLAGS = -std=gnu99 $(LIBNICE_CFLAGS) $(am__append_1) AM_CPPFLAGS = -I$(top_srcdir) stund_SOURCES = stund.c stund.h stund_LDADD = $(top_builddir)/stun/libstun.la stunbdc_SOURCES = stunbdc.c stunbdc_LDADD = $(top_builddir)/stun/libstun.la $(am__append_2) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu stun/tools/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu stun/tools/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list stunbdc$(EXEEXT): $(stunbdc_OBJECTS) $(stunbdc_DEPENDENCIES) $(EXTRA_stunbdc_DEPENDENCIES) @rm -f stunbdc$(EXEEXT) $(AM_V_CCLD)$(LINK) $(stunbdc_OBJECTS) $(stunbdc_LDADD) $(LIBS) stund$(EXEEXT): $(stund_OBJECTS) $(stund_DEPENDENCIES) $(EXTRA_stund_DEPENDENCIES) @rm -f stund$(EXEEXT) $(AM_V_CCLD)$(LINK) $(stund_OBJECTS) $(stund_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stunbdc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stund.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/stun/tools/Makefile.am0000664000076400007640000000114212363772107014330 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. # include $(top_srcdir)/common.mk AM_CFLAGS = -std=gnu99 $(LIBNICE_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir) bin_PROGRAMS = stunbdc stund check_PROGRAMS = stund stund_SOURCES = stund.c stund.h stund_LDADD = $(top_builddir)/stun/libstun.la stunbdc_SOURCES = stunbdc.c stunbdc_LDADD = $(top_builddir)/stun/libstun.la if WINDOWS AM_CFLAGS += -DWINVER=0x0501 # _WIN32_WINNT_WINXP stunbdc_LDADD += -lws2_32 endif libnice-0.1.14/stun/tools/stund.h0000664000076400007640000000347011522161146013577 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef NICE_STUN_STUND_H # define NICE_STUN_STUND_H 1 int listen_socket (int fam, int type, int proto, unsigned port); ssize_t send_safe (int fd, const struct msghdr *msg); ssize_t recv_safe (int fd, struct msghdr *msg); #endif libnice-0.1.14/stun/tools/stund.c0000664000076400007640000001624212415560725013603 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef __sun #define _XPG4_2 1 #endif #ifndef _WIN32 #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef SOL_IP # define SOL_IP IPPROTO_IP #endif #ifndef SOL_IPV6 # define SOL_IPV6 IPPROTO_IPV6 #endif #ifndef IPV6_RECVPKTINFO # define IPV6_RECVPKTINFO IPV6_PKTINFO #endif /** Default port for STUN binding discovery */ #define IPPORT_STUN 3478 #include "stun/stunagent.h" #include "stund.h" static const uint16_t known_attributes[] = { 0 }; /* * Creates a listening socket */ int listen_socket (int fam, int type, int proto, unsigned int port) { int yes = 1; int fd = socket (fam, type, proto); union { struct sockaddr addr; struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_storage storage; } addr; if (fd == -1) { perror ("Error opening IP port"); return -1; } if (fd < 3) goto error; memset (&addr, 0, sizeof (addr)); addr.storage.ss_family = fam; #ifdef HAVE_SA_LEN addr.storage.ss_len = sizeof (addr); #endif switch (fam) { case AF_INET: addr.in.sin_port = htons (port); break; case AF_INET6: #ifdef IPV6_V6ONLY setsockopt (fd, SOL_IPV6, IPV6_V6ONLY, &yes, sizeof (yes)); #endif addr.in6.sin6_port = htons (port); break; default: assert (0); /* should never be reached */ } if (bind (fd, &addr.addr, sizeof (struct sockaddr))) { perror ("Error opening IP port"); goto error; } if ((type == SOCK_DGRAM) || (type == SOCK_RAW)) { switch (fam) { case AF_INET: #ifdef IP_RECVERR setsockopt (fd, SOL_IP, IP_RECVERR, &yes, sizeof (yes)); #endif break; case AF_INET6: #ifdef IPV6_RECVERR setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &yes, sizeof (yes)); #endif break; default: assert (0); /* should never be reached */ } } else { if (listen (fd, INT_MAX)) { perror ("Error opening IP port"); goto error; } } return fd; error: close (fd); return -1; } static int dgram_process (int sock, StunAgent *oldagent, StunAgent *newagent) { union { struct sockaddr_storage storage; struct sockaddr addr; } addr; socklen_t addr_len; uint8_t buf[STUN_MAX_MESSAGE_SIZE]; size_t buf_len = 0; size_t len = 0; StunMessage request; StunMessage response; StunValidationStatus validation; StunAgent *agent = NULL; addr_len = sizeof (struct sockaddr_in); len = recvfrom (sock, buf, sizeof(buf), 0, &addr.addr, &addr_len); if (len == (size_t)-1) return -1; validation = stun_agent_validate (newagent, &request, buf, len, NULL, 0); if (validation == STUN_VALIDATION_SUCCESS) { agent = newagent; } else { validation = stun_agent_validate (oldagent, &request, buf, len, NULL, 0); agent = oldagent; } /* Unknown attributes */ if (validation == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE) { buf_len = stun_agent_build_unknown_attributes_error (agent, &response, buf, sizeof (buf), &request); goto send_buf; } /* Mal-formatted packets */ if (validation != STUN_VALIDATION_SUCCESS || stun_message_get_class (&request) != STUN_REQUEST) { return -1; } switch (stun_message_get_method (&request)) { case STUN_BINDING: stun_agent_init_response (agent, &response, buf, sizeof (buf), &request); if (stun_message_has_cookie (&request)) stun_message_append_xor_addr (&response, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr.storage, addr_len); else stun_message_append_addr (&response, STUN_ATTRIBUTE_MAPPED_ADDRESS, &addr.addr, addr_len); break; case STUN_SHARED_SECRET: case STUN_ALLOCATE: case STUN_SEND: case STUN_CONNECT: case STUN_IND_SEND: case STUN_IND_DATA: case STUN_CREATEPERMISSION: case STUN_CHANNELBIND: default: if (!stun_agent_init_error (agent, &response, buf, sizeof (buf), &request, STUN_ERROR_BAD_REQUEST)) return -1; } buf_len = stun_agent_finish_message (agent, &response, NULL, 0); send_buf: len = sendto (sock, buf, buf_len, 0, &addr.addr, addr_len); return (len < buf_len) ? -1 : 0; } static int run (int family, int protocol, unsigned port) { StunAgent oldagent; StunAgent newagent; int sock = listen_socket (family, SOCK_DGRAM, protocol, port); if (sock == -1) return -1; stun_agent_init (&oldagent, known_attributes, STUN_COMPATIBILITY_RFC3489, 0); stun_agent_init (&newagent, known_attributes, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT); for (;;) dgram_process (sock, &oldagent, &newagent); } /* Pretty useless dummy signal handler... * But calling exit() is needed for gcov to work properly. */ static void exit_handler (int signum) { (void)signum; exit (0); } int main (int argc, char *argv[]) { int family = AF_INET; unsigned port = IPPORT_STUN; for (;;) { int c = getopt (argc, argv, "46"); if (c == EOF) break; switch (c) { default: case '4': family = AF_INET; break; case '6': family = AF_INET6; break; } } if (optind < argc) port = atoi (argv[optind++]); signal (SIGINT, exit_handler); signal (SIGTERM, exit_handler); return run (family, IPPROTO_UDP, port) ? EXIT_FAILURE : EXIT_SUCCESS; } #else int main (int argc, char **argv) { return 0; } #endif libnice-0.1.14/stun/tools/stunbdc.c0000664000076400007640000001166012363772107014110 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef _WIN32 # include #else # include # include #endif #include #include "stun/stunagent.h" #include "stun/usages/bind.h" #include #include #include #include #include static int ai_flags = 0; static void printaddr (const char *str, const struct sockaddr *addr, socklen_t addrlen) { char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV]; int val = getnameinfo (addr, addrlen, hostbuf, sizeof (hostbuf), servbuf, sizeof (servbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (val) printf ("%s: %s\n", str, gai_strerror (val)); else printf ("%s: %s port %s\n", str, hostbuf, servbuf); } static int run (int family, const char *hostname, const char *service) { struct addrinfo hints, *res; const struct addrinfo *ptr; int ret = -1; memset (&hints, 0, sizeof (hints)); hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = ai_flags; if (service == NULL) service = "3478"; ret = getaddrinfo (hostname, service, &hints, &res); if (ret) { fprintf (stderr, "%s (port %s): %s\n", hostname, service, gai_strerror (ret)); return -1; } for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { union { struct sockaddr_storage storage; struct sockaddr addr; } addr; socklen_t addrlen = sizeof (addr); StunUsageBindReturn val; printaddr ("Server address", ptr->ai_addr, ptr->ai_addrlen); val = stun_usage_bind_run (ptr->ai_addr, ptr->ai_addrlen, &addr.storage, &addrlen); if (val) fprintf (stderr, "%d\n", val); else { printaddr ("Mapped address", &addr.addr, addrlen); ret = 0; } } freeaddrinfo (res); return ret; } int main (int argc, char *argv[]) { static const struct option opts[] = { { "ipv4", no_argument, NULL, '4' }, { "ipv6", no_argument, NULL, '6' }, { "help", no_argument, NULL, 'h' }, { "numeric", no_argument, NULL, 'n' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; const char *server = NULL, *port = NULL; int family = AF_UNSPEC; for (;;) { int val = getopt_long (argc, argv, "46hnV", opts, NULL); if (val == EOF) break; switch (val) { case '4': family = AF_INET; break; case '6': family = AF_INET6; break; case 'h': printf ("Usage: %s [-4|-6] [port number]\n" "Performs STUN Binding Discovery\n" "\n" " -4, --ipv4 Force IP version 4\n" " -6, --ipv6 Force IP version 6\n" " -n, --numeric Server in numeric form\n" "\n", argv[0]); return 0; case 'n': ai_flags |= AI_NUMERICHOST; break; case 'V': printf ("stunbcd: STUN Binding Discovery client (%s v%s)\n", PACKAGE, VERSION); return 0; default: return 2; } } if (optind < argc) server = argv[optind++]; if (optind < argc) port = argv[optind++]; if (optind < argc) { fprintf (stderr, "%s: extra parameter `%s'\n", argv[0], argv[optind]); return 2; } return run (family, server, port) ? 1 : 0; } libnice-0.1.14/stun/stunhmac.h0000664000076400007640000000470711522161146013130 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _STUN_HMAC_H #define _STUN_HMAC_H #include "stunmessage.h" /* * Computes the MESSAGE-INTEGRITY hash of a STUN message. * @param msg pointer to the STUN message * @param len size of the message from header (inclusive) and up to * MESSAGE-INTEGRITY attribute (inclusive) * @param sha output buffer for SHA1 hash (20 bytes) * @param key HMAC key * @param keylen HMAC key bytes length * * @return fingerprint value in host byte order. */ void stun_sha1 (const uint8_t *msg, size_t len, size_t msg_len, uint8_t *sha, const void *key, size_t keylen, int padding); /* * SIP H(A1) computation */ void stun_hash_creds (const uint8_t *realm, size_t realm_len, const uint8_t *username, size_t username_len, const uint8_t *password, size_t password_len, unsigned char md5[16]); /* * Generates a pseudo-random secure STUN transaction ID. */ void stun_make_transid (StunTransactionId id); #endif /* _STUN_HMAC_H */ libnice-0.1.14/stun/stunagent.h0000664000076400007640000005206513004222455013314 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _STUN_AGENT_H #define _STUN_AGENT_H /** * SECTION:stunagent * @short_description: STUN agent for building and validating STUN messages * @include: stun/stunagent.h * @see_also: #StunMessage * @stability: Stable * * The STUN Agent allows you to create and validate STUN messages easily. * It's main purpose is to make sure the building and validation methods used * are compatible with the RFC you create it with. It also tracks the transaction * ids of the requests you send, so you can validate if a STUN response you * received should be processed by that agent or not. * */ #ifdef _WIN32 #include "win32_common.h" #else #include #include #endif #include /** * StunAgent: * * An opaque structure representing the STUN agent. */ typedef struct stun_agent_t StunAgent; #include "stunmessage.h" #include "debug.h" /** * StunCompatibility: * @STUN_COMPATIBILITY_RFC3489: Use the STUN specifications compatible with * RFC 3489 * @STUN_COMPATIBILITY_RFC5389: Use the STUN specifications compatible with * RFC 5389 * @STUN_COMPATIBILITY_MSICE2: Use the STUN specifications compatible with * [MS-ICE2] (a mix between RFC3489 and RFC5389) * @STUN_COMPATIBILITY_OC2007: Use the STUN specifications compatible with * Microsoft Office Communicator 2007 (basically RFC3489 with swapped * REALM and NONCE attribute hex IDs, attributes are not aligned) * @STUN_COMPATIBILITY_WLM2009: An alias for @STUN_COMPATIBILITY_MSICE2 * @STUN_COMPATIBILITY_LAST: Dummy last compatibility mode * * Enum that specifies the STUN compatibility mode of the #StunAgent * * @STUN_COMPATIBILITY_WLM2009 is deprecated and should not be used * in newly-written code. It is kept for compatibility reasons and represents * the same compatibility as @STUN_COMPATIBILITY_MSICE2. */ typedef enum { STUN_COMPATIBILITY_RFC3489, STUN_COMPATIBILITY_RFC5389, STUN_COMPATIBILITY_MSICE2, STUN_COMPATIBILITY_OC2007, STUN_COMPATIBILITY_WLM2009 = STUN_COMPATIBILITY_MSICE2, STUN_COMPATIBILITY_LAST = STUN_COMPATIBILITY_OC2007 } StunCompatibility; /** * StunValidationStatus: * @STUN_VALIDATION_SUCCESS: The message is validated * @STUN_VALIDATION_NOT_STUN: This is not a valid STUN message * @STUN_VALIDATION_INCOMPLETE_STUN: The message seems to be valid but incomplete * @STUN_VALIDATION_BAD_REQUEST: The message does not have the cookie or the * fingerprint while the agent needs it with its usage * @STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST: The message is valid but * unauthorized with no username and message-integrity attributes. * A BAD_REQUEST error must be generated * @STUN_VALIDATION_UNAUTHORIZED: The message is valid but unauthorized as * the username/password do not match. * An UNAUTHORIZED error must be generated * @STUN_VALIDATION_UNMATCHED_RESPONSE: The message is valid but this is a * response/error that doesn't match a previously sent request * @STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE: The message is valid but * contains one or more unknown comprehension attributes. * stun_agent_build_unknown_attributes_error() should be called * @STUN_VALIDATION_UNKNOWN_ATTRIBUTE: The message is valid but contains one * or more unknown comprehension attributes. This is a response, or error, * or indication message and no error response should be sent * * This enum is used as the return value of stun_agent_validate() and represents * the status result of the validation of a STUN message. */ typedef enum { STUN_VALIDATION_SUCCESS, STUN_VALIDATION_NOT_STUN, STUN_VALIDATION_INCOMPLETE_STUN, STUN_VALIDATION_BAD_REQUEST, STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST, STUN_VALIDATION_UNAUTHORIZED, STUN_VALIDATION_UNMATCHED_RESPONSE, STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE, STUN_VALIDATION_UNKNOWN_ATTRIBUTE, } StunValidationStatus; /** * StunAgentUsageFlags: * @STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS: The agent should be using the short * term credentials mechanism for authenticating STUN messages * @STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS: The agent should be using the long * term credentials mechanism for authenticating STUN messages * @STUN_AGENT_USAGE_USE_FINGERPRINT: The agent should add the FINGERPRINT * attribute to the STUN messages it creates. * @STUN_AGENT_USAGE_ADD_SOFTWARE: The agent should add the SOFTWARE attribute * to the STUN messages it creates. Calling nice_agent_set_software() will have * the same effect as enabling this Usage. STUN Indications do not have the * SOFTWARE attributes added to them though. The SOFTWARE attribute is only * added for the RFC5389 and MSICE2 compatibility modes. * @STUN_AGENT_USAGE_IGNORE_CREDENTIALS: The agent should ignore any credentials * in the STUN messages it receives (the MESSAGE-INTEGRITY attribute * will never be validated by stun_agent_validate()) * @STUN_AGENT_USAGE_NO_INDICATION_AUTH: The agent should ignore credentials * in the STUN messages it receives if the #StunClass of the message is * #STUN_INDICATION (some implementation require #STUN_INDICATION messages to * be authenticated, while others never add a MESSAGE-INTEGRITY attribute to a * #STUN_INDICATION message) * @STUN_AGENT_USAGE_FORCE_VALIDATER: The agent should always try to validate * the password of a STUN message, even if it already knows what the password * should be (a response to a previously created request). This means that the * #StunMessageIntegrityValidate callback will always be called when there is * a MESSAGE-INTEGRITY attribute. * @STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES: The agent should not assume STUN * attributes are aligned on 32-bit boundaries when parsing messages and also * do not add padding when creating messages. * * This enum defines a bitflag usages for a #StunAgent and they will define how * the agent should behave, independently of the compatibility mode it uses. * See also: stun_agent_init() * See also: stun_agent_validate() */ typedef enum { STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS = (1 << 0), STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS = (1 << 1), STUN_AGENT_USAGE_USE_FINGERPRINT = (1 << 2), STUN_AGENT_USAGE_ADD_SOFTWARE = (1 << 3), STUN_AGENT_USAGE_IGNORE_CREDENTIALS = (1 << 4), STUN_AGENT_USAGE_NO_INDICATION_AUTH = (1 << 5), STUN_AGENT_USAGE_FORCE_VALIDATER = (1 << 6), STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES = (1 << 7), } StunAgentUsageFlags; typedef struct { StunTransactionId id; StunMethod method; uint8_t *key; size_t key_len; uint8_t long_term_key[16]; bool long_term_valid; bool valid; } StunAgentSavedIds; struct stun_agent_t { StunCompatibility compatibility; StunAgentSavedIds sent_ids[STUN_AGENT_MAX_SAVED_IDS]; uint16_t *known_attributes; StunAgentUsageFlags usage_flags; const char *software_attribute; bool ms_ice2_send_legacy_connchecks; }; /** * StunDefaultValidaterData: * @username: The username * @username_len: The length of the @username * @password: The password * @password_len: The length of the @password * * This structure is used as an element of the user_data to the * stun_agent_default_validater() function for authenticating a STUN * message during validationg. * See also: stun_agent_default_validater() */ typedef struct { uint8_t *username; size_t username_len; uint8_t *password; size_t password_len; } StunDefaultValidaterData; /** * StunMessageIntegrityValidate: * @agent: The #StunAgent * @message: The #StunMessage being validated * @username: The username found in the @message * @username_len: The length of @username * @password: The password associated with that username. This argument is a * pointer to a byte array that must be set by the validater function. * @password_len: The length of @password which must also be set by the * validater function. * @user_data: Data to give the function * * This is the prototype for the @validater argument of the stun_agent_validate() * function. * See also: stun_agent_validate() * Returns: %TRUE if the authentication was successful, * %FALSE if the authentication failed */ typedef bool (*StunMessageIntegrityValidate) (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data); /** * stun_agent_default_validater: * @agent: The #StunAgent * @message: The #StunMessage being validated * @username: The username found in the @message * @username_len: The length of @username * @password: The password associated with that username. This argument is a * pointer to a byte array that must be set by the validater function. * @password_len: The length of @password which must also be set by the * validater function. * @user_data: This must be an array of #StunDefaultValidaterData structures. * The last element in the array must have a username set to NULL * * This is a helper function to be used with stun_agent_validate(). If no * complicated processing of the username needs to be done, this function can * be used with stun_agent_validate() to quickly and easily match the username * of a STUN message with its password. Its @user_data argument must be an array * of #StunDefaultValidaterData which will allow us to map a username to a * password * See also: stun_agent_validate() * Returns: %TRUE if the authentication was successful, * %FALSE if the authentication failed */ bool stun_agent_default_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data); /** * stun_agent_init: * @agent: The #StunAgent to initialize * @known_attributes: An array of #uint16_t specifying which attributes should * be known by the agent. Any STUN message received that contains a mandatory * attribute that is not in this array will yield a * #STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE or a * #STUN_VALIDATION_UNKNOWN_ATTRIBUTE error when calling stun_agent_validate() * @compatibility: The #StunCompatibility to use for this agent. This will affect * how the agent builds and validates the STUN messages * @usage_flags: A bitflag using #StunAgentUsageFlags values to define which * STUN usages the agent should use. * * This function must be called to initialize an agent before it is being used. * The @known_attributes data must exist in memory as long as the @agent is used If the #STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS and #STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS usage flags are not set, then the agent will default in using the short term credentials mechanism The #STUN_AGENT_USAGE_USE_FINGERPRINT and #STUN_AGENT_USAGE_ADD_SOFTWARE usage flags are only valid if the #STUN_COMPATIBILITY_RFC5389 or #STUN_COMPATIBILITY_MSICE2 @compatibility is used */ void stun_agent_init (StunAgent *agent, const uint16_t *known_attributes, StunCompatibility compatibility, StunAgentUsageFlags usage_flags); /** * stun_agent_validate: * @agent: The #StunAgent * @msg: The #StunMessage to build * @buffer: The data buffer of the STUN message * @buffer_len: The length of @buffer * @validater: A #StunMessageIntegrityValidate function callback that will * be called if the agent needs to validate a MESSAGE-INTEGRITY attribute. It * will only be called if the agent finds a message that needs authentication * and a USERNAME is present in the STUN message, but no password is known. * The validater will not be called if the #STUN_AGENT_USAGE_IGNORE_CREDENTIALS * usage flag is set on the agent, and it will always be called if the * #STUN_AGENT_USAGE_FORCE_VALIDATER usage flag is set on the agent. * @validater_data: A user data to give to the @validater callback when it gets * called. * * This function is used to validate an inbound STUN message and transform its * data buffer into a #StunMessage. It will take care of various validation * algorithms to make sure that the STUN message is valid and correctly * authenticated. * See also: stun_agent_default_validater() * Returns: A #StunValidationStatus if the return value is different from #STUN_VALIDATION_NOT_STUN or #STUN_VALIDATION_INCOMPLETE_STUN, then the @msg argument will contain a valid STUN message that can be used. This means that you can use the @msg variable as the @request argument to functions like stun_agent_init_error() or stun_agent_build_unknown_attributes_error(). If the return value is #STUN_VALIDATION_BAD_REQUEST, #STUN_VALIDATION_UNAUTHORIZED or #STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST then the @key in the #StunMessage will not be set, so that error responses will not have a MESSAGE-INTEGRITY attribute. */ StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg, const uint8_t *buffer, size_t buffer_len, StunMessageIntegrityValidate validater, void * validater_data); /** * stun_agent_init_request: * @agent: The #StunAgent * @msg: The #StunMessage to build * @buffer: The buffer to use in the #StunMessage * @buffer_len: The length of the buffer * @m: The #StunMethod of the request * * Creates a new STUN message of class #STUN_REQUEST and with the method @m * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise */ bool stun_agent_init_request (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMethod m); /** * stun_agent_init_indication: * @agent: The #StunAgent * @msg: The #StunMessage to build * @buffer: The buffer to use in the #StunMessage * @buffer_len: The length of the buffer * @m: The #StunMethod of the indication * * Creates a new STUN message of class #STUN_INDICATION and with the method @m * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise */ bool stun_agent_init_indication (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMethod m); /** * stun_agent_init_response: * @agent: The #StunAgent * @msg: The #StunMessage to build * @buffer: The buffer to use in the #StunMessage * @buffer_len: The length of the buffer * @request: The #StunMessage of class #STUN_REQUEST that this response is for * * Creates a new STUN message of class #STUN_RESPONSE and with the same method * and transaction ID as the message @request. This will also copy the pointer * to the key that was used to authenticate the request, so you won't need to * specify the key with stun_agent_finish_message() * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise */ bool stun_agent_init_response (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const StunMessage *request); /** * stun_agent_init_error: * @agent: The #StunAgent * @msg: The #StunMessage to build * @buffer: The buffer to use in the #StunMessage * @buffer_len: The length of the buffer * @request: The #StunMessage of class #STUN_REQUEST that this error response * is for * @err: The #StunError to put in the ERROR-CODE attribute of the error response * * Creates a new STUN message of class #STUN_ERROR and with the same method * and transaction ID as the message @request. This will also copy the pointer * to the key that was used to authenticate the request (if authenticated), * so you won't need to specify the key with stun_agent_finish_message(). * It will then add the ERROR-CODE attribute with code @err and the associated * string. * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise */ bool stun_agent_init_error (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const StunMessage *request, StunError err); /** * stun_agent_build_unknown_attributes_error: * @agent: The #StunAgent * @msg: The #StunMessage to build * @buffer: The buffer to use in the #StunMessage * @buffer_len: The length of the buffer * @request: The #StunMessage of class #STUN_REQUEST that this response is for * * Creates a new STUN message of class #STUN_ERROR and with the same method * and transaction ID as the message @request. It will then add the ERROR-CODE * attribute with code #STUN_ERROR_UNKNOWN_ATTRIBUTE and add all the unknown * mandatory attributes from the @request STUN message in the * #STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES attribute, it will then finish the message * by calling stun_agent_finish_message() * Returns: The size of the message built */ size_t stun_agent_build_unknown_attributes_error (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const StunMessage *request); /** * stun_agent_finish_message: * @agent: The #StunAgent * @msg: The #StunMessage to finish * @key: The key to use for the MESSAGE-INTEGRITY attribute * @key_len: The length of the @key * * This function will 'finish' a message and make it ready to be sent. It will * add the MESSAGE-INTEGRITY and FINGERPRINT attributes if necessary. If the * STUN message has a #STUN_REQUEST class, it will save the transaction id of * the message in the agent for future matching of the response. * See also: stun_agent_forget_transaction() * Returns: The final size of the message built or 0 if an error occured * The return value must always be checked. a value of 0 means the either the buffer's size is too small to contain the finishing attributes (MESSAGE-INTEGRITY, FINGERPRINT), or that there is no more free slots for saving the sent id in the agent's state. Everytime stun_agent_finish_message() is called for a #STUN_REQUEST message, you must make sure to call stun_agent_forget_transaction() in case the response times out and is never received. This is to avoid filling up the #StunAgent's sent ids state preventing any further use of the stun_agent_finish_message() */ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg, const uint8_t *key, size_t key_len); /** * stun_agent_forget_transaction: * @agent: The #StunAgent * @id: The #StunTransactionId of the transaction to forget * * This function is used to make the #StunAgent forget about a previously * created transaction. * * This function should be called when a STUN request was previously * created with stun_agent_finish_message() and for which no response was ever * received (timed out). The #StunAgent keeps a list of the sent transactions * in order to validate the responses received. If the response is never received * this will allow the #StunAgent to forget about the timed out transaction and * free its slot for future transactions. * * Since: 0.0.6 * Returns: %TRUE if the transaction was found, %FALSE otherwise */ bool stun_agent_forget_transaction (StunAgent *agent, StunTransactionId id); /** * stun_agent_set_software: * @agent: The #StunAgent * @software: The value of the SOFTWARE attribute to add. * * This function will set the value of the SOFTWARE attribute to be added to * STUN requests, responses and error responses. * * Calling this function will automatically enable the addition of the SOFTWARE * attribute for RFC5389 and MSICE2 compatibility modes. * * * The @software argument must be in UTF-8 encoding and only the first 128 characters will be sent. The value of the @software argument must stay valid throughout the life of the StunAgent's life. Do not free its content. * * Since: 0.0.10 * */ void stun_agent_set_software (StunAgent *agent, const char *software); #endif /* _STUN_AGENT_H */ libnice-0.1.14/stun/debug.c0000664000076400007640000000623512732066227012375 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "debug.h" static int debug_enabled = 0; void stun_debug_enable (void) { debug_enabled = 1; } void stun_debug_disable (void) { debug_enabled = 0; } #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) #define GNUC_PRINTF(format_idx, arg_idx) \ __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else #define GNUC_PRINTF( format_idx, arg_idx) #endif static void default_handler (const char *format, va_list ap) GNUC_PRINTF (1, 0); static void default_handler (const char *format, va_list ap) { vfprintf (stderr, format, ap); fprintf (stderr, "\n"); } static StunDebugHandler handler = default_handler; void stun_debug (const char *fmt, ...) { va_list ap; if (debug_enabled) { va_start (ap, fmt); handler (fmt, ap); va_end (ap); } } void stun_debug_bytes (const char *prefix, const void *data, size_t len) { size_t i; size_t prefix_len = strlen (prefix); char *bytes; char *j; unsigned char k; const char *hex = "0123456789abcdef"; if (!debug_enabled) return; bytes = malloc (prefix_len + 2 + (len * 2) + 1); bytes[0] = 0; strcpy (bytes, prefix); strcpy (bytes + prefix_len, "0x"); j = bytes + prefix_len + 2; for (i = 0; i < len; i++) { k = ((const unsigned char *)data)[i]; j[0] = hex[(k & 0xf0) >> 4]; j[1] = hex[k & 0xf]; j = j + 2; } j[0] = 0; stun_debug ("%s", bytes); free (bytes); } void stun_set_debug_handler (StunDebugHandler _handler) { if (_handler == NULL) _handler = default_handler; handler = _handler; } libnice-0.1.14/stun/stun5389.c0000664000076400007640000000700011522161146012610 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef _WIN32 #include #else #include #include /* htons() */ #endif #include #include #include "stun5389.h" #include "stuncrc32.h" #include "stunmessage.h" static const char utf8_skip_data[256] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 }; #define next_utf8_char(p) (char *)((p) + \ utf8_skip_data[*(const unsigned char *)(p)]) uint32_t stun_fingerprint (const uint8_t *msg, size_t len, bool wlm2009_stupid_crc32_typo) { crc_data data[3]; uint16_t fakelen = htons (len - 20u); // assert (len >= 28u); data[0].buf = (void *)msg; data[0].len = 2; data[1].buf = (uint8_t *)&fakelen; data[1].len = 2; data[2].buf = (void *)(msg + 4); /* first 4 bytes done, last 8 bytes not summed */ data[2].len = len - 12u; return htonl (stun_crc32 (data, 3, wlm2009_stupid_crc32_typo) ^ 0x5354554e); } bool stun_message_has_cookie (const StunMessage *msg) { StunTransactionId id; uint32_t cookie = htonl (STUN_MAGIC_COOKIE); stun_message_id (msg, id); return memcmp (id, &cookie, sizeof (cookie)) == 0; } StunMessageReturn stun_message_append_software (StunMessage *msg, const char *software) { int len = 0; const char *ptr = NULL; if (software == NULL) software = PACKAGE_STRING; ptr = software; while (*ptr && len < 128) { ptr = next_utf8_char (ptr); len++; } return stun_message_append_bytes (msg, STUN_ATTRIBUTE_SOFTWARE, software, ptr - software); } libnice-0.1.14/stun/stunagent.c0000664000076400007640000006007413004222455013306 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "stunmessage.h" #include "stunagent.h" #include "stunhmac.h" #include "stun5389.h" #include "utils.h" #include #include #include static bool stun_agent_is_unknown (StunAgent *agent, uint16_t type); static unsigned stun_agent_find_unknowns (StunAgent *agent, const StunMessage * msg, uint16_t *list, unsigned max); void stun_agent_init (StunAgent *agent, const uint16_t *known_attributes, StunCompatibility compatibility, StunAgentUsageFlags usage_flags) { int i; agent->known_attributes = (uint16_t *) known_attributes; agent->compatibility = compatibility; agent->usage_flags = usage_flags; agent->software_attribute = NULL; agent->ms_ice2_send_legacy_connchecks = compatibility == STUN_COMPATIBILITY_MSICE2; for (i = 0; i < STUN_AGENT_MAX_SAVED_IDS; i++) { agent->sent_ids[i].valid = FALSE; } } bool stun_agent_default_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { StunDefaultValidaterData* val = (StunDefaultValidaterData *) user_data; int i; for (i = 0; val && val[i].username ; i++) { #if 0 stun_debug ("Comparing username of size %d and %" PRIuPTR ": %d", username_len, val[i].username_len, (memcmp (username, val[i].username, username_len) == 0)); #endif stun_debug_bytes (" First username: ", username, username_len); stun_debug_bytes (" Second username: ", val[i].username, val[i].username_len); if (username_len == val[i].username_len && memcmp (username, val[i].username, username_len) == 0) { *password = (uint8_t *) val[i].password; *password_len = val[i].password_len; stun_debug ("Found valid username, returning password : '%s'", *password); return TRUE; } } return FALSE; } static bool stun_agent_check_fingerprint(StunAgent *agent, StunMessage *msg) { uint32_t fpr; uint32_t crc32; uint16_t msg_len; /* Looks for FINGERPRINT */ if (stun_message_find32 (msg, STUN_ATTRIBUTE_FINGERPRINT, &fpr) != STUN_MESSAGE_RETURN_SUCCESS) { stun_debug ("STUN demux error: no FINGERPRINT attribute!"); return FALSE; } msg_len = stun_message_length (msg); /* Checks FINGERPRINT */ crc32 = stun_fingerprint (msg->buffer, msg_len, FALSE); fpr = ntohl (fpr); if (fpr != crc32) { uint16_t palen; /* [MS-ICE2] 3.1.4.8.2 Connectivity Checks Phase - legacy compatibility */ if (agent->compatibility == STUN_COMPATIBILITY_MSICE2 && stun_message_find (msg, STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION, &palen) == NULL && fpr == stun_fingerprint (msg->buffer, msg_len, TRUE)) { return TRUE; } stun_debug ("STUN demux error: bad fingerprint: 0x%08x, expected: 0x%08x!", fpr, crc32); return FALSE; } return TRUE; } StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg, const uint8_t *buffer, size_t buffer_len, StunMessageIntegrityValidate validater, void * validater_data) { StunTransactionId msg_id; int len; uint8_t *username = NULL; uint16_t username_len; uint8_t *key = NULL; size_t key_len; uint8_t *hash; uint8_t sha[20]; uint16_t hlen; uint32_t implementation_version; int sent_id_idx = -1; uint16_t unknown; int error_code; int ignore_credentials = 0; uint8_t long_term_key[16] = { 0 }; bool long_term_key_valid = FALSE; len = stun_message_validate_buffer_length (buffer, buffer_len, !(agent->usage_flags & STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES)); if (len == STUN_MESSAGE_BUFFER_INVALID) { return STUN_VALIDATION_NOT_STUN; } else if (len == STUN_MESSAGE_BUFFER_INCOMPLETE) { return STUN_VALIDATION_INCOMPLETE_STUN; } else if (len != (int) buffer_len) { return STUN_VALIDATION_NOT_STUN; } msg->buffer = (uint8_t *) buffer; msg->buffer_len = buffer_len; msg->agent = agent; msg->key = NULL; msg->key_len = 0; msg->long_term_valid = FALSE; /* TODO: reject it or not ? */ if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) && !stun_message_has_cookie (msg)) { stun_debug ("STUN demux error: no cookie!"); return STUN_VALIDATION_BAD_REQUEST; } if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) && agent->usage_flags & STUN_AGENT_USAGE_USE_FINGERPRINT) { if (stun_agent_check_fingerprint(agent, msg) == FALSE) { return STUN_VALIDATION_BAD_REQUEST; } stun_debug ("STUN demux: OK!"); } if (stun_message_get_class (msg) == STUN_RESPONSE || stun_message_get_class (msg) == STUN_ERROR) { stun_message_id (msg, msg_id); for (sent_id_idx = 0; sent_id_idx < STUN_AGENT_MAX_SAVED_IDS; sent_id_idx++) { if (agent->sent_ids[sent_id_idx].valid == TRUE && agent->sent_ids[sent_id_idx].method == stun_message_get_method (msg) && memcmp (msg_id, agent->sent_ids[sent_id_idx].id, sizeof(StunTransactionId)) == 0) { key = agent->sent_ids[sent_id_idx].key; key_len = agent->sent_ids[sent_id_idx].key_len; memcpy (long_term_key, agent->sent_ids[sent_id_idx].long_term_key, sizeof(long_term_key)); long_term_key_valid = agent->sent_ids[sent_id_idx].long_term_valid; break; } } if (sent_id_idx == STUN_AGENT_MAX_SAVED_IDS) { return STUN_VALIDATION_UNMATCHED_RESPONSE; } } ignore_credentials = (agent->usage_flags & STUN_AGENT_USAGE_IGNORE_CREDENTIALS) || (stun_message_get_class (msg) == STUN_ERROR && stun_message_find_error (msg, &error_code) == STUN_MESSAGE_RETURN_SUCCESS && (error_code == 400 || error_code == 401 || error_code == 438)) || (stun_message_get_class (msg) == STUN_INDICATION && (agent->usage_flags & STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS || agent->usage_flags & STUN_AGENT_USAGE_NO_INDICATION_AUTH)); if (key == NULL && ignore_credentials == 0 && (stun_message_get_class (msg) == STUN_REQUEST || stun_message_get_class (msg) == STUN_INDICATION) && (((agent->usage_flags & STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS) && (!stun_message_has_attribute (msg, STUN_ATTRIBUTE_USERNAME) || !stun_message_has_attribute (msg, STUN_ATTRIBUTE_MESSAGE_INTEGRITY))) || ((agent->usage_flags & STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS) && stun_message_get_class (msg) == STUN_REQUEST && (!stun_message_has_attribute (msg, STUN_ATTRIBUTE_USERNAME) || !stun_message_has_attribute (msg, STUN_ATTRIBUTE_MESSAGE_INTEGRITY) || !stun_message_has_attribute (msg, STUN_ATTRIBUTE_NONCE) || !stun_message_has_attribute (msg, STUN_ATTRIBUTE_REALM))) || ((agent->usage_flags & STUN_AGENT_USAGE_IGNORE_CREDENTIALS) == 0 && stun_message_has_attribute (msg, STUN_ATTRIBUTE_USERNAME) && !stun_message_has_attribute (msg, STUN_ATTRIBUTE_MESSAGE_INTEGRITY)))) { return STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST; } if (stun_message_has_attribute (msg, STUN_ATTRIBUTE_MESSAGE_INTEGRITY) && ((key == NULL && ignore_credentials == 0) || (agent->usage_flags & STUN_AGENT_USAGE_FORCE_VALIDATER))) { username_len = 0; username = (uint8_t *) stun_message_find (msg, STUN_ATTRIBUTE_USERNAME, &username_len); if (validater == NULL || validater (agent, msg, username, username_len, &key, &key_len, validater_data) == FALSE) { return STUN_VALIDATION_UNAUTHORIZED; } } if (ignore_credentials == 0 && key != NULL && key_len > 0) { hash = (uint8_t *) stun_message_find (msg, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, &hlen); if (hash) { /* We must give the size from start to the end of the attribute because you might have a FINGERPRINT attribute after it... */ if (agent->usage_flags & STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS) { uint8_t *realm = NULL; uint16_t realm_len; uint8_t md5[16]; if (long_term_key_valid) { memcpy (md5, long_term_key, sizeof (md5)); } else { realm = (uint8_t *) stun_message_find (msg, STUN_ATTRIBUTE_REALM, &realm_len); username = (uint8_t *) stun_message_find (msg, STUN_ATTRIBUTE_USERNAME, &username_len); if (username == NULL || realm == NULL) { return STUN_VALIDATION_UNAUTHORIZED; } stun_hash_creds (realm, realm_len, username, username_len, key, key_len, md5); } memcpy (msg->long_term_key, md5, sizeof(md5)); msg->long_term_valid = TRUE; if (agent->compatibility == STUN_COMPATIBILITY_RFC3489 || agent->compatibility == STUN_COMPATIBILITY_OC2007) { stun_sha1 (msg->buffer, hash + 20 - msg->buffer, hash - msg->buffer, sha, md5, sizeof(md5), TRUE); } else if (agent->compatibility == STUN_COMPATIBILITY_MSICE2) { stun_sha1 (msg->buffer, hash + 20 - msg->buffer, stun_message_length (msg) - 20, sha, md5, sizeof(md5), TRUE); } else { stun_sha1 (msg->buffer, hash + 20 - msg->buffer, hash - msg->buffer, sha, md5, sizeof(md5), FALSE); } } else { if (agent->compatibility == STUN_COMPATIBILITY_RFC3489 || agent->compatibility == STUN_COMPATIBILITY_OC2007) { stun_sha1 (msg->buffer, hash + 20 - msg->buffer, hash - msg->buffer, sha, key, key_len, TRUE); } else if (agent->compatibility == STUN_COMPATIBILITY_MSICE2) { stun_sha1 (msg->buffer, hash + 20 - msg->buffer, stun_message_length (msg) - 20, sha, key, key_len, TRUE); } else { stun_sha1 (msg->buffer, hash + 20 - msg->buffer, hash - msg->buffer, sha, key, key_len, FALSE); } } stun_debug (" Message HMAC-SHA1 fingerprint:"); stun_debug_bytes (" key : ", key, key_len); stun_debug_bytes (" expected: ", sha, sizeof (sha)); stun_debug_bytes (" received: ", hash, sizeof (sha)); if (memcmp (sha, hash, sizeof (sha))) { stun_debug ("STUN auth error: SHA1 fingerprint mismatch!"); return STUN_VALIDATION_UNAUTHORIZED; } stun_debug ("STUN auth: OK!"); msg->key = key; msg->key_len = key_len; } else if (!(stun_message_get_class (msg) == STUN_ERROR && stun_message_find_error (msg, &error_code) == STUN_MESSAGE_RETURN_SUCCESS && (error_code == 400 || error_code == 401))) { stun_debug ("STUN auth error: No message integrity attribute!"); return STUN_VALIDATION_UNAUTHORIZED; } } if (sent_id_idx != -1 && sent_id_idx < STUN_AGENT_MAX_SAVED_IDS) { agent->sent_ids[sent_id_idx].valid = FALSE; } /* [MS-ICE2] 3.1.4.8.2 stop sending additional connectivity checks */ if (stun_message_find32(msg, STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION, &implementation_version) == STUN_MESSAGE_RETURN_SUCCESS) { msg->agent->ms_ice2_send_legacy_connchecks = FALSE; } if (stun_agent_find_unknowns (agent, msg, &unknown, 1) > 0) { if (stun_message_get_class (msg) == STUN_REQUEST) return STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE; else return STUN_VALIDATION_UNKNOWN_ATTRIBUTE; } return STUN_VALIDATION_SUCCESS; } bool stun_agent_forget_transaction (StunAgent *agent, StunTransactionId id) { int i; for (i = 0; i < STUN_AGENT_MAX_SAVED_IDS; i++) { if (agent->sent_ids[i].valid == TRUE && memcmp (id, agent->sent_ids[i].id, sizeof(StunTransactionId)) == 0) { agent->sent_ids[i].valid = FALSE; return TRUE; } } return FALSE; } bool stun_agent_init_request (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMethod m) { bool ret; StunTransactionId id; msg->buffer = buffer; msg->buffer_len = buffer_len; msg->agent = agent; msg->key = NULL; msg->key_len = 0; msg->long_term_valid = FALSE; stun_make_transid (id); ret = stun_message_init (msg, STUN_REQUEST, m, id); if (ret) { if (agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) { uint32_t cookie = htonl (STUN_MAGIC_COOKIE); memcpy (msg->buffer + STUN_MESSAGE_TRANS_ID_POS, &cookie, sizeof (cookie)); } if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) && (agent->software_attribute != NULL || agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE)) { stun_message_append_software (msg, agent->software_attribute); } } return ret; } bool stun_agent_init_indication (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMethod m) { bool ret; StunTransactionId id; msg->buffer = buffer; msg->buffer_len = buffer_len; msg->agent = agent; msg->key = NULL; msg->key_len = 0; msg->long_term_valid = FALSE; stun_make_transid (id); ret = stun_message_init (msg, STUN_INDICATION, m, id); if (ret) { if (agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) { uint32_t cookie = htonl (STUN_MAGIC_COOKIE); memcpy (msg->buffer + STUN_MESSAGE_TRANS_ID_POS, &cookie, sizeof (cookie)); } } return ret; } bool stun_agent_init_response (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const StunMessage *request) { StunTransactionId id; if (stun_message_get_class (request) != STUN_REQUEST) { return FALSE; } msg->buffer = buffer; msg->buffer_len = buffer_len; msg->agent = agent; msg->key = request->key; msg->key_len = request->key_len; memmove (msg->long_term_key, request->long_term_key, sizeof(msg->long_term_key)); msg->long_term_valid = request->long_term_valid; stun_message_id (request, id); if (stun_message_init (msg, STUN_RESPONSE, stun_message_get_method (request), id)) { if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) && (agent->software_attribute != NULL || agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE)) { stun_message_append_software (msg, agent->software_attribute); } return TRUE; } return FALSE; } bool stun_agent_init_error (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const StunMessage *request, StunError err) { StunTransactionId id; if (stun_message_get_class (request) != STUN_REQUEST) { return FALSE; } msg->buffer = buffer; msg->buffer_len = buffer_len; msg->agent = agent; msg->key = request->key; msg->key_len = request->key_len; memmove (msg->long_term_key, request->long_term_key, sizeof(msg->long_term_key)); msg->long_term_valid = request->long_term_valid; stun_message_id (request, id); if (stun_message_init (msg, STUN_ERROR, stun_message_get_method (request), id)) { if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) && (agent->software_attribute != NULL || agent->usage_flags & STUN_AGENT_USAGE_ADD_SOFTWARE)) { stun_message_append_software (msg, agent->software_attribute); } if (stun_message_append_error (msg, err) == STUN_MESSAGE_RETURN_SUCCESS) { return TRUE; } } return FALSE; } size_t stun_agent_build_unknown_attributes_error (StunAgent *agent, StunMessage *msg, uint8_t *buffer, size_t buffer_len, const StunMessage *request) { unsigned counter; uint16_t ids[STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES]; counter = stun_agent_find_unknowns (agent, request, ids, STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES); if (stun_agent_init_error (agent, msg, buffer, buffer_len, request, STUN_ERROR_UNKNOWN_ATTRIBUTE) == FALSE) { return 0; } /* NOTE: Old RFC3489 compatibility: * When counter is odd, duplicate one value for 32-bits padding. */ if (!stun_message_has_cookie (request) && (counter & 1)) ids[counter++] = ids[0]; if (stun_message_append_bytes (msg, STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES, ids, counter * 2) == STUN_MESSAGE_RETURN_SUCCESS) { return stun_agent_finish_message (agent, msg, request->key, request->key_len); } return 0; } size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg, const uint8_t *key, size_t key_len) { uint8_t *ptr; uint32_t fpr; int saved_id_idx = 0; uint8_t md5[16]; bool remember_transaction; remember_transaction = (stun_message_get_class (msg) == STUN_REQUEST); if (agent->compatibility == STUN_COMPATIBILITY_OC2007 && stun_message_get_method (msg) == STUN_SEND) { /* As per [MS-TURN] Section 2.2.1, the TURN server doesn't send responses to * STUN_SEND requests, so don't bother waiting for them. More details at * https://msdn.microsoft.com/en-us/library/dd946797%28v=office.12%29.aspx. */ remember_transaction = FALSE; } if (remember_transaction) { for (saved_id_idx = 0; saved_id_idx < STUN_AGENT_MAX_SAVED_IDS; saved_id_idx++) { if (agent->sent_ids[saved_id_idx].valid == FALSE) { break; } } } if (saved_id_idx == STUN_AGENT_MAX_SAVED_IDS) { stun_debug ("WARNING: Saved IDs full. STUN message dropped."); return 0; } if (msg->key != NULL) { key = msg->key; key_len = msg->key_len; } if (key != NULL) { bool skip = FALSE; if (msg->long_term_valid) { memcpy (md5, msg->long_term_key, sizeof(msg->long_term_key)); } else if (agent->usage_flags & STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS) { uint8_t *realm = NULL; uint8_t *username = NULL; uint16_t realm_len; uint16_t username_len; realm = (uint8_t *) stun_message_find (msg, STUN_ATTRIBUTE_REALM, &realm_len); username = (uint8_t *) stun_message_find (msg, STUN_ATTRIBUTE_USERNAME, &username_len); if (username == NULL || realm == NULL) { skip = TRUE; } else { stun_hash_creds (realm, realm_len, username, username_len, key, key_len, md5); memcpy (msg->long_term_key, md5, sizeof(msg->long_term_key)); msg->long_term_valid = TRUE; } } /* If no realm/username and long term credentials, then don't send the message integrity */ if (skip == FALSE) { ptr = stun_message_append (msg, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, 20); if (ptr == NULL) { return 0; } if (agent->usage_flags & STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS) { if (agent->compatibility == STUN_COMPATIBILITY_RFC3489 || agent->compatibility == STUN_COMPATIBILITY_OC2007) { stun_sha1 (msg->buffer, stun_message_length (msg), stun_message_length (msg) - 20, ptr, md5, sizeof(md5), TRUE); } else if (agent->compatibility == STUN_COMPATIBILITY_MSICE2) { size_t minus = 20; if (agent->usage_flags & STUN_AGENT_USAGE_USE_FINGERPRINT) minus -= 8; stun_sha1 (msg->buffer, stun_message_length (msg), stun_message_length (msg) - minus, ptr, md5, sizeof(md5), TRUE); } else { stun_sha1 (msg->buffer, stun_message_length (msg), stun_message_length (msg) - 20, ptr, md5, sizeof(md5), FALSE); } } else { if (agent->compatibility == STUN_COMPATIBILITY_RFC3489 || agent->compatibility == STUN_COMPATIBILITY_OC2007) { stun_sha1 (msg->buffer, stun_message_length (msg), stun_message_length (msg) - 20, ptr, key, key_len, TRUE); } else if (agent->compatibility == STUN_COMPATIBILITY_MSICE2) { size_t minus = 20; if (agent->usage_flags & STUN_AGENT_USAGE_USE_FINGERPRINT) minus -= 8; stun_sha1 (msg->buffer, stun_message_length (msg), stun_message_length (msg) - minus, ptr, key, key_len, TRUE); } else { stun_sha1 (msg->buffer, stun_message_length (msg), stun_message_length (msg) - 20, ptr, key, key_len, FALSE); } } stun_debug (" Message HMAC-SHA1 message integrity:"); stun_debug_bytes (" key : ", key, key_len); stun_debug_bytes (" sent : ", ptr, 20); } } if ((agent->compatibility == STUN_COMPATIBILITY_RFC5389 || agent->compatibility == STUN_COMPATIBILITY_MSICE2) && agent->usage_flags & STUN_AGENT_USAGE_USE_FINGERPRINT) { ptr = stun_message_append (msg, STUN_ATTRIBUTE_FINGERPRINT, 4); if (ptr == NULL) { return 0; } fpr = stun_fingerprint (msg->buffer, stun_message_length (msg), FALSE); memcpy (ptr, &fpr, sizeof (fpr)); stun_debug_bytes (" Message HMAC-SHA1 fingerprint: ", ptr, 4); } if (remember_transaction) { stun_message_id (msg, agent->sent_ids[saved_id_idx].id); agent->sent_ids[saved_id_idx].method = stun_message_get_method (msg); agent->sent_ids[saved_id_idx].key = (uint8_t *) key; agent->sent_ids[saved_id_idx].key_len = key_len; memcpy (agent->sent_ids[saved_id_idx].long_term_key, msg->long_term_key, sizeof(msg->long_term_key)); agent->sent_ids[saved_id_idx].long_term_valid = msg->long_term_valid; agent->sent_ids[saved_id_idx].valid = TRUE; } msg->key = (uint8_t *) key; msg->key_len = key_len; return stun_message_length (msg); } static bool stun_agent_is_unknown (StunAgent *agent, uint16_t type) { uint16_t *known_attr = agent->known_attributes; while(*known_attr != 0) { if (*known_attr == type) { return FALSE; } known_attr++; } return TRUE; } static unsigned stun_agent_find_unknowns (StunAgent *agent, const StunMessage * msg, uint16_t *list, unsigned max) { unsigned count = 0; uint16_t len = stun_message_length (msg); size_t offset = 0; offset = STUN_MESSAGE_ATTRIBUTES_POS; while ((offset < len) && (count < max)) { size_t alen = stun_getw (msg->buffer + offset + STUN_ATTRIBUTE_TYPE_LEN); uint16_t atype = stun_getw (msg->buffer + offset); if (!stun_optional (atype) && stun_agent_is_unknown (agent, atype)) { stun_debug ("STUN unknown: attribute 0x%04x(%u bytes)", (unsigned)atype, (unsigned)alen); list[count++] = htons (atype); } if (!(agent->usage_flags & STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES)) alen = stun_align (alen); offset += STUN_ATTRIBUTE_VALUE_POS + alen; } stun_debug ("STUN unknown: %u mandatory attribute(s)!", count); return count; } void stun_agent_set_software (StunAgent *agent, const char *software) { agent->software_attribute = software; } libnice-0.1.14/stun/rand.h0000664000076400007640000000330713070464721012232 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. All rights reserved. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef RAND_H #define RAND_H #ifdef _WIN32 #include "win32_common.h" #else #include #endif void nice_RAND_nonce (uint8_t *dst, int len); #endif /* RAND_H */ libnice-0.1.14/stun/utils.h0000664000076400007640000000437112363772107012454 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef STUN_UTILS_H # define STUN_UTILS_H 1 /* * @file utils.h * @brief STUN client generic utility functions */ #include "stunmessage.h" #ifdef _WIN32 #include #include #else #include #include #include #endif # ifdef __cplusplus extern "C" { # endif size_t stun_padding (size_t l); size_t stun_align (size_t l); uint16_t stun_getw (const uint8_t *ptr); void *stun_setw (uint8_t *ptr, uint16_t value); void stun_set_type (uint8_t *h, StunClass c, StunMethod m); StunMessageReturn stun_xor_address (const StunMessage *msg, struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie); # ifdef __cplusplus } # endif #endif /* STUN_UTILS_H */ libnice-0.1.14/stun/rand.c0000664000076400007640000000466313070464721012233 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. All rights reserved. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "rand.h" #ifdef _WIN32 #include #include void nice_RAND_bytes (uint8_t *dst, int len) { HCRYPTPROV hCryptProv; LPCSTR container = "Libnice key container"; if(!CryptAcquireContext(&hCryptProv, container, NULL, PROV_RSA_FULL, 0)) { /* non existing container. try to create a new one */ // I hope this cast here doesn't cause issues // gcc was complaining about comparing signed and unsigned values if (GetLastError() == (DWORD) NTE_BAD_KEYSET) { if(!CryptAcquireContext(&hCryptProv, container, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { return; } } return; } CryptGenRandom (hCryptProv, len, dst); CryptReleaseContext(hCryptProv,0); } #else #include #include #include void nice_RAND_nonce (uint8_t *dst, int len) { gnutls_rnd (GNUTLS_RND_NONCE, dst, len); } #endif /* _WIN32 */ libnice-0.1.14/stun/win32_common.h0000664000076400007640000000600012520743534013612 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008-2009 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Danny Smith * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* ISO C9x 7.18 Integer types * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794) * * THIS SOFTWARE IS NOT COPYRIGHTED * * Contributor: Danny Smith * * This source code is offered for use in the public domain. You may * use, modify or distribute it freely. * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Date: 2000-12-02 */ #ifndef _WIN32_COMMON_H #define _WIN32_COMMON_H #include "config.h" #include /* 7.18.1.1 Exact-width integer types */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef int int32_t; typedef unsigned uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; /* Using the [S]SIZE_T definitions from: * http://msdn.microsoft.com/en-gb/library/windows/desktop/aa383751%28v=vs.85%29.aspx#SSIZE_T */ #ifndef HAVE_SIZE_T #if defined(_WIN64) typedef unsigned __int64 size_t; #else typedef unsigned long size_t; #endif #endif /* !HAVE_SSIZE_T */ #ifndef HAVE_SSIZE_T #if defined(_WIN64) typedef signed __int64 ssize_t; #else typedef signed long ssize_t; #endif #endif /* !HAVE_SSIZE_T */ typedef uint8_t bool; #define true 1 #define false 0 #endif /* _WIN32_COMMON_H */ libnice-0.1.14/stun/stunhmac.c0000664000076400007640000000757113070511101013113 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "rand.h" #include "stunmessage.h" #include "stunhmac.h" #include #include #include #include void stun_sha1 (const uint8_t *msg, size_t len, size_t msg_len, uint8_t *sha, const void *key, size_t keylen, int padding) { uint16_t fakelen = htons (msg_len); uint8_t pad_char[64] = {0}; gnutls_hmac_hd_t handle; #ifdef NDEBUG #define TRY(x) x; #else int ret; #define TRY(x) \ ret = x; \ assert (ret >= 0); #endif assert (len >= 44u); assert (gnutls_hmac_get_len (GNUTLS_MAC_SHA1) == 20); TRY (gnutls_hmac_init (&handle, GNUTLS_MAC_SHA1, key, keylen)); TRY (gnutls_hmac (handle, msg, 2)); TRY (gnutls_hmac (handle, &fakelen, 2)); TRY (gnutls_hmac (handle, msg + 4, len - 28)); /* RFC 3489 specifies that the message's size should be 64 bytes, and \x00 padding should be done */ if (padding && ((len - 24) % 64) > 0) { uint16_t pad_size = 64 - ((len - 24) % 64); TRY (gnutls_hmac (handle, pad_char, pad_size)); } gnutls_hmac_deinit (handle, sha); #undef TRY } static const uint8_t *priv_trim_var (const uint8_t *var, size_t *var_len) { const uint8_t *ptr = var; while (*ptr == '"') { ptr++; (*var_len)--; } while(ptr[*var_len-1] == '"' || ptr[*var_len-1] == 0) { (*var_len)--; } return ptr; } void stun_hash_creds (const uint8_t *realm, size_t realm_len, const uint8_t *username, size_t username_len, const uint8_t *password, size_t password_len, unsigned char md5[16]) { const uint8_t *username_trimmed = priv_trim_var (username, &username_len); const uint8_t *password_trimmed = priv_trim_var (password, &password_len); const uint8_t *realm_trimmed = priv_trim_var (realm, &realm_len); const uint8_t *colon = (uint8_t *)":"; gnutls_hash_hd_t handle; gnutls_hash_init (&handle, GNUTLS_DIG_MD5); gnutls_hash (handle, username_trimmed, username_len); gnutls_hash (handle, colon, 1); gnutls_hash (handle, realm_trimmed, realm_len); gnutls_hash (handle, colon, 1); gnutls_hash (handle, password_trimmed, password_len); gnutls_hash_deinit (handle, md5); } void stun_make_transid (StunTransactionId id) { nice_RAND_nonce (id, 16); } libnice-0.1.14/stun/stuncrc32.c0000664000076400007640000001721511522161146013125 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * COPYRIGHT (C) 1986 Gary S. Brown * See documentation of the function crc32() below. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * Gary S. Brown * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /*- * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or * code or tables extracted from it, as desired without restriction. * * Extracted from FreeBSD CVS (src/sys/libkern/crc32.c) * and adapted by Rémi Denis-Courmont, 2007. */ /* * First, the polynomial itself and its table of feedback terms. The * polynomial is * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 * * Note that we take it "backwards" and put the highest-order term in * the lowest-order bit. The X^32 term is "implied"; the LSB is the * X^31 term, etc. The X^0 term (usually shown as "+1") results in * the MSB being 1 * * Note that the usual hardware shift register implementation, which * is what we're using (we're merely optimizing it by doing eight-bit * chunks at a time) shifts bits into the lowest-order term. In our * implementation, that means shifting towards the right. Why do we * do it this way? Because the calculated CRC must be transmitted in * order from highest-order term to lowest-order term. UARTs transmit * characters in order from LSB to MSB. By storing the CRC this way * we hand it to the UART in the order low-byte to high-byte; the UART * sends each low-bit to hight-bit; and the result is transmission bit * by bit from highest- to lowest-order term without requiring any bit * shuffling on our part. Reception works similarly * * The feedback terms table consists of 256, 32-bit entries. Notes * * The table can be generated at runtime if desired; code to do so * is shown later. It might not be obvious, but the feedback * terms simply represent the results of eight shift/xor opera * tions for all combinations of data and CRC register values * * The values must be right-shifted by eight bits by the "updcrc * logic; the shift must be unsigned (bring in zeroes). On some * hardware you could probably optimize the shift in assembler by * using byte-swap instructions * polynomial $edb88320 * * * CRC32 code derived from work by Gary S. Brown. */ #ifdef HAVE_CONFIG_H # include #endif #include "stuncrc32.h" static const uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; uint32_t stun_crc32 (const crc_data *data, size_t n, bool wlm2009_stupid_crc32_typo) { size_t i; uint32_t crc = 0xffffffff; for (i = 0; i < n; i++) { const uint8_t *p = data[i].buf; size_t size = data[i].len; while (size--) { uint32_t lkp = crc32_tab[(crc ^ *p++) & 0xFF]; if (lkp == 0x8bbeb8ea && wlm2009_stupid_crc32_typo) lkp = 0x8bbe8ea; crc = lkp ^ (crc >> 8); } } return crc ^ 0xffffffff; } libnice-0.1.14/stun/stunmessage.c0000664000076400007640000004777113067553427013664 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Rémi Denis-Courmont * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Rémi Denis-Courmont, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include "stunmessage.h" #include "utils.h" #ifdef _WIN32 #include #include #else #include #include #include #endif #include #include bool stun_message_init (StunMessage *msg, StunClass c, StunMethod m, const StunTransactionId id) { if (msg->buffer_len < STUN_MESSAGE_HEADER_LENGTH) return FALSE; memset (msg->buffer, 0, 4); stun_set_type (msg->buffer, c, m); memcpy (msg->buffer + STUN_MESSAGE_TRANS_ID_POS, id, STUN_MESSAGE_TRANS_ID_LEN); return TRUE; } uint16_t stun_message_length (const StunMessage *msg) { return stun_getw (msg->buffer + STUN_MESSAGE_LENGTH_POS) + STUN_MESSAGE_HEADER_LENGTH; } const void * stun_message_find (const StunMessage *msg, StunAttribute type, uint16_t *palen) { size_t length = stun_message_length (msg); size_t offset = 0; /* In MS-TURN, IDs of REALM and NONCE STUN attributes are swapped. */ if (msg->agent && msg->agent->compatibility == STUN_COMPATIBILITY_OC2007) { if (type == STUN_ATTRIBUTE_REALM) type = STUN_ATTRIBUTE_NONCE; else if (type == STUN_ATTRIBUTE_NONCE) type = STUN_ATTRIBUTE_REALM; } offset = STUN_MESSAGE_ATTRIBUTES_POS; while (offset < length) { uint16_t atype = stun_getw (msg->buffer + offset); size_t alen = stun_getw (msg->buffer + offset + STUN_ATTRIBUTE_TYPE_LEN); offset += STUN_ATTRIBUTE_VALUE_POS; if (atype == type) { *palen = alen; return msg->buffer + offset; } /* Look for and ignore misordered attributes */ switch (atype) { case STUN_ATTRIBUTE_MESSAGE_INTEGRITY: /* Only fingerprint may come after M-I */ if (type == STUN_ATTRIBUTE_FINGERPRINT) break; case STUN_ATTRIBUTE_FINGERPRINT: /* Nothing may come after FPR */ return NULL; default: /* Nothing misordered. */ break; } if (!(msg->agent && (msg->agent->usage_flags & STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES))) alen = stun_align (alen); offset += alen; } return NULL; } StunMessageReturn stun_message_find_flag (const StunMessage *msg, StunAttribute type) { const void *ptr; uint16_t len = 0; ptr = stun_message_find (msg, type, &len); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_FOUND; return (len == 0) ? STUN_MESSAGE_RETURN_SUCCESS : STUN_MESSAGE_RETURN_INVALID; } StunMessageReturn stun_message_find32 (const StunMessage *msg, StunAttribute type, uint32_t *pval) { const void *ptr; uint16_t len = 0; ptr = stun_message_find (msg, type, &len); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_FOUND; if (len == 4) { uint32_t val; memcpy (&val, ptr, sizeof (val)); *pval = ntohl (val); return STUN_MESSAGE_RETURN_SUCCESS; } return STUN_MESSAGE_RETURN_INVALID; } StunMessageReturn stun_message_find64 (const StunMessage *msg, StunAttribute type, uint64_t *pval) { const void *ptr; uint16_t len = 0; ptr = stun_message_find (msg, type, &len); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_FOUND; if (len == 8) { uint32_t tab[2]; memcpy (tab, ptr, sizeof (tab)); *pval = ((uint64_t)ntohl (tab[0]) << 32) | ntohl (tab[1]); return STUN_MESSAGE_RETURN_SUCCESS; } return STUN_MESSAGE_RETURN_INVALID; } StunMessageReturn stun_message_find_string (const StunMessage *msg, StunAttribute type, char *buf, size_t buflen) { const unsigned char *ptr; uint16_t len = 0; ptr = stun_message_find (msg, type, &len); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_FOUND; if (len >= buflen) return STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE; memcpy (buf, ptr, len); buf[len] = '\0'; return STUN_MESSAGE_RETURN_SUCCESS; } StunMessageReturn stun_message_find_addr (const StunMessage *msg, StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen) { const uint8_t *ptr; uint16_t len = 0; ptr = stun_message_find (msg, type, &len); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_FOUND; if (len < 4) return STUN_MESSAGE_RETURN_INVALID; switch (ptr[1]) { case 1: { struct sockaddr_in *ip4 = (struct sockaddr_in *)addr; if (((size_t) *addrlen < sizeof (*ip4)) || (len != 8)) { *addrlen = sizeof (*ip4); return STUN_MESSAGE_RETURN_INVALID; } memset (ip4, 0, *addrlen); ip4->sin_family = AF_INET; #ifdef HAVE_SA_LEN ip4->sin_len = #endif *addrlen = sizeof (*ip4); memcpy (&ip4->sin_port, ptr + 2, 2); memcpy (&ip4->sin_addr, ptr + 4, 4); return STUN_MESSAGE_RETURN_SUCCESS; } case 2: { struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)addr; if (((size_t) *addrlen < sizeof (*ip6)) || (len != 20)) { *addrlen = sizeof (*ip6); return STUN_MESSAGE_RETURN_INVALID; } memset (ip6, 0, *addrlen); ip6->sin6_family = AF_INET6; #ifdef HAVE_SA_LEN ip6->sin6_len = #endif *addrlen = sizeof (*ip6); memcpy (&ip6->sin6_port, ptr + 2, 2); memcpy (&ip6->sin6_addr, ptr + 4, 16); return STUN_MESSAGE_RETURN_SUCCESS; } default: return STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS; } } StunMessageReturn stun_message_find_xor_addr (const StunMessage *msg, StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen) { StunMessageReturn val = stun_message_find_addr (msg, type, addr, addrlen); if (val) return val; return stun_xor_address (msg, addr, *addrlen, STUN_MAGIC_COOKIE); } StunMessageReturn stun_message_find_xor_addr_full (const StunMessage *msg, StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen, uint32_t magic_cookie) { StunMessageReturn val = stun_message_find_addr (msg, type, addr, addrlen); if (val) return val; return stun_xor_address (msg, addr, *addrlen, magic_cookie); } StunMessageReturn stun_message_find_error (const StunMessage *msg, int *code) { uint16_t alen = 0; const uint8_t *ptr = stun_message_find (msg, STUN_ATTRIBUTE_ERROR_CODE, &alen); uint8_t class, number; if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_FOUND; if (alen < 4) return STUN_MESSAGE_RETURN_INVALID; class = ptr[2] & 0x7; number = ptr[3]; if ((class < 3) || (class > 6) || (number > 99)) return STUN_MESSAGE_RETURN_INVALID; *code = (class * 100) + number; return STUN_MESSAGE_RETURN_SUCCESS; } void * stun_message_append (StunMessage *msg, StunAttribute type, size_t length) { uint8_t *a; uint16_t mlen = stun_message_length (msg); /* In MS-TURN, IDs of REALM and NONCE STUN attributes are swapped. */ if (msg->agent && msg->agent->compatibility == STUN_COMPATIBILITY_OC2007) { if (type == STUN_ATTRIBUTE_NONCE) type = STUN_ATTRIBUTE_REALM; else if (type == STUN_ATTRIBUTE_REALM) type = STUN_ATTRIBUTE_NONCE; } if ((size_t)mlen + STUN_ATTRIBUTE_HEADER_LENGTH + length > msg->buffer_len) return NULL; a = msg->buffer + mlen; a = stun_setw (a, type); if (msg->agent && (msg->agent->usage_flags & STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES)) { a = stun_setw (a, length); } else { /* NOTE: If cookie is not present, we need to force the attribute length * to a multiple of 4 for compatibility with old RFC3489 */ a = stun_setw (a, stun_message_has_cookie (msg) ? length : stun_align (length)); /* Add padding if needed. Avoid a zero-length memset() call. */ if (stun_padding (length) > 0) { memset (a + length, ' ', stun_padding (length)); mlen += stun_padding (length); } } mlen += 4 + length; stun_setw (msg->buffer + STUN_MESSAGE_LENGTH_POS, mlen - STUN_MESSAGE_HEADER_LENGTH); return a; } StunMessageReturn stun_message_append_bytes (StunMessage *msg, StunAttribute type, const void *data, size_t len) { void *ptr = stun_message_append (msg, type, len); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE; if (len > 0) memcpy (ptr, data, len); return STUN_MESSAGE_RETURN_SUCCESS; } StunMessageReturn stun_message_append_flag (StunMessage *msg, StunAttribute type) { return stun_message_append_bytes (msg, type, NULL, 0); } StunMessageReturn stun_message_append32 (StunMessage *msg, StunAttribute type, uint32_t value) { value = htonl (value); return stun_message_append_bytes (msg, type, &value, 4); } StunMessageReturn stun_message_append64 (StunMessage *msg, StunAttribute type, uint64_t value) { uint32_t tab[2]; tab[0] = htonl ((uint32_t)(value >> 32)); tab[1] = htonl ((uint32_t)value); return stun_message_append_bytes (msg, type, tab, 8); } StunMessageReturn stun_message_append_string (StunMessage * msg, StunAttribute type, const char *str) { return stun_message_append_bytes (msg, type, str, strlen (str)); } StunMessageReturn stun_message_append_addr (StunMessage *msg, StunAttribute type, const struct sockaddr *addr, socklen_t addrlen) { const void *pa; uint8_t *ptr; uint16_t alen, port; uint8_t family; union { const struct sockaddr *addr; const struct sockaddr_in *in; const struct sockaddr_in6 *in6; } sa; if ((size_t) addrlen < sizeof (struct sockaddr)) return STUN_MESSAGE_RETURN_INVALID; sa.addr = addr; switch (addr->sa_family) { case AF_INET: { const struct sockaddr_in *ip4 = sa.in; family = 1; port = ip4->sin_port; alen = 4; pa = &ip4->sin_addr; break; } case AF_INET6: { const struct sockaddr_in6 *ip6 = sa.in6; if ((size_t) addrlen < sizeof (*ip6)) return STUN_MESSAGE_RETURN_INVALID; family = 2; port = ip6->sin6_port; alen = 16; pa = &ip6->sin6_addr; break; } default: return STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS; } ptr = stun_message_append (msg, type, 4 + alen); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE; ptr[0] = 0; ptr[1] = family; memcpy (ptr + 2, &port, 2); memcpy (ptr + 4, pa, alen); return STUN_MESSAGE_RETURN_SUCCESS; } StunMessageReturn stun_message_append_xor_addr (StunMessage *msg, StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen) { StunMessageReturn val; /* Must be big enough to hold any supported address: */ struct sockaddr_storage tmpaddr; if ((size_t) addrlen > sizeof (tmpaddr)) addrlen = sizeof (tmpaddr); memcpy (&tmpaddr, addr, addrlen); val = stun_xor_address (msg, &tmpaddr, addrlen, STUN_MAGIC_COOKIE); if (val) return val; return stun_message_append_addr (msg, type, (struct sockaddr *) &tmpaddr, addrlen); } StunMessageReturn stun_message_append_xor_addr_full (StunMessage *msg, StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen, uint32_t magic_cookie) { StunMessageReturn val; /* Must be big enough to hold any supported address: */ struct sockaddr_storage tmpaddr; if ((size_t) addrlen > sizeof (tmpaddr)) addrlen = sizeof (tmpaddr); memcpy (&tmpaddr, addr, addrlen); val = stun_xor_address (msg, &tmpaddr, addrlen, magic_cookie); if (val) return val; return stun_message_append_addr (msg, type, (struct sockaddr *) &tmpaddr, addrlen); } StunMessageReturn stun_message_append_error (StunMessage *msg, StunError code) { const char *str = stun_strerror (code); size_t len = strlen (str); uint8_t *ptr = stun_message_append (msg, STUN_ATTRIBUTE_ERROR_CODE, 4 + len); if (ptr == NULL) return STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE; memset (ptr, 0, 2); ptr[2] = code / 100; ptr[3] = code % 100; memcpy (ptr + 4, str, len); return STUN_MESSAGE_RETURN_SUCCESS; } /* Fast validity check for a potential STUN packet. Examines the type and * length, but none of the attributes. Designed to allow vectored I/O on all * incoming packets, filtering packets for closer inspection as to whether * they’re STUN packets. If they look like they might be, their buffers are * compacted to allow a more thorough check. */ ssize_t stun_message_validate_buffer_length_fast (StunInputVector *buffers, int n_buffers, size_t total_length, bool has_padding) { size_t mlen; if (total_length < 1 || n_buffers == 0 || buffers[0].buffer == NULL) { stun_debug ("STUN error: No data!"); return STUN_MESSAGE_BUFFER_INVALID; } if (buffers[0].buffer[0] >> 6) { return STUN_MESSAGE_BUFFER_INVALID; // RTP or other non-STUN packet } if (total_length < STUN_MESSAGE_LENGTH_POS + STUN_MESSAGE_LENGTH_LEN) { stun_debug ("STUN error: Incomplete STUN message header!"); return STUN_MESSAGE_BUFFER_INCOMPLETE; } if (buffers[0].size >= STUN_MESSAGE_LENGTH_POS + STUN_MESSAGE_LENGTH_LEN) { /* Fast path. */ mlen = stun_getw (buffers[0].buffer + STUN_MESSAGE_LENGTH_POS); } else { /* Slow path. Tiny buffers abound. */ size_t skip_remaining = STUN_MESSAGE_LENGTH_POS; unsigned int i; /* Skip bytes. */ for (i = 0; (n_buffers >= 0 && i < (unsigned int) n_buffers) || (n_buffers < 0 && buffers[i].buffer != NULL); i++) { if (buffers[i].size <= skip_remaining) skip_remaining -= buffers[i].size; else break; } /* Read bytes. May be split over two buffers. We’ve already checked that * @total_length is long enough, so @n_buffers should be too. */ if (buffers[i].size - skip_remaining > 1) { mlen = stun_getw (buffers[i].buffer + skip_remaining); } else { mlen = (*(buffers[i].buffer + skip_remaining) << 8) | (*(buffers[i + 1].buffer)); } } mlen += STUN_MESSAGE_HEADER_LENGTH; if (has_padding && stun_padding (mlen)) { stun_debug ("STUN error: Invalid message length: %u!", (unsigned)mlen); return STUN_MESSAGE_BUFFER_INVALID; // wrong padding } if (total_length < mlen) { stun_debug ("STUN error: Incomplete message: %u of %u bytes!", (unsigned) total_length, (unsigned) mlen); return STUN_MESSAGE_BUFFER_INCOMPLETE; // partial message } return mlen; } int stun_message_validate_buffer_length (const uint8_t *msg, size_t length, bool has_padding) { ssize_t fast_retval; size_t mlen; size_t len; StunInputVector input_buffer = { msg, length }; /* Fast pre-check first. */ fast_retval = stun_message_validate_buffer_length_fast (&input_buffer, 1, length, has_padding); if (fast_retval <= 0) return fast_retval; mlen = fast_retval; /* Skip past the header (validated above). */ msg += 20; len = mlen - 20; /* from then on, we know we have the entire packet in buffer */ while (len > 0) { size_t alen; if (len < 4) { stun_debug ("STUN error: Incomplete STUN attribute header of length " "%u bytes!", (unsigned)len); return STUN_MESSAGE_BUFFER_INVALID; } alen = stun_getw (msg + STUN_ATTRIBUTE_TYPE_LEN); if (has_padding) alen = stun_align (alen); /* thanks to padding check, if (end > msg) then there is not only one * but at least 4 bytes left */ len -= 4; if (len < alen) { stun_debug ("STUN error: %u instead of %u bytes for attribute!", (unsigned)len, (unsigned)alen); return STUN_MESSAGE_BUFFER_INVALID; // no room for attribute value + padding } len -= alen; msg += 4 + alen; } return mlen; } void stun_message_id (const StunMessage *msg, StunTransactionId id) { memcpy (id, msg->buffer + STUN_MESSAGE_TRANS_ID_POS, STUN_MESSAGE_TRANS_ID_LEN); } StunMethod stun_message_get_method (const StunMessage *msg) { uint16_t t = stun_getw (msg->buffer); /* HACK HACK HACK A google/msn data indication is 0x0115 which is contrary to the RFC 5389 which states that 8th and 12th bits are for the class and that 0x01 is for indications... So 0x0115 is reported as a "connect error response", while it should be a data indication, which message type should actually be 0x0017 This should fix the issue, and it's considered safe since the "connect" method doesn't exist anymore */ if (t == 0x0115) t = 0x0017; return (StunMethod)(((t & 0x3e00) >> 2) | ((t & 0x00e0) >> 1) | (t & 0x000f)); } StunClass stun_message_get_class (const StunMessage *msg) { uint16_t t = stun_getw (msg->buffer); /* HACK HACK HACK A google/msn data indication is 0x0115 which is contrary to the RFC 5389 which states that 8th and 12th bits are for the class and that 0x01 is for indications... So 0x0115 is reported as a "connect error response", while it should be a data indication, which message type should actually be 0x0017 This should fix the issue, and it's considered safe since the "connect" method doesn't exist anymore */ if (t == 0x0115) t = 0x0017; return (StunClass)(((t & 0x0100) >> 7) | ((t & 0x0010) >> 4)); } bool stun_message_has_attribute (const StunMessage *msg, StunAttribute type) { uint16_t dummy; return stun_message_find (msg, type, &dummy) != NULL; } bool stun_optional (uint16_t t) { return (t >> 15) == 1; } const char *stun_strerror (StunError code) { static const struct { StunError code; char phrase[32]; } tab[] = { { STUN_ERROR_TRY_ALTERNATE, "Try alternate server" }, { STUN_ERROR_BAD_REQUEST, "Bad request" }, { STUN_ERROR_UNAUTHORIZED, "Unauthorized" }, { STUN_ERROR_UNKNOWN_ATTRIBUTE, "Unknown Attribute" }, { STUN_ERROR_ALLOCATION_MISMATCH, "Allocation Mismatch" }, { STUN_ERROR_STALE_NONCE, "Stale Nonce" }, { STUN_ERROR_ACT_DST_ALREADY, "Active Destination Already Set" }, { STUN_ERROR_UNSUPPORTED_FAMILY, "Address Family not Supported" }, { STUN_ERROR_UNSUPPORTED_TRANSPORT, "Unsupported Transport Protocol" }, { STUN_ERROR_INVALID_IP, "Invalid IP Address" }, { STUN_ERROR_INVALID_PORT, "Invalid Port" }, { STUN_ERROR_OP_TCP_ONLY, "Operation for TCP Only" }, { STUN_ERROR_CONN_ALREADY, "Connection Already Exists" }, { STUN_ERROR_ALLOCATION_QUOTA_REACHED, "Allocation Quota Reached" }, { STUN_ERROR_ROLE_CONFLICT, "Role conflict" }, { STUN_ERROR_SERVER_ERROR, "Server Error" }, { STUN_ERROR_SERVER_CAPACITY, "Insufficient Capacity" }, { STUN_ERROR_INSUFFICIENT_CAPACITY, "Insufficient Capacity" }, }; const char *str = "Unknown error"; size_t i; for (i = 0; i < (sizeof (tab) / sizeof (tab[0])); i++) { if (tab[i].code == code) { str = tab[i].phrase; break; } } /* Maximum allowed error message length */ // assert (strlen (str) < 128); return str; } libnice-0.1.14/COPYING.LGPL0000644000076400007640000006363711241364464011747 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libnice-0.1.14/compile0000755000076400007640000001624513067560510011524 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnice-0.1.14/nice/0000775000076400007640000000000013070512356011135 500000000000000libnice-0.1.14/nice/test-symbols.sh0000775000076400007640000000051112725333757014072 00000000000000#!/bin/sh set -e if test -z "$srcdir"; then srcdir=. fi check_symbols=$srcdir/../scripts/check-symbols.sh if ! test -f $check_symbols; then echo "cannot find check-symbols.sh" exit 1 fi if ! test -f .libs/libnice.so; then echo "no shared object found" >&2 exit 77 fi sh $check_symbols .libs/libnice.so libnice.symbols libnice-0.1.14/nice/nice.h0000664000076400007640000000325711522161146012150 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _NICE_H #define _NICE_H #include "agent.h" #include "interfaces.h" #endif /* _NICE_H */ libnice-0.1.14/nice/Makefile.in0000664000076400007640000010740713070512350013125 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = nice ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = nice.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(pkgincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = am_libnice_la_OBJECTS = libnice_la_OBJECTS = $(am_libnice_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libnice_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libnice_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libnice_la_SOURCES) DIST_SOURCES = $(libnice_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(pkgconfig_DATA) HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/nice.pc.in \ $(top_srcdir)/common.mk $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda libnice.symbols libnice-symbols-test.c \ libnice-symbols-test.o lib_LTLIBRARIES = libnice.la libnice_la_SOURCES = libnice_la_DEPENDENCIES = \ $(top_builddir)/agent/libagent.la \ libnice.sym libnice_la_LIBADD = \ $(GLIB_LIBS) \ $(GUPNP_LIBS) \ $(top_builddir)/agent/libagent.la libnice_la_LDFLAGS = \ -export-symbols $(srcdir)/libnice.sym \ $(LIBNICE_LT_LDFLAGS) AM_CFLAGS = \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun check_SCRIPTS = test-symbols.sh check_DATA = libnice.symbols TESTS = $(check_SCRIPTS) EXTRA_DIST = $(check_SCRIPTS) libnice.sym libnice.ver pkginclude_HEADERS = nice.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = nice.pc all: all-am .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu nice/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu nice/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): nice.pc: $(top_builddir)/config.status $(srcdir)/nice.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libnice.la: $(libnice_la_OBJECTS) $(libnice_la_DEPENDENCIES) $(EXTRA_libnice_la_DEPENDENCIES) $(AM_V_CCLD)$(libnice_la_LINK) -rpath $(libdir) $(libnice_la_OBJECTS) $(libnice_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_SCRIPTS) $(check_DATA) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test-symbols.sh.log: test-symbols.sh @p='test-symbols.sh'; \ b='test-symbols.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) $(check_DATA) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgconfigDATA install-pkgincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigDATA \ uninstall-pkgincludeHEADERS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-pkgconfigDATA install-pkgincludeHEADERS \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ uninstall-libLTLIBRARIES uninstall-pkgconfigDATA \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind test-symbols.sh:: chmod +x $(srcdir)/$@ libnice-symbols-test.c: libnice.sym rm -f $@ while read s; do echo "void $$s(void) { }" ; done < $? > $@ libnice-symbols-test.o: libnice-symbols-test.c $(CC) $(CFLAGS) -c -o $@ $? libnice.symbols: libnice-symbols-test.o rm -f $@ $(top_srcdir)/scripts/make-symbol-list.sh $? > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/nice/Makefile.am0000664000076400007640000000251012363772107013115 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include $(top_srcdir)/common.mk lib_LTLIBRARIES = libnice.la libnice_la_SOURCES = libnice_la_DEPENDENCIES = \ $(top_builddir)/agent/libagent.la \ libnice.sym libnice_la_LIBADD = \ $(GLIB_LIBS) \ $(GUPNP_LIBS) \ $(top_builddir)/agent/libagent.la libnice_la_LDFLAGS = \ -export-symbols $(srcdir)/libnice.sym \ $(LIBNICE_LT_LDFLAGS) AM_CFLAGS = \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun test-symbols.sh:: chmod +x $(srcdir)/$@ libnice-symbols-test.c: libnice.sym rm -f $@ while read s; do echo "void $$s(void) { }" ; done < $? > $@ libnice-symbols-test.o: libnice-symbols-test.c $(CC) $(CFLAGS) -c -o $@ $? libnice.symbols: libnice-symbols-test.o rm -f $@ $(top_srcdir)/scripts/make-symbol-list.sh $? > $@ CLEANFILES += libnice.symbols libnice-symbols-test.c libnice-symbols-test.o check_SCRIPTS = test-symbols.sh check_DATA = libnice.symbols TESTS = $(check_SCRIPTS) EXTRA_DIST = $(check_SCRIPTS) libnice.sym libnice.ver pkginclude_HEADERS = nice.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = nice.pc libnice-0.1.14/nice/libnice.sym0000664000076400007640000000727212724403337013227 00000000000000nice_address_copy_to_sockaddr nice_address_dup nice_address_equal nice_address_equal_no_port nice_address_free nice_address_get_port nice_address_init nice_address_ip_version nice_address_is_private nice_address_is_valid nice_address_new nice_address_set_from_sockaddr nice_address_set_from_string nice_address_set_ipv4 nice_address_set_ipv6 nice_address_set_port nice_address_to_string nice_agent_add_local_address nice_agent_add_stream nice_agent_recv nice_agent_recv_messages nice_agent_recv_nonblocking nice_agent_recv_messages_nonblocking nice_agent_attach_recv nice_agent_forget_relays nice_agent_gather_candidates nice_agent_generate_local_candidate_sdp nice_agent_generate_local_sdp nice_agent_generate_local_stream_sdp nice_agent_get_component_state nice_agent_get_default_local_candidate nice_agent_get_io_stream nice_agent_get_local_candidates nice_agent_get_local_credentials nice_agent_get_remote_candidates nice_agent_get_selected_pair nice_agent_get_selected_socket nice_agent_get_stream_name nice_agent_get_type nice_agent_new nice_agent_new_reliable nice_agent_parse_remote_candidate_sdp nice_agent_parse_remote_sdp nice_agent_parse_remote_stream_sdp nice_agent_remove_stream nice_agent_restart nice_agent_restart_stream nice_agent_send nice_agent_send_messages_nonblocking nice_agent_set_port_range nice_agent_set_relay_info nice_agent_set_remote_candidates nice_agent_set_remote_credentials nice_agent_set_local_credentials nice_agent_set_selected_pair nice_agent_set_selected_remote_candidate nice_agent_set_software nice_agent_set_stream_name nice_agent_set_stream_tos nice_candidate_copy nice_candidate_free nice_candidate_new nice_component_state_to_string nice_debug_disable nice_debug_enable nice_interfaces_get_ip_for_interface nice_interfaces_get_local_interfaces nice_interfaces_get_local_ips nice_io_stream_new nice_input_stream_new nice_output_stream_new pseudo_tcp_set_debug_level pseudo_tcp_socket_close pseudo_tcp_socket_connect pseudo_tcp_socket_get_error pseudo_tcp_socket_get_next_clock pseudo_tcp_socket_get_type pseudo_tcp_socket_is_closed pseudo_tcp_socket_is_closed_remotely pseudo_tcp_socket_new pseudo_tcp_socket_notify_clock pseudo_tcp_socket_notify_mtu pseudo_tcp_socket_notify_packet pseudo_tcp_socket_recv pseudo_tcp_socket_send pseudo_tcp_socket_shutdown stun_agent_build_unknown_attributes_error stun_agent_default_validater stun_agent_finish_message stun_agent_forget_transaction stun_agent_init stun_agent_init_error stun_agent_init_indication stun_agent_init_request stun_agent_init_response stun_agent_set_software stun_agent_validate stun_debug_disable stun_debug_enable stun_message_append stun_message_append32 stun_message_append64 stun_message_append_addr stun_message_append_bytes stun_message_append_error stun_message_append_flag stun_message_append_string stun_message_append_xor_addr stun_message_append_xor_addr_full stun_message_find stun_message_find32 stun_message_find64 stun_message_find_addr stun_message_find_error stun_message_find_flag stun_message_find_string stun_message_find_xor_addr stun_message_find_xor_addr_full stun_message_get_class stun_message_get_method stun_message_has_attribute stun_message_has_cookie stun_message_id stun_message_init stun_message_length stun_message_validate_buffer_length stun_optional stun_strerror stun_timer_refresh stun_timer_remainder stun_timer_start stun_timer_start_reliable stun_usage_bind_create stun_usage_bind_keepalive stun_usage_bind_process stun_usage_bind_run stun_usage_ice_conncheck_create stun_usage_ice_conncheck_create_reply stun_usage_ice_conncheck_priority stun_usage_ice_conncheck_process stun_usage_ice_conncheck_use_candidate stun_usage_turn_create stun_usage_turn_create_refresh stun_usage_turn_process stun_usage_turn_refresh_process libnice-0.1.14/nice/nice.pc.in0000664000076400007640000000055313070464720012730 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ upnp_enabled=@UPNP_ENABLED@ Name: libnice Description: ICE library Version: @VERSION@ Requires: @NICE_PACKAGES_PUBLIC@ @GUPNP_PACKAGES_PUBLIC@ Requires.private: @NICE_PACKAGES_PRIVATE@ @GUPNP_PACKAGES_PRIVATE@ Libs: -L${libdir} -lnice Cflags: -I${includedir}/nice -I${includedir} libnice-0.1.14/nice/libnice.ver0000644000076400007640000000007011241364464013176 00000000000000 libnice { global: nice_*; }; HIDDEN { local: *; }; libnice-0.1.14/scripts/0000775000076400007640000000000013070512355011705 500000000000000libnice-0.1.14/scripts/make-symbol-list.sh0000755000076400007640000000021611241364464015356 00000000000000#!/bin/sh test -n "$1" || exit 1 nm --print-file-name --defined-only --extern-only "$1" | \ cut -d ' ' -f 2,3 | \ grep -v '^[rA]' | \ sort libnice-0.1.14/scripts/lcov.sh0000755000076400007640000000017611241364464013135 00000000000000#!/bin/sh make -f scripts/lcov.mk lcov-clean && \ make -f scripts/lcov.mk lcov-build && \ make -f scripts/lcov.mk lcov-report libnice-0.1.14/scripts/valgrind.sh0000775000076400007640000000101212520743534013770 00000000000000#!/bin/sh export G_SLICE=always-malloc export G_DEBUG=gc-friendly tests_dir="`dirname $0`/../tests" report=`libtool --mode=execute valgrind \ --leak-check=full \ --show-reachable=no \ --error-exitcode=1 \ --suppressions=$tests_dir/libnice.supp \ --num-callers=30 \ $1 2>&1` #if echo "$report" | grep -q ==; then if test $? != 0; then echo "$report" exit 1 fi if echo "$report" | grep -q "definitely lost"; then if ! echo "$report" | grep -q "definitely lost: 0 bytes"; then echo "$report" exit 1 fi fi libnice-0.1.14/scripts/check-symbols.sh0000755000076400007640000000135611241364464014736 00000000000000#!/bin/sh usage() { echo "usage: $0 library symbol-file" exit 1 } test -n "$1" || usage lib="$1" test -n "$2" || usage symbol_file="$2" make_symbol_list=`dirname $0`/make-symbol-list.sh test -f "$make_symbol_list" || exit 1 if ! test -f "$symbol_file"; then echo "$symbol_file doesn't exist" exit 1 fi diff=`sh $make_symbol_list "$lib" | \ diff -uB "$symbol_file" - | tail -n +3` # stop if there are no differences test -z "$diff" && exit 0 echo "symbols for $lib changed" if echo "$diff" | grep -q '^-'; then echo " missing:" echo "$diff" | grep '^-' | cut -b 2- | \ xargs -i echo " " "{}" fi if echo "$diff" | grep -q '^+'; then echo " extra:" echo "$diff" | grep '^+' | cut -b 2- | \ xargs -i echo " " "{}" fi exit 1 libnice-0.1.14/scripts/lcov.mk0000644000076400007640000000134211241364464013123 00000000000000 # ccache breaks -fprofile-arcs export CCACHE_DISABLE=1 OUT=lcov lcov-clean: $(MAKE) clean find -name "*.gcno" -o -name "*.gcda" -exec rm '{}' ';' rm -rf $(OUT) lcov-build: $(MAKE) CFLAGS="-O0 -fprofile-arcs -ftest-coverage" LDFLAGS="-lgcov" check lcov-report: # hack: move gcov file from libraries back to source directory for dir in `find -name .libs`; do \ (cd `dirname $$dir`; mv .libs/*.gc?? . || true) 2>/dev/null; \ done mkdir -p $(OUT) lcov -d . -c >$(OUT)/lcov.info 2>/dev/null lcov -l $(OUT)/lcov.info 2>/dev/null |\ egrep '(^/usr|/test.*\.c)' |\ cut -d: -f1 >$(OUT)/lcov.remove lcov -r $(OUT)/lcov.info `cat $(OUT)/lcov.remove` 2>/dev/null >$(OUT)/lcov.info.clean genhtml -o lcov $(OUT)/lcov.info.clean libnice-0.1.14/agent/0000775000076400007640000000000013070512356011315 500000000000000libnice-0.1.14/agent/inputstream.h0000664000076400007640000000555012363772107013774 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __NICE_INPUT_STREAM_H__ #define __NICE_INPUT_STREAM_H__ #include #include #include "agent.h" G_BEGIN_DECLS /* TYPE MACROS */ #define NICE_TYPE_INPUT_STREAM \ (nice_input_stream_get_type ()) #define NICE_INPUT_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), NICE_TYPE_INPUT_STREAM, \ NiceInputStream)) #define NICE_INPUT_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), NICE_TYPE_INPUT_STREAM, \ NiceInputStreamClass)) #define NICE_IS_INPUT_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj), NICE_TYPE_INPUT_STREAM)) #define NICE_IS_INPUT_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass), NICE_TYPE_INPUT_STREAM)) #define NICE_INPUT_STREAM_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), NICE_TYPE_INPUT_STREAM, \ NiceInputStreamClass)) typedef struct _NiceInputStreamPrivate NiceInputStreamPrivate; typedef struct _NiceInputStreamClass NiceInputStreamClass; typedef struct _NiceInputStream NiceInputStream; GType nice_input_stream_get_type (void); struct _NiceInputStreamClass { GInputStreamClass parent_class; }; struct _NiceInputStream { GInputStream parent_instance; NiceInputStreamPrivate *priv; }; NiceInputStream *nice_input_stream_new (NiceAgent *agent, guint stream_id, guint component_id); G_END_DECLS #endif /* __NICE_INPUT_STREAM_H__ */ libnice-0.1.14/agent/agent-priv.h0000664000076400007640000002376713067552405013506 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _NICE_AGENT_PRIV_H #define _NICE_AGENT_PRIV_H /* note: this is a private header part of agent.h */ #ifdef HAVE_CONFIG_H # include #else #define NICEAPI_EXPORT #endif #include #include "agent.h" /** * NiceInputMessageIter: * @message: index of the message currently being written into * @buffer: index of the buffer currently being written into * @offset: byte offset into the buffer * * Iterator for sequentially writing into an array of #NiceInputMessages, * tracking the current write position (i.e. the index of the next byte to be * written). * * If @message is equal to the number of messages in the associated * #NiceInputMessage array, and @buffer and @offset are zero, the iterator is at * the end of the messages array, and the array is (presumably) full. * * Since: 0.1.5 */ typedef struct { guint message; guint buffer; gsize offset; } NiceInputMessageIter; void nice_input_message_iter_reset (NiceInputMessageIter *iter); gboolean nice_input_message_iter_is_at_end (NiceInputMessageIter *iter, NiceInputMessage *messages, guint n_messages); guint nice_input_message_iter_get_n_valid_messages (NiceInputMessageIter *iter); gboolean nice_input_message_iter_compare (const NiceInputMessageIter *a, const NiceInputMessageIter *b); #include "socket.h" #include "candidate.h" #include "stream.h" #include "conncheck.h" #include "component.h" #include "random.h" #include "stun/stunagent.h" #include "stun/usages/turn.h" #include "stun/usages/ice.h" #ifdef HAVE_GUPNP #include #endif /* XXX: starting from ICE ID-18, Ta SHOULD now be set according * to session bandwidth -> this is not yet implemented in NICE */ #define NICE_AGENT_TIMER_TA_DEFAULT 20 /* timer Ta, msecs (impl. defined) */ #define NICE_AGENT_TIMER_TR_DEFAULT 25000 /* timer Tr, msecs (impl. defined) */ #define NICE_AGENT_TIMER_TR_MIN 15000 /* timer Tr, msecs (ICE ID-19) */ #define NICE_AGENT_MAX_CONNECTIVITY_CHECKS_DEFAULT 100 /* see spec 5.7.3 (ID-19) */ /* An upper limit to size of STUN packets handled (based on Ethernet * MTU and estimated typical sizes of ICE STUN packet */ #define MAX_STUN_DATAGRAM_PAYLOAD 1300 struct _NiceAgent { GObject parent; /* gobject pointer */ gboolean full_mode; /* property: full-mode */ gchar *stun_server_ip; /* property: STUN server IP */ guint stun_server_port; /* property: STUN server port */ gchar *proxy_ip; /* property: Proxy server IP */ guint proxy_port; /* property: Proxy server port */ NiceProxyType proxy_type; /* property: Proxy type */ gchar *proxy_username; /* property: Proxy username */ gchar *proxy_password; /* property: Proxy password */ gboolean controlling_mode; /* property: controlling-mode */ guint timer_ta; /* property: timer Ta */ guint max_conn_checks; /* property: max connectivity checks */ gboolean force_relay; /* property: force relay */ GSList *local_addresses; /* list of NiceAddresses for local interfaces */ GSList *streams; /* list of Stream objects */ GMainContext *main_context; /* main context pointer */ guint next_candidate_id; /* id of next created candidate */ guint next_stream_id; /* id of next created candidate */ NiceRNG *rng; /* random number generator */ GSList *discovery_list; /* list of CandidateDiscovery items */ GSList *triggered_check_queue; /* pairs in the triggered check list */ guint discovery_unsched_items; /* number of discovery items unscheduled */ GSource *discovery_timer_source; /* source of discovery timer */ GSource *conncheck_timer_source; /* source of conncheck timer */ GSource *keepalive_timer_source; /* source of keepalive timer */ GSList *refresh_list; /* list of CandidateRefresh items */ guint64 tie_breaker; /* tie breaker (ICE sect 5.2 "Determining Role" ID-19) */ NiceCompatibility compatibility; /* property: Compatibility mode */ gboolean media_after_tick; /* Received media after keepalive tick */ #ifdef HAVE_GUPNP GUPnPSimpleIgdThread* upnp; /* GUPnP Single IGD agent */ gboolean upnp_enabled; /* whether UPnP discovery is enabled */ guint upnp_timeout; /* UPnP discovery timeout */ GSList *upnp_mapping; /* NiceAddresses of cands being mapped */ GSource *upnp_timer_source; /* source of upnp timeout timer */ #endif gchar *software_attribute; /* SOFTWARE attribute */ gboolean reliable; /* property: reliable */ gboolean keepalive_conncheck; /* property: keepalive_conncheck */ GQueue pending_signals; guint16 rfc4571_expecting_length; gboolean use_ice_udp; gboolean use_ice_tcp; /* XXX: add pointer to internal data struct for ABI-safe extensions */ }; gboolean agent_find_component ( NiceAgent *agent, guint stream_id, guint component_id, NiceStream **stream, NiceComponent **component) G_GNUC_WARN_UNUSED_RESULT; NiceStream *agent_find_stream (NiceAgent *agent, guint stream_id); void agent_gathering_done (NiceAgent *agent); void agent_signal_gathering_done (NiceAgent *agent); void agent_lock (void); void agent_unlock (void); void agent_unlock_and_emit (NiceAgent *agent); void agent_signal_new_selected_pair ( NiceAgent *agent, guint stream_id, guint component_id, NiceCandidate *lcandidate, NiceCandidate *rcandidate); void agent_signal_component_state_change ( NiceAgent *agent, guint stream_id, guint component_id, NiceComponentState state); void agent_signal_new_candidate ( NiceAgent *agent, NiceCandidate *candidate); void agent_signal_new_remote_candidate (NiceAgent *agent, NiceCandidate *candidate); void agent_signal_initial_binding_request_received (NiceAgent *agent, NiceStream *stream); guint64 agent_candidate_pair_priority (NiceAgent *agent, NiceCandidate *local, NiceCandidate *remote); void agent_timeout_add_with_context (NiceAgent *agent, GSource **out, const gchar *name, guint interval, GSourceFunc function, gpointer data); StunUsageIceCompatibility agent_to_ice_compatibility (NiceAgent *agent); StunUsageTurnCompatibility agent_to_turn_compatibility (NiceAgent *agent); NiceTurnSocketCompatibility agent_to_turn_socket_compatibility (NiceAgent *agent); void agent_remove_local_candidate (NiceAgent *agent, NiceCandidate *candidate); void nice_agent_init_stun_agent (NiceAgent *agent, StunAgent *stun_agent); void _priv_set_socket_tos (NiceAgent *agent, NiceSocket *sock, gint tos); void _tcp_sock_is_writable (NiceSocket *sock, gpointer user_data); gboolean component_io_cb ( GSocket *gsocket, GIOCondition condition, gpointer data); gsize memcpy_buffer_to_input_message (NiceInputMessage *message, const guint8 *buffer, gsize buffer_length); guint8 * compact_input_message (const NiceInputMessage *message, gsize *buffer_length); guint8 * compact_output_message (const NiceOutputMessage *message, gsize *buffer_length); gsize output_message_get_size (const NiceOutputMessage *message); gssize agent_socket_send (NiceSocket *sock, const NiceAddress *addr, gsize len, const gchar *buf); guint32 nice_candidate_jingle_priority (NiceCandidate *candidate); guint32 nice_candidate_msn_priority (NiceCandidate *candidate); guint32 nice_candidate_ice_priority_full (guint type_pref, guint local_pref, guint component_id); guint32 nice_candidate_ice_priority (const NiceCandidate *candidate, gboolean reliable, gboolean nat_assisted); guint32 nice_candidate_ms_ice_priority (const NiceCandidate *candidate, gboolean reliable, gboolean nat_assisted); guint64 nice_candidate_pair_priority (guint32 o_prio, guint32 a_prio); /* * nice_debug_init: * * Initialize the debugging system. Uses the NICE_DEBUG environment variable * to set the appropriate debugging flags */ void nice_debug_init (void); #ifdef NDEBUG static inline gboolean nice_debug_is_enabled (void) { return FALSE; } static inline gboolean nice_debug_is_verbose (void) { return FALSE; } static inline void nice_debug (const char *fmt, ...) { } static inline void nice_debug_verbose (const char *fmt, ...) { } #else gboolean nice_debug_is_enabled (void); gboolean nice_debug_is_verbose (void); void nice_debug (const char *fmt, ...) G_GNUC_PRINTF (1, 2); void nice_debug_verbose (const char *fmt, ...) G_GNUC_PRINTF (1, 2); #endif #endif /*_NICE_AGENT_PRIV_H */ libnice-0.1.14/agent/conncheck.c0000664000076400007640000037754413067571702013366 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Kai Vehmanen, Nokia * Youness Alaoui, Collabora Ltd. * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * @file conncheck.c * @brief ICE connectivity checks */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "debug.h" #include "agent.h" #include "agent-priv.h" #include "conncheck.h" #include "discovery.h" #include "stun/stun5389.h" #include "stun/usages/ice.h" #include "stun/usages/bind.h" #include "stun/usages/turn.h" static void priv_update_check_list_failed_components (NiceAgent *agent, NiceStream *stream); static void priv_update_check_list_state_for_ready (NiceAgent *agent, NiceStream *stream, NiceComponent *component); static guint priv_prune_pending_checks (NiceStream *stream, guint component_id); static gboolean priv_schedule_triggered_check (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *local_socket, NiceCandidate *remote_cand, gboolean use_candidate); static void priv_mark_pair_nominated (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceCandidate *localcand, NiceCandidate *remotecand); static size_t priv_create_username (NiceAgent *agent, NiceStream *stream, guint component_id, NiceCandidate *remote, NiceCandidate *local, uint8_t *dest, guint dest_len, gboolean inbound); static size_t priv_get_password (NiceAgent *agent, NiceStream *stream, NiceCandidate *remote, uint8_t **password); static void conn_check_free_item (gpointer data); static CandidateCheckPair *priv_conn_check_add_for_candidate_pair_matched ( NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local, NiceCandidate *remote, NiceCheckState initial_state); static int priv_timer_expired (GTimeVal *timer, GTimeVal *now) { return (now->tv_sec == timer->tv_sec) ? now->tv_usec >= timer->tv_usec : now->tv_sec >= timer->tv_sec; } static gchar priv_state_to_gchar (NiceCheckState state) { switch (state) { case NICE_CHECK_WAITING: return 'W'; case NICE_CHECK_IN_PROGRESS: return 'I'; case NICE_CHECK_SUCCEEDED: return 'S'; case NICE_CHECK_FAILED: return 'F'; case NICE_CHECK_FROZEN: return 'Z'; case NICE_CHECK_CANCELLED: return 'C'; case NICE_CHECK_DISCOVERED: return 'D'; default: g_assert_not_reached (); } } static const gchar * priv_candidate_type_to_string (NiceCandidateType type) { switch (type) { case NICE_CANDIDATE_TYPE_HOST: return "host"; case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: return "srflx"; case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: return "prflx"; case NICE_CANDIDATE_TYPE_RELAYED: return "relay"; default: g_assert_not_reached (); } } /* * Dump the conncheck lists of the agent */ static void priv_print_conn_check_lists (NiceAgent *agent, const gchar *where, const gchar *detail) { GSList *i, *k; guint j; if (!nice_debug_is_verbose ()) return; #define PRIORITY_LEN 32 nice_debug ("Agent %p : *** conncheck list DUMP (called from %s%s)", agent, where, detail ? detail : ""); for (i = agent->streams; i ; i = i->next) { NiceStream *stream = i->data; for (j = 1; j <= stream->n_components; j++) { for (k = stream->conncheck_list; k ; k = k->next) { CandidateCheckPair *pair = k->data; if (pair->component_id == j) { gchar local_addr[INET6_ADDRSTRLEN]; gchar remote_addr[INET6_ADDRSTRLEN]; StunTimer *timer = &pair->timer; nice_address_to_string (&pair->local->addr, local_addr); nice_address_to_string (&pair->remote->addr, remote_addr); nice_debug ("Agent %p : *** sc=%d/%d : pair %p : " "f=%s t=%s:%s timer=%d/%d %d/%dms " "[%s]:%u > [%s]:%u state=%c%s%s%s", agent, pair->stream_id, pair->component_id, pair, pair->foundation, priv_candidate_type_to_string (pair->local->type), priv_candidate_type_to_string (pair->remote->type), timer->retransmissions, timer->max_retransmissions, timer->delay - stun_timer_remainder (timer), timer->delay, local_addr, nice_address_get_port (&pair->local->addr), remote_addr, nice_address_get_port (&pair->remote->addr), priv_state_to_gchar (pair->state), pair->valid ? "V" : "", pair->nominated ? "N" : "", g_slist_find (agent->triggered_check_queue, pair) ? "T" : ""); } } } } } /* Add the pair to the triggered checks list, if not already present */ static void priv_add_pair_to_triggered_check_queue (NiceAgent *agent, CandidateCheckPair *pair) { g_assert (pair); if (agent->triggered_check_queue == NULL || g_slist_find (agent->triggered_check_queue, pair) == NULL) agent->triggered_check_queue = g_slist_append (agent->triggered_check_queue, pair); } /* Remove the pair from the triggered checks list */ static void priv_remove_pair_from_triggered_check_queue (NiceAgent *agent, CandidateCheckPair *pair) { g_assert (pair); agent->triggered_check_queue = g_slist_remove (agent->triggered_check_queue, pair); } /* Get the pair from the triggered checks list */ static CandidateCheckPair * priv_get_pair_from_triggered_check_queue (NiceAgent *agent) { CandidateCheckPair *pair = NULL; if (agent->triggered_check_queue) { pair = (CandidateCheckPair *)agent->triggered_check_queue->data; priv_remove_pair_from_triggered_check_queue (agent, pair); } return pair; } /* * Finds the next connectivity check in WAITING state. */ static CandidateCheckPair *priv_conn_check_find_next_waiting (GSList *conn_check_list) { GSList *i; /* note: list is sorted in priority order to first waiting check has * the highest priority */ for (i = conn_check_list; i ; i = i->next) { CandidateCheckPair *p = i->data; if (p->state == NICE_CHECK_WAITING) return p; } return NULL; } /* * Initiates a new connectivity check for a ICE candidate pair. * * @return TRUE on success, FALSE on error */ static gboolean priv_conn_check_initiate (NiceAgent *agent, CandidateCheckPair *pair) { g_get_current_time (&pair->next_tick); g_time_val_add (&pair->next_tick, agent->timer_ta * 1000); pair->state = NICE_CHECK_IN_PROGRESS; nice_debug ("Agent %p : pair %p state IN_PROGRESS", agent, pair); conn_check_send (agent, pair); return TRUE; } /* * Unfreezes the next connectivity check in the list. Follows the * algorithm (2.) defined in 5.7.4 (Computing States) of the ICE spec * (ID-19), with some exceptions (see comments in code). * * See also sect 7.1.2.2.3 (Updating Pair States), and * priv_conn_check_unfreeze_related(). * * @return TRUE on success, and FALSE if no frozen candidates were found. */ static gboolean priv_conn_check_unfreeze_next (NiceAgent *agent) { CandidateCheckPair *pair = NULL; GSList *i, *j; /* XXX: the unfreezing is implemented a bit differently than in the * current ICE spec, but should still be interoperate: * - checks are not grouped by foundation * - one frozen check is unfrozen (lowest component-id, highest * priority) */ priv_print_conn_check_lists (agent, G_STRFUNC, NULL); for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; guint64 max_frozen_priority = 0; for (j = stream->conncheck_list; j ; j = j->next) { CandidateCheckPair *p = j->data; /* XXX: the prio check could be removed as the pairs are sorted * already */ if (p->state == NICE_CHECK_FROZEN) { if (p->priority > max_frozen_priority) { max_frozen_priority = p->priority; pair = p; } } } if (pair) break; } if (pair) { nice_debug ("Agent %p : Pair %p with s/c-id %u/%u (%s) unfrozen.", agent, pair, pair->stream_id, pair->component_id, pair->foundation); pair->state = NICE_CHECK_WAITING; nice_debug ("Agent %p : pair %p state WAITING", agent, pair); return TRUE; } return FALSE; } /* * Unfreezes the next next connectivity check in the list after * check 'success_check' has successfully completed. * * See sect 7.1.2.2.3 (Updating Pair States) of ICE spec (ID-19). * * @param agent context * @param ok_check a connectivity check that has just completed * * @return TRUE on success, and FALSE if no frozen candidates were found. */ static void priv_conn_check_unfreeze_related (NiceAgent *agent, NiceStream *stream, CandidateCheckPair *ok_check) { GSList *i, *j; guint unfrozen = 0; g_assert (ok_check); g_assert (ok_check->state == NICE_CHECK_SUCCEEDED); g_assert (stream); g_assert (stream->id == ok_check->stream_id); priv_print_conn_check_lists (agent, G_STRFUNC, NULL); /* step: perform the step (1) of 'Updating Pair States' */ for (i = stream->conncheck_list; i ; i = i->next) { CandidateCheckPair *p = i->data; if (p->stream_id == ok_check->stream_id) { if (p->state == NICE_CHECK_FROZEN && strncmp (p->foundation, ok_check->foundation, NICE_CANDIDATE_PAIR_MAX_FOUNDATION) == 0) { nice_debug ("Agent %p : Unfreezing check %p (after successful check %p).", agent, p, ok_check); p->state = NICE_CHECK_WAITING; nice_debug ("Agent %p : pair %p state WAITING", agent, p); ++unfrozen; } } } /* step: perform the step (2) of 'Updating Pair States' */ stream = agent_find_stream (agent, ok_check->stream_id); if (nice_stream_all_components_ready (stream)) { /* step: unfreeze checks from other streams */ for (i = agent->streams; i ; i = i->next) { NiceStream *s = i->data; for (j = stream->conncheck_list; j ; j = j->next) { CandidateCheckPair *p = j->data; if (p->stream_id == s->id && p->stream_id != ok_check->stream_id) { if (p->state == NICE_CHECK_FROZEN && strcmp (p->foundation, ok_check->foundation) == 0) { nice_debug ("Agent %p : Unfreezing check %p from stream %u (after successful check %p).", agent, p, s->id, ok_check); p->state = NICE_CHECK_WAITING; nice_debug ("Agent %p : pair %p state WAITING", agent, p); ++unfrozen; } } } /* note: only unfreeze check from one stream at a time */ if (unfrozen) break; } } if (unfrozen == 0) priv_conn_check_unfreeze_next (agent); } static void candidate_check_pair_fail (NiceStream *stream, NiceAgent *agent, CandidateCheckPair *p) { StunTransactionId id; NiceComponent *component; component = nice_stream_find_component_by_id (stream, p->component_id); p->state = NICE_CHECK_FAILED; nice_debug ("Agent %p : pair %p state FAILED", agent, p); if (p->stun_message.buffer != NULL) { stun_message_id (&p->stun_message, id); stun_agent_forget_transaction (&component->stun_agent, id); } p->stun_message.buffer = NULL; p->stun_message.buffer_len = 0; } /* * Helper function for connectivity check timer callback that * runs through the stream specific part of the state machine. * * @param schedule if TRUE, schedule a new check * * @return will return FALSE when no more pending timers. */ static gboolean priv_conn_check_tick_stream (NiceStream *stream, NiceAgent *agent, GTimeVal *now, gboolean *stun_transmitted) { gboolean keep_timer_going = FALSE; guint s_inprogress = 0, s_succeeded = 0, s_discovered = 0, s_nominated = 0, s_waiting_for_nomination = 0, s_valid = 0; guint frozen = 0, waiting = 0; GSList *i, *k; for (i = stream->conncheck_list; i ; i = i->next) { CandidateCheckPair *p = i->data; if (p->state == NICE_CHECK_IN_PROGRESS) { if (p->stun_message.buffer == NULL) { nice_debug ("Agent %p : STUN connectivity check was cancelled, marking as done.", agent); p->state = NICE_CHECK_FAILED; nice_debug ("Agent %p : pair %p state FAILED", agent, p); } else if (priv_timer_expired (&p->next_tick, now)) { switch (stun_timer_refresh (&p->timer)) { case STUN_USAGE_TIMER_RETURN_TIMEOUT: { /* case: error, abort processing */ gchar tmpbuf1[INET6_ADDRSTRLEN], tmpbuf2[INET6_ADDRSTRLEN]; nice_address_to_string (&p->local->addr, tmpbuf1); nice_address_to_string (&p->remote->addr, tmpbuf2); nice_debug ("Agent %p : Retransmissions failed, giving up on connectivity check %p", agent, p); nice_debug ("Agent %p : Failed pair is [%s]:%u --> [%s]:%u", agent, tmpbuf1, nice_address_get_port (&p->local->addr), tmpbuf2, nice_address_get_port (&p->remote->addr)); candidate_check_pair_fail (stream, agent, p); priv_print_conn_check_lists (agent, G_STRFUNC, ", retransmission failed"); break; } case STUN_USAGE_TIMER_RETURN_RETRANSMIT: { /* case: not ready, so schedule a new timeout */ unsigned int timeout = stun_timer_remainder (&p->timer); nice_debug ("Agent %p :STUN transaction retransmitted on pair %p " "(timeout %dms, delay=%dms, retrans=%d).", agent, p, timeout, p->timer.delay, p->timer.retransmissions); agent_socket_send (p->sockptr, &p->remote->addr, stun_message_length (&p->stun_message), (gchar *)p->stun_buffer); /* note: convert from milli to microseconds for g_time_val_add() */ p->next_tick = *now; g_time_val_add (&p->next_tick, timeout * 1000); *stun_transmitted = TRUE; return TRUE; } case STUN_USAGE_TIMER_RETURN_SUCCESS: { unsigned int timeout = stun_timer_remainder (&p->timer); /* note: convert from milli to microseconds for g_time_val_add() */ p->next_tick = *now; g_time_val_add (&p->next_tick, timeout * 1000); keep_timer_going = TRUE; break; } default: /* Nothing to do. */ break; } } } if (p->state == NICE_CHECK_FROZEN) ++frozen; else if (p->state == NICE_CHECK_IN_PROGRESS) ++s_inprogress; else if (p->state == NICE_CHECK_WAITING) ++waiting; else if (p->state == NICE_CHECK_SUCCEEDED) ++s_succeeded; else if (p->state == NICE_CHECK_DISCOVERED) ++s_discovered; if (p->valid) ++s_valid; if ((p->state == NICE_CHECK_SUCCEEDED || p->state == NICE_CHECK_DISCOVERED) && p->nominated) ++s_nominated; else if ((p->state == NICE_CHECK_SUCCEEDED || p->state == NICE_CHECK_DISCOVERED) && !p->nominated) ++s_waiting_for_nomination; } /* note: keep the timer going as long as there is work to be done */ if (s_inprogress) keep_timer_going = TRUE; /* note: if some components have established connectivity, * but yet no nominated pair, keep timer going */ if (s_nominated < stream->n_components && s_waiting_for_nomination) { keep_timer_going = TRUE; if (agent->controlling_mode) { GSList *component_item; for (component_item = stream->components; component_item; component_item = component_item->next) { NiceComponent *component = component_item->data; for (k = stream->conncheck_list; k ; k = k->next) { CandidateCheckPair *p = k->data; /* note: highest priority item selected (list always sorted) */ if (p->component_id == component->id && (p->state == NICE_CHECK_SUCCEEDED || p->state == NICE_CHECK_DISCOVERED)) { nice_debug ("Agent %p : restarting check %p as the nominated pair.", agent, p); p->nominated = TRUE; priv_add_pair_to_triggered_check_queue (agent, p); break; /* move to the next component */ } } } } } if (stream->tick_counter++ % 50 == 0) nice_debug ("Agent %p : stream %u: timer tick #%u: %u frozen, %u in-progress, " "%u waiting, %u succeeded, %u discovered, %u nominated, " "%u waiting-for-nom, %u valid.", agent, stream->id, stream->tick_counter, frozen, s_inprogress, waiting, s_succeeded, s_discovered, s_nominated, s_waiting_for_nomination, s_valid); return keep_timer_going; } static void conn_check_stop (NiceAgent *agent) { if (agent->conncheck_timer_source == NULL) return; g_source_destroy (agent->conncheck_timer_source); g_source_unref (agent->conncheck_timer_source); agent->conncheck_timer_source = NULL; } /* * Timer callback that handles initiating and managing connectivity * checks (paced by the Ta timer). * * This function is designed for the g_timeout_add() interface. * * @return will return FALSE when no more pending timers. */ static gboolean priv_conn_check_tick_unlocked (NiceAgent *agent) { CandidateCheckPair *pair = NULL; gboolean keep_timer_going = FALSE; gboolean res; /* note: we try to only generate a single stun transaction per timer * callback, to respect some pacing of STUN transaction, as per * appendix B.1 of ICE spec. */ gboolean stun_transmitted = FALSE; GSList *i, *j; GTimeVal now; /* step: process ongoing STUN transactions */ g_get_current_time (&now); for (j = agent->streams; j; j = j->next) { NiceStream *stream = j->data; res = priv_conn_check_tick_stream (stream, agent, &now, &stun_transmitted); if (res) keep_timer_going = res; if (stun_transmitted) return TRUE; } /* step: first initiate a conncheck with a pair from the triggered list */ pair = priv_get_pair_from_triggered_check_queue (agent); if (pair) { priv_print_conn_check_lists (agent, G_STRFUNC, ", got a pair from triggered check list"); priv_conn_check_initiate (agent, pair); return TRUE; } /* step: when the triggered list is empty, * find the highest priority waiting check and send it */ for (i = agent->streams; i ; i = i->next) { NiceStream *stream = i->data; pair = priv_conn_check_find_next_waiting (stream->conncheck_list); if (pair) break; } if (pair) { priv_conn_check_initiate (agent, pair); return TRUE; } /* step: when there's no pair in the Waiting state, * unfreeze a new pair and check it */ res = priv_conn_check_unfreeze_next (agent); for (i = agent->streams; i ; i = i->next) { NiceStream *stream = i->data; pair = priv_conn_check_find_next_waiting (stream->conncheck_list); if (pair) break; } if (pair) { priv_print_conn_check_lists (agent, G_STRFUNC, ", got a pair in Waiting state"); priv_conn_check_initiate (agent, pair); return TRUE; } /* step: stop timer if no work left */ if (keep_timer_going != TRUE) { nice_debug ("Agent %p : %s: stopping conncheck timer", agent, G_STRFUNC); for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; priv_update_check_list_failed_components (agent, stream); for (j = stream->components; j; j = j->next) { NiceComponent *component = j->data; priv_update_check_list_state_for_ready (agent, stream, component); } } priv_print_conn_check_lists (agent, G_STRFUNC, ", conncheck timer stopped"); /* Stopping the timer so destroy the source.. this will allow the timer to be reset if we get a set_remote_candidates after this point */ conn_check_stop (agent); /* XXX: what to signal, is all processing now really done? */ nice_debug ("Agent %p : changing conncheck state to COMPLETED.", agent); } return keep_timer_going; } static gboolean priv_conn_check_tick (gpointer pointer) { gboolean ret; NiceAgent *agent = pointer; agent_lock(); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in priv_conn_check_tick"); agent_unlock (); return FALSE; } ret = priv_conn_check_tick_unlocked (agent); agent_unlock_and_emit (agent); return ret; } static gboolean priv_conn_keepalive_retransmissions_tick (gpointer pointer) { CandidatePair *pair = (CandidatePair *) pointer; agent_lock(); /* A race condition might happen where the mutex above waits for the lock * and in the meantime another thread destroys the source. * In that case, we don't need to run our retransmission tick since it should * have been cancelled */ if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in priv_conn_keepalive_retransmissions_tick"); agent_unlock (); return FALSE; } g_source_destroy (pair->keepalive.tick_source); g_source_unref (pair->keepalive.tick_source); pair->keepalive.tick_source = NULL; switch (stun_timer_refresh (&pair->keepalive.timer)) { case STUN_USAGE_TIMER_RETURN_TIMEOUT: { /* Time out */ StunTransactionId id; NiceComponent *component; if (!agent_find_component (pair->keepalive.agent, pair->keepalive.stream_id, pair->keepalive.component_id, NULL, &component)) { nice_debug ("Could not find stream or component in" " priv_conn_keepalive_retransmissions_tick"); agent_unlock (); return FALSE; } stun_message_id (&pair->keepalive.stun_message, id); stun_agent_forget_transaction (&component->stun_agent, id); pair->keepalive.stun_message.buffer = NULL; if (pair->keepalive.agent->media_after_tick) { nice_debug ("Agent %p : Keepalive conncheck timed out!! " "but media was received. Suspecting keepalive lost because of " "network bottleneck", pair->keepalive.agent); } else { nice_debug ("Agent %p : Keepalive conncheck timed out!! " "peer probably lost connection", pair->keepalive.agent); agent_signal_component_state_change (pair->keepalive.agent, pair->keepalive.stream_id, pair->keepalive.component_id, NICE_COMPONENT_STATE_FAILED); } break; } case STUN_USAGE_TIMER_RETURN_RETRANSMIT: /* Retransmit */ agent_socket_send (pair->local->sockptr, &pair->remote->addr, stun_message_length (&pair->keepalive.stun_message), (gchar *)pair->keepalive.stun_buffer); nice_debug ("Agent %p : Retransmitting keepalive conncheck", pair->keepalive.agent); agent_timeout_add_with_context (pair->keepalive.agent, &pair->keepalive.tick_source, "Pair keepalive", stun_timer_remainder (&pair->keepalive.timer), priv_conn_keepalive_retransmissions_tick, pair); break; case STUN_USAGE_TIMER_RETURN_SUCCESS: agent_timeout_add_with_context (pair->keepalive.agent, &pair->keepalive.tick_source, "Pair keepalive", stun_timer_remainder (&pair->keepalive.timer), priv_conn_keepalive_retransmissions_tick, pair); break; default: g_assert_not_reached(); break; } agent_unlock_and_emit (pair->keepalive.agent); return FALSE; } static guint32 peer_reflexive_candidate_priority (NiceAgent *agent, NiceCandidate *local_candidate) { NiceCandidate *candidate_priority = nice_candidate_new (NICE_CANDIDATE_TYPE_PEER_REFLEXIVE); guint32 priority; candidate_priority->transport = local_candidate->transport; candidate_priority->component_id = local_candidate->component_id; candidate_priority->base_addr = local_candidate->addr; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { priority = nice_candidate_jingle_priority (candidate_priority); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { priority = nice_candidate_msn_priority (candidate_priority); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { priority = nice_candidate_ms_ice_priority (candidate_priority, agent->reliable, FALSE); } else { priority = nice_candidate_ice_priority (candidate_priority, agent->reliable, FALSE); } nice_candidate_free (candidate_priority); return priority; } static void ms_ice2_legacy_conncheck_send(StunMessage *msg, NiceSocket *sock, const NiceAddress *remote_addr) { uint32_t *fingerprint_attr; uint32_t fingerprint_orig; uint16_t fingerprint_len; size_t buffer_len; if (msg->agent->ms_ice2_send_legacy_connchecks == FALSE) { return; } fingerprint_attr = (uint32_t *)stun_message_find (msg, STUN_ATTRIBUTE_FINGERPRINT, &fingerprint_len); if (fingerprint_attr == NULL) { nice_debug ("FINGERPRINT not found."); return; } if (fingerprint_len != sizeof (fingerprint_orig)) { nice_debug ("Unexpected FINGERPRINT length %u.", fingerprint_len); return; } memcpy (&fingerprint_orig, fingerprint_attr, sizeof (fingerprint_orig)); buffer_len = stun_message_length (msg); *fingerprint_attr = stun_fingerprint (msg->buffer, buffer_len, TRUE); agent_socket_send (sock, remote_addr, buffer_len, (gchar *)msg->buffer); memcpy (fingerprint_attr, &fingerprint_orig, sizeof (fingerprint_orig)); } /* * Timer callback that handles initiating and managing connectivity * checks (paced by the Ta timer). * * This function is designed for the g_timeout_add() interface. * * @return will return FALSE when no more pending timers. */ static gboolean priv_conn_keepalive_tick_unlocked (NiceAgent *agent) { GSList *i, *j, *k; int errors = 0; gboolean ret = FALSE; size_t buf_len = 0; /* case 1: session established and media flowing * (ref ICE sect 10 "Keepalives" ID-19) */ for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; for (j = stream->components; j; j = j->next) { NiceComponent *component = j->data; if (component->selected_pair.local != NULL) { CandidatePair *p = &component->selected_pair; /* Disable keepalive checks on TCP candidates */ if (p->local->transport != NICE_CANDIDATE_TRANSPORT_UDP) continue; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE || agent->keepalive_conncheck) { uint8_t uname[NICE_STREAM_MAX_UNAME]; size_t uname_len = priv_create_username (agent, agent_find_stream (agent, stream->id), component->id, p->remote, p->local, uname, sizeof (uname), FALSE); uint8_t *password = NULL; size_t password_len = priv_get_password (agent, agent_find_stream (agent, stream->id), p->remote, &password); if (p->keepalive.stun_message.buffer != NULL) { nice_debug ("Agent %p: Keepalive for s%u:c%u still" " retransmitting, not restarting", agent, stream->id, component->id); continue; } if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (&p->remote->addr, tmpbuf); nice_debug ("Agent %p : Keepalive STUN-CC REQ to '%s:%u', " "(c-id:%u), username='%.*s' (%" G_GSIZE_FORMAT "), " "password='%.*s' (%" G_GSIZE_FORMAT "), priority=%u.", agent, tmpbuf, nice_address_get_port (&p->remote->addr), component->id, (int) uname_len, uname, uname_len, (int) password_len, password, password_len, p->prflx_priority); } if (uname_len > 0) { buf_len = stun_usage_ice_conncheck_create (&component->stun_agent, &p->keepalive.stun_message, p->keepalive.stun_buffer, sizeof(p->keepalive.stun_buffer), uname, uname_len, password, password_len, agent->controlling_mode, agent->controlling_mode, p->prflx_priority, agent->tie_breaker, NULL, agent_to_ice_compatibility (agent)); nice_debug ("Agent %p: conncheck created %zd - %p", agent, buf_len, p->keepalive.stun_message.buffer); if (buf_len > 0) { stun_timer_start (&p->keepalive.timer, STUN_TIMER_DEFAULT_TIMEOUT, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); agent->media_after_tick = FALSE; /* send the conncheck */ agent_socket_send (p->local->sockptr, &p->remote->addr, buf_len, (gchar *)p->keepalive.stun_buffer); p->keepalive.stream_id = stream->id; p->keepalive.component_id = component->id; p->keepalive.agent = agent; agent_timeout_add_with_context (p->keepalive.agent, &p->keepalive.tick_source, "Pair keepalive", stun_timer_remainder (&p->keepalive.timer), priv_conn_keepalive_retransmissions_tick, p); } else { ++errors; } } } else { buf_len = stun_usage_bind_keepalive (&component->stun_agent, &p->keepalive.stun_message, p->keepalive.stun_buffer, sizeof(p->keepalive.stun_buffer)); if (buf_len > 0) { agent_socket_send (p->local->sockptr, &p->remote->addr, buf_len, (gchar *)p->keepalive.stun_buffer); if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { ms_ice2_legacy_conncheck_send (&p->keepalive.stun_message, p->local->sockptr, &p->remote->addr); } nice_debug ("Agent %p : stun_bind_keepalive for pair %p res %d.", agent, p, (int) buf_len); } else { ++errors; } } } } } /* case 2: connectivity establishment ongoing * (ref ICE sect 4.1.1.4 "Keeping Candidates Alive" ID-19) */ for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; for (j = stream->components; j; j = j->next) { NiceComponent *component = j->data; if (component->state < NICE_COMPONENT_STATE_READY && agent->stun_server_ip) { NiceAddress stun_server; if (nice_address_set_from_string (&stun_server, agent->stun_server_ip)) { StunAgent stun_agent; uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE_IPV6]; StunMessage stun_message; size_t buffer_len = 0; nice_address_set_port (&stun_server, agent->stun_server_port); nice_agent_init_stun_agent (agent, &stun_agent); buffer_len = stun_usage_bind_create (&stun_agent, &stun_message, stun_buffer, sizeof(stun_buffer)); for (k = component->local_candidates; k; k = k->next) { NiceCandidate *candidate = (NiceCandidate *) k->data; if (candidate->type == NICE_CANDIDATE_TYPE_HOST && candidate->transport == NICE_CANDIDATE_TRANSPORT_UDP) { /* send the conncheck */ nice_debug ("Agent %p : resending STUN on %s to keep the " "candidate alive.", agent, candidate->foundation); agent_socket_send (candidate->sockptr, &stun_server, buffer_len, (gchar *)stun_buffer); } } } } } } if (errors) { nice_debug ("Agent %p : %s: stopping keepalive timer", agent, G_STRFUNC); goto done; } ret = TRUE; done: return ret; } static gboolean priv_conn_keepalive_tick (gpointer pointer) { NiceAgent *agent = pointer; gboolean ret; agent_lock(); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in priv_conn_keepalive_tick"); agent_unlock (); return FALSE; } ret = priv_conn_keepalive_tick_unlocked (agent); if (ret == FALSE) { if (agent->keepalive_timer_source) { g_source_destroy (agent->keepalive_timer_source); g_source_unref (agent->keepalive_timer_source); agent->keepalive_timer_source = NULL; } } agent_unlock_and_emit (agent); return ret; } static gboolean priv_turn_allocate_refresh_retransmissions_tick (gpointer pointer) { CandidateRefresh *cand = (CandidateRefresh *) pointer; NiceAgent *agent = NULL; agent_lock(); /* A race condition might happen where the mutex above waits for the lock * and in the meantime another thread destroys the source. * In that case, we don't need to run our retransmission tick since it should * have been cancelled */ if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in priv_turn_allocate_refresh_retransmissions_tick"); agent_unlock (); return FALSE; } g_source_destroy (cand->tick_source); g_source_unref (cand->tick_source); cand->tick_source = NULL; agent = g_object_ref (cand->agent); switch (stun_timer_refresh (&cand->timer)) { case STUN_USAGE_TIMER_RETURN_TIMEOUT: { /* Time out */ StunTransactionId id; stun_message_id (&cand->stun_message, id); stun_agent_forget_transaction (&cand->stun_agent, id); refresh_cancel (cand); break; } case STUN_USAGE_TIMER_RETURN_RETRANSMIT: /* Retransmit */ agent_socket_send (cand->nicesock, &cand->server, stun_message_length (&cand->stun_message), (gchar *)cand->stun_buffer); agent_timeout_add_with_context (agent, &cand->tick_source, "Candidate TURN refresh", stun_timer_remainder (&cand->timer), priv_turn_allocate_refresh_retransmissions_tick, cand); break; case STUN_USAGE_TIMER_RETURN_SUCCESS: agent_timeout_add_with_context (agent, &cand->tick_source, "Candidate TURN refresh", stun_timer_remainder (&cand->timer), priv_turn_allocate_refresh_retransmissions_tick, cand); break; default: /* Nothing to do. */ break; } agent_unlock_and_emit (agent); g_object_unref (agent); return FALSE; } static void priv_turn_allocate_refresh_tick_unlocked (CandidateRefresh *cand) { uint8_t *username; gsize username_len; uint8_t *password; gsize password_len; size_t buffer_len = 0; StunUsageTurnCompatibility turn_compat = agent_to_turn_compatibility (cand->agent); username = (uint8_t *)cand->candidate->turn->username; username_len = (size_t) strlen (cand->candidate->turn->username); password = (uint8_t *)cand->candidate->turn->password; password_len = (size_t) strlen (cand->candidate->turn->password); if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { username = g_base64_decode ((gchar *)username, &username_len); password = g_base64_decode ((gchar *)password, &password_len); } buffer_len = stun_usage_turn_create_refresh (&cand->stun_agent, &cand->stun_message, cand->stun_buffer, sizeof(cand->stun_buffer), cand->stun_resp_msg.buffer == NULL ? NULL : &cand->stun_resp_msg, -1, username, username_len, password, password_len, turn_compat); if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { g_free (username); g_free (password); } nice_debug ("Agent %p : Sending allocate Refresh %zd", cand->agent, buffer_len); if (cand->tick_source != NULL) { g_source_destroy (cand->tick_source); g_source_unref (cand->tick_source); cand->tick_source = NULL; } if (buffer_len > 0) { stun_timer_start (&cand->timer, STUN_TIMER_DEFAULT_TIMEOUT, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); /* send the refresh */ agent_socket_send (cand->nicesock, &cand->server, buffer_len, (gchar *)cand->stun_buffer); agent_timeout_add_with_context (cand->agent, &cand->tick_source, "Candidate TURN refresh", stun_timer_remainder (&cand->timer), priv_turn_allocate_refresh_retransmissions_tick, cand); } } /* * Timer callback that handles refreshing TURN allocations * * This function is designed for the g_timeout_add() interface. * * @return will return FALSE when no more pending timers. */ static gboolean priv_turn_allocate_refresh_tick (gpointer pointer) { CandidateRefresh *cand = (CandidateRefresh *) pointer; agent_lock(); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in priv_turn_allocate_refresh_tick"); agent_unlock (); return FALSE; } priv_turn_allocate_refresh_tick_unlocked (cand); agent_unlock_and_emit (cand->agent); return FALSE; } /* * Initiates the next pending connectivity check. */ void conn_check_schedule_next (NiceAgent *agent) { if (agent->discovery_unsched_items > 0) nice_debug ("Agent %p : WARN: starting conn checks before local candidate gathering is finished.", agent); /* step: schedule timer if not running yet */ if (agent->conncheck_timer_source == NULL) { agent_timeout_add_with_context (agent, &agent->conncheck_timer_source, "Connectivity check schedule", agent->timer_ta, priv_conn_check_tick, agent); } /* step: also start the keepalive timer */ if (agent->keepalive_timer_source == NULL) { agent_timeout_add_with_context (agent, &agent->keepalive_timer_source, "Connectivity keepalive timeout", NICE_AGENT_TIMER_TR_DEFAULT, priv_conn_keepalive_tick, agent); } } /* * Compares two connectivity check items. Checkpairs are sorted * in descending priority order, with highest priority item at * the start of the list. */ gint conn_check_compare (const CandidateCheckPair *a, const CandidateCheckPair *b) { if (a->priority > b->priority) return -1; else if (a->priority < b->priority) return 1; return 0; } /* * Preprocesses a new connectivity check by going through list * of a any stored early incoming connectivity checks from * the remote peer. If a matching incoming check has been already * received, update the state of the new outgoing check 'pair'. * * @param agent context pointer * @param stream which stream (of the agent) * @param component pointer to component object to which 'pair'has been added * @param pair newly added connectivity check */ static void priv_preprocess_conn_check_pending_data (NiceAgent *agent, NiceStream *stream, NiceComponent *component, CandidateCheckPair *pair) { GSList *i; for (i = component->incoming_checks; i; i = i->next) { IncomingCheck *icheck = i->data; if (nice_address_equal (&icheck->from, &pair->remote->addr) && icheck->local_socket == pair->sockptr) { nice_debug ("Agent %p : Updating check %p with stored early-icheck %p, %p/%u/%u (agent/stream/component).", agent, pair, icheck, agent, stream->id, component->id); if (icheck->use_candidate) priv_mark_pair_nominated (agent, stream, component, pair->local, pair->remote); priv_schedule_triggered_check (agent, stream, component, icheck->local_socket, pair->remote, icheck->use_candidate); } } } static GSList *prune_cancelled_conn_check (GSList *conncheck_list) { GSList *item = conncheck_list; while (item) { CandidateCheckPair *pair = item->data; GSList *next = item->next; if (pair->state == NICE_CHECK_CANCELLED) { conn_check_free_item (pair); conncheck_list = g_slist_delete_link (conncheck_list, item); } item = next; } return conncheck_list; } /* * Handle any processing steps for connectivity checks after * remote candidates have been set. This function handles * the special case where answerer has sent us connectivity * checks before the answer (containing candidate information), * reaches us. The special case is documented in sect 7.2 * if ICE spec (ID-19). */ void conn_check_remote_candidates_set(NiceAgent *agent, NiceStream *stream, NiceComponent *component) { GSList *j, *k, *l, *m, *n; for (j = stream->conncheck_list; j ; j = j->next) { CandidateCheckPair *pair = j->data; if (pair->component_id == component->id) { gboolean match = FALSE; /* performn delayed processing of spec steps section 7.2.1.4, and section 7.2.1.5 */ priv_preprocess_conn_check_pending_data (agent, stream, component, pair); for (k = component->incoming_checks; k; k = k->next) { IncomingCheck *icheck = k->data; /* sect 7.2.1.3., "Learning Peer Reflexive Candidates", has to * be handled separately */ for (l = component->remote_candidates; l; l = l->next) { NiceCandidate *cand = l->data; if (nice_address_equal (&icheck->from, &cand->addr)) { match = TRUE; break; } } if (match != TRUE) { /* note: we have gotten an incoming connectivity check from * an address that is not a known remote candidate */ NiceCandidate *local_candidate = NULL; NiceCandidate *remote_candidate = NULL; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE || agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { /* We need to find which local candidate was used */ uint8_t uname[NICE_STREAM_MAX_UNAME]; guint uname_len; nice_debug ("Agent %p: We have a peer-reflexive candidate in a " "stored pending check", agent); for (m = component->remote_candidates; m != NULL && remote_candidate == NULL; m = m->next) { for (n = component->local_candidates; n; n = n->next) { NiceCandidate *rcand = m->data; NiceCandidate *lcand = n->data; uname_len = priv_create_username (agent, stream, component->id, rcand, lcand, uname, sizeof (uname), TRUE); stun_debug ("pending check, comparing usernames of len %d and %d, equal=%d", icheck->username_len, uname_len, icheck->username && uname_len == icheck->username_len && memcmp (uname, icheck->username, icheck->username_len) == 0); stun_debug_bytes (" first username: ", icheck->username, icheck->username? icheck->username_len : 0); stun_debug_bytes (" second username: ", uname, uname_len); if (icheck->username && uname_len == icheck->username_len && memcmp (uname, icheck->username, icheck->username_len) == 0) { local_candidate = lcand; remote_candidate = rcand; break; } } } } else { for (l = component->local_candidates; l; l = l->next) { NiceCandidate *cand = l->data; if (nice_address_equal (&cand->addr, &icheck->local_socket->addr)) { local_candidate = cand; break; } } } if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE && local_candidate == NULL) { /* if we couldn't match the username, then the matching remote * candidate hasn't been received yet.. we must wait */ nice_debug ("Agent %p : Username check failed. pending check has " "to wait to be processed", agent); } else { NiceCandidate *candidate; nice_debug ("Agent %p : Discovered peer reflexive from early i-check", agent); candidate = discovery_learn_remote_peer_reflexive_candidate (agent, stream, component, icheck->priority, &icheck->from, icheck->local_socket, local_candidate, remote_candidate); if (candidate) { if (local_candidate && local_candidate->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) priv_conn_check_add_for_candidate_pair_matched (agent, stream->id, component, local_candidate, candidate, NICE_CHECK_DISCOVERED); else conn_check_add_for_candidate (agent, stream->id, component, candidate); if (icheck->use_candidate) priv_mark_pair_nominated (agent, stream, component, local_candidate, candidate); priv_schedule_triggered_check (agent, stream, component, icheck->local_socket, candidate, icheck->use_candidate); } } } } } } /* Once we process the pending checks, we should free them to avoid * reprocessing them again if a dribble-mode set_remote_candidates * is called */ g_slist_free_full (component->incoming_checks, (GDestroyNotify) incoming_check_free); component->incoming_checks = NULL; stream->conncheck_list = prune_cancelled_conn_check (stream->conncheck_list); } /* * Enforces the upper limit for connectivity checks as described * in ICE spec section 5.7.3 (ID-19). See also * conn_check_add_for_candidate(). */ static void priv_limit_conn_check_list_size (GSList *conncheck_list, guint upper_limit) { guint valid = 0; guint cancelled = 0; GSList *item = conncheck_list; while (item) { CandidateCheckPair *pair = item->data; if (pair->state != NICE_CHECK_CANCELLED) { valid++; if (valid > upper_limit) { pair->state = NICE_CHECK_CANCELLED; cancelled++; } } item = item->next; } if (cancelled > 0) nice_debug ("Agent : Pruned %d candidates. Conncheck list has %d elements" " left. Maximum connchecks allowed : %d", cancelled, valid, upper_limit); } /* * Changes the selected pair for the component if 'pair' is nominated * and has higher priority than the currently selected pair. See * ICE sect 11.1.1. "Procedures for Full Implementations" (ID-19). */ static gboolean priv_update_selected_pair (NiceAgent *agent, NiceComponent *component, CandidateCheckPair *pair) { CandidatePair cpair = { 0, }; g_assert (component); g_assert (pair); if (pair->priority > component->selected_pair.priority) { nice_debug ("Agent %p : changing SELECTED PAIR for component %u: %s:%s " "(prio:%" G_GUINT64_FORMAT ").", agent, component->id, pair->local->foundation, pair->remote->foundation, pair->priority); cpair.local = pair->local; cpair.remote = pair->remote; cpair.priority = pair->priority; /* cpair.keepalive is not used by nice_component_update_selected_pair() */ nice_component_update_selected_pair (component, &cpair); priv_conn_keepalive_tick_unlocked (agent); agent_signal_new_selected_pair (agent, pair->stream_id, component->id, pair->local, pair->remote); } return TRUE; } /* * Updates the check list state. * * Implements parts of the algorithm described in * ICE sect 8.1.2. "Updating States" (ID-19): if for any * component, all checks have been completed and have * failed, mark that component's state to NICE_CHECK_FAILED. * * Sends a component state changesignal via 'agent'. */ static void priv_update_check_list_failed_components (NiceAgent *agent, NiceStream *stream) { GSList *i; /* note: emitting a signal might cause the client * to remove the stream, thus the component count * must be fetched before entering the loop*/ guint c, components = stream->n_components; for (i = agent->discovery_list; i; i = i->next) { CandidateDiscovery *d = i->data; /* There is still discovery ogoing for this stream, * so don't fail any of it's candidates. */ if (d->stream == stream && !d->done) return; } if (agent->discovery_list != NULL) return; /* note: iterate the conncheck list for each component separately */ for (c = 0; c < components; c++) { NiceComponent *comp = NULL; if (!agent_find_component (agent, stream->id, c+1, NULL, &comp)) continue; for (i = stream->conncheck_list; i; i = i->next) { CandidateCheckPair *p = i->data; g_assert (p->agent == agent); g_assert (p->stream_id == stream->id); if (p->component_id == (c + 1)) { if (p->state != NICE_CHECK_FAILED) break; } } /* note: all checks have failed * Set the component to FAILED only if it actually had remote candidates * that failed.. */ if (i == NULL && comp != NULL && comp->remote_candidates != NULL) agent_signal_component_state_change (agent, stream->id, (c + 1), /* component-id */ NICE_COMPONENT_STATE_FAILED); } } /* * Updates the check list state for a stream component. * * Implements the algorithm described in ICE sect 8.1.2 * "Updating States" (ID-19) as it applies to checks of * a certain component. If there are any nominated pairs, * ICE processing may be concluded, and component state is * changed to READY. * * Sends a component state changesignal via 'agent'. */ static void priv_update_check_list_state_for_ready (NiceAgent *agent, NiceStream *stream, NiceComponent *component) { GSList *i; guint valid = 0, nominated = 0; g_assert (component); /* step: search for at least one nominated pair */ for (i = stream->conncheck_list; i; i = i->next) { CandidateCheckPair *p = i->data; if (p->component_id == component->id) { if (p->valid) { ++valid; if (p->nominated == TRUE) { ++nominated; priv_update_selected_pair (agent, component, p); } } } } if (nominated > 0) { /* Only go to READY if no checks are left in progress. If there are * any that are kept, then this function will be called again when the * conncheck tick timer finishes them all */ if (priv_prune_pending_checks (stream, component->id) == 0) { /* Continue through the states to give client code a nice * logical progression. See http://phabricator.freedesktop.org/D218 for * discussion. */ if (component->state < NICE_COMPONENT_STATE_CONNECTING || component->state == NICE_COMPONENT_STATE_FAILED) agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_CONNECTING); if (component->state < NICE_COMPONENT_STATE_CONNECTED) agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_CONNECTED); agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_READY); } } nice_debug ("Agent %p : conn.check list status: %u nominated, %u valid, c-id %u.", agent, nominated, valid, component->id); } /* * The remote party has signalled that the candidate pair * described by 'component' and 'remotecand' is nominated * for use. */ static void priv_mark_pair_nominated (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceCandidate *localcand, NiceCandidate *remotecand) { GSList *i; g_assert (component); /* step: search for at least one nominated pair */ for (i = stream->conncheck_list; i; i = i->next) { CandidateCheckPair *pair = i->data; if (pair->local == localcand && pair->remote == remotecand) { nice_debug ("Agent %p : marking pair %p (%s) as nominated", agent, pair, pair->foundation); pair->nominated = TRUE; if (pair->valid) { priv_update_selected_pair (agent, component, pair); /* Do not step down to CONNECTED if we're already at state READY*/ if (component->state != NICE_COMPONENT_STATE_READY) { /* step: notify the client of a new component state (must be done * before the possible check list state update step */ agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_CONNECTED); } } priv_update_check_list_state_for_ready (agent, stream, component); } } } guint32 ensure_unique_priority (NiceComponent *component, guint32 priority) { GSList *item; again: if (priority == 0) priority--; for (item = component->local_candidates; item; item = item->next) { NiceCandidate *cand = item->data; if (cand->priority == priority) { priority--; goto again; } } for (item = component->stream->conncheck_list; item; item = item->next) { CandidateCheckPair *p = item->data; if (p->component_id == component->id && p->prflx_priority == priority) { priority--; goto again; } } return priority; } /* * Creates a new connectivity check pair and adds it to * the agent's list of checks. */ static CandidateCheckPair *priv_add_new_check_pair (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local, NiceCandidate *remote, NiceCheckState initial_state, gboolean use_candidate) { NiceStream *stream; CandidateCheckPair *pair; g_assert (local != NULL); g_assert (remote != NULL); stream = agent_find_stream (agent, stream_id); pair = g_slice_new0 (CandidateCheckPair); pair->agent = agent; pair->stream_id = stream_id; pair->component_id = component->id;; pair->local = local; pair->remote = remote; /* note: we use the remote sockptr only in the case * of TCP transport */ if (local->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE && remote->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE) pair->sockptr = (NiceSocket *) remote->sockptr; else pair->sockptr = (NiceSocket *) local->sockptr; g_snprintf (pair->foundation, NICE_CANDIDATE_PAIR_MAX_FOUNDATION, "%s:%s", local->foundation, remote->foundation); pair->priority = agent_candidate_pair_priority (agent, local, remote); pair->state = initial_state; nice_debug ("Agent %p : creating new pair %p state %d", agent, pair, initial_state); { gchar tmpbuf1[INET6_ADDRSTRLEN]; gchar tmpbuf2[INET6_ADDRSTRLEN]; nice_address_to_string (&pair->local->addr, tmpbuf1); nice_address_to_string (&pair->remote->addr, tmpbuf2); nice_debug ("Agent %p : new pair %p : [%s]:%u --> [%s]:%u", agent, pair, tmpbuf1, nice_address_get_port (&pair->local->addr), tmpbuf2, nice_address_get_port (&pair->remote->addr)); } pair->nominated = use_candidate; pair->controlling = agent->controlling_mode; pair->prflx_priority = ensure_unique_priority (component, peer_reflexive_candidate_priority (agent, local)); stream->conncheck_list = g_slist_insert_sorted (stream->conncheck_list, pair, (GCompareFunc)conn_check_compare); nice_debug ("Agent %p : added a new conncheck %p with foundation of '%s' to list %u.", agent, pair, pair->foundation, stream_id); /* implement the hard upper limit for number of checks (see sect 5.7.3 ICE ID-19): */ if (agent->compatibility == NICE_COMPATIBILITY_RFC5245) { priv_limit_conn_check_list_size (stream->conncheck_list, agent->max_conn_checks); } return pair; } NiceCandidateTransport conn_check_match_transport (NiceCandidateTransport transport) { switch (transport) { case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: return NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; break; case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: return NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; break; case NICE_CANDIDATE_TRANSPORT_TCP_SO: case NICE_CANDIDATE_TRANSPORT_UDP: default: return transport; break; } } static CandidateCheckPair *priv_conn_check_add_for_candidate_pair_matched ( NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local, NiceCandidate *remote, NiceCheckState initial_state) { CandidateCheckPair *pair; nice_debug ("Agent %p : Adding check pair between %s and %s for s%d/c%d", agent, local->foundation, remote->foundation, stream_id, component->id); pair = priv_add_new_check_pair (agent, stream_id, component, local, remote, initial_state, FALSE); if (component->state == NICE_COMPONENT_STATE_CONNECTED || component->state == NICE_COMPONENT_STATE_READY) { agent_signal_component_state_change (agent, stream_id, component->id, NICE_COMPONENT_STATE_CONNECTED); } else { agent_signal_component_state_change (agent, stream_id, component->id, NICE_COMPONENT_STATE_CONNECTING); } return pair; } gboolean conn_check_add_for_candidate_pair (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local, NiceCandidate *remote) { gboolean ret = FALSE; g_assert (local != NULL); g_assert (remote != NULL); /* note: do not create pairs where the local candidate is * a srv-reflexive (ICE 5.7.3. "Pruning the pairs" ID-9) */ if ((agent->compatibility == NICE_COMPATIBILITY_RFC5245 || agent->compatibility == NICE_COMPATIBILITY_WLM2009 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && local->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE) { return FALSE; } /* note: do not create pairs where local candidate has TCP passive transport * (ice-tcp-13 6.2. "Forming the Check Lists") */ if (local->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) { return FALSE; } /* note: match pairs only if transport and address family are the same */ if (local->transport == conn_check_match_transport (remote->transport) && local->addr.s.addr.sa_family == remote->addr.s.addr.sa_family) { priv_conn_check_add_for_candidate_pair_matched (agent, stream_id, component, local, remote, NICE_CHECK_FROZEN); ret = TRUE; } return ret; } /* * Forms new candidate pairs by matching the new remote candidate * 'remote_cand' with all existing local candidates of 'component'. * Implements the logic described in ICE sect 5.7.1. "Forming Candidate * Pairs" (ID-19). * * @param agent context * @param component pointer to the component * @param remote remote candidate to match with * * @return number of checks added, negative on fatal errors */ int conn_check_add_for_candidate (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *remote) { GSList *i; int added = 0; int ret = 0; g_assert (remote != NULL); for (i = component->local_candidates; i ; i = i->next) { NiceCandidate *local = i->data; if (agent->force_relay && local->type != NICE_CANDIDATE_TYPE_RELAYED) continue; ret = conn_check_add_for_candidate_pair (agent, stream_id, component, local, remote); if (ret) { ++added; } } return added; } /* * Forms new candidate pairs by matching the new local candidate * 'local_cand' with all existing remote candidates of 'component'. * * @param agent context * @param component pointer to the component * @param local local candidate to match with * * @return number of checks added, negative on fatal errors */ int conn_check_add_for_local_candidate (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local) { GSList *i; int added = 0; int ret = 0; g_assert (local != NULL); for (i = component->remote_candidates; i ; i = i->next) { NiceCandidate *remote = i->data; ret = conn_check_add_for_candidate_pair (agent, stream_id, component, local, remote); if (ret) { ++added; } } return added; } /* * Frees the CandidateCheckPair structure pointer to * by 'user data'. Compatible with GDestroyNotify. */ static void conn_check_free_item (gpointer data) { CandidateCheckPair *pair = data; if (pair->agent) priv_remove_pair_from_triggered_check_queue (pair->agent, pair); pair->stun_message.buffer = NULL; pair->stun_message.buffer_len = 0; g_slice_free (CandidateCheckPair, pair); } /* * Frees all resources of all connectivity checks. */ void conn_check_free (NiceAgent *agent) { GSList *i; for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; if (stream->conncheck_list) { nice_debug ("Agent %p, freeing conncheck_list of stream %p", agent, stream); g_slist_free_full (stream->conncheck_list, conn_check_free_item); stream->conncheck_list = NULL; } } conn_check_stop (agent); } /* * Prunes the list of connectivity checks for items related * to stream 'stream_id'. * * @return TRUE on success, FALSE on a fatal error */ void conn_check_prune_stream (NiceAgent *agent, NiceStream *stream) { GSList *i; gboolean keep_going = FALSE; if (stream->conncheck_list) { nice_debug ("Agent %p, freeing conncheck_list of stream %p", agent, stream); g_slist_free_full (stream->conncheck_list, conn_check_free_item); stream->conncheck_list = NULL; } for (i = agent->streams; i; i = i->next) { NiceStream *s = i->data; if (s->conncheck_list) { keep_going = TRUE; break; } } if (!keep_going) conn_check_stop (agent); } /* * Fills 'dest' with a username string for use in an outbound connectivity * checks. No more than 'dest_len' characters (including terminating * NULL) is ever written to the 'dest'. */ static size_t priv_gen_username (NiceAgent *agent, guint component_id, gchar *remote, gchar *local, uint8_t *dest, guint dest_len) { guint len = 0; gsize remote_len = strlen (remote); gsize local_len = strlen (local); if (remote_len > 0 && local_len > 0) { if (agent->compatibility == NICE_COMPATIBILITY_RFC5245 && dest_len >= remote_len + local_len + 1) { memcpy (dest, remote, remote_len); len += remote_len; memcpy (dest + len, ":", 1); len++; memcpy (dest + len, local, local_len); len += local_len; } else if ((agent->compatibility == NICE_COMPATIBILITY_WLM2009 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && dest_len >= remote_len + local_len + 4 ) { memcpy (dest, remote, remote_len); len += remote_len; memcpy (dest + len, ":", 1); len++; memcpy (dest + len, local, local_len); len += local_len; if (len % 4 != 0) { memset (dest + len, 0, 4 - (len % 4)); len += 4 - (len % 4); } } else if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE && dest_len >= remote_len + local_len) { memcpy (dest, remote, remote_len); len += remote_len; memcpy (dest + len, local, local_len); len += local_len; } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { gchar component_str[10]; guchar *local_decoded = NULL; guchar *remote_decoded = NULL; gsize local_decoded_len; gsize remote_decoded_len; gsize total_len; int padding; g_snprintf (component_str, sizeof(component_str), "%d", component_id); local_decoded = g_base64_decode (local, &local_decoded_len); remote_decoded = g_base64_decode (remote, &remote_decoded_len); total_len = remote_decoded_len + local_decoded_len + 3 + 2*strlen (component_str); padding = 4 - (total_len % 4); if (dest_len >= total_len + padding) { guchar pad_char[1] = {0}; int i; memcpy (dest, remote_decoded, remote_decoded_len); len += remote_decoded_len; memcpy (dest + len, ":", 1); len++; memcpy (dest + len, component_str, strlen (component_str)); len += strlen (component_str); memcpy (dest + len, ":", 1); len++; memcpy (dest + len, local_decoded, local_decoded_len); len += local_decoded_len; memcpy (dest + len, ":", 1); len++; memcpy (dest + len, component_str, strlen (component_str));; len += strlen (component_str); for (i = 0; i < padding; i++) { memcpy (dest + len, pad_char, 1); len++; } } g_free (local_decoded); g_free (remote_decoded); } } return len; } /* * Fills 'dest' with a username string for use in an outbound connectivity * checks. No more than 'dest_len' characters (including terminating * NULL) is ever written to the 'dest'. */ static size_t priv_create_username (NiceAgent *agent, NiceStream *stream, guint component_id, NiceCandidate *remote, NiceCandidate *local, uint8_t *dest, guint dest_len, gboolean inbound) { gchar *local_username = NULL; gchar *remote_username = NULL; if (remote && remote->username) { remote_username = remote->username; } if (local && local->username) { local_username = local->username; } if (stream) { if (remote_username == NULL) { remote_username = stream->remote_ufrag; } if (local_username == NULL) { local_username = stream->local_ufrag; } } if (local_username && remote_username) { if (inbound) { return priv_gen_username (agent, component_id, local_username, remote_username, dest, dest_len); } else { return priv_gen_username (agent, component_id, remote_username, local_username, dest, dest_len); } } return 0; } /* * Returns a password string for use in an outbound connectivity * check. */ static size_t priv_get_password (NiceAgent *agent, NiceStream *stream, NiceCandidate *remote, uint8_t **password) { if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) return 0; if (remote && remote->password) { *password = (uint8_t *)remote->password; return strlen (remote->password); } if (stream) { *password = (uint8_t *)stream->remote_password; return strlen (stream->remote_password); } return 0; } /* Implement the computation specific in RFC 5245 section 16 */ static unsigned int priv_compute_conncheck_timer (NiceAgent *agent) { GSList *item1, *item2; guint waiting_and_in_progress = 0; unsigned int rto = 0; for (item1 = agent->streams; item1; item1 = item1->next) { NiceStream *stream = item1->data;; for (item2 = stream->conncheck_list; item2; item2 = item2->next) { CandidateCheckPair *pair = item2->data; if (pair->state == NICE_CHECK_IN_PROGRESS || pair->state == NICE_CHECK_WAITING) waiting_and_in_progress++; } } rto = agent->timer_ta * waiting_and_in_progress; /* We assume non-reliable streams are RTP, so we use 100 as the max */ nice_debug ("Agent %p : timer set to %dms (waiting+in_progress=%d)", agent, agent->reliable ? MAX (rto, 500) : MAX (rto, 100), waiting_and_in_progress); if (agent->reliable) return MAX (rto, 500); else return MAX (rto, 100); } /* * Sends a connectivity check over candidate pair 'pair'. * * @return zero on success, non-zero on error */ int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair) { /* note: following information is supplied: * - username (for USERNAME attribute) * - password (for MESSAGE-INTEGRITY) * - priority (for PRIORITY) * - ICE-CONTROLLED/ICE-CONTROLLING (for role conflicts) * - USE-CANDIDATE (if sent by the controlling agent) */ uint8_t uname[NICE_STREAM_MAX_UNAME]; NiceStream *stream; NiceComponent *component; gsize uname_len; uint8_t *password = NULL; gsize password_len; bool controlling = agent->controlling_mode; /* XXX: add API to support different nomination modes: */ bool cand_use = controlling; size_t buffer_len; unsigned int timeout; if (!agent_find_component (agent, pair->stream_id, pair->component_id, &stream, &component)) return -1; uname_len = priv_create_username (agent, stream, pair->component_id, pair->remote, pair->local, uname, sizeof (uname), FALSE); password_len = priv_get_password (agent, stream, pair->remote, &password); if (password != NULL && (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007)) { password = g_base64_decode ((gchar *) password, &password_len); } if (nice_debug_is_enabled ()) { gchar tmpbuf1[INET6_ADDRSTRLEN]; gchar tmpbuf2[INET6_ADDRSTRLEN]; nice_address_to_string (&pair->local->addr, tmpbuf1); nice_address_to_string (&pair->remote->addr, tmpbuf2); nice_debug ("Agent %p : STUN-CC REQ [%s]:%u --> [%s]:%u, socket=%u, " "pair=%s (c-id:%u), tie=%llu, username='%.*s' (%" G_GSIZE_FORMAT "), " "password='%.*s' (%" G_GSIZE_FORMAT "), prio=%u, cont=%d.", agent, tmpbuf1, nice_address_get_port (&pair->local->addr), tmpbuf2, nice_address_get_port (&pair->remote->addr), pair->sockptr->fileno ? g_socket_get_fd(pair->sockptr->fileno) : -1, pair->foundation, pair->component_id, (unsigned long long)agent->tie_breaker, (int) uname_len, uname, uname_len, (int) password_len, password, password_len, pair->prflx_priority, controlling); } if (cand_use) pair->nominated = controlling; if (uname_len > 0) { buffer_len = stun_usage_ice_conncheck_create (&component->stun_agent, &pair->stun_message, pair->stun_buffer, sizeof(pair->stun_buffer), uname, uname_len, password, password_len, cand_use, controlling, pair->prflx_priority, agent->tie_breaker, pair->local->foundation, agent_to_ice_compatibility (agent)); nice_debug ("Agent %p: conncheck created %zd - %p", agent, buffer_len, pair->stun_message.buffer); if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { g_free (password); } if (buffer_len > 0) { if (nice_socket_is_reliable(pair->sockptr)) { stun_timer_start_reliable(&pair->timer, STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT); } else { stun_timer_start (&pair->timer, priv_compute_conncheck_timer (agent), STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); } /* TCP-ACTIVE candidate must create a new socket before sending * by connecting to the peer. The new socket is stored in the candidate * check pair, until we discover a new local peer reflexive */ if (pair->sockptr->fileno == NULL && pair->sockptr->type != NICE_SOCKET_TYPE_UDP_TURN && pair->local->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) { NiceStream *stream2 = NULL; NiceComponent *component2 = NULL; NiceSocket *new_socket; if (agent_find_component (agent, pair->stream_id, pair->component_id, &stream2, &component2)) { new_socket = nice_tcp_active_socket_connect (pair->sockptr, &pair->remote->addr); if (new_socket) { pair->sockptr = new_socket; _priv_set_socket_tos (agent, pair->sockptr, stream2->tos); if (agent->reliable) { nice_socket_set_writable_callback (pair->sockptr, _tcp_sock_is_writable, component2); } nice_component_attach_socket (component2, new_socket); } } } /* send the conncheck */ agent_socket_send (pair->sockptr, &pair->remote->addr, buffer_len, (gchar *)pair->stun_buffer); if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { ms_ice2_legacy_conncheck_send (&pair->stun_message, pair->sockptr, &pair->remote->addr); } timeout = stun_timer_remainder (&pair->timer); /* note: convert from milli to microseconds for g_time_val_add() */ g_get_current_time (&pair->next_tick); g_time_val_add (&pair->next_tick, timeout * 1000); } else { nice_debug ("Agent %p: buffer is empty, cancelling conncheck", agent); pair->stun_message.buffer = NULL; pair->stun_message.buffer_len = 0; return -1; } } else { nice_debug ("Agent %p: no credentials found, cancelling conncheck", agent); pair->stun_message.buffer = NULL; pair->stun_message.buffer_len = 0; return -1; } return 0; } /* * Implemented the pruning steps described in ICE sect 8.1.2 * "Updating States" (ID-19) after a pair has been nominated. * * @see priv_update_check_list_state_failed_components() */ static guint priv_prune_pending_checks (NiceStream *stream, guint component_id) { GSList *i; guint64 highest_nominated_priority = 0; guint in_progress = 0; nice_debug ("Agent XXX: Finding highest priority for component %d", component_id); for (i = stream->conncheck_list; i; i = i->next) { CandidateCheckPair *p = i->data; if (p->component_id == component_id && p->valid == TRUE && p->nominated == TRUE) { if (p->priority > highest_nominated_priority) { highest_nominated_priority = p->priority; } } } nice_debug ("Agent XXX: Pruning pending checks. Highest nominated priority " "is %" G_GUINT64_FORMAT, highest_nominated_priority); /* step: cancel all FROZEN and WAITING pairs for the component */ for (i = stream->conncheck_list; i; i = i->next) { CandidateCheckPair *p = i->data; if (p->component_id == component_id) { if (p->state == NICE_CHECK_FROZEN || p->state == NICE_CHECK_WAITING) { p->state = NICE_CHECK_CANCELLED; nice_debug ("Agent XXX : pair %p state CANCELED", p); } /* note: a SHOULD level req. in ICE 8.1.2. "Updating States" (ID-19) */ if (p->state == NICE_CHECK_IN_PROGRESS) { if (highest_nominated_priority != 0 && p->priority < highest_nominated_priority) { p->stun_message.buffer = NULL; p->stun_message.buffer_len = 0; p->state = NICE_CHECK_CANCELLED; nice_debug ("Agent XXX : pair %p state CANCELED", p); } else { /* We must keep the higher priority pairs running because if a udp * packet was lost, we might end up using a bad candidate */ nice_debug ("Agent XXX : pair %p kept IN_PROGRESS because priority %" G_GUINT64_FORMAT " is higher than currently nominated pair %" G_GUINT64_FORMAT, p, p->priority, highest_nominated_priority); in_progress++; } } } } return in_progress; } /* * Schedules a triggered check after a successfully inbound * connectivity check. Implements ICE sect 7.2.1.4 "Triggered Checks" (ID-19). * * @param agent self pointer * @param component the check is related to * @param local_socket socket from which the inbound check was received * @param remote_cand remote candidate from which the inbound check was sent * @param use_candidate whether the original check had USE-CANDIDATE attribute set */ static gboolean priv_schedule_triggered_check (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *local_socket, NiceCandidate *remote_cand, gboolean use_candidate) { GSList *i; NiceCandidate *local = NULL; g_assert (remote_cand != NULL); for (i = stream->conncheck_list; i ; i = i->next) { CandidateCheckPair *p = i->data; if (p->component_id == component->id && p->remote == remote_cand && ((p->local->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE && p->sockptr == local_socket) || (p->local->transport != NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE && p->local->sockptr == local_socket))) { /* We don't check for p->sockptr because in the case of * tcp-active we don't want to retrigger a check on a pair that * was FAILED when a peer-reflexive pair was created */ nice_debug ("Agent %p : Found a matching pair %p for triggered check.", agent, p); if (p->state == NICE_CHECK_WAITING || p->state == NICE_CHECK_FROZEN) priv_add_pair_to_triggered_check_queue (agent, p); else if (p->state == NICE_CHECK_IN_PROGRESS) { /* XXX: according to ICE 7.2.1.4 "Triggered Checks" (ID-19), * we should cancel the existing one, instead we reset our timer, so * we'll resend the exiting transactions faster if needed...? :P */ nice_debug ("Agent %p : check already in progress, " "restarting the timer again?: %s ..", agent, p->timer_restarted ? "no" : "yes"); if (!nice_socket_is_reliable (p->sockptr) && !p->timer_restarted) { stun_timer_start (&p->timer, priv_compute_conncheck_timer (agent), STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); p->timer_restarted = TRUE; } } else if (p->state == NICE_CHECK_SUCCEEDED || p->state == NICE_CHECK_DISCOVERED) { nice_debug ("Agent %p : Skipping triggered check, already completed..", agent); /* note: this is a bit unsure corner-case -- let's do the same state update as for processing responses to our own checks */ /* note: this update is required by the dribble test, to * ensure the transition ready -> connected -> ready, because * an incoming stun request generates a discovered peer reflexive, * that causes the ready -> connected transition. */ priv_update_check_list_state_for_ready (agent, stream, component); /* note: this new check is required by the new-dribble test, * when early icheck on the peer controlled agent causes an * incoming stun request to an already succeeded (and * nominated) pair on the controlling agent. If the * controlling agent doesn't retrigger a check with * USE-CANDIDATE=1, the peer agent has no way to nominate it. * * This behavior differs from ICE spec 7.2.1.4 */ if ((agent->compatibility == NICE_COMPATIBILITY_RFC5245 || agent->compatibility == NICE_COMPATIBILITY_WLM2009 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && agent->controlling_mode) { priv_add_pair_to_triggered_check_queue (agent, p); conn_check_schedule_next(agent); } } else if (p->state == NICE_CHECK_FAILED) { /* 7.2.1.4 Triggered Checks * If the state of the pair is Failed, it is changed to Waiting and the agent MUST create a new connectivity check for that pair (representing a new STUN Binding request transaction), by enqueueing the pair in the triggered check queue. */ priv_add_pair_to_triggered_check_queue (agent, p); } /* note: the spec says the we SHOULD retransmit in-progress * checks immediately, but we won't do that now */ return TRUE; } } for (i = component->local_candidates; i ; i = i->next) { local = i->data; if (local->sockptr == local_socket) break; } if (i) { nice_debug ("Agent %p : Adding a triggered check to conn.check list (local=%p).", agent, local); priv_add_new_check_pair (agent, stream->id, component, local, remote_cand, NICE_CHECK_WAITING, use_candidate); return TRUE; } else { nice_debug ("Agent %p : Didn't find a matching pair for triggered check (remote-cand=%p).", agent, remote_cand); return FALSE; } } /* * Sends a reply to an successfully received STUN connectivity * check request. Implements parts of the ICE spec section 7.2 (STUN * Server Procedures). * * @param agent context pointer * @param stream which stream (of the agent) * @param component which component (of the stream) * @param rcand remote candidate from which the request came, if NULL, * the response is sent immediately but no other processing is done * @param toaddr address to which reply is sent * @param socket the socket over which the request came * @param rbuf_len length of STUN message to send * @param msg the STUN message to send * @param use_candidate whether the request had USE_CANDIDATE attribute * * @pre (rcand == NULL || nice_address_equal(rcand->addr, toaddr) == TRUE) */ static void priv_reply_to_conn_check (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceCandidate *lcand, NiceCandidate *rcand, const NiceAddress *toaddr, NiceSocket *sockptr, size_t rbuf_len, StunMessage *msg, gboolean use_candidate) { g_assert (rcand == NULL || nice_address_equal(&rcand->addr, toaddr) == TRUE); if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (toaddr, tmpbuf); nice_debug ("Agent %p : STUN-CC RESP to '%s:%u', socket=%u, len=%u, cand=%p (c-id:%u), use-cand=%d.", agent, tmpbuf, nice_address_get_port (toaddr), sockptr->fileno ? g_socket_get_fd(sockptr->fileno) : -1, (unsigned)rbuf_len, rcand, component->id, (int)use_candidate); } agent_socket_send (sockptr, toaddr, rbuf_len, (const gchar*)msg->buffer); if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { ms_ice2_legacy_conncheck_send(msg, sockptr, toaddr); } if (rcand) { /* note: upon successful check, make the reserve check immediately */ priv_schedule_triggered_check (agent, stream, component, sockptr, rcand, use_candidate); if (use_candidate) priv_mark_pair_nominated (agent, stream, component, lcand, rcand); } } /* * Stores information of an incoming STUN connectivity check * for later use. This is only needed when a check is received * before we get information about the remote candidates (via * SDP or other signaling means). * * @return non-zero on error, zero on success */ static int priv_store_pending_check (NiceAgent *agent, NiceComponent *component, const NiceAddress *from, NiceSocket *sockptr, uint8_t *username, uint16_t username_len, uint32_t priority, gboolean use_candidate) { IncomingCheck *icheck; nice_debug ("Agent %p : Storing pending check.", agent); if (component->incoming_checks && g_slist_length (component->incoming_checks) >= NICE_AGENT_MAX_REMOTE_CANDIDATES) { nice_debug ("Agent %p : WARN: unable to store information for early incoming check.", agent); return -1; } icheck = g_slice_new0 (IncomingCheck); component->incoming_checks = g_slist_append (component->incoming_checks, icheck); icheck->from = *from; icheck->local_socket = sockptr; icheck->priority = priority; icheck->use_candidate = use_candidate; icheck->username_len = username_len; icheck->username = NULL; if (username_len > 0) icheck->username = g_memdup (username, username_len); return 0; } /* * Adds a new pair, discovered from an incoming STUN response, to * the connectivity check list. * * @return created pair, or NULL on fatal (memory allocation) errors */ static CandidateCheckPair *priv_add_peer_reflexive_pair (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local_cand, CandidateCheckPair *parent_pair) { CandidateCheckPair *pair = g_slice_new0 (CandidateCheckPair); NiceStream *stream = agent_find_stream (agent, stream_id); pair->agent = agent; pair->stream_id = stream_id; pair->component_id = component->id;; pair->local = local_cand; pair->remote = parent_pair->remote; pair->sockptr = local_cand->sockptr; pair->state = NICE_CHECK_DISCOVERED; nice_debug ("Agent %p : new pair %p state DISCOVERED", agent, pair); { gchar tmpbuf1[INET6_ADDRSTRLEN]; gchar tmpbuf2[INET6_ADDRSTRLEN]; nice_address_to_string (&pair->local->addr, tmpbuf1); nice_address_to_string (&pair->remote->addr, tmpbuf2); nice_debug ("Agent %p : new pair %p : [%s]:%u --> [%s]:%u", agent, pair, tmpbuf1, nice_address_get_port (&pair->local->addr), tmpbuf2, nice_address_get_port (&pair->remote->addr)); } g_snprintf (pair->foundation, NICE_CANDIDATE_PAIR_MAX_FOUNDATION, "%s:%s", local_cand->foundation, parent_pair->remote->foundation); if (agent->controlling_mode == TRUE) pair->priority = nice_candidate_pair_priority (pair->local->priority, pair->remote->priority); else pair->priority = nice_candidate_pair_priority (pair->remote->priority, pair->local->priority); pair->nominated = FALSE; pair->controlling = agent->controlling_mode; pair->prflx_priority = ensure_unique_priority (component, peer_reflexive_candidate_priority (agent, local_cand)); nice_debug ("Agent %p : added a new peer-discovered pair with foundation of '%s'.", agent, pair->foundation); stream->conncheck_list = g_slist_insert_sorted (stream->conncheck_list, pair, (GCompareFunc)conn_check_compare); return pair; } /* * Recalculates priorities of all candidate pairs. This * is required after a conflict in ICE roles. */ static void priv_recalculate_pair_priorities (NiceAgent *agent) { GSList *i, *j; for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; for (j = stream->conncheck_list; j; j = j->next) { CandidateCheckPair *p = j->data; p->priority = agent_candidate_pair_priority (agent, p->local, p->remote); } stream->conncheck_list = g_slist_sort (stream->conncheck_list, (GCompareFunc)conn_check_compare); } } /* * Change the agent role if different from 'control'. Can be * initiated both by handling of incoming connectivity checks, * and by processing the responses to checks sent by us. */ static void priv_check_for_role_conflict (NiceAgent *agent, gboolean control) { /* role conflict, change mode; wait for a new conn. check */ if (control != agent->controlling_mode) { nice_debug ("Agent %p : Role conflict, changing agent role to %d.", agent, control); agent->controlling_mode = control; /* the pair priorities depend on the roles, so recalculation * is needed */ priv_recalculate_pair_priorities (agent); } else nice_debug ("Agent %p : Role conflict, agent role already changed to %d.", agent, control); } /* * Checks whether the mapped address in connectivity check response * matches any of the known local candidates. If not, apply the * mechanism for "Discovering Peer Reflexive Candidates" ICE ID-19) * * @param agent context pointer * @param stream which stream (of the agent) * @param component which component (of the stream) * @param p the connectivity check pair for which we got a response * @param socketptr socket used to send the reply * @param mapped_sockaddr mapped address in the response * * @return pointer to a candidate pair, found in conncheck list or newly created */ static CandidateCheckPair *priv_process_response_check_for_reflexive(NiceAgent *agent, NiceStream *stream, NiceComponent *component, CandidateCheckPair *p, NiceSocket *sockptr, struct sockaddr *mapped_sockaddr, NiceCandidate *local_candidate, NiceCandidate *remote_candidate) { CandidateCheckPair *new_pair = NULL; NiceAddress mapped; GSList *i, *j; NiceCandidate *local_cand = NULL; nice_address_set_from_sockaddr (&mapped, mapped_sockaddr); for (j = component->local_candidates; j; j = j->next) { NiceCandidate *cand = j->data; if (nice_address_equal (&mapped, &cand->addr)) { local_cand = cand; /* We always need to select the peer-reflexive Candidate Pair in the case * of a TCP-ACTIVE local candidate, so we find it even if an incoming * check matched an existing pair because it could be the original * ACTIVE-PASSIVE candidate pair which was retriggered */ for (i = stream->conncheck_list; i; i = i->next) { CandidateCheckPair *pair = i->data; if (pair->local == cand && remote_candidate == pair->remote) { new_pair = pair; break; } } break; } } if (new_pair) { p->state = NICE_CHECK_SUCCEEDED; nice_debug ("Agent %p : conncheck %p SUCCEEDED.", agent, p); priv_conn_check_unfreeze_related (agent, stream, p); } else { if (!local_cand) { if (!agent->force_relay) local_cand = discovery_add_peer_reflexive_candidate (agent, stream->id, component->id, &mapped, sockptr, local_candidate, remote_candidate); p->state = NICE_CHECK_FAILED; nice_debug ("Agent %p : pair %p state FAILED", agent, p); } /* step: add a new discovered pair (see RFC 5245 7.1.3.2.2 "Constructing a Valid Pair") */ if (local_cand) new_pair = priv_add_peer_reflexive_pair (agent, stream->id, component, local_cand, p); nice_debug ("Agent %p : conncheck %p FAILED, %p DISCOVERED.", agent, p, new_pair); } /* note: this is same as "adding to VALID LIST" in the spec text */ if (new_pair) new_pair->valid = TRUE; return new_pair; } /* * Tries to match STUN reply in 'buf' to an existing STUN connectivity * check transaction. If found, the reply is processed. Implements * section 7.1.2 "Processing the Response" of ICE spec (ID-19). * * @return TRUE if a matching transaction is found */ static gboolean priv_map_reply_to_conn_check_request (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *sockptr, const NiceAddress *from, NiceCandidate *local_candidate, NiceCandidate *remote_candidate, StunMessage *resp) { union { struct sockaddr_storage storage; struct sockaddr addr; } sockaddr; socklen_t socklen = sizeof (sockaddr); GSList *i; StunUsageIceReturn res; gboolean trans_found = FALSE; StunTransactionId discovery_id; StunTransactionId response_id; stun_message_id (resp, response_id); for (i = stream->conncheck_list; i && trans_found != TRUE; i = i->next) { CandidateCheckPair *p = i->data; if (p->stun_message.buffer) { stun_message_id (&p->stun_message, discovery_id); if (memcmp (discovery_id, response_id, sizeof(StunTransactionId)) == 0) { res = stun_usage_ice_conncheck_process (resp, &sockaddr.storage, &socklen, agent_to_ice_compatibility (agent)); nice_debug ("Agent %p : stun_bind_process/conncheck for %p res %d " "(controlling=%d).", agent, p, (int)res, agent->controlling_mode); if (res == STUN_USAGE_ICE_RETURN_SUCCESS || res == STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS) { /* case: found a matching connectivity check request */ CandidateCheckPair *ok_pair = NULL; nice_debug ("Agent %p : conncheck %p MATCHED.", agent, p); p->stun_message.buffer = NULL; p->stun_message.buffer_len = 0; /* step: verify that response came from the same IP address we * sent the original request to (see 7.1.2.1. "Failure * Cases") */ if (nice_address_equal (from, &p->remote->addr) != TRUE) { p->state = NICE_CHECK_FAILED; if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; gchar tmpbuf2[INET6_ADDRSTRLEN]; nice_debug ("Agent %p : conncheck %p FAILED" " (mismatch of source address).", agent, p); nice_address_to_string (&p->remote->addr, tmpbuf); nice_address_to_string (from, tmpbuf2); nice_debug ("Agent %p : '%s:%u' != '%s:%u'", agent, tmpbuf, nice_address_get_port (&p->remote->addr), tmpbuf2, nice_address_get_port (from)); } trans_found = TRUE; break; } /* note: CONNECTED but not yet READY, see docs */ /* step: handle the possible case of a peer-reflexive * candidate where the mapped-address in response does * not match any local candidate, see 7.1.2.2.1 * "Discovering Peer Reflexive Candidates" ICE ID-19) */ if (res == STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS) { /* note: this is same as "adding to VALID LIST" in the spec text */ p->state = NICE_CHECK_SUCCEEDED; p->valid = TRUE; g_assert_not_reached (); nice_debug ("Agent %p : Mapped address not found." " conncheck %p SUCCEEDED.", agent, p); priv_conn_check_unfreeze_related (agent, stream, p); } else { ok_pair = priv_process_response_check_for_reflexive (agent, stream, component, p, sockptr, &sockaddr.addr, local_candidate, remote_candidate); } if (!ok_pair) ok_pair = p; /* step: updating nominated flag (ICE 7.1.2.2.4 "Updating the Nominated Flag" (ID-19) */ if (ok_pair->nominated == TRUE) { priv_update_selected_pair (agent, component, ok_pair); priv_print_conn_check_lists (agent, G_STRFUNC, ", got a nominated pair"); /* Do not step down to CONNECTED if we're already at state READY*/ if (component->state != NICE_COMPONENT_STATE_READY) { /* step: notify the client of a new component state (must be done * before the possible check list state update step */ agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_CONNECTED); } } /* step: update pair states (ICE 7.1.2.2.3 "Updating pair states" and 8.1.2 "Updating States", ID-19) */ priv_update_check_list_state_for_ready (agent, stream, component); trans_found = TRUE; } else if (res == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT) { /* case: role conflict error, need to restart with new role */ nice_debug ("Agent %p : conncheck %p ROLE CONFLICT, restarting", agent, p); /* note: our role might already have changed due to an * incoming request, but if not, change role now; * follows ICE 7.1.2.1 "Failure Cases" (ID-19) */ priv_check_for_role_conflict (agent, !p->controlling); p->stun_message.buffer = NULL; p->stun_message.buffer_len = 0; p->state = NICE_CHECK_WAITING; priv_add_pair_to_triggered_check_queue (agent, p); nice_debug ("Agent %p : pair %p state WAITING", agent, p); trans_found = TRUE; } else { /* case: STUN error, the check STUN context was freed */ nice_debug ("Agent %p : conncheck %p FAILED.", agent, p); p->stun_message.buffer = NULL; p->stun_message.buffer_len = 0; trans_found = TRUE; } } } } stream->conncheck_list = prune_cancelled_conn_check (stream->conncheck_list); return trans_found; } /* * Tries to match STUN reply in 'buf' to an existing STUN discovery * transaction. If found, a reply is sent. * * @return TRUE if a matching transaction is found */ static gboolean priv_map_reply_to_discovery_request (NiceAgent *agent, StunMessage *resp) { union { struct sockaddr_storage storage; struct sockaddr addr; } sockaddr; socklen_t socklen = sizeof (sockaddr); union { struct sockaddr_storage storage; struct sockaddr addr; } alternate; socklen_t alternatelen = sizeof (sockaddr); GSList *i; StunUsageBindReturn res; gboolean trans_found = FALSE; StunTransactionId discovery_id; StunTransactionId response_id; stun_message_id (resp, response_id); for (i = agent->discovery_list; i && trans_found != TRUE; i = i->next) { CandidateDiscovery *d = i->data; if (d->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE && d->stun_message.buffer) { stun_message_id (&d->stun_message, discovery_id); if (memcmp (discovery_id, response_id, sizeof(StunTransactionId)) == 0) { res = stun_usage_bind_process (resp, &sockaddr.addr, &socklen, &alternate.addr, &alternatelen); nice_debug ("Agent %p : stun_bind_process/disc for %p res %d.", agent, d, (int)res); if (res == STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER) { /* handle alternate server */ NiceAddress niceaddr; nice_address_set_from_sockaddr (&niceaddr, &alternate.addr); d->server = niceaddr; d->pending = FALSE; } else if (res == STUN_USAGE_BIND_RETURN_SUCCESS) { /* case: successful binding discovery, create a new local candidate */ if (!agent->force_relay) { NiceAddress niceaddr; nice_address_set_from_sockaddr (&niceaddr, &sockaddr.addr); discovery_add_server_reflexive_candidate ( d->agent, d->stream->id, d->component->id, &niceaddr, NICE_CANDIDATE_TRANSPORT_UDP, d->nicesock, FALSE); if (d->agent->use_ice_tcp) discovery_discover_tcp_server_reflexive_candidates ( d->agent, d->stream->id, d->component->id, &niceaddr, d->nicesock); } d->stun_message.buffer = NULL; d->stun_message.buffer_len = 0; d->done = TRUE; trans_found = TRUE; } else if (res == STUN_USAGE_BIND_RETURN_ERROR) { /* case: STUN error, the check STUN context was freed */ d->stun_message.buffer = NULL; d->stun_message.buffer_len = 0; d->done = TRUE; trans_found = TRUE; } } } } return trans_found; } static CandidateRefresh * priv_add_new_turn_refresh (CandidateDiscovery *cdisco, NiceCandidate *relay_cand, guint lifetime) { CandidateRefresh *cand; NiceAgent *agent = cdisco->agent; cand = g_slice_new0 (CandidateRefresh); agent->refresh_list = g_slist_append (agent->refresh_list, cand); cand->candidate = relay_cand; cand->nicesock = cdisco->nicesock; cand->server = cdisco->server; cand->stream = cdisco->stream; cand->component = cdisco->component; cand->agent = cdisco->agent; memcpy (&cand->stun_agent, &cdisco->stun_agent, sizeof(StunAgent)); /* Use previous stun response for authentication credentials */ if (cdisco->stun_resp_msg.buffer != NULL) { memcpy(cand->stun_resp_buffer, cdisco->stun_resp_buffer, sizeof(cand->stun_resp_buffer)); memcpy(&cand->stun_resp_msg, &cdisco->stun_resp_msg, sizeof(StunMessage)); cand->stun_resp_msg.buffer = cand->stun_resp_buffer; cand->stun_resp_msg.agent = NULL; cand->stun_resp_msg.key = NULL; } nice_debug ("Agent %p : Adding new refresh candidate %p with timeout %d", agent, cand, (lifetime - 60) * 1000); /* step: also start the refresh timer */ /* refresh should be sent 1 minute before it expires */ agent_timeout_add_with_context (agent, &cand->timer_source, "Candidate TURN refresh", (lifetime - 60) * 1000, priv_turn_allocate_refresh_tick, cand); nice_debug ("timer source is : %p", cand->timer_source); return cand; } /* * Tries to match STUN reply in 'buf' to an existing STUN discovery * transaction. If found, a reply is sent. * * @return TRUE if a matching transaction is found */ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage *resp) { union { struct sockaddr_storage storage; struct sockaddr addr; } sockaddr; socklen_t socklen = sizeof (sockaddr); union { struct sockaddr_storage storage; struct sockaddr addr; } alternate; socklen_t alternatelen = sizeof (alternate); union { struct sockaddr_storage storage; struct sockaddr addr; } relayaddr; socklen_t relayaddrlen = sizeof (relayaddr); uint32_t lifetime; uint32_t bandwidth; GSList *i; StunUsageTurnReturn res; gboolean trans_found = FALSE; StunTransactionId discovery_id; StunTransactionId response_id; stun_message_id (resp, response_id); for (i = agent->discovery_list; i && trans_found != TRUE; i = i->next) { CandidateDiscovery *d = i->data; if (d->type == NICE_CANDIDATE_TYPE_RELAYED && d->stun_message.buffer) { stun_message_id (&d->stun_message, discovery_id); if (memcmp (discovery_id, response_id, sizeof(StunTransactionId)) == 0) { res = stun_usage_turn_process (resp, &relayaddr.storage, &relayaddrlen, &sockaddr.storage, &socklen, &alternate.storage, &alternatelen, &bandwidth, &lifetime, agent_to_turn_compatibility (agent)); nice_debug ("Agent %p : stun_turn_process/disc for %p res %d.", agent, d, (int)res); if (res == STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER) { /* handle alternate server */ nice_address_set_from_sockaddr (&d->server, &alternate.addr); nice_address_set_from_sockaddr (&d->turn->server, &alternate.addr); d->pending = FALSE; } else if (res == STUN_USAGE_TURN_RETURN_RELAY_SUCCESS || res == STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS) { /* case: successful allocate, create a new local candidate */ NiceAddress niceaddr; NiceCandidate *relay_cand; if (res == STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS) { /* We also received our mapped address */ nice_address_set_from_sockaddr (&niceaddr, &sockaddr.addr); /* TCP or TLS TURNS means the server-reflexive address was * on a TCP connection, which cannot be used for server-reflexive * discovery of candidates. */ if (d->turn->type == NICE_RELAY_TYPE_TURN_UDP && !agent->force_relay) { discovery_add_server_reflexive_candidate ( d->agent, d->stream->id, d->component->id, &niceaddr, NICE_CANDIDATE_TRANSPORT_UDP, d->nicesock, FALSE); } if (d->agent->use_ice_tcp) discovery_discover_tcp_server_reflexive_candidates ( d->agent, d->stream->id, d->component->id, &niceaddr, d->nicesock); } nice_address_set_from_sockaddr (&niceaddr, &relayaddr.addr); if (nice_socket_is_reliable (d->nicesock)) { relay_cand = discovery_add_relay_candidate ( d->agent, d->stream->id, d->component->id, &niceaddr, NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE, d->nicesock, d->turn); if (relay_cand) { if (agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { nice_udp_turn_socket_set_ms_realm(relay_cand->sockptr, &d->stun_message); nice_udp_turn_socket_set_ms_connection_id(relay_cand->sockptr, resp); } else { priv_add_new_turn_refresh (d, relay_cand, lifetime); } } relay_cand = discovery_add_relay_candidate ( d->agent, d->stream->id, d->component->id, &niceaddr, NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE, d->nicesock, d->turn); } else { relay_cand = discovery_add_relay_candidate ( d->agent, d->stream->id, d->component->id, &niceaddr, NICE_CANDIDATE_TRANSPORT_UDP, d->nicesock, d->turn); } if (relay_cand) { if (d->stun_resp_msg.buffer) nice_udp_turn_socket_cache_realm_nonce (relay_cand->sockptr, &d->stun_resp_msg); if (agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { /* These data are needed on TURN socket when sending requests, * but never reach nice_turn_socket_parse_recv() where it could * be read directly, as the socket does not exist when allocate * response arrives to _nice_agent_recv(). We must set them right * after socket gets created in discovery_add_relay_candidate(), * so we are doing it here. */ nice_udp_turn_socket_set_ms_realm(relay_cand->sockptr, &d->stun_message); nice_udp_turn_socket_set_ms_connection_id(relay_cand->sockptr, resp); } else { priv_add_new_turn_refresh (d, relay_cand, lifetime); } /* In case a new candidate has been added */ conn_check_schedule_next (agent); } d->stun_message.buffer = NULL; d->stun_message.buffer_len = 0; d->done = TRUE; trans_found = TRUE; } else if (res == STUN_USAGE_TURN_RETURN_ERROR) { int code = -1; uint8_t *sent_realm = NULL; uint8_t *recv_realm = NULL; uint16_t sent_realm_len = 0; uint16_t recv_realm_len = 0; sent_realm = (uint8_t *) stun_message_find (&d->stun_message, STUN_ATTRIBUTE_REALM, &sent_realm_len); recv_realm = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_REALM, &recv_realm_len); /* check for unauthorized error response */ if ((agent->compatibility == NICE_COMPATIBILITY_RFC5245 || agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && stun_message_get_class (resp) == STUN_ERROR && stun_message_find_error (resp, &code) == STUN_MESSAGE_RETURN_SUCCESS && recv_realm != NULL && recv_realm_len > 0) { if (code == 438 || (code == 401 && !(recv_realm_len == sent_realm_len && sent_realm != NULL && memcmp (sent_realm, recv_realm, sent_realm_len) == 0))) { d->stun_resp_msg = *resp; memcpy (d->stun_resp_buffer, resp->buffer, stun_message_length (resp)); d->stun_resp_msg.buffer = d->stun_resp_buffer; d->stun_resp_msg.buffer_len = sizeof(d->stun_resp_buffer); d->pending = FALSE; } else { /* case: a real unauthorized error */ d->stun_message.buffer = NULL; d->stun_message.buffer_len = 0; d->done = TRUE; } } else { /* case: STUN error, the check STUN context was freed */ d->stun_message.buffer = NULL; d->stun_message.buffer_len = 0; d->done = TRUE; } trans_found = TRUE; } } } } return trans_found; } /* * Tries to match STUN reply in 'buf' to an existing STUN discovery * transaction. If found, a reply is sent. * * @return TRUE if a matching transaction is found */ static gboolean priv_map_reply_to_relay_refresh (NiceAgent *agent, StunMessage *resp) { uint32_t lifetime; GSList *i; StunUsageTurnReturn res; gboolean trans_found = FALSE; StunTransactionId refresh_id; StunTransactionId response_id; stun_message_id (resp, response_id); for (i = agent->refresh_list; i && trans_found != TRUE; i = i->next) { CandidateRefresh *cand = i->data; if (cand->stun_message.buffer) { stun_message_id (&cand->stun_message, refresh_id); if (memcmp (refresh_id, response_id, sizeof(StunTransactionId)) == 0) { res = stun_usage_turn_refresh_process (resp, &lifetime, agent_to_turn_compatibility (cand->agent)); nice_debug ("Agent %p : stun_turn_refresh_process for %p res %d.", agent, cand, (int)res); if (res == STUN_USAGE_TURN_RETURN_RELAY_SUCCESS) { /* refresh should be sent 1 minute before it expires */ agent_timeout_add_with_context (cand->agent, &cand->timer_source, "Candidate TURN refresh", (lifetime - 60) * 1000, priv_turn_allocate_refresh_tick, cand); g_source_destroy (cand->tick_source); g_source_unref (cand->tick_source); cand->tick_source = NULL; } else if (res == STUN_USAGE_TURN_RETURN_ERROR) { int code = -1; uint8_t *sent_realm = NULL; uint8_t *recv_realm = NULL; uint16_t sent_realm_len = 0; uint16_t recv_realm_len = 0; sent_realm = (uint8_t *) stun_message_find (&cand->stun_message, STUN_ATTRIBUTE_REALM, &sent_realm_len); recv_realm = (uint8_t *) stun_message_find (resp, STUN_ATTRIBUTE_REALM, &recv_realm_len); /* check for unauthorized error response */ if (cand->agent->compatibility == NICE_COMPATIBILITY_RFC5245 && stun_message_get_class (resp) == STUN_ERROR && stun_message_find_error (resp, &code) == STUN_MESSAGE_RETURN_SUCCESS && recv_realm != NULL && recv_realm_len > 0) { if (code == 438 || (code == 401 && !(recv_realm_len == sent_realm_len && sent_realm != NULL && memcmp (sent_realm, recv_realm, sent_realm_len) == 0))) { cand->stun_resp_msg = *resp; memcpy (cand->stun_resp_buffer, resp->buffer, stun_message_length (resp)); cand->stun_resp_msg.buffer = cand->stun_resp_buffer; cand->stun_resp_msg.buffer_len = sizeof(cand->stun_resp_buffer); priv_turn_allocate_refresh_tick_unlocked (cand); } else { /* case: a real unauthorized error */ refresh_cancel (cand); } } else { /* case: STUN error, the check STUN context was freed */ refresh_cancel (cand); } trans_found = TRUE; } } } } return trans_found; } static gboolean priv_map_reply_to_keepalive_conncheck (NiceAgent *agent, NiceComponent *component, StunMessage *resp) { StunTransactionId conncheck_id; StunTransactionId response_id; stun_message_id (resp, response_id); if (component->selected_pair.keepalive.stun_message.buffer) { stun_message_id (&component->selected_pair.keepalive.stun_message, conncheck_id); if (memcmp (conncheck_id, response_id, sizeof(StunTransactionId)) == 0) { nice_debug ("Agent %p : Keepalive for selected pair received.", agent); if (component->selected_pair.keepalive.tick_source) { g_source_destroy (component->selected_pair.keepalive.tick_source); g_source_unref (component->selected_pair.keepalive.tick_source); component->selected_pair.keepalive.tick_source = NULL; } component->selected_pair.keepalive.stun_message.buffer = NULL; return TRUE; } } return FALSE; } typedef struct { NiceAgent *agent; NiceStream *stream; NiceComponent *component; uint8_t *password; } conncheck_validater_data; static bool conncheck_stun_validater (StunAgent *agent, StunMessage *message, uint8_t *username, uint16_t username_len, uint8_t **password, size_t *password_len, void *user_data) { conncheck_validater_data *data = (conncheck_validater_data*) user_data; GSList *i; gchar *ufrag = NULL; gsize ufrag_len; gboolean msn_msoc_nice_compatibility = data->agent->compatibility == NICE_COMPATIBILITY_MSN || data->agent->compatibility == NICE_COMPATIBILITY_OC2007; if (data->agent->compatibility == NICE_COMPATIBILITY_OC2007 && stun_message_get_class (message) == STUN_RESPONSE) i = data->component->remote_candidates; else i = data->component->local_candidates; for (; i; i = i->next) { NiceCandidate *cand = i->data; ufrag = NULL; if (cand->username) ufrag = cand->username; else if (data->stream) ufrag = data->stream->local_ufrag; ufrag_len = ufrag? strlen (ufrag) : 0; if (ufrag && msn_msoc_nice_compatibility) ufrag = (gchar *)g_base64_decode (ufrag, &ufrag_len); if (ufrag == NULL) continue; stun_debug ("Comparing username/ufrag of len %d and %" G_GSIZE_FORMAT ", equal=%d", username_len, ufrag_len, username_len >= ufrag_len ? memcmp (username, ufrag, ufrag_len) : 0); stun_debug_bytes (" username: ", username, username_len); stun_debug_bytes (" ufrag: ", ufrag, ufrag_len); if (ufrag_len > 0 && username_len >= ufrag_len && memcmp (username, ufrag, ufrag_len) == 0) { gchar *pass = NULL; if (cand->password) pass = cand->password; else if(data->stream->local_password[0]) pass = data->stream->local_password; if (pass) { *password = (uint8_t *) pass; *password_len = strlen (pass); if (msn_msoc_nice_compatibility) { gsize pass_len; data->password = g_base64_decode (pass, &pass_len); *password = data->password; *password_len = pass_len; } } if (msn_msoc_nice_compatibility) g_free (ufrag); stun_debug ("Found valid username, returning password: '%s'", *password); return TRUE; } if (msn_msoc_nice_compatibility) g_free (ufrag); } return FALSE; } /* * Processing an incoming STUN message. * * @param agent self pointer * @param stream stream the packet is related to * @param component component the packet is related to * @param nicesock socket from which the packet was received * @param from address of the sender * @param buf message contents * @param buf message length * * @pre contents of 'buf' is a STUN message * * @return XXX (what FALSE means exactly?) */ gboolean conn_check_handle_inbound_stun (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *nicesock, const NiceAddress *from, gchar *buf, guint len) { union { struct sockaddr_storage storage; struct sockaddr addr; } sockaddr; uint8_t rbuf[MAX_STUN_DATAGRAM_PAYLOAD]; ssize_t res; size_t rbuf_len = sizeof (rbuf); bool control = agent->controlling_mode; uint8_t uname[NICE_STREAM_MAX_UNAME]; guint uname_len; uint8_t *username; uint16_t username_len; StunMessage req; StunMessage msg; StunValidationStatus valid; conncheck_validater_data validater_data = {agent, stream, component, NULL}; GSList *i, *j; NiceCandidate *remote_candidate = NULL; NiceCandidate *remote_candidate2 = NULL; NiceCandidate *local_candidate = NULL; gboolean discovery_msg = FALSE; nice_address_copy_to_sockaddr (from, &sockaddr.addr); /* note: contents of 'buf' already validated, so it is * a valid and fully received STUN message */ if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (from, tmpbuf); nice_debug ("Agent %p: inbound STUN packet for %u/%u (stream/component) from [%s]:%u (%u octets) :", agent, stream->id, component->id, tmpbuf, nice_address_get_port (from), len); } /* note: ICE 7.2. "STUN Server Procedures" (ID-19) */ valid = stun_agent_validate (&component->stun_agent, &req, (uint8_t *) buf, len, conncheck_stun_validater, &validater_data); /* Check for discovery candidates stun agents */ if (valid == STUN_VALIDATION_BAD_REQUEST || valid == STUN_VALIDATION_UNMATCHED_RESPONSE) { for (i = agent->discovery_list; i; i = i->next) { CandidateDiscovery *d = i->data; if (d->stream == stream && d->component == component && d->nicesock == nicesock) { valid = stun_agent_validate (&d->stun_agent, &req, (uint8_t *) buf, len, conncheck_stun_validater, &validater_data); if (valid == STUN_VALIDATION_UNMATCHED_RESPONSE) continue; discovery_msg = TRUE; break; } } } /* Check for relay refresh stun agents */ if (valid == STUN_VALIDATION_BAD_REQUEST || valid == STUN_VALIDATION_UNMATCHED_RESPONSE) { for (i = agent->refresh_list; i; i = i->next) { CandidateRefresh *r = i->data; nice_debug_verbose ("Comparing %p to %p, %p to %p and %p and %p to %p", r->stream, stream, r->component, component, r->nicesock, r->candidate->sockptr, nicesock); if (r->stream == stream && r->component == component && (r->nicesock == nicesock || r->candidate->sockptr == nicesock)) { valid = stun_agent_validate (&r->stun_agent, &req, (uint8_t *) buf, len, conncheck_stun_validater, &validater_data); nice_debug ("Validating gave %d", valid); if (valid == STUN_VALIDATION_UNMATCHED_RESPONSE) continue; discovery_msg = TRUE; break; } } } g_free (validater_data.password); if (valid == STUN_VALIDATION_NOT_STUN || valid == STUN_VALIDATION_INCOMPLETE_STUN || valid == STUN_VALIDATION_BAD_REQUEST) { nice_debug ("Agent %p : Incorrectly multiplexed STUN message ignored.", agent); return FALSE; } if (valid == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE) { nice_debug ("Agent %p : Unknown mandatory attributes in message.", agent); if (agent->compatibility != NICE_COMPATIBILITY_MSN && agent->compatibility != NICE_COMPATIBILITY_OC2007) { rbuf_len = stun_agent_build_unknown_attributes_error (&component->stun_agent, &msg, rbuf, rbuf_len, &req); if (rbuf_len != 0) agent_socket_send (nicesock, from, rbuf_len, (const gchar*)rbuf); } return TRUE; } if (valid == STUN_VALIDATION_UNAUTHORIZED) { nice_debug ("Agent %p : Integrity check failed.", agent); if (stun_agent_init_error (&component->stun_agent, &msg, rbuf, rbuf_len, &req, STUN_ERROR_UNAUTHORIZED)) { rbuf_len = stun_agent_finish_message (&component->stun_agent, &msg, NULL, 0); if (rbuf_len > 0 && agent->compatibility != NICE_COMPATIBILITY_MSN && agent->compatibility != NICE_COMPATIBILITY_OC2007) agent_socket_send (nicesock, from, rbuf_len, (const gchar*)rbuf); } return TRUE; } if (valid == STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST) { nice_debug ("Agent %p : Integrity check failed - bad request.", agent); if (stun_agent_init_error (&component->stun_agent, &msg, rbuf, rbuf_len, &req, STUN_ERROR_BAD_REQUEST)) { rbuf_len = stun_agent_finish_message (&component->stun_agent, &msg, NULL, 0); if (rbuf_len > 0 && agent->compatibility != NICE_COMPATIBILITY_MSN && agent->compatibility != NICE_COMPATIBILITY_OC2007) agent_socket_send (nicesock, from, rbuf_len, (const gchar*)rbuf); } return TRUE; } username = (uint8_t *) stun_message_find (&req, STUN_ATTRIBUTE_USERNAME, &username_len); for (i = component->remote_candidates; i; i = i->next) { NiceCandidate *cand = i->data; if (nice_address_equal (from, &cand->addr)) { remote_candidate = cand; break; } } for (i = component->local_candidates; i; i = i->next) { NiceCandidate *cand = i->data; if (nice_address_equal (&nicesock->addr, &cand->addr)) { local_candidate = cand; break; } } if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE || agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { /* We need to find which local candidate was used */ for (i = component->remote_candidates; i != NULL && remote_candidate2 == NULL; i = i->next) { for (j = component->local_candidates; j; j = j->next) { gboolean inbound = TRUE; NiceCandidate *rcand = i->data; NiceCandidate *lcand = j->data; /* If we receive a response, then the username is local:remote */ if (agent->compatibility != NICE_COMPATIBILITY_MSN) { if (stun_message_get_class (&req) == STUN_REQUEST || stun_message_get_class (&req) == STUN_INDICATION) { inbound = TRUE; } else { inbound = FALSE; } } uname_len = priv_create_username (agent, stream, component->id, rcand, lcand, uname, sizeof (uname), inbound); stun_debug ("Comparing usernames of size %d and %d: %d", username_len, uname_len, username && uname_len == username_len && memcmp (username, uname, uname_len) == 0); stun_debug_bytes (" First username: ", username, username ? username_len : 0); stun_debug_bytes (" Second uname: ", uname, uname_len); if (username && uname_len == username_len && memcmp (uname, username, username_len) == 0) { local_candidate = lcand; remote_candidate2 = rcand; break; } } } } if (component->remote_candidates && agent->compatibility == NICE_COMPATIBILITY_GOOGLE && local_candidate == NULL && discovery_msg == FALSE) { /* if we couldn't match the username and the stun agent has IGNORE_CREDENTIALS then we have an integrity check failing. This could happen with the race condition of receiving connchecks before the remote candidates are added. Just drop the message, and let the retransmissions make it work. */ nice_debug ("Agent %p : Username check failed.", agent); return TRUE; } if (valid != STUN_VALIDATION_SUCCESS) { nice_debug ("Agent %p : STUN message is unsuccessfull %d, ignoring", agent, valid); return FALSE; } if (stun_message_get_class (&req) == STUN_REQUEST) { if ( agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { if (local_candidate && remote_candidate2) { gsize key_len; if (agent->compatibility == NICE_COMPATIBILITY_MSN) { username = (uint8_t *) stun_message_find (&req, STUN_ATTRIBUTE_USERNAME, &username_len); uname_len = priv_create_username (agent, stream, component->id, remote_candidate2, local_candidate, uname, sizeof (uname), FALSE); memcpy (username, uname, MIN (uname_len, username_len)); req.key = g_base64_decode ((gchar *) remote_candidate2->password, &key_len); req.key_len = key_len; } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007) { req.key = g_base64_decode ((gchar *) local_candidate->password, &key_len); req.key_len = key_len; } } else { nice_debug ("Agent %p : received MSN incoming check from unknown remote candidate. " "Ignoring request", agent); return TRUE; } } rbuf_len = sizeof (rbuf); res = stun_usage_ice_conncheck_create_reply (&component->stun_agent, &req, &msg, rbuf, &rbuf_len, &sockaddr.storage, sizeof (sockaddr), &control, agent->tie_breaker, agent_to_ice_compatibility (agent)); if ( agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { g_free (req.key); } if (res == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT) priv_check_for_role_conflict (agent, control); if (res == STUN_USAGE_ICE_RETURN_SUCCESS || res == STUN_USAGE_ICE_RETURN_ROLE_CONFLICT) { /* case 1: valid incoming request, send a reply/error */ bool use_candidate = stun_usage_ice_conncheck_use_candidate (&req); uint32_t priority = stun_usage_ice_conncheck_priority (&req); if (agent->controlling_mode || agent->compatibility == NICE_COMPATIBILITY_GOOGLE || agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) use_candidate = TRUE; if (stream->initial_binding_request_received != TRUE) agent_signal_initial_binding_request_received (agent, stream); if (component->remote_candidates && remote_candidate == NULL) { nice_debug ("Agent %p : No matching remote candidate for incoming check ->" "peer-reflexive candidate.", agent); remote_candidate = discovery_learn_remote_peer_reflexive_candidate ( agent, stream, component, priority, from, nicesock, local_candidate, remote_candidate2 ? remote_candidate2 : remote_candidate); if(remote_candidate) { if (local_candidate && local_candidate->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) { CandidateCheckPair *pair; pair = priv_conn_check_add_for_candidate_pair_matched (agent, stream->id, component, local_candidate, remote_candidate, NICE_CHECK_DISCOVERED); if (pair) { pair->valid = TRUE; } } else conn_check_add_for_candidate (agent, stream->id, component, remote_candidate); } } priv_reply_to_conn_check (agent, stream, component, local_candidate, remote_candidate, from, nicesock, rbuf_len, &msg, use_candidate); if (component->remote_candidates == NULL) { /* case: We've got a valid binding request to a local candidate * but we do not yet know remote credentials nor * candidates. As per sect 7.2 of ICE (ID-19), we send a reply * immediately but postpone all other processing until * we get information about the remote candidates */ /* step: send a reply immediately but postpone other processing */ priv_store_pending_check (agent, component, from, nicesock, username, username_len, priority, use_candidate); } } else { nice_debug ("Agent %p : Invalid STUN packet, ignoring... %s", agent, strerror(errno)); return FALSE; } } else { /* case 2: not a new request, might be a reply... */ gboolean trans_found = FALSE; /* note: ICE sect 7.1.2. "Processing the Response" (ID-19) */ /* step: let's try to match the response to an existing check context */ if (trans_found != TRUE) trans_found = priv_map_reply_to_conn_check_request (agent, stream, component, nicesock, from, local_candidate, remote_candidate, &req); /* step: let's try to match the response to an existing discovery */ if (trans_found != TRUE) trans_found = priv_map_reply_to_discovery_request (agent, &req); /* step: let's try to match the response to an existing turn allocate */ if (trans_found != TRUE) trans_found = priv_map_reply_to_relay_request (agent, &req); /* step: let's try to match the response to an existing turn refresh */ if (trans_found != TRUE) trans_found = priv_map_reply_to_relay_refresh (agent, &req); /* step: let's try to match the response to an existing keepalive conncheck */ if (trans_found != TRUE) trans_found = priv_map_reply_to_keepalive_conncheck (agent, component, &req); if (trans_found != TRUE) nice_debug ("Agent %p : Unable to match to an existing transaction, " "probably a keepalive.", agent); } return TRUE; } /* Remove all pointers to the given @sock from the connection checking process. * These are entirely NiceCandidates pointed to from various places. */ void conn_check_prune_socket (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *sock) { GSList *l; if (component->selected_pair.local && component->selected_pair.local->sockptr == sock && component->state == NICE_COMPONENT_STATE_READY) { nice_debug ("Agent %p: Selected pair socket %p has been destroyed, " "declaring failed", agent, sock); agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_FAILED); } /* Prune from the candidate check pairs. */ for (l = stream->conncheck_list; l != NULL;) { CandidateCheckPair *p = l->data; GSList *next = l->next; if ((p->local != NULL && p->local->sockptr == sock) || (p->remote != NULL && p->remote->sockptr == sock) || (p->sockptr == sock)) { nice_debug ("Agent %p : Retransmissions failed, giving up on " "connectivity check %p", agent, p); candidate_check_pair_fail (stream, agent, p); conn_check_free_item (p); stream->conncheck_list = g_slist_delete_link (stream->conncheck_list, l); } l = next; } } libnice-0.1.14/agent/discovery.c0000664000076400007640000011234712732323553013423 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * @file discovery.c * @brief ICE candidate discovery functions */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "debug.h" #include "agent.h" #include "agent-priv.h" #include "component.h" #include "discovery.h" #include "stun/usages/bind.h" #include "stun/usages/turn.h" #include "socket.h" static inline int priv_timer_expired (GTimeVal *timer, GTimeVal *now) { return (now->tv_sec == timer->tv_sec) ? now->tv_usec >= timer->tv_usec : now->tv_sec >= timer->tv_sec; } /* * Frees the CandidateDiscovery structure pointed to * by 'user data'. Compatible with g_slist_free_full(). */ static void discovery_free_item (CandidateDiscovery *cand) { if (cand->turn) turn_server_unref (cand->turn); g_slice_free (CandidateDiscovery, cand); } /* * Frees all discovery related resources for the agent. */ void discovery_free (NiceAgent *agent) { g_slist_free_full (agent->discovery_list, (GDestroyNotify) discovery_free_item); agent->discovery_list = NULL; agent->discovery_unsched_items = 0; if (agent->discovery_timer_source != NULL) { g_source_destroy (agent->discovery_timer_source); g_source_unref (agent->discovery_timer_source); agent->discovery_timer_source = NULL; } } /* * Prunes the list of discovery processes for items related * to stream 'stream_id'. * * @return TRUE on success, FALSE on a fatal error */ void discovery_prune_stream (NiceAgent *agent, guint stream_id) { GSList *i; for (i = agent->discovery_list; i ; ) { CandidateDiscovery *cand = i->data; GSList *next = i->next; if (cand->stream->id == stream_id) { agent->discovery_list = g_slist_remove (agent->discovery_list, cand); discovery_free_item (cand); } i = next; } if (agent->discovery_list == NULL) { /* noone using the timer anymore, clean it up */ discovery_free (agent); } } /* * Prunes the list of discovery processes for items related * to socket @sock. * * @return TRUE on success, FALSE on a fatal error */ void discovery_prune_socket (NiceAgent *agent, NiceSocket *sock) { GSList *i; for (i = agent->discovery_list; i ; ) { CandidateDiscovery *discovery = i->data; GSList *next = i->next; if (discovery->nicesock == sock) { agent->discovery_list = g_slist_remove (agent->discovery_list, discovery); discovery_free_item (discovery); } i = next; } if (agent->discovery_list == NULL) { /* noone using the timer anymore, clean it up */ discovery_free (agent); } } /* * Frees the CandidateDiscovery structure pointed to * by 'user data'. Compatible with g_slist_free_full(). */ static void refresh_free_item (CandidateRefresh *cand) { NiceAgent *agent = cand->agent; uint8_t *username; gsize username_len; uint8_t *password; gsize password_len; size_t buffer_len = 0; StunUsageTurnCompatibility turn_compat = agent_to_turn_compatibility (agent); if (cand->timer_source != NULL) { g_source_destroy (cand->timer_source); g_source_unref (cand->timer_source); cand->timer_source = NULL; } if (cand->tick_source != NULL) { g_source_destroy (cand->tick_source); g_source_unref (cand->tick_source); cand->tick_source = NULL; } username = (uint8_t *)cand->candidate->turn->username; username_len = (size_t) strlen (cand->candidate->turn->username); password = (uint8_t *)cand->candidate->turn->password; password_len = (size_t) strlen (cand->candidate->turn->password); if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { username = g_base64_decode ((gchar *)username, &username_len); password = g_base64_decode ((gchar *)password, &password_len); } buffer_len = stun_usage_turn_create_refresh (&cand->stun_agent, &cand->stun_message, cand->stun_buffer, sizeof(cand->stun_buffer), cand->stun_resp_msg.buffer == NULL ? NULL : &cand->stun_resp_msg, 0, username, username_len, password, password_len, agent_to_turn_compatibility (agent)); if (buffer_len > 0) { StunTransactionId id; /* forget the transaction since we don't care about the result and * we don't implement retransmissions/timeout */ stun_message_id (&cand->stun_message, id); stun_agent_forget_transaction (&cand->stun_agent, id); /* send the refresh twice since we won't do retransmissions */ agent_socket_send (cand->nicesock, &cand->server, buffer_len, (gchar *)cand->stun_buffer); if (!nice_socket_is_reliable (cand->nicesock)) { agent_socket_send (cand->nicesock, &cand->server, buffer_len, (gchar *)cand->stun_buffer); } } if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { g_free (username); g_free (password); } g_slice_free (CandidateRefresh, cand); } /* * Frees all discovery related resources for the agent. */ void refresh_free (NiceAgent *agent) { g_slist_free_full (agent->refresh_list, (GDestroyNotify) refresh_free_item); agent->refresh_list = NULL; } /* * Prunes the list of discovery processes for items related * to stream 'stream_id'. * * @return TRUE on success, FALSE on a fatal error */ void refresh_prune_stream (NiceAgent *agent, guint stream_id) { GSList *i; for (i = agent->refresh_list; i ;) { CandidateRefresh *cand = i->data; GSList *next = i->next; /* Don't free the candidate refresh to the currently selected local candidate * unless the whole pair is being destroyed. */ if (cand->stream->id == stream_id) { agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); refresh_free_item (cand); } i = next; } } void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate) { GSList *i; for (i = agent->refresh_list; i;) { GSList *next = i->next; CandidateRefresh *refresh = i->data; if (refresh->candidate == candidate) { agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); refresh_free_item (refresh); } i = next; } } void refresh_prune_socket (NiceAgent *agent, NiceSocket *sock) { GSList *i; for (i = agent->refresh_list; i;) { GSList *next = i->next; CandidateRefresh *refresh = i->data; if (refresh->nicesock == sock) { agent->refresh_list = g_slist_delete_link (agent->refresh_list, i); refresh_free_item (refresh); } i = next; } } void refresh_cancel (CandidateRefresh *refresh) { refresh->agent->refresh_list = g_slist_remove (refresh->agent->refresh_list, refresh); refresh_free_item (refresh); } /* * Adds a new local candidate. Implements the candidate pruning * defined in ICE spec section 4.1.3 "Eliminating Redundant * Candidates" (ID-19). */ static gboolean priv_add_local_candidate_pruned (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *candidate) { GSList *i; g_assert (candidate != NULL); for (i = component->local_candidates; i ; i = i->next) { NiceCandidate *c = i->data; if (nice_address_equal (&c->base_addr, &candidate->base_addr) && nice_address_equal (&c->addr, &candidate->addr) && c->transport == candidate->transport) { nice_debug ("Candidate %p (component-id %u) redundant, ignoring.", candidate, component->id); return FALSE; } } component->local_candidates = g_slist_append (component->local_candidates, candidate); conn_check_add_for_local_candidate(agent, stream_id, component, candidate); return TRUE; } static guint priv_highest_remote_foundation (NiceComponent *component) { GSList *i; guint highest = 1; gchar foundation[NICE_CANDIDATE_MAX_FOUNDATION]; for (highest = 1;; highest++) { gboolean taken = FALSE; g_snprintf (foundation, NICE_CANDIDATE_MAX_FOUNDATION, "remote-%u", highest); for (i = component->remote_candidates; i; i = i->next) { NiceCandidate *cand = i->data; if (strncmp (foundation, cand->foundation, NICE_CANDIDATE_MAX_FOUNDATION) == 0) { taken = TRUE; break; } } if (!taken) return highest; } g_return_val_if_reached (highest); } /* From RFC 5245 section 4.1.3: * * for reflexive and relayed candidates, the STUN or TURN servers * used to obtain them have the same IP address. */ static gboolean priv_compare_turn_servers (TurnServer *turn1, TurnServer *turn2) { if (turn1 == turn2) return TRUE; if (turn1 == NULL || turn2 == NULL) return FALSE; return nice_address_equal_no_port (&turn1->server, &turn2->server); } /* * Assings a foundation to the candidate. * * Implements the mechanism described in ICE sect * 4.1.1.3 "Computing Foundations" (ID-19). */ static void priv_assign_foundation (NiceAgent *agent, NiceCandidate *candidate) { GSList *i, *j, *k; for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; for (j = stream->components; j; j = j->next) { NiceComponent *component = j->data; for (k = component->local_candidates; k; k = k->next) { NiceCandidate *n = k->data; /* note: candidate must not on the local candidate list */ g_assert (candidate != n); if (candidate->type == n->type && candidate->transport == n->transport && nice_address_equal_no_port (&candidate->base_addr, &n->base_addr) && (candidate->type != NICE_CANDIDATE_TYPE_RELAYED || priv_compare_turn_servers (candidate->turn, n->turn)) && !(agent->compatibility == NICE_COMPATIBILITY_GOOGLE && n->type == NICE_CANDIDATE_TYPE_RELAYED)) { /* note: currently only one STUN server per stream at a * time is supported, so there is no need to check * for candidates that would otherwise share the * foundation, but have different STUN servers */ g_strlcpy (candidate->foundation, n->foundation, NICE_CANDIDATE_MAX_FOUNDATION); if (n->username) { g_free (candidate->username); candidate->username = g_strdup (n->username); } if (n->password) { g_free (candidate->password); candidate->password = g_strdup (n->password); } return; } } } } g_snprintf (candidate->foundation, NICE_CANDIDATE_MAX_FOUNDATION, "%u", agent->next_candidate_id++); } static void priv_assign_remote_foundation (NiceAgent *agent, NiceCandidate *candidate) { GSList *i, *j, *k; guint next_remote_id; NiceComponent *component = NULL; for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; for (j = stream->components; j; j = j->next) { NiceComponent *c = j->data; if (c->id == candidate->component_id) component = c; for (k = c->remote_candidates; k; k = k->next) { NiceCandidate *n = k->data; /* note: candidate must not on the remote candidate list */ g_assert (candidate != n); if (candidate->type == n->type && candidate->transport == n->transport && candidate->stream_id == n->stream_id && nice_address_equal_no_port (&candidate->addr, &n->addr)) { /* note: No need to check for STUN/TURN servers, as these candidate * will always be peer reflexive, never relayed or serve reflexive. */ g_strlcpy (candidate->foundation, n->foundation, NICE_CANDIDATE_MAX_FOUNDATION); if (n->username) { g_free (candidate->username); candidate->username = g_strdup (n->username); } if (n->password) { g_free (candidate->password); candidate->password = g_strdup (n->password); } return; } } } } if (component) { next_remote_id = priv_highest_remote_foundation (component); g_snprintf (candidate->foundation, NICE_CANDIDATE_MAX_FOUNDATION, "remote-%u", next_remote_id); } } static void priv_generate_candidate_credentials (NiceAgent *agent, NiceCandidate *candidate) { if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { guchar username[32]; guchar password[16]; g_free (candidate->username); g_free (candidate->password); nice_rng_generate_bytes (agent->rng, 32, (gchar *)username); nice_rng_generate_bytes (agent->rng, 16, (gchar *)password); candidate->username = g_base64_encode (username, 32); candidate->password = g_base64_encode (password, 16); } else if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { gchar username[16]; g_free (candidate->username); g_free (candidate->password); candidate->password = NULL; nice_rng_generate_bytes_print (agent->rng, 16, (gchar *)username); candidate->username = g_strndup (username, 16); } } /* * Creates a local host candidate for 'component_id' of stream * 'stream_id'. * * @return pointer to the created candidate, or NULL on error */ HostCandidateResult discovery_add_local_host_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceCandidateTransport transport, NiceCandidate **outcandidate) { NiceCandidate *candidate; NiceComponent *component; NiceStream *stream; NiceSocket *nicesock = NULL; HostCandidateResult res = HOST_CANDIDATE_FAILED; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return res; candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_HOST); candidate->transport = transport; candidate->stream_id = stream_id; candidate->component_id = component_id; candidate->addr = *address; candidate->base_addr = *address; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { candidate->priority = nice_candidate_jingle_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { candidate->priority = nice_candidate_ms_ice_priority (candidate, agent->reliable, FALSE); } else { candidate->priority = nice_candidate_ice_priority (candidate, agent->reliable, FALSE); } candidate->priority = ensure_unique_priority (component, candidate->priority); priv_generate_candidate_credentials (agent, candidate); priv_assign_foundation (agent, candidate); /* note: candidate username and password are left NULL as stream level ufrag/password are used */ if (transport == NICE_CANDIDATE_TRANSPORT_UDP) { nicesock = nice_udp_bsd_socket_new (address); } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) { nicesock = nice_tcp_active_socket_new (agent->main_context, address); } else if (transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) { nicesock = nice_tcp_passive_socket_new (agent->main_context, address); } else { /* TODO: Add TCP-SO */ } if (!nicesock) { res = HOST_CANDIDATE_CANT_CREATE_SOCKET; goto errors; } candidate->sockptr = nicesock; candidate->addr = nicesock->addr; candidate->base_addr = nicesock->addr; if (!priv_add_local_candidate_pruned (agent, stream_id, component, candidate)) { res = HOST_CANDIDATE_REDUNDANT; goto errors; } _priv_set_socket_tos (agent, nicesock, stream->tos); nice_component_attach_socket (component, nicesock); *outcandidate = candidate; return HOST_CANDIDATE_SUCCESS; errors: nice_candidate_free (candidate); if (nicesock) nice_socket_free (nicesock); return res; } /* * Creates a server reflexive candidate for 'component_id' of stream * 'stream_id'. * * @return pointer to the created candidate, or NULL on error */ NiceCandidate* discovery_add_server_reflexive_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceCandidateTransport transport, NiceSocket *base_socket, gboolean nat_assisted) { NiceCandidate *candidate; NiceComponent *component; NiceStream *stream; gboolean result = FALSE; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return NULL; candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE); candidate->transport = transport; candidate->stream_id = stream_id; candidate->component_id = component_id; candidate->addr = *address; /* step: link to the base candidate+socket */ candidate->sockptr = base_socket; candidate->base_addr = base_socket->addr; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { candidate->priority = nice_candidate_jingle_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { candidate->priority = nice_candidate_ms_ice_priority (candidate, agent->reliable, nat_assisted); } else { candidate->priority = nice_candidate_ice_priority (candidate, agent->reliable, nat_assisted); } candidate->priority = ensure_unique_priority (component, candidate->priority); priv_generate_candidate_credentials (agent, candidate); priv_assign_foundation (agent, candidate); result = priv_add_local_candidate_pruned (agent, stream_id, component, candidate); if (result) { agent_signal_new_candidate (agent, candidate); } else { /* error: duplicate candidate */ nice_candidate_free (candidate), candidate = NULL; } return candidate; } /* * Creates a server reflexive candidate for 'component_id' of stream * 'stream_id' for each TCP_PASSIVE and TCP_ACTIVE candidates for each * base address. * * @return pointer to the created candidate, or NULL on error */ void discovery_discover_tcp_server_reflexive_candidates ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceSocket *base_socket) { NiceComponent *component; NiceStream *stream; NiceAddress base_addr = base_socket->addr; GSList *i; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return; nice_address_set_port (&base_addr, 0); for (i = component->local_candidates; i; i = i ->next) { NiceCandidate *c = i->data; NiceAddress caddr; caddr = c->addr; nice_address_set_port (&caddr, 0); if (c->transport != NICE_CANDIDATE_TRANSPORT_UDP && c->type == NICE_CANDIDATE_TYPE_HOST && nice_address_equal (&base_addr, &caddr)) { nice_address_set_port (address, nice_address_get_port (&c->addr)); discovery_add_server_reflexive_candidate ( agent, stream_id, component_id, address, c->transport, c->sockptr, FALSE); } } } /* * Creates a server reflexive candidate for 'component_id' of stream * 'stream_id'. * * @return pointer to the created candidate, or NULL on error */ NiceCandidate* discovery_add_relay_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceCandidateTransport transport, NiceSocket *base_socket, TurnServer *turn) { NiceCandidate *candidate; NiceComponent *component; NiceStream *stream; NiceSocket *relay_socket = NULL; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return NULL; candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_RELAYED); candidate->transport = transport; candidate->stream_id = stream_id; candidate->component_id = component_id; candidate->addr = *address; candidate->turn = turn_server_ref (turn); /* step: link to the base candidate+socket */ relay_socket = nice_udp_turn_socket_new (agent->main_context, address, base_socket, &turn->server, turn->username, turn->password, agent_to_turn_socket_compatibility (agent)); if (!relay_socket) goto errors; candidate->sockptr = relay_socket; candidate->base_addr = base_socket->addr; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { candidate->priority = nice_candidate_jingle_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { candidate->priority = nice_candidate_ms_ice_priority (candidate, agent->reliable, FALSE); } else { candidate->priority = nice_candidate_ice_priority (candidate, agent->reliable, FALSE); } candidate->priority = ensure_unique_priority (component, candidate->priority); priv_generate_candidate_credentials (agent, candidate); /* Google uses the turn username as the candidate username */ if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { g_free (candidate->username); candidate->username = g_strdup (turn->username); } priv_assign_foundation (agent, candidate); if (!priv_add_local_candidate_pruned (agent, stream_id, component, candidate)) goto errors; nice_component_attach_socket (component, relay_socket); agent_signal_new_candidate (agent, candidate); return candidate; errors: nice_candidate_free (candidate); if (relay_socket) nice_socket_free (relay_socket); return NULL; } /* * Creates a peer reflexive candidate for 'component_id' of stream * 'stream_id'. * * @return pointer to the created candidate, or NULL on error */ NiceCandidate* discovery_add_peer_reflexive_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceSocket *base_socket, NiceCandidate *local, NiceCandidate *remote) { NiceCandidate *candidate; NiceComponent *component; NiceStream *stream; gboolean result; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return NULL; candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_PEER_REFLEXIVE); if (local) candidate->transport = local->transport; else if (remote) candidate->transport = conn_check_match_transport (remote->transport); else { if (base_socket->type == NICE_SOCKET_TYPE_UDP_BSD || base_socket->type == NICE_SOCKET_TYPE_UDP_TURN) candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; else candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; } candidate->stream_id = stream_id; candidate->component_id = component_id; candidate->addr = *address; candidate->sockptr = base_socket; candidate->base_addr = base_socket->addr; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { candidate->priority = nice_candidate_jingle_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { candidate->priority = nice_candidate_ms_ice_priority (candidate, agent->reliable, FALSE); } else { candidate->priority = nice_candidate_ice_priority (candidate, agent->reliable, FALSE); } candidate->priority = ensure_unique_priority (component, candidate->priority); priv_assign_foundation (agent, candidate); if ((agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) && remote && local) { guchar *new_username = NULL; guchar *decoded_local = NULL; guchar *decoded_remote = NULL; gsize local_size; gsize remote_size; g_free(candidate->username); g_free(candidate->password); decoded_local = g_base64_decode (local->username, &local_size); decoded_remote = g_base64_decode (remote->username, &remote_size); new_username = g_new0(guchar, local_size + remote_size); memcpy(new_username, decoded_local, local_size); memcpy(new_username + local_size, decoded_remote, remote_size); candidate->username = g_base64_encode (new_username, local_size + remote_size); g_free(new_username); g_free(decoded_local); g_free(decoded_remote); candidate->password = g_strdup(local->password); } else if (local) { g_free(candidate->username); g_free(candidate->password); candidate->username = g_strdup(local->username); candidate->password = g_strdup(local->password); } result = priv_add_local_candidate_pruned (agent, stream_id, component, candidate); if (result != TRUE) { /* error: memory allocation, or duplicate candidate */ nice_candidate_free (candidate), candidate = NULL; } return candidate; } /* * Adds a new peer reflexive candidate to the list of known * remote candidates. The candidate is however not paired with * existing local candidates. * * See ICE sect 7.2.1.3 "Learning Peer Reflexive Candidates" (ID-19). * * @return pointer to the created candidate, or NULL on error */ NiceCandidate *discovery_learn_remote_peer_reflexive_candidate ( NiceAgent *agent, NiceStream *stream, NiceComponent *component, guint32 priority, const NiceAddress *remote_address, NiceSocket *nicesock, NiceCandidate *local, NiceCandidate *remote) { NiceCandidate *candidate; candidate = nice_candidate_new (NICE_CANDIDATE_TYPE_PEER_REFLEXIVE); candidate->addr = *remote_address; candidate->base_addr = *remote_address; if (remote) candidate->transport = remote->transport; else if (local) candidate->transport = conn_check_match_transport (local->transport); else { if (nicesock->type == NICE_SOCKET_TYPE_UDP_BSD || nicesock->type == NICE_SOCKET_TYPE_UDP_TURN) candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP; else candidate->transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; } candidate->sockptr = nicesock; candidate->stream_id = stream->id; candidate->component_id = component->id; /* if the check didn't contain the PRIORITY attribute, then the priority will * be 0, which is invalid... */ if (priority != 0) { candidate->priority = priority; } else if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { candidate->priority = nice_candidate_jingle_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) { candidate->priority = nice_candidate_msn_priority (candidate); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { candidate->priority = nice_candidate_ms_ice_priority (candidate, agent->reliable, FALSE); } else { candidate->priority = nice_candidate_ice_priority (candidate, agent->reliable, FALSE); } priv_assign_remote_foundation (agent, candidate); if ((agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_OC2007) && remote && local) { guchar *new_username = NULL; guchar *decoded_local = NULL; guchar *decoded_remote = NULL; gsize local_size; gsize remote_size; g_free(candidate->username); g_free (candidate->password); decoded_local = g_base64_decode (local->username, &local_size); decoded_remote = g_base64_decode (remote->username, &remote_size); new_username = g_new0(guchar, local_size + remote_size); memcpy(new_username, decoded_remote, remote_size); memcpy(new_username + remote_size, decoded_local, local_size); candidate->username = g_base64_encode (new_username, local_size + remote_size); g_free(new_username); g_free(decoded_local); g_free(decoded_remote); candidate->password = g_strdup(remote->password); } else if (remote) { g_free (candidate->username); g_free (candidate->password); candidate->username = g_strdup(remote->username); candidate->password = g_strdup(remote->password); } /* note: candidate username and password are left NULL as stream level ufrag/password are used */ component->remote_candidates = g_slist_append (component->remote_candidates, candidate); agent_signal_new_remote_candidate (agent, candidate); return candidate; } /* * Timer callback that handles scheduling new candidate discovery * processes (paced by the Ta timer), and handles running of the * existing discovery processes. * * This function is designed for the g_timeout_add() interface. * * @return will return FALSE when no more pending timers. */ static gboolean priv_discovery_tick_unlocked (gpointer pointer) { CandidateDiscovery *cand; NiceAgent *agent = pointer; GSList *i; int not_done = 0; /* note: track whether to continue timer */ size_t buffer_len = 0; { static int tick_counter = 0; if (tick_counter++ % 50 == 0) nice_debug ("Agent %p : discovery tick #%d with list %p (1)", agent, tick_counter, agent->discovery_list); } for (i = agent->discovery_list; i ; i = i->next) { cand = i->data; if (cand->pending != TRUE) { cand->pending = TRUE; if (agent->discovery_unsched_items) --agent->discovery_unsched_items; if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (&cand->server, tmpbuf); nice_debug ("Agent %p : discovery - scheduling cand type %u addr %s.", agent, cand->type, tmpbuf); } if (nice_address_is_valid (&cand->server) && (cand->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || cand->type == NICE_CANDIDATE_TYPE_RELAYED)) { if (cand->component->state == NICE_COMPONENT_STATE_DISCONNECTED || cand->component->state == NICE_COMPONENT_STATE_FAILED) agent_signal_component_state_change (agent, cand->stream->id, cand->component->id, NICE_COMPONENT_STATE_GATHERING); if (cand->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE) { buffer_len = stun_usage_bind_create (&cand->stun_agent, &cand->stun_message, cand->stun_buffer, sizeof(cand->stun_buffer)); } else if (cand->type == NICE_CANDIDATE_TYPE_RELAYED) { uint8_t *username = (uint8_t *)cand->turn->username; gsize username_len = strlen (cand->turn->username); uint8_t *password = (uint8_t *)cand->turn->password; gsize password_len = strlen (cand->turn->password); StunUsageTurnCompatibility turn_compat = agent_to_turn_compatibility (agent); if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { username = g_base64_decode ((gchar *)username, &username_len); password = g_base64_decode ((gchar *)password, &password_len); } buffer_len = stun_usage_turn_create (&cand->stun_agent, &cand->stun_message, cand->stun_buffer, sizeof(cand->stun_buffer), cand->stun_resp_msg.buffer == NULL ? NULL : &cand->stun_resp_msg, STUN_USAGE_TURN_REQUEST_PORT_NORMAL, -1, -1, username, username_len, password, password_len, turn_compat); if (turn_compat == STUN_USAGE_TURN_COMPATIBILITY_MSN || turn_compat == STUN_USAGE_TURN_COMPATIBILITY_OC2007) { g_free (username); g_free (password); } } if (buffer_len > 0) { if (nice_socket_is_reliable (cand->nicesock)) { stun_timer_start_reliable (&cand->timer, STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT); } else { stun_timer_start (&cand->timer, 200, STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS); } /* send the conncheck */ agent_socket_send (cand->nicesock, &cand->server, buffer_len, (gchar *)cand->stun_buffer); /* case: success, start waiting for the result */ g_get_current_time (&cand->next_tick); } else { /* case: error in starting discovery, start the next discovery */ cand->done = TRUE; cand->stun_message.buffer = NULL; cand->stun_message.buffer_len = 0; continue; } } else /* allocate relayed candidates */ g_assert_not_reached (); ++not_done; /* note: new discovery scheduled */ } if (cand->done != TRUE) { GTimeVal now; g_get_current_time (&now); if (cand->stun_message.buffer == NULL) { nice_debug ("Agent %p : STUN discovery was cancelled, marking discovery done.", agent); cand->done = TRUE; } else if (priv_timer_expired (&cand->next_tick, &now)) { switch (stun_timer_refresh (&cand->timer)) { case STUN_USAGE_TIMER_RETURN_TIMEOUT: { /* Time out */ /* case: error, abort processing */ StunTransactionId id; stun_message_id (&cand->stun_message, id); stun_agent_forget_transaction (&cand->stun_agent, id); cand->done = TRUE; cand->stun_message.buffer = NULL; cand->stun_message.buffer_len = 0; nice_debug ("Agent %p : bind discovery timed out, aborting discovery item.", agent); break; } case STUN_USAGE_TIMER_RETURN_RETRANSMIT: { /* case: not ready complete, so schedule next timeout */ unsigned int timeout = stun_timer_remainder (&cand->timer); stun_debug ("STUN transaction retransmitted (timeout %dms).", timeout); /* retransmit */ agent_socket_send (cand->nicesock, &cand->server, stun_message_length (&cand->stun_message), (gchar *)cand->stun_buffer); /* note: convert from milli to microseconds for g_time_val_add() */ cand->next_tick = now; g_time_val_add (&cand->next_tick, timeout * 1000); ++not_done; /* note: retry later */ break; } case STUN_USAGE_TIMER_RETURN_SUCCESS: { unsigned int timeout = stun_timer_remainder (&cand->timer); cand->next_tick = now; g_time_val_add (&cand->next_tick, timeout * 1000); ++not_done; /* note: retry later */ break; } default: /* Nothing to do. */ break; } } else { ++not_done; /* note: discovery not expired yet */ } } } if (not_done == 0) { nice_debug ("Agent %p : Candidate gathering FINISHED, stopping discovery timer.", agent); discovery_free (agent); agent_gathering_done (agent); /* note: no pending timers, return FALSE to stop timer */ return FALSE; } return TRUE; } static gboolean priv_discovery_tick (gpointer pointer) { NiceAgent *agent = pointer; gboolean ret; agent_lock(); if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in priv_discovery_tick"); agent_unlock (); return FALSE; } ret = priv_discovery_tick_unlocked (pointer); if (ret == FALSE) { if (agent->discovery_timer_source != NULL) { g_source_destroy (agent->discovery_timer_source); g_source_unref (agent->discovery_timer_source); agent->discovery_timer_source = NULL; } } agent_unlock_and_emit (agent); return ret; } /* * Initiates the candidate discovery process by starting * the necessary timers. * * @pre agent->discovery_list != NULL // unsched discovery items available */ void discovery_schedule (NiceAgent *agent) { g_assert (agent->discovery_list != NULL); if (agent->discovery_unsched_items > 0) { if (agent->discovery_timer_source == NULL) { /* step: run first iteration immediately */ gboolean res = priv_discovery_tick_unlocked (agent); if (res == TRUE) { agent_timeout_add_with_context (agent, &agent->discovery_timer_source, "Candidate discovery tick", agent->timer_ta, priv_discovery_tick, agent); } } } } libnice-0.1.14/agent/Makefile.in0000664000076400007640000006541213070512350013304 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @WINDOWS_TRUE@am__append_1 = -DWINVER=0x0501 # _WIN32_WINNT_WINXP @WINDOWS_TRUE@am__append_2 = -liphlpapi -lws2_32 @HAVE_INTROSPECTION_TRUE@am__append_3 = Nice-0.1.gir @HAVE_INTROSPECTION_TRUE@am__append_4 = $(gir_DATA) $(typelib_DATA) subdir = agent ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = am_libagent_la_OBJECTS = address.lo debug.lo candidate.lo component.lo \ agent.lo stream.lo conncheck.lo discovery.lo interfaces.lo \ pseudotcp.lo iostream.lo inputstream.lo outputstream.lo libagent_la_OBJECTS = $(am_libagent_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libagent_la_SOURCES) DIST_SOURCES = $(libagent_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(girdir)" "$(DESTDIR)$(typelibdir)" \ "$(DESTDIR)$(pkgincludedir)" DATA = $(gir_DATA) $(typelib_DATA) HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda $(am__append_4) AM_CFLAGS = -DG_LOG_DOMAIN=\"libnice\" $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) $(GUPNP_CFLAGS) -I $(top_srcdir) -I \ $(top_srcdir)/random -I $(top_srcdir)/socket -I \ $(top_srcdir)/stun $(am__append_1) noinst_LTLIBRARIES = libagent.la libagent_la_SOURCES = \ address.h \ address.c \ debug.h \ debug.c \ candidate.h \ candidate.c \ component.h \ component.c \ agent.h \ agent-priv.h \ agent.c \ stream.h \ stream.c \ conncheck.c \ conncheck.h \ discovery.c \ discovery.h \ interfaces.c \ interfaces.h \ pseudotcp.h \ pseudotcp.c \ iostream.h \ iostream.c \ inputstream.h \ inputstream.c \ outputstream.h \ outputstream.c \ $(BUILT_SOURCES) libagent_la_LIBADD = $(top_builddir)/random/libnice-random.la \ $(top_builddir)/socket/libsocket.la \ $(top_builddir)/stun/libstun.la $(GLIB_LIBS) $(GUPNP_LIBS) \ $(NULL) $(am__append_2) libagent_la_DEPENDENCIES = \ $(top_builddir)/random/libnice-random.la \ $(top_builddir)/socket/libsocket.la \ $(top_builddir)/stun/libstun.la pkginclude_HEADERS = \ agent.h \ candidate.h \ debug.h \ address.h \ interfaces.h \ pseudotcp.h \ $(NULL) INTROSPECTION_GIRS = $(am__append_3) INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --warn-all --accept-unprefixed INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) @HAVE_INTROSPECTION_TRUE@introspection_sources = $(pkginclude_HEADERS) @HAVE_INTROSPECTION_TRUE@Nice_0_1_gir_INCLUDES = GObject-2.0 Gio-2.0 @HAVE_INTROSPECTION_TRUE@Nice_0_1_gir_EXPORT_PACKAGES = nice @HAVE_INTROSPECTION_TRUE@Nice_0_1_gir_CFLAGS = $(AM_CFLAGS) @HAVE_INTROSPECTION_TRUE@Nice_0_1_gir_LIBS = libagent.la @HAVE_INTROSPECTION_TRUE@Nice_0_1_gir_FILES = $(introspection_sources) @HAVE_INTROSPECTION_TRUE@girdir = $(datadir)/gir-1.0 @HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS) @HAVE_INTROSPECTION_TRUE@typelibdir = $(libdir)/girepository-1.0 @HAVE_INTROSPECTION_TRUE@typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu agent/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu agent/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libagent.la: $(libagent_la_OBJECTS) $(libagent_la_DEPENDENCIES) $(EXTRA_libagent_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libagent_la_OBJECTS) $(libagent_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/candidate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/component.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conncheck.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/discovery.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inputstream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interfaces.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iostream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/outputstream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pseudotcp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-girDATA: $(gir_DATA) @$(NORMAL_INSTALL) @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(girdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(girdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(girdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(girdir)" || exit $$?; \ done uninstall-girDATA: @$(NORMAL_UNINSTALL) @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(girdir)'; $(am__uninstall_files_from_dir) install-typelibDATA: $(typelib_DATA) @$(NORMAL_INSTALL) @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(typelibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(typelibdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(typelibdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(typelibdir)" || exit $$?; \ done uninstall-typelibDATA: @$(NORMAL_UNINSTALL) @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(typelibdir)'; $(am__uninstall_files_from_dir) install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(girdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-girDATA install-pkgincludeHEADERS \ install-typelibDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-girDATA uninstall-pkgincludeHEADERS \ uninstall-typelibDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-girDATA install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgincludeHEADERS install-ps \ install-ps-am install-strip install-typelibDATA installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-girDATA \ uninstall-pkgincludeHEADERS uninstall-typelibDATA .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind # # GObject introspection # # We need --accept-unprefixed because of PseudoTcp and TurnServer. # -include $(INTROSPECTION_MAKEFILE) @HAVE_INTROSPECTION_TRUE@Nice-0.1.gir: libagent.la # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/agent/address.h0000664000076400007640000001625012520743534013042 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Dafydd Harries, Collabora Ltd. * Kai Vehmanen * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __LIBNICE_ADDRESS_H__ #define __LIBNICE_ADDRESS_H__ /** * SECTION:address * @short_description: IP address convenience library * @stability: Stable * * The #NiceAddress structure will allow you to easily set/get and modify an IPv4 * or IPv6 address in order to communicate with the #NiceAgent. */ #include #ifdef G_OS_WIN32 #include #include #else #include #include #include #include #endif G_BEGIN_DECLS /** * NiceAddress: * * The #NiceAddress structure that represents an IPv4 or IPv6 address. */ struct _NiceAddress { union { struct sockaddr addr; struct sockaddr_in ip4; struct sockaddr_in6 ip6; } s; }; /** * NICE_ADDRESS_STRING_LEN: * * The maximum string length representation of an address. * When using nice_address_to_string() make sure the string has a size of * at least %NICE_ADDRESS_STRING_LEN */ #define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN typedef struct _NiceAddress NiceAddress; /** * nice_address_init: * @addr: The #NiceAddress to init * * Initialize a #NiceAddress into an undefined address */ void nice_address_init (NiceAddress *addr); /** * nice_address_new: * * Create a new #NiceAddress with undefined address * You must free it with nice_address_free() * * Returns: The new #NiceAddress */ NiceAddress * nice_address_new (void); /** * nice_address_free: * @addr: The #NiceAddress to free * * Frees a #NiceAddress created with nice_address_new() or nice_address_dup() */ void nice_address_free (NiceAddress *addr); /** * nice_address_dup: * @addr: The #NiceAddress to dup * * Creates a new #NiceAddress with the same address as @addr * * Returns: The new #NiceAddress */ NiceAddress * nice_address_dup (const NiceAddress *addr); /** * nice_address_set_ipv4: * @addr: The #NiceAddress to modify * @addr_ipv4: The IPv4 address * * Set @addr to an IPv4 address using the data from @addr_ipv4 * This function will reset the port to 0, so make sure you call it before nice_address_set_port() */ void nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4); /** * nice_address_set_ipv6: * @addr: The #NiceAddress to modify * @addr_ipv6: The IPv6 address * * Set @addr to an IPv6 address using the data from @addr_ipv6 * This function will reset the port to 0, so make sure you call it before nice_address_set_port() */ void nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6); /** * nice_address_set_port: * @addr: The #NiceAddress to modify * @port: The port to set * * Set the port of @addr to @port */ void nice_address_set_port (NiceAddress *addr, guint port); /** * nice_address_get_port: * @addr: The #NiceAddress to query * * Retreive the port of @addr * * Returns: The port of @addr */ guint nice_address_get_port (const NiceAddress *addr); /** * nice_address_set_from_string: * @addr: The #NiceAddress to modify * @str: The string to set * * Sets an IPv4 or IPv6 address from the string @str * * Returns: %TRUE if success, %FALSE on error */ gboolean nice_address_set_from_string (NiceAddress *addr, const gchar *str); /** * nice_address_set_from_sockaddr: * @addr: The #NiceAddress to modify * @sin: The sockaddr to set * * Sets an IPv4 or IPv6 address from the sockaddr structure @sin * */ void nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin); /** * nice_address_copy_to_sockaddr: * @addr: The #NiceAddress to query * @sin: The sockaddr to fill * * Fills the sockaddr structure @sin with the address contained in @addr * */ void nice_address_copy_to_sockaddr (const NiceAddress *addr, struct sockaddr *sin); /** * nice_address_equal: * @a: First #NiceAddress to compare * @b: Second #NiceAddress to compare * * Compares two #NiceAddress structures to see if they contain the same address * and the same port. * * Returns: %TRUE if @a and @b are the same address, %FALSE if they are different */ gboolean nice_address_equal (const NiceAddress *a, const NiceAddress *b); /** * nice_address_equal_no_port: * @a: First #NiceAddress to compare * @b: Second #NiceAddress to compare * * Compares two #NiceAddress structures to see if they contain the same address, * ignoring the port. * * Returns: %TRUE if @a and @b are the same address, %FALSE if they * are different * * Since: 0.1.8 */ gboolean nice_address_equal_no_port (const NiceAddress *a, const NiceAddress *b); /** * nice_address_to_string: * @addr: The #NiceAddress to query * @dst: The string to fill * * Transforms the address @addr into a human readable string * */ void nice_address_to_string (const NiceAddress *addr, gchar *dst); /** * nice_address_is_private: * @addr: The #NiceAddress to query * * Verifies if the address in @addr is a private address or not * * Returns: %TRUE if @addr is a private address, %FALSE otherwise */ gboolean nice_address_is_private (const NiceAddress *addr); /** * nice_address_is_valid: * @addr: The #NiceAddress to query * * Validate whether the #NiceAddress @addr is a valid IPv4 or IPv6 address * * Returns: %TRUE if @addr is valid, %FALSE otherwise */ G_GNUC_WARN_UNUSED_RESULT gboolean nice_address_is_valid (const NiceAddress *addr); /** * nice_address_ip_version: * @addr: The #NiceAddress to query * * Returns the IP version of the address * * Returns: 4 for IPv4, 6 for IPv6 and 0 for undefined address */ G_GNUC_WARN_UNUSED_RESULT int nice_address_ip_version (const NiceAddress *addr); G_END_DECLS #endif /* __LIBNICE_ADDRESS_H__ */ libnice-0.1.14/agent/Makefile.am0000664000076400007640000000436212733070261013275 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include $(top_srcdir)/common.mk AM_CFLAGS = \ -DG_LOG_DOMAIN=\"libnice\" \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUPNP_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun if WINDOWS AM_CFLAGS += -DWINVER=0x0501 # _WIN32_WINNT_WINXP endif noinst_LTLIBRARIES = libagent.la libagent_la_SOURCES = \ address.h \ address.c \ debug.h \ debug.c \ candidate.h \ candidate.c \ component.h \ component.c \ agent.h \ agent-priv.h \ agent.c \ stream.h \ stream.c \ conncheck.c \ conncheck.h \ discovery.c \ discovery.h \ interfaces.c \ interfaces.h \ pseudotcp.h \ pseudotcp.c \ iostream.h \ iostream.c \ inputstream.h \ inputstream.c \ outputstream.h \ outputstream.c \ $(BUILT_SOURCES) libagent_la_LIBADD = \ $(top_builddir)/random/libnice-random.la \ $(top_builddir)/socket/libsocket.la \ $(top_builddir)/stun/libstun.la \ $(GLIB_LIBS) \ $(GUPNP_LIBS) \ $(NULL) libagent_la_DEPENDENCIES = \ $(top_builddir)/random/libnice-random.la \ $(top_builddir)/socket/libsocket.la \ $(top_builddir)/stun/libstun.la pkginclude_HEADERS = \ agent.h \ candidate.h \ debug.h \ address.h \ interfaces.h \ pseudotcp.h \ $(NULL) if WINDOWS libagent_la_LIBADD += -liphlpapi -lws2_32 endif # # GObject introspection # # We need --accept-unprefixed because of PseudoTcp and TurnServer. # -include $(INTROSPECTION_MAKEFILE) INTROSPECTION_GIRS = INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --warn-all --accept-unprefixed INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) if HAVE_INTROSPECTION introspection_sources = $(pkginclude_HEADERS) Nice-0.1.gir: libagent.la Nice_0_1_gir_INCLUDES = GObject-2.0 Gio-2.0 Nice_0_1_gir_EXPORT_PACKAGES = nice Nice_0_1_gir_CFLAGS = $(AM_CFLAGS) Nice_0_1_gir_LIBS = libagent.la Nice_0_1_gir_FILES = $(introspection_sources) INTROSPECTION_GIRS += Nice-0.1.gir girdir = $(datadir)/gir-1.0 gir_DATA = $(INTROSPECTION_GIRS) typelibdir = $(libdir)/girepository-1.0 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) CLEANFILES += $(gir_DATA) $(typelib_DATA) endif libnice-0.1.14/agent/debug.h0000664000076400007640000000732712520743534012510 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __LIBNICE_DEBUG_H__ #define __LIBNICE_DEBUG_H__ /** * SECTION:debug * @short_description: Debug messages utility functions * @stability: Unstable * * Libnice can output a lot of information when debug messages are enabled. * This can significantly help track down problems and/or understand what * it's doing. * * You can enable/disable the debug messages by calling nice_debug_enable() * or nice_debug_disable() and choosing whether you want only ICE debug messages * or also stun debug messages. * * By default, the debug messages are disabled, unless the environment * variable NICE_DEBUG is set, in which case, it must contain a comma separated * list of flags specifying which debug to enable. * The currently available flags are "nice", "stun", "pseudotcp", * "pseudotcp-verbose" or "all" to enable all debug messages. * If the 'pseudotcp' flag is enabled, then 'pseudotcp-verbose' gets * automatically disabled. This is to allow the use of the 'all' flag without * having verbose messages from pseudotcp. You can enable verbose debug messages * from the pseudotcp layer by specifying 'pseudotcp-verbose' without the * 'pseudotcp' flag. * * * This API is unstable and is subject to change at any time... * More flags are to come and a better API to enable/disable each flag * should be added. */ #include G_BEGIN_DECLS /** * nice_debug_enable: * @with_stun: Also enable STUN debugging messages * * Enables libnice debug output to the terminal. Note that the * `G_MESSAGES_DEBUG` and `NICE_DEBUG` environment variables must be set to the * set of logging domains to print, in order for any output to be printed. Set * them to `all` to print all debugging messages, or any of the following * domains: * - `libnice-stun` * - `libnice-tests` * - `libnice-socket` * - `libnice` * - `libnice-pseudotcp` * - `libnice-pseudotcp-verbose` */ void nice_debug_enable (gboolean with_stun); /** * nice_debug_disable: * @with_stun: Also disable stun debugging messages * * Disables libnice debug output to the terminal */ void nice_debug_disable (gboolean with_stun); G_END_DECLS #endif /* __LIBNICE_DEBUG_H__ */ libnice-0.1.14/agent/outputstream.h0000664000076400007640000000561012363772107014172 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __NICE_OUTPUT_STREAM_H__ #define __NICE_OUTPUT_STREAM_H__ #include #include #include "agent.h" G_BEGIN_DECLS /* TYPE MACROS */ #define NICE_TYPE_OUTPUT_STREAM \ (nice_output_stream_get_type ()) #define NICE_OUTPUT_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), NICE_TYPE_OUTPUT_STREAM, \ NiceOutputStream)) #define NICE_OUTPUT_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), NICE_TYPE_OUTPUT_STREAM, \ NiceOutputStreamClass)) #define NICE_IS_OUTPUT_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj), NICE_TYPE_OUTPUT_STREAM)) #define NICE_IS_OUTPUT_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass), NICE_TYPE_OUTPUT_STREAM)) #define NICE_OUTPUT_STREAM_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), NICE_TYPE_OUTPUT_STREAM, \ NiceOutputStreamClass)) typedef struct _NiceOutputStreamPrivate NiceOutputStreamPrivate; typedef struct _NiceOutputStreamClass NiceOutputStreamClass; typedef struct _NiceOutputStream NiceOutputStream; GType nice_output_stream_get_type (void); struct _NiceOutputStreamClass { GOutputStreamClass parent_class; }; struct _NiceOutputStream { GOutputStream parent_instance; NiceOutputStreamPrivate *priv; }; NiceOutputStream *nice_output_stream_new (NiceAgent *agent, guint stream_id, guint component_id); G_END_DECLS #endif /* __NICE_OUTPUT_STREAM_H__ */ libnice-0.1.14/agent/stream.c0000664000076400007640000001237112733070261012677 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "stream.h" /* Simple tracking for the number of alive streams. These must be accessed * atomically. */ static volatile unsigned int n_streams_created = 0; static volatile unsigned int n_streams_destroyed = 0; G_DEFINE_TYPE (NiceStream, nice_stream, G_TYPE_OBJECT); static void nice_stream_finalize (GObject *obj); /* * @file stream.c * @brief ICE stream functionality */ NiceStream * nice_stream_new (guint n_components, NiceAgent *agent) { NiceStream *stream = NULL; guint n; stream = g_object_new (NICE_TYPE_STREAM, NULL); /* Create the components. */ for (n = 0; n < n_components; n++) { NiceComponent *component = NULL; component = nice_component_new (n + 1, agent, stream); stream->components = g_slist_append (stream->components, component); } stream->n_components = n_components; return stream; } void nice_stream_close (NiceStream *stream) { GSList *i; for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; nice_component_close (component); } } NiceComponent * nice_stream_find_component_by_id (NiceStream *stream, guint id) { GSList *i; for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; if (component && component->id == id) return component; } return NULL; } /* * Returns true if all components of the stream are either * 'CONNECTED' or 'READY' (connected plus nominated). */ gboolean nice_stream_all_components_ready (NiceStream *stream) { GSList *i; for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; if (component && !(component->state == NICE_COMPONENT_STATE_CONNECTED || component->state == NICE_COMPONENT_STATE_READY)) return FALSE; } return TRUE; } /* * Initialized the local crendentials for the stream. */ void nice_stream_initialize_credentials (NiceStream *stream, NiceRNG *rng) { /* note: generate ufrag/pwd for the stream (see ICE 15.4. * '"ice-ufrag" and "ice-pwd" Attributes', ID-19) */ nice_rng_generate_bytes_print (rng, NICE_STREAM_DEF_UFRAG - 1, stream->local_ufrag); nice_rng_generate_bytes_print (rng, NICE_STREAM_DEF_PWD - 1, stream->local_password); } /* * Resets the stream state to that of a ICE restarted * session. */ void nice_stream_restart (NiceStream *stream, NiceAgent *agent) { GSList *i; /* step: clean up all connectivity checks */ conn_check_prune_stream (agent, stream); stream->initial_binding_request_received = FALSE; nice_stream_initialize_credentials (stream, agent->rng); for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; nice_component_restart (component); } } static void nice_stream_class_init (NiceStreamClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = nice_stream_finalize; } static void nice_stream_init (NiceStream *stream) { g_atomic_int_inc (&n_streams_created); nice_debug ("Created NiceStream (%u created, %u destroyed)", n_streams_created, n_streams_destroyed); stream->n_components = 0; stream->initial_binding_request_received = FALSE; } /* Must be called with the agent lock released as it could dispose of * NiceIOStreams. */ static void nice_stream_finalize (GObject *obj) { NiceStream *stream; stream = NICE_STREAM (obj); g_free (stream->name); g_slist_free_full (stream->components, (GDestroyNotify) g_object_unref); g_atomic_int_inc (&n_streams_destroyed); nice_debug ("Destroyed NiceStream (%u created, %u destroyed)", n_streams_created, n_streams_destroyed); G_OBJECT_CLASS (nice_stream_parent_class)->finalize (obj); } libnice-0.1.14/agent/outputstream.c0000664000076400007640000004742012661700132014160 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /*** * SECTION:nice_output_stream * @short_description: #GOutputStream implementation for libnice * @see_also: #NiceAgent * @include: outputstream.h * @stability: Stable * * #NiceOutputStream is a #GOutputStream wrapper for a single reliable stream * and component of a #NiceAgent. Given an existing reliable #NiceAgent, plus * the IDs of an existing stream and component in the agent, it will provide a * streaming output interface for writing to the given component. * * A single #NiceOutputStream can only be used with a single agent, stream and * component triple, and will be closed as soon as that stream is removed from * the agent (e.g. if nice_agent_remove_stream() is called from another thread). * If g_output_stream_close() is called on a #NiceOutputStream, the output * stream and underlying #NiceAgent stream will be closed, but the underlying * stream will not be removed. Use nice_agent_remove_stream() to do that. * * The output stream can only be used once the * #NiceAgent::reliable-transport-writable signal has been received for the * stream/component pair. Any calls to g_output_stream_write() before then will * return %G_IO_ERROR_BROKEN_PIPE. * * Since: 0.1.5 */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "outputstream.h" #include "agent-priv.h" static void nice_output_stream_init_pollable ( GPollableOutputStreamInterface *iface); static void streams_removed_cb (NiceAgent *agent, guint *stream_ids, gpointer user_data); G_DEFINE_TYPE_WITH_CODE (NiceOutputStream, nice_output_stream, G_TYPE_OUTPUT_STREAM, G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, nice_output_stream_init_pollable)); enum { PROP_AGENT = 1, PROP_STREAM_ID, PROP_COMPONENT_ID, }; struct _NiceOutputStreamPrivate { GWeakRef/**/ agent_ref; guint stream_id; guint component_id; GCancellable *closed_cancellable; }; static void nice_output_stream_dispose (GObject *object); static void nice_output_stream_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void nice_output_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static gssize nice_output_stream_write (GOutputStream *stream, const void *buffer, gsize count, GCancellable *cancellable, GError **error); static gboolean nice_output_stream_close (GOutputStream *stream, GCancellable *cancellable, GError **error); static gboolean nice_output_stream_is_writable (GPollableOutputStream *stream); static gssize nice_output_stream_write_nonblocking ( GPollableOutputStream *stream, const void *buffer, gsize count, GError **error); static GSource *nice_output_stream_create_source (GPollableOutputStream *stream, GCancellable *cancellable); /* Output Stream */ static void nice_output_stream_class_init (NiceOutputStreamClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass); g_type_class_add_private (klass, sizeof (NiceOutputStreamPrivate)); stream_class->write_fn = nice_output_stream_write; stream_class->close_fn = nice_output_stream_close; gobject_class->set_property = nice_output_stream_set_property; gobject_class->get_property = nice_output_stream_get_property; gobject_class->dispose = nice_output_stream_dispose; /*** * NiceOutputStream:agent: * * The #NiceAgent to wrap with an output stream. This must be an existing * reliable agent. * * A reference is not held on the #NiceAgent. If the agent is destroyed before * the #NiceOutputStream, %G_IO_ERROR_CLOSED will be returned for all * subsequent operations on the stream. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_AGENT, g_param_spec_object ("agent", "NiceAgent", "The underlying NiceAgent", NICE_TYPE_AGENT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /*** * NiceOutputStream:stream-id: * * ID of the stream to use in the #NiceOutputStream:agent. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_STREAM_ID, g_param_spec_uint ( "stream-id", "Agent’s stream ID", "The ID of the agent’s stream to wrap.", 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /*** * NiceOutputStream:component-id: * * ID of the component to use in the #NiceOutputStream:agent. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_COMPONENT_ID, g_param_spec_uint ( "component-id", "Agent’s component ID", "The ID of the agent’s component to wrap.", 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void nice_output_stream_dispose (GObject *object) { NiceOutputStream *self = NICE_OUTPUT_STREAM (object); NiceAgent *agent; /* Ensure the stream is closed first, otherwise the agent can’t be found in * the close handler called by the parent implementation. */ if (!g_output_stream_is_closed (G_OUTPUT_STREAM (object))) g_output_stream_close (G_OUTPUT_STREAM (object), NULL, NULL); agent = g_weak_ref_get (&self->priv->agent_ref); if (agent != NULL) { g_signal_handlers_disconnect_by_func (agent, streams_removed_cb, self); g_object_unref (agent); } g_weak_ref_clear (&self->priv->agent_ref); g_clear_object (&self->priv->closed_cancellable); G_OBJECT_CLASS (nice_output_stream_parent_class)->dispose (object); } static void nice_output_stream_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NiceOutputStream *self = NICE_OUTPUT_STREAM (object); switch (prop_id) { case PROP_AGENT: g_value_take_object (value, g_weak_ref_get (&self->priv->agent_ref)); break; case PROP_STREAM_ID: g_value_set_uint (value, self->priv->stream_id); break; case PROP_COMPONENT_ID: g_value_set_uint (value, self->priv->component_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void nice_output_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NiceOutputStream *self = NICE_OUTPUT_STREAM (object); switch (prop_id) { case PROP_AGENT: { /* Construct only. */ NiceAgent *agent = g_value_dup_object (value); g_weak_ref_set (&self->priv->agent_ref, agent); /* agent may be NULL if the stream is being constructed by * nice_io_stream_get_output_stream() after the NiceIOStream’s agent has * already been finalised. */ if (agent != NULL) { g_signal_connect (agent, "streams-removed", (GCallback) streams_removed_cb, self); g_object_unref (agent); } break; } case PROP_STREAM_ID: /* Construct only. */ self->priv->stream_id = g_value_get_uint (value); break; case PROP_COMPONENT_ID: /* Construct only. */ self->priv->component_id = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void nice_output_stream_init (NiceOutputStream *stream) { stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, NICE_TYPE_OUTPUT_STREAM, NiceOutputStreamPrivate); g_weak_ref_init (&stream->priv->agent_ref, NULL); stream->priv->closed_cancellable = g_cancellable_new (); } static void nice_output_stream_init_pollable (GPollableOutputStreamInterface *iface) { iface->is_writable = nice_output_stream_is_writable; iface->write_nonblocking = nice_output_stream_write_nonblocking; iface->create_source = nice_output_stream_create_source; } /*** * nice_output_stream_new: * @agent: A #NiceAgent * @stream_id: The ID of the agent’s stream to wrap * @component_id: The ID of the agent’s component to wrap * * Create a new #NiceOutputStream wrapping the given stream/component from * @agent, which must be a reliable #NiceAgent. * * The constructed #NiceOutputStream will not hold a reference to @agent. If * @agent is destroyed before the output stream, %G_IO_ERROR_CLOSED will be * returned for all subsequent operations on the stream. * * Returns: The new #NiceOutputStream object * * Since: 0.1.5 */ NiceOutputStream * nice_output_stream_new (NiceAgent *agent, guint stream_id, guint component_id) { g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (component_id >= 1, NULL); return g_object_new (NICE_TYPE_OUTPUT_STREAM, "agent", agent, "stream-id", stream_id, "component-id", component_id, NULL); } typedef struct { volatile gint ref_count; GCond cond; GMutex mutex; gboolean writable; gboolean cancelled; } WriteData; static WriteData * write_data_ref (WriteData *write_data) { g_atomic_int_inc (&write_data->ref_count); return write_data; } static void write_data_unref (WriteData *write_data) { if (g_atomic_int_dec_and_test (&write_data->ref_count)) { g_cond_clear (&write_data->cond); g_mutex_clear (&write_data->mutex); g_slice_free (WriteData, write_data); } } static void write_cancelled_cb (GCancellable *cancellable, gpointer user_data) { WriteData *write_data = user_data; g_mutex_lock (&write_data->mutex); g_cond_broadcast (&write_data->cond); write_data->cancelled = TRUE; g_mutex_unlock (&write_data->mutex); } static void reliable_transport_writeable_cb (NiceAgent *agent, guint stream_id, guint component_id, gpointer user_data) { WriteData *write_data = user_data; g_mutex_lock (&write_data->mutex); write_data->writable = TRUE; g_cond_broadcast (&write_data->cond); g_mutex_unlock (&write_data->mutex); } static gssize nice_output_stream_write (GOutputStream *stream, const void *buffer, gsize count, GCancellable *cancellable, GError **error) { NiceOutputStream *self = NICE_OUTPUT_STREAM (stream); const gchar* buf = buffer; gssize len = 0; gint n_sent; NiceAgent *agent = NULL; /* owned */ gulong cancel_id = 0, closed_cancel_id, writeable_id; WriteData *write_data; /* Closed streams are not writeable. */ if (g_output_stream_is_closed (stream)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Stream is closed."); return -1; } /* Has the agent disappeared? */ agent = g_weak_ref_get (&self->priv->agent_ref); if (agent == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Stream is closed due to the NiceAgent being finalised."); return -1; } if (count == 0) { g_object_unref (agent); return 0; } /* FIXME: nice_agent_send() is non-blocking, which is a bit unexpected * since nice_agent_recv() is blocking. Currently this uses a fairly dodgy * GCond solution; would be much better for nice_agent_send() to block * properly in the main loop. */ write_data = g_slice_new0 (WriteData); write_data->ref_count = 1; g_mutex_init (&write_data->mutex); g_cond_init (&write_data->cond); if (cancellable != NULL) { cancel_id = g_cancellable_connect (cancellable, (GCallback) write_cancelled_cb, write_data_ref (write_data), (GDestroyNotify) write_data_unref); } closed_cancel_id = g_cancellable_connect (self->priv->closed_cancellable, (GCallback) write_cancelled_cb, write_data_ref (write_data), (GDestroyNotify) write_data_unref); g_mutex_lock (&write_data->mutex); writeable_id = g_signal_connect_data (G_OBJECT (agent), "reliable-transport-writable", (GCallback) reliable_transport_writeable_cb, write_data_ref (write_data), (GClosureNotify) write_data_unref, 0); do { /* Have to unlock while calling into the agent because * it will take the agent lock which will cause a deadlock if one of * the callbacks is called. */ if (g_cancellable_is_cancelled (cancellable) || g_cancellable_is_cancelled (self->priv->closed_cancellable)) break; write_data->writable = FALSE; g_mutex_unlock (&write_data->mutex); n_sent = nice_agent_send (agent, self->priv->stream_id, self->priv->component_id, count - len, buf + len); g_mutex_lock (&write_data->mutex); if (n_sent <= 0) { if (!write_data->writable && !write_data->cancelled) g_cond_wait (&write_data->cond, &write_data->mutex); } else if (n_sent > 0) { /* Success. */ len += n_sent; } } while ((gsize) len < count); g_signal_handler_disconnect (G_OBJECT (agent), writeable_id); g_mutex_unlock (&write_data->mutex); if (cancel_id) g_cancellable_disconnect (cancellable, cancel_id); g_cancellable_disconnect (self->priv->closed_cancellable, closed_cancel_id); if (len == 0) { len = -1; if (!g_cancellable_set_error_if_cancelled (cancellable, error)) { if (g_cancellable_is_cancelled (self->priv->closed_cancellable)) g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Stream has been removed from agent"); } } write_data_unref (write_data); g_object_unref (agent); g_assert (len != 0); return len; } static gboolean nice_output_stream_close (GOutputStream *stream, GCancellable *cancellable, GError **error) { NiceOutputStreamPrivate *priv = NICE_OUTPUT_STREAM (stream)->priv; NiceComponent *component = NULL; NiceStream *_stream = NULL; NiceAgent *agent; /* owned */ /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) return TRUE; agent_lock (); /* Shut down the write side of the pseudo-TCP stream. */ if (agent_find_component (agent, priv->stream_id, priv->component_id, &_stream, &component) && agent->reliable && !pseudo_tcp_socket_is_closed (component->tcp)) { pseudo_tcp_socket_shutdown (component->tcp, PSEUDO_TCP_SHUTDOWN_WR); } agent_unlock (); g_object_unref (agent); return TRUE; } static gboolean nice_output_stream_is_writable (GPollableOutputStream *stream) { NiceOutputStreamPrivate *priv = NICE_OUTPUT_STREAM (stream)->priv; NiceComponent *component = NULL; NiceStream *_stream = NULL; gboolean retval = FALSE; NiceAgent *agent; /* owned */ /* Closed streams are not writeable. */ if (g_output_stream_is_closed (G_OUTPUT_STREAM (stream))) return FALSE; /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) return FALSE; agent_lock (); if (!agent_find_component (agent, priv->stream_id, priv->component_id, &_stream, &component)) { g_warning ("Could not find component %u in stream %u", priv->component_id, priv->stream_id); goto done; } if (component->selected_pair.local != NULL) { NiceSocket *sockptr = component->selected_pair.local->sockptr; /* If it’s a reliable agent, see if there’s any space in the pseudo-TCP * output buffer. */ if (!nice_socket_is_reliable (sockptr)) { retval = pseudo_tcp_socket_can_send (component->tcp); } else { retval = (g_socket_condition_check (sockptr->fileno, G_IO_OUT) != 0); } } done: agent_unlock (); g_object_unref (agent); return retval; } static gssize nice_output_stream_write_nonblocking (GPollableOutputStream *stream, const void *buffer, gsize count, GError **error) { NiceOutputStreamPrivate *priv = NICE_OUTPUT_STREAM (stream)->priv; NiceAgent *agent; /* owned */ gint n_sent; /* Closed streams are not writeable. */ if (g_output_stream_is_closed (G_OUTPUT_STREAM (stream))) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Stream is closed."); return -1; } /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Stream is closed due to the NiceAgent being finalised."); return -1; } if (count == 0) { n_sent = 0; goto done; } n_sent = nice_agent_send (agent, priv->stream_id, priv->component_id, count, buffer); if (n_sent == -1) g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, g_strerror (EAGAIN)); done: g_object_unref (agent); return n_sent; } static GSource * nice_output_stream_create_source (GPollableOutputStream *stream, GCancellable *cancellable) { NiceOutputStreamPrivate *priv = NICE_OUTPUT_STREAM (stream)->priv; GSource *component_source = NULL; NiceComponent *component = NULL; NiceStream *_stream = NULL; NiceAgent *agent; /* owned */ component_source = g_pollable_source_new (G_OBJECT (stream)); if (cancellable) { GSource *cancellable_source = g_cancellable_source_new (cancellable); g_source_set_dummy_callback (cancellable_source); g_source_add_child_source (component_source, cancellable_source); g_source_unref (cancellable_source); } /* Closed streams cannot have sources. */ if (g_output_stream_is_closed (G_OUTPUT_STREAM (stream))) return component_source; /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) return component_source; agent_lock (); /* Grab the socket for this component. */ if (!agent_find_component (agent, priv->stream_id, priv->component_id, &_stream, &component)) { g_warning ("Could not find component %u in stream %u", priv->component_id, priv->stream_id); goto done; } if (component->tcp_writable_cancellable) { GSource *cancellable_source = g_cancellable_source_new (component->tcp_writable_cancellable); g_source_set_dummy_callback (cancellable_source); g_source_add_child_source (component_source, cancellable_source); g_source_unref (cancellable_source); } done: agent_unlock (); g_object_unref (agent); return component_source; } static void streams_removed_cb (NiceAgent *agent, guint *stream_ids, gpointer user_data) { NiceOutputStream *self = NICE_OUTPUT_STREAM (user_data); guint i; for (i = 0; stream_ids[i] != 0; i++) { if (stream_ids[i] == self->priv->stream_id) { /* The socket has been closed. */ g_cancellable_cancel (self->priv->closed_cancellable); g_output_stream_close (G_OUTPUT_STREAM (self), NULL, NULL); break; } } } libnice-0.1.14/agent/component.c0000664000076400007640000012377313070507156013422 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * @file component.c * @brief ICE component functions */ /* Simple tracking for the number of alive components. These must be accessed * atomically. */ static volatile unsigned int n_components_created = 0; static volatile unsigned int n_components_destroyed = 0; #ifdef HAVE_CONFIG_H # include #endif #include #include "debug.h" #include "component.h" #include "discovery.h" #include "agent-priv.h" G_DEFINE_TYPE (NiceComponent, nice_component, G_TYPE_OBJECT); typedef enum { PROP_ID = 1, PROP_AGENT, PROP_STREAM, } NiceComponentProperty; static void nice_component_constructed (GObject *obj); static void nice_component_get_property (GObject *obj, guint property_id, GValue *value, GParamSpec *pspec); static void nice_component_set_property (GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec); static void nice_component_finalize (GObject *obj); static void nice_component_schedule_io_callback (NiceComponent *component); static void nice_component_deschedule_io_callback (NiceComponent *component); static void nice_component_detach_socket (NiceComponent *component, NiceSocket *nicesock); static void nice_component_clear_selected_pair (NiceComponent *component); void incoming_check_free (IncomingCheck *icheck) { g_free (icheck->username); g_slice_free (IncomingCheck, icheck); } /* Must *not* take the agent lock, since it’s called from within * nice_component_set_io_context(), which holds the Component’s I/O lock. */ static void socket_source_attach (SocketSource *socket_source, GMainContext *context) { GSource *source; if (socket_source->socket->fileno == NULL) return; /* Create a source. */ source = g_socket_create_source (socket_source->socket->fileno, G_IO_IN, NULL); g_source_set_callback (source, (GSourceFunc) component_io_cb, socket_source, NULL); /* Add the source. */ nice_debug ("Attaching source %p (socket %p, FD %d) to context %p", source, socket_source->socket, g_socket_get_fd (socket_source->socket->fileno), context); g_assert (socket_source->source == NULL); socket_source->source = source; g_source_attach (source, context); } static void socket_source_detach (SocketSource *source) { nice_debug ("Detaching source %p (socket %p, FD %d) from context %p", source->source, source->socket, (source->socket->fileno != NULL) ? g_socket_get_fd (source->socket->fileno) : 0, (source->source != NULL) ? g_source_get_context (source->source) : 0); if (source->source != NULL) { g_source_destroy (source->source); g_source_unref (source->source); } source->source = NULL; } static void socket_source_free (SocketSource *source) { socket_source_detach (source); nice_socket_free (source->socket); g_slice_free (SocketSource, source); } NiceComponent * nice_component_new (guint id, NiceAgent *agent, NiceStream *stream) { return g_object_new (NICE_TYPE_COMPONENT, "id", id, "agent", agent, "stream", stream, NULL); } void nice_component_remove_socket (NiceComponent *cmp, NiceSocket *nsocket) { GSList *i; for (i = cmp->local_candidates; i;) { NiceCandidate *candidate = i->data; GSList *next = i->next; if (!nice_socket_is_based_on (candidate->sockptr, nsocket)) { i = next; continue; } if (candidate == cmp->selected_pair.local) { nice_component_clear_selected_pair (cmp); agent_signal_component_state_change (cmp->agent, cmp->stream->id, cmp->id, NICE_COMPONENT_STATE_FAILED); } refresh_prune_candidate (cmp->agent, candidate); if (candidate->sockptr != nsocket) { discovery_prune_socket (cmp->agent, candidate->sockptr); conn_check_prune_socket (cmp->agent, cmp->stream, cmp, candidate->sockptr); nice_component_detach_socket (cmp, candidate->sockptr); } agent_remove_local_candidate (cmp->agent, candidate); nice_candidate_free (candidate); cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i); i = next; } discovery_prune_socket (cmp->agent, nsocket); conn_check_prune_socket (cmp->agent, cmp->stream, cmp, nsocket); nice_component_detach_socket (cmp, nsocket); } void nice_component_clean_turn_servers (NiceComponent *cmp) { GSList *i; g_list_free_full (cmp->turn_servers, (GDestroyNotify) turn_server_unref); cmp->turn_servers = NULL; for (i = cmp->local_candidates; i;) { NiceCandidate *candidate = i->data; GSList *next = i->next; if (candidate->type != NICE_CANDIDATE_TYPE_RELAYED) { i = next; continue; } /* note: do not remove the remote candidate that is * currently part of the 'selected pair', see ICE * 9.1.1.1. "ICE Restarts" (ID-19) * * So what we do instead is that we put the selected candidate * in a special location and keep it "alive" that way. This is * especially important for TURN, because refresh requests to the * server need to keep happening. */ if (candidate == cmp->selected_pair.local) { if (cmp->turn_candidate) { refresh_prune_candidate (cmp->agent, cmp->turn_candidate); discovery_prune_socket (cmp->agent, cmp->turn_candidate->sockptr); conn_check_prune_socket (cmp->agent, cmp->stream, cmp, cmp->turn_candidate->sockptr); nice_component_detach_socket (cmp, cmp->turn_candidate->sockptr); nice_candidate_free (cmp->turn_candidate); } /* Bring the priority down to 0, so that it will be replaced * on the new run. */ cmp->selected_pair.priority = 0; cmp->turn_candidate = candidate; } else { refresh_prune_candidate (cmp->agent, candidate); discovery_prune_socket (cmp->agent, candidate->sockptr); conn_check_prune_socket (cmp->agent, cmp->stream, cmp, candidate->sockptr); nice_component_detach_socket (cmp, candidate->sockptr); agent_remove_local_candidate (cmp->agent, candidate); nice_candidate_free (candidate); } cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, i); i = next; } } static void nice_component_clear_selected_pair (NiceComponent *component) { if (component->selected_pair.keepalive.tick_source != NULL) { g_source_destroy (component->selected_pair.keepalive.tick_source); g_source_unref (component->selected_pair.keepalive.tick_source); component->selected_pair.keepalive.tick_source = NULL; } memset (&component->selected_pair, 0, sizeof(CandidatePair)); } /* Must be called with the agent lock held as it touches internal Component * state. */ void nice_component_close (NiceComponent *cmp) { IOCallbackData *data; GOutputVector *vec; /* Start closing the pseudo-TCP socket first. FIXME: There is a very big and * reliably triggerable race here. pseudo_tcp_socket_close() does not block * on the socket closing — it only sends the first packet of the FIN * handshake. nice_component_close() will immediately afterwards close the * underlying component sockets, aborting the handshake. * * On the principle that starting the FIN handshake is better than not * starting it, even if it’s later truncated, call pseudo_tcp_socket_close(). * A long-term fix is needed in the form of making nice_component_close() (and * all its callers) async, so we can properly block on closure. */ if (cmp->tcp) { pseudo_tcp_socket_close (cmp->tcp, TRUE); } if (cmp->restart_candidate) nice_candidate_free (cmp->restart_candidate), cmp->restart_candidate = NULL; if (cmp->turn_candidate) nice_candidate_free (cmp->turn_candidate), cmp->turn_candidate = NULL; while (cmp->local_candidates) { agent_remove_local_candidate (cmp->agent, cmp->local_candidates->data); nice_candidate_free (cmp->local_candidates->data); cmp->local_candidates = g_slist_delete_link (cmp->local_candidates, cmp->local_candidates); } g_slist_free_full (cmp->remote_candidates, (GDestroyNotify) nice_candidate_free); cmp->remote_candidates = NULL; nice_component_free_socket_sources (cmp); g_slist_free_full (cmp->incoming_checks, (GDestroyNotify) incoming_check_free); cmp->incoming_checks = NULL; nice_component_clean_turn_servers (cmp); if (cmp->tcp_clock) { g_source_destroy (cmp->tcp_clock); g_source_unref (cmp->tcp_clock); cmp->tcp_clock = NULL; } if (cmp->tcp_writable_cancellable) { g_cancellable_cancel (cmp->tcp_writable_cancellable); g_clear_object (&cmp->tcp_writable_cancellable); } while ((data = g_queue_pop_head (&cmp->pending_io_messages)) != NULL) io_callback_data_free (data); nice_component_deschedule_io_callback (cmp); g_cancellable_cancel (cmp->stop_cancellable); while ((vec = g_queue_pop_head (&cmp->queued_tcp_packets)) != NULL) { g_free ((gpointer) vec->buffer); g_slice_free (GOutputVector, vec); } } /* * Finds a candidate pair that has matching foundation ids. * * @return TRUE if pair found, pointer to pair stored at 'pair' */ gboolean nice_component_find_pair (NiceComponent *cmp, NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair) { GSList *i; CandidatePair result = { 0, }; for (i = cmp->local_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; if (strncmp (candidate->foundation, lfoundation, NICE_CANDIDATE_MAX_FOUNDATION) == 0) { result.local = candidate; break; } } for (i = cmp->remote_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; if (strncmp (candidate->foundation, rfoundation, NICE_CANDIDATE_MAX_FOUNDATION) == 0) { result.remote = candidate; break; } } if (result.local && result.remote) { result.priority = agent_candidate_pair_priority (agent, result.local, result.remote); if (pair) *pair = result; return TRUE; } return FALSE; } /* * Resets the component state to that of a ICE restarted * session. */ void nice_component_restart (NiceComponent *cmp) { GSList *i; for (i = cmp->remote_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; /* note: do not remove the local candidate that is * currently part of the 'selected pair', see ICE * 9.1.1.1. "ICE Restarts" (ID-19) */ if (candidate == cmp->selected_pair.remote) { if (cmp->restart_candidate) nice_candidate_free (cmp->restart_candidate); cmp->restart_candidate = candidate; } else nice_candidate_free (candidate); } g_slist_free (cmp->remote_candidates), cmp->remote_candidates = NULL; g_slist_free_full (cmp->incoming_checks, (GDestroyNotify) incoming_check_free); cmp->incoming_checks = NULL; /* Reset the priority to 0 to make sure we get a new pair */ cmp->selected_pair.priority = 0; /* note: component state managed by agent */ } /* * Changes the selected pair for the component to 'pair'. Does not * emit the "selected-pair-changed" signal. */ void nice_component_update_selected_pair (NiceComponent *component, const CandidatePair *pair) { g_assert (component); g_assert (pair); nice_debug ("setting SELECTED PAIR for component %u: %s:%s (prio:%" G_GUINT64_FORMAT ").", component->id, pair->local->foundation, pair->remote->foundation, pair->priority); if (component->selected_pair.local && component->selected_pair.local == component->turn_candidate) { refresh_prune_candidate (component->agent, component->turn_candidate); discovery_prune_socket (component->agent, component->turn_candidate->sockptr); conn_check_prune_socket (component->agent, component->stream, component, component->turn_candidate->sockptr); nice_component_detach_socket (component, component->turn_candidate->sockptr); nice_candidate_free (component->turn_candidate); component->turn_candidate = NULL; } nice_component_clear_selected_pair (component); component->selected_pair.local = pair->local; component->selected_pair.remote = pair->remote; component->selected_pair.priority = pair->priority; component->selected_pair.prflx_priority = pair->prflx_priority; } /* * Finds a remote candidate with matching address and * transport. * * @return pointer to candidate or NULL if not found */ NiceCandidate * nice_component_find_remote_candidate (NiceComponent *component, const NiceAddress *addr, NiceCandidateTransport transport) { GSList *i; for (i = component->remote_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; if (nice_address_equal(&candidate->addr, addr) && candidate->transport == transport) return candidate; } return NULL; } /* * Sets the desired remote candidate as the selected pair * * It will start sending on the highest priority pair available with * this candidate. */ NiceCandidate * nice_component_set_selected_remote_candidate (NiceComponent *component, NiceAgent *agent, NiceCandidate *candidate) { NiceCandidate *local = NULL; NiceCandidate *remote = NULL; guint64 priority = 0; GSList *item = NULL; g_assert (candidate != NULL); for (item = component->local_candidates; item; item = g_slist_next (item)) { NiceCandidate *tmp = item->data; guint64 tmp_prio = 0; if (tmp->transport != conn_check_match_transport(candidate->transport) || tmp->addr.s.addr.sa_family != candidate->addr.s.addr.sa_family || tmp->type != NICE_CANDIDATE_TYPE_HOST) continue; tmp_prio = agent_candidate_pair_priority (agent, tmp, candidate); if (tmp_prio > priority) { priority = tmp_prio; local = tmp; } } if (local == NULL) return NULL; remote = nice_component_find_remote_candidate (component, &candidate->addr, candidate->transport); if (!remote) { remote = nice_candidate_copy (candidate); component->remote_candidates = g_slist_append (component->remote_candidates, remote); agent_signal_new_remote_candidate (agent, remote); } nice_component_clear_selected_pair (component); component->selected_pair.local = local; component->selected_pair.remote = remote; component->selected_pair.priority = priority; return local; } static gint _find_socket_source (gconstpointer a, gconstpointer b) { const SocketSource *source_a = a; const NiceSocket *socket_b = b; return (source_a->socket == socket_b) ? 0 : 1; } /* This takes ownership of the socket. * It creates and attaches a source to the component’s context. */ void nice_component_attach_socket (NiceComponent *component, NiceSocket *nicesock) { GSList *l; SocketSource *socket_source; g_assert (component != NULL); g_assert (nicesock != NULL); g_assert (component->ctx != NULL); /* Find an existing SocketSource in the component which contains @socket, or * create a new one. * * Whenever a source is added or remove to socket_sources, socket_sources_age * must be incremented. */ l = g_slist_find_custom (component->socket_sources, nicesock, _find_socket_source); if (l != NULL) { socket_source = l->data; } else { socket_source = g_slice_new0 (SocketSource); socket_source->socket = nicesock; socket_source->component = component; component->socket_sources = g_slist_prepend (component->socket_sources, socket_source); if (nicesock->fileno != NULL) component->socket_sources_age++; } /* Create and attach a source */ nice_debug ("Component %p (agent %p): Attach source (stream %u).", component, component->agent, component->stream->id); socket_source_attach (socket_source, component->ctx); } /* Reattaches socket handles of @component to the main context. * * Must *not* take the agent lock, since it’s called from within * nice_component_set_io_context(), which holds the Component’s I/O lock. */ static void nice_component_reattach_all_sockets (NiceComponent *component) { GSList *i; for (i = component->socket_sources; i != NULL; i = i->next) { SocketSource *socket_source = i->data; nice_debug ("Reattach source %p.", socket_source->source); socket_source_detach (socket_source); socket_source_attach (socket_source, component->ctx); } } /** * nice_component_detach_socket: * @component: a #NiceComponent * @socket: the socket to detach the source for * * Detach the #GSource for the single specified @socket. It also closes it * and frees it! * * If the @socket doesn’t exist in this @component, do nothing. */ static void nice_component_detach_socket (NiceComponent *component, NiceSocket *nicesock) { GSList *l; SocketSource *socket_source; nice_debug ("Detach socket %p.", nicesock); /* Remove the socket from various lists. */ for (l = component->incoming_checks; l != NULL;) { IncomingCheck *icheck = l->data; GSList *next = l->next; if (icheck->local_socket == nicesock) { component->incoming_checks = g_slist_delete_link (component->incoming_checks, l); incoming_check_free (icheck); } l = next; } /* Find the SocketSource for the socket. */ l = g_slist_find_custom (component->socket_sources, nicesock, _find_socket_source); if (l == NULL) return; /* Detach the source. */ socket_source = l->data; component->socket_sources = g_slist_delete_link (component->socket_sources, l); component->socket_sources_age++; socket_source_detach (socket_source); socket_source_free (socket_source); } /* * Detaches socket handles of @component from the main context. Leaves the * sockets themselves untouched. * * Must *not* take the agent lock, since it’s called from within * nice_component_set_io_context(), which holds the Component’s I/O lock. */ void nice_component_detach_all_sockets (NiceComponent *component) { GSList *i; for (i = component->socket_sources; i != NULL; i = i->next) { SocketSource *socket_source = i->data; nice_debug ("Detach source %p, socket %p.", socket_source->source, socket_source->socket); socket_source_detach (socket_source); } } void nice_component_free_socket_sources (NiceComponent *component) { nice_debug ("Free socket sources for component %p.", component); g_slist_free_full (component->socket_sources, (GDestroyNotify) socket_source_free); component->socket_sources = NULL; component->socket_sources_age++; nice_component_clear_selected_pair (component); } GMainContext * nice_component_dup_io_context (NiceComponent *component) { return g_main_context_ref (component->own_ctx); } /* If @context is %NULL, it's own context is used, so component->ctx is always * guaranteed to be non-%NULL. */ void nice_component_set_io_context (NiceComponent *component, GMainContext *context) { g_mutex_lock (&component->io_mutex); if (component->ctx != context) { if (context == NULL) context = g_main_context_ref (component->own_ctx); else g_main_context_ref (context); nice_component_detach_all_sockets (component); g_main_context_unref (component->ctx); component->ctx = context; nice_component_reattach_all_sockets (component); } g_mutex_unlock (&component->io_mutex); } /* (func, user_data) and (recv_messages, n_recv_messages) are mutually * exclusive. At most one of the two must be specified; if both are NULL, the * Component will not receive any data (i.e. reception is paused). * * Apart from during setup, this must always be called with the agent lock held, * and the I/O lock released (because it takes the I/O lock itself). Requiring * the agent lock to be held means it can’t be called between a packet being * dequeued from the kernel buffers in agent.c, and an I/O callback being * emitted for it (which could cause data loss if the I/O callback function was * unset in that time). */ void nice_component_set_io_callback (NiceComponent *component, NiceAgentRecvFunc func, gpointer user_data, NiceInputMessage *recv_messages, guint n_recv_messages, GError **error) { g_assert (func == NULL || recv_messages == NULL); g_assert (n_recv_messages == 0 || recv_messages != NULL); g_assert (error == NULL || *error == NULL); g_mutex_lock (&component->io_mutex); if (func != NULL) { component->io_callback = func; component->io_user_data = user_data; component->recv_messages = NULL; component->n_recv_messages = 0; nice_component_schedule_io_callback (component); } else { component->io_callback = NULL; component->io_user_data = NULL; component->recv_messages = recv_messages; component->n_recv_messages = n_recv_messages; nice_component_deschedule_io_callback (component); } nice_input_message_iter_reset (&component->recv_messages_iter); component->recv_buf_error = error; g_mutex_unlock (&component->io_mutex); } gboolean nice_component_has_io_callback (NiceComponent *component) { gboolean has_io_callback; g_mutex_lock (&component->io_mutex); has_io_callback = (component->io_callback != NULL); g_mutex_unlock (&component->io_mutex); return has_io_callback; } IOCallbackData * io_callback_data_new (const guint8 *buf, gsize buf_len) { IOCallbackData *data; data = g_slice_new0 (IOCallbackData); data->buf = g_memdup (buf, buf_len); data->buf_len = buf_len; data->offset = 0; return data; } void io_callback_data_free (IOCallbackData *data) { g_free (data->buf); g_slice_free (IOCallbackData, data); } /* This is called with the global agent lock released. It does not take that * lock, but does take the io_mutex. */ static gboolean emit_io_callback_cb (gpointer user_data) { NiceComponent *component = user_data; IOCallbackData *data; NiceAgentRecvFunc io_callback; gpointer io_user_data; guint stream_id, component_id; NiceAgent *agent; agent = component->agent; g_object_ref (agent); stream_id = component->stream->id; component_id = component->id; g_mutex_lock (&component->io_mutex); /* The members of Component are guaranteed not to have changed since this * GSource was attached in nice_component_emit_io_callback(). The Component’s agent * and stream are immutable after construction, as are the stream and * component IDs. The callback and its user data may have changed, but are * guaranteed to be non-%NULL at the start as the idle source is removed when * the callback is set to %NULL. They may become %NULL during the io_callback, * so must be re-checked every loop iteration. The data buffer is copied into * the #IOCallbackData closure. * * If the component is destroyed (which happens if the agent or stream are * destroyed) between attaching the GSource and firing it, the GSource is * detached during dispose and this callback is never invoked. If the * agent is destroyed during an io_callback, its weak pointer will be * nullified. Similarly, the Component needs to be re-queried for after every * iteration, just in case the client has removed the stream in the * callback. */ while (TRUE) { io_callback = component->io_callback; io_user_data = component->io_user_data; data = g_queue_peek_head (&component->pending_io_messages); if (data == NULL || io_callback == NULL) break; g_mutex_unlock (&component->io_mutex); io_callback (agent, stream_id, component_id, data->buf_len - data->offset, (gchar *) data->buf + data->offset, io_user_data); /* Check for the user destroying things underneath our feet. */ if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) { nice_debug ("%s: Agent or component destroyed.", G_STRFUNC); goto done; } g_queue_pop_head (&component->pending_io_messages); io_callback_data_free (data); g_mutex_lock (&component->io_mutex); } component->io_callback_id = 0; g_mutex_unlock (&component->io_mutex); done: g_object_unref (agent); return G_SOURCE_REMOVE; } /* This must be called with the agent lock *held*. */ void nice_component_emit_io_callback (NiceComponent *component, const guint8 *buf, gsize buf_len) { NiceAgent *agent; guint stream_id, component_id; NiceAgentRecvFunc io_callback; gpointer io_user_data; g_assert (component != NULL); g_assert (buf != NULL); g_assert (buf_len > 0); agent = component->agent; stream_id = component->stream->id; component_id = component->id; g_mutex_lock (&component->io_mutex); io_callback = component->io_callback; io_user_data = component->io_user_data; g_mutex_unlock (&component->io_mutex); /* Allow this to be called with a NULL io_callback, since the caller can’t * lock io_mutex to check beforehand. */ if (io_callback == NULL) return; g_assert (NICE_IS_AGENT (agent)); g_assert (stream_id > 0); g_assert (component_id > 0); g_assert (io_callback != NULL); /* Only allocate a closure if the callback is being deferred to an idle * handler. */ if (g_main_context_is_owner (component->ctx)) { /* Thread owns the main context, so invoke the callback directly. */ agent_unlock_and_emit (agent); io_callback (agent, stream_id, component_id, buf_len, (gchar *) buf, io_user_data); agent_lock (); } else { IOCallbackData *data; g_mutex_lock (&component->io_mutex); /* Slow path: Current thread doesn’t own the Component’s context at the * moment, so schedule the callback in an idle handler. */ data = io_callback_data_new (buf, buf_len); g_queue_push_tail (&component->pending_io_messages, data); /* transfer ownership */ nice_debug ("%s: **WARNING: SLOW PATH**", G_STRFUNC); nice_component_schedule_io_callback (component); g_mutex_unlock (&component->io_mutex); } } /* Note: Must be called with the io_mutex held. */ static void nice_component_schedule_io_callback (NiceComponent *component) { GSource *source; /* Already scheduled or nothing to schedule? */ if (component->io_callback_id != 0 || g_queue_is_empty (&component->pending_io_messages)) return; /* Add the idle callback. If nice_agent_attach_recv() is called with a * NULL callback before this source is dispatched, the source will be * destroyed, but any pending data will remain in * component->pending_io_messages, ready to be picked up when a callback * is re-attached, or if nice_agent_recv() is called. */ source = g_idle_source_new (); g_source_set_priority (source, G_PRIORITY_DEFAULT); g_source_set_callback (source, emit_io_callback_cb, component, NULL); component->io_callback_id = g_source_attach (source, component->ctx); g_source_unref (source); } /* Note: Must be called with the io_mutex held. */ static void nice_component_deschedule_io_callback (NiceComponent *component) { /* Already descheduled? */ if (component->io_callback_id == 0) return; g_source_remove (component->io_callback_id); component->io_callback_id = 0; } static void nice_component_class_init (NiceComponentClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructed = nice_component_constructed; object_class->get_property = nice_component_get_property; object_class->set_property = nice_component_set_property; object_class->finalize = nice_component_finalize; /** * NiceComponent:id: * * The unique numeric ID of the component. * * Since: 0.1.14 */ g_object_class_install_property (object_class, PROP_ID, g_param_spec_uint ( "id", "ID", "The unique numeric ID of the component.", 1, G_MAXUINT, 1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * NiceComponent:agent: * * The #NiceAgent this component belongs to. * * Since: 0.1.14 */ g_object_class_install_property (object_class, PROP_AGENT, g_param_spec_object ( "agent", "Agent", "The NiceAgent this component belongs to.", NICE_TYPE_AGENT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * NiceComponent:stream: * * The #NiceStream this component belongs to. * * Since: 0.1.14 */ g_object_class_install_property (object_class, PROP_STREAM, g_param_spec_object ( "stream", "Stream", "The NiceStream this component belongs to.", NICE_TYPE_STREAM, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void nice_component_init (NiceComponent *component) { g_atomic_int_inc (&n_components_created); nice_debug ("Created NiceComponent (%u created, %u destroyed)", n_components_created, n_components_destroyed); component->id = 0; component->state = NICE_COMPONENT_STATE_DISCONNECTED; component->restart_candidate = NULL; component->tcp = NULL; component->agent = NULL; component->stream = NULL; g_mutex_init (&component->io_mutex); g_queue_init (&component->pending_io_messages); component->io_callback_id = 0; component->own_ctx = g_main_context_new (); component->stop_cancellable = g_cancellable_new (); component->stop_cancellable_source = g_cancellable_source_new (component->stop_cancellable); g_source_set_dummy_callback (component->stop_cancellable_source); g_source_attach (component->stop_cancellable_source, component->own_ctx); component->ctx = g_main_context_ref (component->own_ctx); /* Start off with a fresh main context and all I/O paused. This * will be updated when nice_agent_attach_recv() or nice_agent_recv_messages() * are called. */ nice_component_set_io_context (component, NULL); nice_component_set_io_callback (component, NULL, NULL, NULL, 0, NULL); g_queue_init (&component->queued_tcp_packets); } static void nice_component_constructed (GObject *obj) { NiceComponent *component; component = NICE_COMPONENT (obj); g_assert (component->agent != NULL); nice_agent_init_stun_agent (component->agent, &component->stun_agent); G_OBJECT_CLASS (nice_component_parent_class)->constructed (obj); } static void nice_component_get_property (GObject *obj, guint property_id, GValue *value, GParamSpec *pspec) { NiceComponent *component; component = NICE_COMPONENT (obj); switch ((NiceComponentProperty) property_id) { case PROP_ID: g_value_set_uint (value, component->id); break; case PROP_AGENT: g_value_set_object (value, component->agent); break; case PROP_STREAM: g_value_set_object (value, component->stream); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); } } static void nice_component_set_property (GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec) { NiceComponent *component; component = NICE_COMPONENT (obj); switch ((NiceComponentProperty) property_id) { case PROP_ID: component->id = g_value_get_uint (value); break; case PROP_AGENT: component->agent = g_value_get_object (value); break; case PROP_STREAM: component->stream = g_value_get_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); } } /* Must be called with the agent lock released as it could dispose of * NiceIOStreams. */ static void nice_component_finalize (GObject *obj) { NiceComponent *cmp; cmp = NICE_COMPONENT (obj); /* Component should have been closed already. */ g_warn_if_fail (cmp->local_candidates == NULL); g_warn_if_fail (cmp->remote_candidates == NULL); g_warn_if_fail (cmp->incoming_checks == NULL); g_clear_object (&cmp->tcp); g_clear_object (&cmp->stop_cancellable); g_clear_object (&cmp->iostream); g_mutex_clear (&cmp->io_mutex); if (cmp->stop_cancellable_source != NULL) { g_source_destroy (cmp->stop_cancellable_source); g_source_unref (cmp->stop_cancellable_source); } if (cmp->ctx != NULL) { g_main_context_unref (cmp->ctx); cmp->ctx = NULL; } g_main_context_unref (cmp->own_ctx); g_atomic_int_inc (&n_components_destroyed); nice_debug ("Destroyed NiceComponent (%u created, %u destroyed)", n_components_created, n_components_destroyed); G_OBJECT_CLASS (nice_component_parent_class)->finalize (obj); } /** * ComponentSource: * * This is a GSource which wraps a single Component and is dispatched whenever * any of its NiceSockets are dispatched, i.e. it proxies all poll() events for * every socket in the Component. It is designed for use by GPollableInputStream * and GPollableOutputStream, so that a Component can be incorporated into a * custom main context iteration. * * The callbacks dispatched by a ComponentSource have type GPollableSourceFunc. * * ComponentSource supports adding a GCancellable child source which will * additionally dispatch if a provided GCancellable is cancelled. * * Internally, ComponentSource adds a new GSocketSource for each socket in the * Component. Changes to the Component’s list of sockets are detected on each * call to component_source_prepare(), which compares a stored age with the * current age of the Component’s socket list — if the socket list has changed, * the age will have increased (indicating added sockets) or will have been * reset to 0 (indicating all sockets have been closed). */ typedef struct { GSource parent; GObject *pollable_stream; /* owned */ GWeakRef agent_ref; guint stream_id; guint component_id; guint component_socket_sources_age; /* SocketSource, free with free_child_socket_source() */ GSList *socket_sources; GIOCondition condition; } ComponentSource; static gboolean component_source_prepare (GSource *source, gint *timeout_) { ComponentSource *component_source = (ComponentSource *) source; NiceAgent *agent; NiceComponent *component; GSList *parentl, *childl; agent = g_weak_ref_get (&component_source->agent_ref); if (!agent) return FALSE; /* Needed due to accessing the Component. */ agent_lock (); if (!agent_find_component (agent, component_source->stream_id, component_source->component_id, NULL, &component)) goto done; if (component->socket_sources_age == component_source->component_socket_sources_age) goto done; /* If the age has changed, either * - one or more new socket has been prepended * - old sockets have been removed */ /* Add the new child sources. */ for (parentl = component->socket_sources; parentl; parentl = parentl->next) { SocketSource *parent_socket_source = parentl->data; SocketSource *child_socket_source; if (parent_socket_source->socket->fileno == NULL) continue; /* Iterating the list of socket sources every time isn't a big problem * because the number of pairs is limited ~100 normally, so there will * rarely be more than 10. */ childl = g_slist_find_custom (component_source->socket_sources, parent_socket_source->socket, _find_socket_source); /* If we have reached this state, then all sources new sources have been * added, because they are always prepended. */ if (childl) break; child_socket_source = g_slice_new0 (SocketSource); child_socket_source->socket = parent_socket_source->socket; child_socket_source->source = g_socket_create_source (child_socket_source->socket->fileno, G_IO_IN, NULL); g_source_set_dummy_callback (child_socket_source->source); g_source_add_child_source (source, child_socket_source->source); g_source_unref (child_socket_source->source); component_source->socket_sources = g_slist_prepend (component_source->socket_sources, child_socket_source); } for (childl = component_source->socket_sources; childl;) { SocketSource *child_socket_source = childl->data; GSList *next = childl->next; parentl = g_slist_find_custom (component->socket_sources, child_socket_source->socket, _find_socket_source); /* If this is not a currently used socket, remove the relevant source */ if (!parentl) { g_source_remove_child_source (source, child_socket_source->source); g_slice_free (SocketSource, child_socket_source); component_source->socket_sources = g_slist_delete_link (component_source->socket_sources, childl); } childl = next; } /* Update the age. */ component_source->component_socket_sources_age = component->socket_sources_age; done: agent_unlock_and_emit (agent); g_object_unref (agent); /* We can’t be sure if the ComponentSource itself needs to be dispatched until * poll() is called on all the child sources. */ return FALSE; } static gboolean component_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { ComponentSource *component_source = (ComponentSource *) source; GPollableSourceFunc func = (GPollableSourceFunc) callback; return func (component_source->pollable_stream, user_data); } static void free_child_socket_source (gpointer data) { g_slice_free (SocketSource, data); } static void component_source_finalize (GSource *source) { ComponentSource *component_source = (ComponentSource *) source; g_slist_free_full (component_source->socket_sources, free_child_socket_source); g_weak_ref_clear (&component_source->agent_ref); g_object_unref (component_source->pollable_stream); component_source->pollable_stream = NULL; } static gboolean component_source_closure_callback (GObject *pollable_stream, gpointer user_data) { GClosure *closure = user_data; GValue param_value = G_VALUE_INIT; GValue result_value = G_VALUE_INIT; gboolean retval; g_value_init (&result_value, G_TYPE_BOOLEAN); g_value_init (¶m_value, G_TYPE_OBJECT); g_value_set_object (¶m_value, pollable_stream); g_closure_invoke (closure, &result_value, 1, ¶m_value, NULL); retval = g_value_get_boolean (&result_value); g_value_unset (¶m_value); g_value_unset (&result_value); return retval; } static GSourceFuncs component_source_funcs = { component_source_prepare, NULL, /* check */ component_source_dispatch, component_source_finalize, (GSourceFunc) component_source_closure_callback, }; /** * nice_component_source_new: * @agent: a #NiceAgent * @stream_id: The stream's id * @component_id: The component's number * @pollable_stream: a #GPollableInputStream or #GPollableOutputStream to pass * to dispatched callbacks * @cancellable: (allow-none): a #GCancellable, or %NULL * * Create a new #ComponentSource, a type of #GSource which proxies poll events * from all sockets in the given @component. * * A callback function of type #GPollableSourceFunc must be connected to the * returned #GSource using g_source_set_callback(). @pollable_stream is passed * to all callbacks dispatched from the #GSource, and a reference is held on it * by the #GSource. * * The #GSource will automatically update to poll sockets as they’re added to * the @component (e.g. during peer discovery). * * Returns: (transfer full): a new #ComponentSource; unref with g_source_unref() */ GSource * nice_component_input_source_new (NiceAgent *agent, guint stream_id, guint component_id, GPollableInputStream *pollable_istream, GCancellable *cancellable) { ComponentSource *component_source; g_assert (G_IS_POLLABLE_INPUT_STREAM (pollable_istream)); component_source = (ComponentSource *) g_source_new (&component_source_funcs, sizeof (ComponentSource)); g_source_set_name ((GSource *) component_source, "ComponentSource"); component_source->component_socket_sources_age = 0; component_source->pollable_stream = g_object_ref (pollable_istream); g_weak_ref_init (&component_source->agent_ref, agent); component_source->stream_id = stream_id; component_source->component_id = component_id; /* Add a cancellable source. */ if (cancellable != NULL) { GSource *cancellable_source; cancellable_source = g_cancellable_source_new (cancellable); g_source_set_dummy_callback (cancellable_source); g_source_add_child_source ((GSource *) component_source, cancellable_source); g_source_unref (cancellable_source); } return (GSource *) component_source; } TurnServer * turn_server_new (const gchar *server_ip, guint server_port, const gchar *username, const gchar *password, NiceRelayType type) { TurnServer *turn = g_slice_new (TurnServer); nice_address_init (&turn->server); turn->ref_count = 1; if (nice_address_set_from_string (&turn->server, server_ip)) { nice_address_set_port (&turn->server, server_port); } else { g_slice_free (TurnServer, turn); return NULL; } turn->username = g_strdup (username); turn->password = g_strdup (password); turn->type = type; return turn; } TurnServer * turn_server_ref (TurnServer *turn) { turn->ref_count++; return turn; } void turn_server_unref (TurnServer *turn) { turn->ref_count--; if (turn->ref_count == 0) { g_free (turn->username); g_free (turn->password); g_slice_free (TurnServer, turn); } } libnice-0.1.14/agent/stream.h0000664000076400007640000000744612733101312012703 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2010 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2010 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _NICE_STREAM_H #define _NICE_STREAM_H #include typedef struct _NiceStream NiceStream; #include "component.h" #include "random.h" G_BEGIN_DECLS /* Maximum and default sizes for ICE attributes, * last updated from ICE ID-19 * (the below sizes include the terminating NULL): */ #define NICE_STREAM_MAX_UFRAG 256 + 1 /* ufrag + NULL */ #define NICE_STREAM_MAX_UNAME 256 * 2 + 1 + 1 /* 2*ufrag + colon + NULL */ #define NICE_STREAM_MAX_PWD 256 + 1 /* pwd + NULL */ #define NICE_STREAM_DEF_UFRAG 4 + 1 /* ufrag + NULL */ #define NICE_STREAM_DEF_PWD 22 + 1 /* pwd + NULL */ #define NICE_TYPE_STREAM nice_stream_get_type() #define NICE_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), NICE_TYPE_STREAM, NiceStream)) #define NICE_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), NICE_TYPE_STREAM, NiceStreamClass)) #define NICE_IS_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NICE_TYPE_STREAM)) #define NICE_IS_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), NICE_TYPE_STREAM)) #define NICE_STREAM_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), NICE_TYPE_STREAM, NiceStreamClass)) struct _NiceStream { /*< private >*/ GObject parent; gchar *name; guint id; guint n_components; gboolean initial_binding_request_received; GSList *components; /* list of 'NiceComponent' objects */ GSList *conncheck_list; /* list of CandidateCheckPair items */ gchar local_ufrag[NICE_STREAM_MAX_UFRAG]; gchar local_password[NICE_STREAM_MAX_PWD]; gchar remote_ufrag[NICE_STREAM_MAX_UFRAG]; gchar remote_password[NICE_STREAM_MAX_PWD]; gboolean gathering; gboolean gathering_started; gint tos; guint tick_counter; }; typedef struct { GObjectClass parent_class; } NiceStreamClass; GType nice_stream_get_type (void); NiceStream * nice_stream_new (guint n_components, NiceAgent *agent); void nice_stream_close (NiceStream *stream); gboolean nice_stream_all_components_ready (NiceStream *stream); NiceComponent * nice_stream_find_component_by_id (NiceStream *stream, guint id); void nice_stream_initialize_credentials (NiceStream *stream, NiceRNG *rng); void nice_stream_restart (NiceStream *stream, NiceAgent *agent); G_END_DECLS #endif /* _NICE_STREAM_H */ libnice-0.1.14/agent/agent.c0000664000076400007640000057021013070507156012506 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2010, 2013 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2010 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #else #define NICEAPI_EXPORT #endif #include #include #include #include #ifndef G_OS_WIN32 #include #include #include #endif #include "debug.h" #include "socket.h" #include "stun/usages/turn.h" #include "candidate.h" #include "component.h" #include "conncheck.h" #include "discovery.h" #include "agent.h" #include "agent-priv.h" #include "iostream.h" #include "stream.h" #include "interfaces.h" #include "pseudotcp.h" /* Maximum size of a UDP packet’s payload, as the packet’s length field is 16b * wide. */ #define MAX_BUFFER_SIZE ((1 << 16) - 1) /* 65535 */ #define DEFAULT_STUN_PORT 3478 #define DEFAULT_UPNP_TIMEOUT 200 /* milliseconds */ #define MAX_TCP_MTU 1400 /* Use 1400 because of VPNs and we assume IEE 802.3 */ static void nice_debug_input_message_composition (const NiceInputMessage *messages, guint n_messages); static const gchar *_cand_type_to_sdp (NiceCandidateType type); G_DEFINE_TYPE (NiceAgent, nice_agent, G_TYPE_OBJECT); enum { PROP_COMPATIBILITY = 1, PROP_MAIN_CONTEXT, PROP_STUN_SERVER, PROP_STUN_SERVER_PORT, PROP_CONTROLLING_MODE, PROP_FULL_MODE, PROP_STUN_PACING_TIMER, PROP_MAX_CONNECTIVITY_CHECKS, PROP_PROXY_TYPE, PROP_PROXY_IP, PROP_PROXY_PORT, PROP_PROXY_USERNAME, PROP_PROXY_PASSWORD, PROP_UPNP, PROP_UPNP_TIMEOUT, PROP_RELIABLE, PROP_ICE_UDP, PROP_ICE_TCP, PROP_BYTESTREAM_TCP, PROP_KEEPALIVE_CONNCHECK, PROP_FORCE_RELAY, }; enum { SIGNAL_COMPONENT_STATE_CHANGED, SIGNAL_CANDIDATE_GATHERING_DONE, SIGNAL_NEW_SELECTED_PAIR, SIGNAL_NEW_CANDIDATE, SIGNAL_NEW_REMOTE_CANDIDATE, SIGNAL_INITIAL_BINDING_REQUEST_RECEIVED, SIGNAL_RELIABLE_TRANSPORT_WRITABLE, SIGNAL_STREAMS_REMOVED, SIGNAL_NEW_SELECTED_PAIR_FULL, SIGNAL_NEW_CANDIDATE_FULL, SIGNAL_NEW_REMOTE_CANDIDATE_FULL, N_SIGNALS, }; static guint signals[N_SIGNALS]; static GMutex agent_mutex; /* Mutex used for thread-safe lib */ static void priv_stop_upnp (NiceAgent *agent); static void pseudo_tcp_socket_opened (PseudoTcpSocket *sock, gpointer user_data); static void pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data); static void pseudo_tcp_socket_writable (PseudoTcpSocket *sock, gpointer user_data); static void pseudo_tcp_socket_closed (PseudoTcpSocket *sock, guint32 err, gpointer user_data); static PseudoTcpWriteResult pseudo_tcp_socket_write_packet (PseudoTcpSocket *sock, const gchar *buffer, guint32 len, gpointer user_data); static void adjust_tcp_clock (NiceAgent *agent, NiceStream *stream, NiceComponent *component); static void nice_agent_dispose (GObject *object); static void nice_agent_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void nice_agent_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); void agent_lock (void) { g_mutex_lock (&agent_mutex); } void agent_unlock (void) { g_mutex_unlock (&agent_mutex); } static GType _nice_agent_stream_ids_get_type (void); G_DEFINE_POINTER_TYPE (_NiceAgentStreamIds, _nice_agent_stream_ids); #define NICE_TYPE_AGENT_STREAM_IDS _nice_agent_stream_ids_get_type () typedef struct { guint signal_id; GSignalQuery query; GValue *params; } QueuedSignal; static void free_queued_signal (QueuedSignal *sig) { guint i; g_value_unset (&sig->params[0]); for (i = 0; i < sig->query.n_params; i++) { if (G_VALUE_HOLDS(&sig->params[i + 1], NICE_TYPE_AGENT_STREAM_IDS)) g_free (g_value_get_pointer (&sig->params[i + 1])); g_value_unset (&sig->params[i + 1]); } g_slice_free1 (sizeof(GValue) * (sig->query.n_params + 1), sig->params); g_slice_free (QueuedSignal, sig); } void agent_unlock_and_emit (NiceAgent *agent) { GQueue queue = G_QUEUE_INIT; QueuedSignal *sig; queue = agent->pending_signals; g_queue_init (&agent->pending_signals); agent_unlock (); while ((sig = g_queue_pop_head (&queue))) { g_signal_emitv (sig->params, sig->signal_id, 0, NULL); free_queued_signal (sig); } } static void agent_queue_signal (NiceAgent *agent, guint signal_id, ...) { QueuedSignal *sig; guint i; gchar *error = NULL; va_list var_args; sig = g_slice_new (QueuedSignal); g_signal_query (signal_id, &sig->query); sig->signal_id = signal_id; sig->params = g_slice_alloc0 (sizeof(GValue) * (sig->query.n_params + 1)); g_value_init (&sig->params[0], G_TYPE_OBJECT); g_value_set_object (&sig->params[0], agent); va_start (var_args, signal_id); for (i = 0; i < sig->query.n_params; i++) { G_VALUE_COLLECT_INIT (&sig->params[i + 1], sig->query.param_types[i], var_args, 0, &error); if (error) break; } va_end (var_args); if (error) { free_queued_signal (sig); g_critical ("Error collecting values for signal: %s", error); g_free (error); return; } g_queue_push_tail (&agent->pending_signals, sig); } StunUsageIceCompatibility agent_to_ice_compatibility (NiceAgent *agent) { return agent->compatibility == NICE_COMPATIBILITY_GOOGLE ? STUN_USAGE_ICE_COMPATIBILITY_GOOGLE : agent->compatibility == NICE_COMPATIBILITY_MSN ? STUN_USAGE_ICE_COMPATIBILITY_MSN : agent->compatibility == NICE_COMPATIBILITY_WLM2009 ? STUN_USAGE_ICE_COMPATIBILITY_MSICE2 : agent->compatibility == NICE_COMPATIBILITY_OC2007 ? STUN_USAGE_ICE_COMPATIBILITY_MSN : agent->compatibility == NICE_COMPATIBILITY_OC2007R2 ? STUN_USAGE_ICE_COMPATIBILITY_MSICE2 : STUN_USAGE_ICE_COMPATIBILITY_RFC5245; } StunUsageTurnCompatibility agent_to_turn_compatibility (NiceAgent *agent) { return agent->compatibility == NICE_COMPATIBILITY_GOOGLE ? STUN_USAGE_TURN_COMPATIBILITY_GOOGLE : agent->compatibility == NICE_COMPATIBILITY_MSN ? STUN_USAGE_TURN_COMPATIBILITY_MSN : agent->compatibility == NICE_COMPATIBILITY_WLM2009 ? STUN_USAGE_TURN_COMPATIBILITY_MSN : agent->compatibility == NICE_COMPATIBILITY_OC2007 ? STUN_USAGE_TURN_COMPATIBILITY_OC2007 : agent->compatibility == NICE_COMPATIBILITY_OC2007R2 ? STUN_USAGE_TURN_COMPATIBILITY_OC2007 : STUN_USAGE_TURN_COMPATIBILITY_RFC5766; } NiceTurnSocketCompatibility agent_to_turn_socket_compatibility (NiceAgent *agent) { return agent->compatibility == NICE_COMPATIBILITY_GOOGLE ? NICE_TURN_SOCKET_COMPATIBILITY_GOOGLE : agent->compatibility == NICE_COMPATIBILITY_MSN ? NICE_TURN_SOCKET_COMPATIBILITY_MSN : agent->compatibility == NICE_COMPATIBILITY_WLM2009 ? NICE_TURN_SOCKET_COMPATIBILITY_MSN : agent->compatibility == NICE_COMPATIBILITY_OC2007 ? NICE_TURN_SOCKET_COMPATIBILITY_OC2007 : agent->compatibility == NICE_COMPATIBILITY_OC2007R2 ? NICE_TURN_SOCKET_COMPATIBILITY_OC2007 : NICE_TURN_SOCKET_COMPATIBILITY_RFC5766; } NiceStream *agent_find_stream (NiceAgent *agent, guint stream_id) { GSList *i; for (i = agent->streams; i; i = i->next) { NiceStream *s = i->data; if (s->id == stream_id) return s; } return NULL; } gboolean agent_find_component ( NiceAgent *agent, guint stream_id, guint component_id, NiceStream **stream, NiceComponent **component) { NiceStream *s; NiceComponent *c; s = agent_find_stream (agent, stream_id); if (s == NULL) return FALSE; c = nice_stream_find_component_by_id (s, component_id); if (c == NULL) return FALSE; if (stream) *stream = s; if (component) *component = c; return TRUE; } static void nice_agent_class_init (NiceAgentClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->get_property = nice_agent_get_property; gobject_class->set_property = nice_agent_set_property; gobject_class->dispose = nice_agent_dispose; /* install properties */ /** * NiceAgent:main-context: * * A GLib main context is needed for all timeouts used by libnice. * This is a property being set by the nice_agent_new() call. */ g_object_class_install_property (gobject_class, PROP_MAIN_CONTEXT, g_param_spec_pointer ( "main-context", "The GMainContext to use for timeouts", "The GMainContext to use for timeouts", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * NiceAgent:compatibility: * * The Nice agent can work in various compatibility modes depending on * what the application/peer needs. * See also: #NiceCompatibility */ g_object_class_install_property (gobject_class, PROP_COMPATIBILITY, g_param_spec_uint ( "compatibility", "ICE specification compatibility", "The compatibility mode for the agent", NICE_COMPATIBILITY_RFC5245, NICE_COMPATIBILITY_LAST, NICE_COMPATIBILITY_RFC5245, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_STUN_SERVER, g_param_spec_string ( "stun-server", "STUN server IP address", "The IP address (not the hostname) of the STUN server to use", NULL, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_STUN_SERVER_PORT, g_param_spec_uint ( "stun-server-port", "STUN server port", "Port of the STUN server used to gather server-reflexive candidates", 1, 65536, 1, /* not a construct property, ignored */ G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_CONTROLLING_MODE, g_param_spec_boolean ( "controlling-mode", "ICE controlling mode", "Whether the agent is in controlling mode", FALSE, /* not a construct property, ignored */ G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_FULL_MODE, g_param_spec_boolean ( "full-mode", "ICE full mode", "Whether agent runs in ICE full mode", TRUE, /* use full mode by default */ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_STUN_PACING_TIMER, g_param_spec_uint ( "stun-pacing-timer", "STUN pacing timer", "Timer 'Ta' (msecs) used in the IETF ICE specification for pacing " "candidate gathering and sending of connectivity checks", 1, 0xffffffff, NICE_AGENT_TIMER_TA_DEFAULT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); /* note: according to spec recommendation in sect 5.7.3 (ID-19) */ g_object_class_install_property (gobject_class, PROP_MAX_CONNECTIVITY_CHECKS, g_param_spec_uint ( "max-connectivity-checks", "Maximum number of connectivity checks", "Upper limit for the total number of connectivity checks performed", 0, 0xffffffff, 0, /* default set in init */ G_PARAM_READWRITE)); /** * NiceAgent:proxy-ip: * * The proxy server IP used to bypass a proxy firewall * * Since: 0.0.4 */ g_object_class_install_property (gobject_class, PROP_PROXY_IP, g_param_spec_string ( "proxy-ip", "Proxy server IP", "The proxy server IP used to bypass a proxy firewall", NULL, G_PARAM_READWRITE)); /** * NiceAgent:proxy-port: * * The proxy server port used to bypass a proxy firewall * * Since: 0.0.4 */ g_object_class_install_property (gobject_class, PROP_PROXY_PORT, g_param_spec_uint ( "proxy-port", "Proxy server port", "The Proxy server port used to bypass a proxy firewall", 1, 65536, 1, G_PARAM_READWRITE)); /** * NiceAgent:proxy-type: * * The type of proxy set in the proxy-ip property * * Since: 0.0.4 */ g_object_class_install_property (gobject_class, PROP_PROXY_TYPE, g_param_spec_uint ( "proxy-type", "Type of proxy to use", "The type of proxy set in the proxy-ip property", NICE_PROXY_TYPE_NONE, NICE_PROXY_TYPE_LAST, NICE_PROXY_TYPE_NONE, G_PARAM_READWRITE)); /** * NiceAgent:proxy-username: * * The username used to authenticate with the proxy * * Since: 0.0.4 */ g_object_class_install_property (gobject_class, PROP_PROXY_USERNAME, g_param_spec_string ( "proxy-username", "Proxy server username", "The username used to authenticate with the proxy", NULL, G_PARAM_READWRITE)); /** * NiceAgent:proxy-password: * * The password used to authenticate with the proxy * * Since: 0.0.4 */ g_object_class_install_property (gobject_class, PROP_PROXY_PASSWORD, g_param_spec_string ( "proxy-password", "Proxy server password", "The password used to authenticate with the proxy", NULL, G_PARAM_READWRITE)); /** * NiceAgent:upnp: * * Whether the agent should use UPnP to open a port in the router and * get the external IP * * Since: 0.0.7 */ g_object_class_install_property (gobject_class, PROP_UPNP, g_param_spec_boolean ( "upnp", #ifdef HAVE_GUPNP "Use UPnP", "Whether the agent should use UPnP to open a port in the router and " "get the external IP", #else "Use UPnP (disabled in build)", "Does nothing because libnice was not built with UPnP support", #endif TRUE, /* enable UPnP by default */ G_PARAM_READWRITE| G_PARAM_CONSTRUCT)); /** * NiceAgent:upnp-timeout: * * The maximum amount of time (in milliseconds) to wait for UPnP discovery to * finish before signaling the #NiceAgent::candidate-gathering-done signal * * Since: 0.0.7 */ g_object_class_install_property (gobject_class, PROP_UPNP_TIMEOUT, g_param_spec_uint ( "upnp-timeout", #ifdef HAVE_GUPNP "Timeout for UPnP discovery", "The maximum amount of time to wait for UPnP discovery to finish before " "signaling the candidate-gathering-done signal", #else "Timeout for UPnP discovery (disabled in build)", "Does nothing because libnice was not built with UPnP support", #endif 100, 60000, DEFAULT_UPNP_TIMEOUT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); /** * NiceAgent:reliable: * * Whether the agent is providing a reliable transport of messages (through * ICE-TCP or PseudoTCP over ICE-UDP) * * Since: 0.0.11 */ g_object_class_install_property (gobject_class, PROP_RELIABLE, g_param_spec_boolean ( "reliable", "reliable mode", "Whether the agent provides a reliable transport of messages", FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * NiceAgent:ice-udp: * * Whether the agent should use ICE-UDP when gathering candidates. * If the option is disabled, no UDP candidates will be generated. If the * agent is in reliable mode, then pseudotcp will not be used since pseudotcp * works on top of UDP candidates. * * This option should be set before gathering candidates and should not be * modified afterwards. * * The #NiceAgent:ice-udp property can be set at the same time as the * #NiceAgent:ice-tcp property, but both cannot be unset at the same time. * If #NiceAgent:ice-tcp is set to %FALSE, then this property cannot be set * to %FALSE as well. * * Since: 0.1.8 */ g_object_class_install_property (gobject_class, PROP_ICE_UDP, g_param_spec_boolean ( "ice-udp", "Use ICE-UDP", "Use ICE-UDP specification to generate UDP candidates", TRUE, /* use ice-udp by default */ G_PARAM_READWRITE)); /** * NiceAgent:ice-tcp: * * Whether the agent should use ICE-TCP when gathering candidates. * If the option is disabled, no TCP candidates will be generated. If the * agent is in reliable mode, then pseudotcp will need to be used over UDP * candidates. * * This option should be set before gathering candidates and should not be * modified afterwards. * * The #NiceAgent:ice-tcp property can be set at the same time as the * #NiceAgent:ice-udp property, but both cannot be unset at the same time. * If #NiceAgent:ice-udp is set to %FALSE, then this property cannot be set * to %FALSE as well. * ICE-TCP is only supported for %NICE_COMPATIBILITY_RFC5245, %NICE_COMPATIBILITY_OC2007 and %NICE_COMPATIBILITY_OC2007R2 compatibility modes. * * * Since: 0.1.8 */ g_object_class_install_property (gobject_class, PROP_ICE_TCP, g_param_spec_boolean ( "ice-tcp", "Use ICE-TCP", "Use ICE-TCP specification to generate TCP candidates", TRUE, /* use ice-tcp by default */ G_PARAM_READWRITE)); /** * NiceAgent:bytestream-tcp: * * This property defines whether receive/send over a TCP or pseudo-TCP, in * reliable mode, are considered as packetized or as bytestream. * In unreliable mode, every send/recv is considered as packetized, and * this property is ignored and cannot be set. * * In reliable mode, this property will always return %TRUE in the * %NICE_COMPATIBILITY_GOOGLE compatibility mode. * * If the property is %TRUE, the stream is considered in bytestream mode * and data can be read with any receive size. If the property is %FALSE, then * the stream is considred packetized and each receive will return one packet * of the same size as what was sent from the peer. If in packetized mode, * then doing a receive with a size smaller than the packet, will cause the * remaining bytes in the packet to be dropped, breaking the reliability * of the stream. * * This property is currently read-only, and will become read/write once * bytestream mode will be supported. * * * Since: 0.1.8 */ g_object_class_install_property (gobject_class, PROP_BYTESTREAM_TCP, g_param_spec_boolean ( "bytestream-tcp", "Bytestream TCP", "Use bytestream mode for reliable TCP and Pseudo-TCP connections", FALSE, G_PARAM_READABLE)); /** * NiceAgent:keepalive-conncheck: * * Use binding requests as keepalives instead of binding * indications. This means that the keepalives may time out which * will change the component state to %NICE_COMPONENT_STATE_FAILED. * * Enabing this is a slight violation of RFC 5245 section 10 which * recommends using Binding Indications for keepalives. * * This is always enabled if the compatibility mode is * %NICE_COMPATIBILITY_GOOGLE. * * Since: 0.1.8 */ g_object_class_install_property (gobject_class, PROP_KEEPALIVE_CONNCHECK, g_param_spec_boolean ( "keepalive-conncheck", "Use conncheck as keepalives", "Use binding requests which require a reply as keepalives instead of " "binding indications which don't.", FALSE, G_PARAM_READWRITE)); /** * NiceAgent:force-relay * * Force all traffic to go through a relay for added privacy, this * allows hiding the local IP address. When this is enabled, so * local candidates are available before relay servers have been set * with nice_agent_set_relay_info(). * * Since: 0.1.14 */ g_object_class_install_property (gobject_class, PROP_FORCE_RELAY, g_param_spec_boolean ( "force-relay", "Force Relay", "Force all traffic to go through a relay for added privacy.", FALSE, G_PARAM_READWRITE)); /* install signals */ /** * NiceAgent::component-state-changed * @agent: The #NiceAgent object * @stream_id: The ID of the stream * @component_id: The ID of the component * @state: The new #NiceComponentState of the component * * This signal is fired whenever a component’s state changes. There are many * valid state transitions. * * ![State transition diagram](states.png) */ signals[SIGNAL_COMPONENT_STATE_CHANGED] = g_signal_new ( "component-state-changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); /** * NiceAgent::candidate-gathering-done: * @agent: The #NiceAgent object * @stream_id: The ID of the stream * * This signal is fired whenever a stream has finished gathering its * candidates after a call to nice_agent_gather_candidates() */ signals[SIGNAL_CANDIDATE_GATHERING_DONE] = g_signal_new ( "candidate-gathering-done", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT, G_TYPE_INVALID); /** * NiceAgent::new-selected-pair * @agent: The #NiceAgent object * @stream_id: The ID of the stream * @component_id: The ID of the component * @lfoundation: The local foundation of the selected candidate pair * @rfoundation: The remote foundation of the selected candidate pair * * This signal is fired once a candidate pair is selected for data * transfer for a stream's component This is emitted along with * #NiceAgent::new-selected-pair-full which has the whole candidate, * the Foundation of a Candidate is not a unique identifier. * * See also: #NiceAgent::new-selected-pair-full * Deprecated: 0.1.8: Use #NiceAgent::new-selected-pair-full */ signals[SIGNAL_NEW_SELECTED_PAIR] = g_signal_new ( "new-selected-pair", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); /** * NiceAgent::new-candidate * @agent: The #NiceAgent object * @stream_id: The ID of the stream * @component_id: The ID of the component * @foundation: The foundation of the new candidate * * This signal is fired when the agent discovers a new local candidate. * When this signal is emitted, a matching #NiceAgent::new-candidate-full is * also emitted with the candidate. * * See also: #NiceAgent::candidate-gathering-done, * #NiceAgent::new-candidate-full * Deprecated: 0.1.8: Use #NiceAgent::new-candidate-full */ signals[SIGNAL_NEW_CANDIDATE] = g_signal_new ( "new-candidate", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); /** * NiceAgent::new-remote-candidate * @agent: The #NiceAgent object * @stream_id: The ID of the stream * @component_id: The ID of the component * @foundation: The foundation of the new candidate * * This signal is fired when the agent discovers a new remote * candidate. This can happen with peer reflexive candidates. When * this signal is emitted, a matching * #NiceAgent::new-remote-candidate-full is also emitted with the * candidate. * * See also: #NiceAgent::new-remote-candidate-full * Deprecated: 0.1.8: Use #NiceAgent::new-remote-candidate-full */ signals[SIGNAL_NEW_REMOTE_CANDIDATE] = g_signal_new ( "new-remote-candidate", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); /** * NiceAgent::initial-binding-request-received * @agent: The #NiceAgent object * @stream_id: The ID of the stream * * This signal is fired when we received our first binding request from * the peer. */ signals[SIGNAL_INITIAL_BINDING_REQUEST_RECEIVED] = g_signal_new ( "initial-binding-request-received", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT, G_TYPE_INVALID); /** * NiceAgent::reliable-transport-writable * @agent: The #NiceAgent object * @stream_id: The ID of the stream * @component_id: The ID of the component * * This signal is fired on the reliable #NiceAgent when the underlying reliable * transport becomes writable. * This signal is only emitted when the nice_agent_send() function returns less * bytes than requested to send (or -1) and once when the connection * is established. * * Since: 0.0.11 */ signals[SIGNAL_RELIABLE_TRANSPORT_WRITABLE] = g_signal_new ( "reliable-transport-writable", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); /** * NiceAgent::streams-removed * @agent: The #NiceAgent object * @stream_ids: (array zero-terminated=1) (element-type uint): An array of * unsigned integer stream IDs, ending with a 0 ID * * This signal is fired whenever one or more streams are removed from the * @agent. * * Since: 0.1.5 */ signals[SIGNAL_STREAMS_REMOVED] = g_signal_new ( "streams-removed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, NICE_TYPE_AGENT_STREAM_IDS, G_TYPE_INVALID); /** * NiceAgent::new-selected-pair-full * @agent: The #NiceAgent object * @stream_id: The ID of the stream * @component_id: The ID of the component * @lcandidate: The local #NiceCandidate of the selected candidate pair * @rcandidate: The remote #NiceCandidate of the selected candidate pair * * This signal is fired once a candidate pair is selected for data * transfer for a stream's component. This is emitted along with * #NiceAgent::new-selected-pair. * * See also: #NiceAgent::new-selected-pair * Since: 0.1.8 */ signals[SIGNAL_NEW_SELECTED_PAIR_FULL] = g_signal_new ( "new-selected-pair-full", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_UINT, NICE_TYPE_CANDIDATE, NICE_TYPE_CANDIDATE, G_TYPE_INVALID); /** * NiceAgent::new-candidate-full * @agent: The #NiceAgent object * @candidate: The new #NiceCandidate * * This signal is fired when the agent discovers a new local candidate. * When this signal is emitted, a matching #NiceAgent::new-candidate is * also emitted with the candidate's foundation. * * See also: #NiceAgent::candidate-gathering-done, * #NiceAgent::new-candidate * Since: 0.1.8 */ signals[SIGNAL_NEW_CANDIDATE_FULL] = g_signal_new ( "new-candidate-full", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, NICE_TYPE_CANDIDATE, G_TYPE_INVALID); /** * NiceAgent::new-remote-candidate-full * @agent: The #NiceAgent object * @candidate: The new #NiceCandidate * * This signal is fired when the agent discovers a new remote candidate. * This can happen with peer reflexive candidates. * When this signal is emitted, a matching #NiceAgent::new-remote-candidate is * also emitted with the candidate's foundation. * * See also: #NiceAgent::new-remote-candidate * Since: 0.1.8 */ signals[SIGNAL_NEW_REMOTE_CANDIDATE_FULL] = g_signal_new ( "new-remote-candidate-full", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, NICE_TYPE_CANDIDATE, G_TYPE_INVALID); /* Init debug options depending on env variables */ nice_debug_init (); } static void priv_generate_tie_breaker (NiceAgent *agent) { nice_rng_generate_bytes (agent->rng, 8, (gchar*)&agent->tie_breaker); } static void nice_agent_init (NiceAgent *agent) { agent->next_candidate_id = 1; agent->next_stream_id = 1; /* set defaults; not construct params, so set here */ agent->stun_server_port = DEFAULT_STUN_PORT; agent->controlling_mode = TRUE; agent->max_conn_checks = NICE_AGENT_MAX_CONNECTIVITY_CHECKS_DEFAULT; agent->discovery_list = NULL; agent->discovery_unsched_items = 0; agent->discovery_timer_source = NULL; agent->conncheck_timer_source = NULL; agent->keepalive_timer_source = NULL; agent->refresh_list = NULL; agent->media_after_tick = FALSE; agent->software_attribute = NULL; agent->compatibility = NICE_COMPATIBILITY_RFC5245; agent->reliable = FALSE; agent->use_ice_udp = TRUE; agent->use_ice_tcp = TRUE; agent->rng = nice_rng_new (); priv_generate_tie_breaker (agent); g_queue_init (&agent->pending_signals); } NICEAPI_EXPORT NiceAgent * nice_agent_new (GMainContext *ctx, NiceCompatibility compat) { NiceAgent *agent = g_object_new (NICE_TYPE_AGENT, "compatibility", compat, "main-context", ctx, "reliable", FALSE, NULL); return agent; } NICEAPI_EXPORT NiceAgent * nice_agent_new_reliable (GMainContext *ctx, NiceCompatibility compat) { NiceAgent *agent = g_object_new (NICE_TYPE_AGENT, "compatibility", compat, "main-context", ctx, "reliable", TRUE, NULL); return agent; } static void nice_agent_get_property ( GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { NiceAgent *agent = NICE_AGENT (object); agent_lock(); switch (property_id) { case PROP_MAIN_CONTEXT: g_value_set_pointer (value, agent->main_context); break; case PROP_COMPATIBILITY: g_value_set_uint (value, agent->compatibility); break; case PROP_STUN_SERVER: g_value_set_string (value, agent->stun_server_ip); break; case PROP_STUN_SERVER_PORT: g_value_set_uint (value, agent->stun_server_port); break; case PROP_CONTROLLING_MODE: g_value_set_boolean (value, agent->controlling_mode); break; case PROP_FULL_MODE: g_value_set_boolean (value, agent->full_mode); break; case PROP_STUN_PACING_TIMER: g_value_set_uint (value, agent->timer_ta); break; case PROP_MAX_CONNECTIVITY_CHECKS: g_value_set_uint (value, agent->max_conn_checks); /* XXX: should we prune the list of already existing checks? */ break; case PROP_PROXY_IP: g_value_set_string (value, agent->proxy_ip); break; case PROP_PROXY_PORT: g_value_set_uint (value, agent->proxy_port); break; case PROP_PROXY_TYPE: g_value_set_uint (value, agent->proxy_type); break; case PROP_PROXY_USERNAME: g_value_set_string (value, agent->proxy_username); break; case PROP_PROXY_PASSWORD: g_value_set_string (value, agent->proxy_password); break; case PROP_UPNP: #ifdef HAVE_GUPNP g_value_set_boolean (value, agent->upnp_enabled); #else g_value_set_boolean (value, FALSE); #endif break; case PROP_UPNP_TIMEOUT: #ifdef HAVE_GUPNP g_value_set_uint (value, agent->upnp_timeout); #else g_value_set_uint (value, DEFAULT_UPNP_TIMEOUT); #endif break; case PROP_RELIABLE: g_value_set_boolean (value, agent->reliable); break; case PROP_ICE_UDP: g_value_set_boolean (value, agent->use_ice_udp); break; case PROP_ICE_TCP: g_value_set_boolean (value, agent->use_ice_tcp); break; case PROP_BYTESTREAM_TCP: if (agent->reliable) { if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) g_value_set_boolean (value, TRUE); else g_value_set_boolean (value, FALSE); } else { g_value_set_boolean (value, FALSE); } break; case PROP_KEEPALIVE_CONNCHECK: if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) g_value_set_boolean (value, TRUE); else g_value_set_boolean (value, agent->keepalive_conncheck); break; case PROP_FORCE_RELAY: g_value_set_boolean (value, agent->force_relay); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } agent_unlock_and_emit(agent); } void nice_agent_init_stun_agent (NiceAgent *agent, StunAgent *stun_agent) { if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_IGNORE_CREDENTIALS); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN) { stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_FORCE_VALIDATER); } else if (agent->compatibility == NICE_COMPATIBILITY_WLM2009) { stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_MSICE2, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_USE_FINGERPRINT); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007) { stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_FORCE_VALIDATER | STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_MSICE2, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_USE_FINGERPRINT | STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES); } else { stun_agent_init (stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_USE_FINGERPRINT); } stun_agent_set_software (stun_agent, agent->software_attribute); } static void nice_agent_reset_all_stun_agents (NiceAgent *agent, gboolean only_software) { GSList *stream_item, *component_item; for (stream_item = agent->streams; stream_item; stream_item = stream_item->next) { NiceStream *stream = stream_item->data; for (component_item = stream->components; component_item; component_item = component_item->next) { NiceComponent *component = component_item->data; if (only_software) stun_agent_set_software (&component->stun_agent, agent->software_attribute); else nice_agent_init_stun_agent(agent, &component->stun_agent); } } } static void nice_agent_set_property ( GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { NiceAgent *agent = NICE_AGENT (object); agent_lock(); switch (property_id) { case PROP_MAIN_CONTEXT: agent->main_context = g_value_get_pointer (value); if (agent->main_context != NULL) g_main_context_ref (agent->main_context); break; case PROP_COMPATIBILITY: agent->compatibility = g_value_get_uint (value); if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE || agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_WLM2009) agent->use_ice_tcp = FALSE; nice_agent_reset_all_stun_agents (agent, FALSE); break; case PROP_STUN_SERVER: g_free (agent->stun_server_ip); agent->stun_server_ip = g_value_dup_string (value); break; case PROP_STUN_SERVER_PORT: agent->stun_server_port = g_value_get_uint (value); break; case PROP_CONTROLLING_MODE: agent->controlling_mode = g_value_get_boolean (value); break; case PROP_FULL_MODE: agent->full_mode = g_value_get_boolean (value); break; case PROP_STUN_PACING_TIMER: agent->timer_ta = g_value_get_uint (value); break; case PROP_MAX_CONNECTIVITY_CHECKS: agent->max_conn_checks = g_value_get_uint (value); break; case PROP_PROXY_IP: g_free (agent->proxy_ip); agent->proxy_ip = g_value_dup_string (value); break; case PROP_PROXY_PORT: agent->proxy_port = g_value_get_uint (value); break; case PROP_PROXY_TYPE: agent->proxy_type = g_value_get_uint (value); break; case PROP_PROXY_USERNAME: g_free (agent->proxy_username); agent->proxy_username = g_value_dup_string (value); break; case PROP_PROXY_PASSWORD: g_free (agent->proxy_password); agent->proxy_password = g_value_dup_string (value); break; case PROP_UPNP_TIMEOUT: #ifdef HAVE_GUPNP agent->upnp_timeout = g_value_get_uint (value); #endif break; case PROP_UPNP: #ifdef HAVE_GUPNP agent->upnp_enabled = g_value_get_boolean (value); #endif break; case PROP_RELIABLE: agent->reliable = g_value_get_boolean (value); break; /* Don't allow ice-udp and ice-tcp to be disabled at the same time */ case PROP_ICE_UDP: if (agent->use_ice_tcp == TRUE || g_value_get_boolean (value) == TRUE) agent->use_ice_udp = g_value_get_boolean (value); break; case PROP_ICE_TCP: if ((agent->compatibility == NICE_COMPATIBILITY_RFC5245 || agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && (agent->use_ice_udp == TRUE || g_value_get_boolean (value) == TRUE)) agent->use_ice_tcp = g_value_get_boolean (value); break; case PROP_BYTESTREAM_TCP: /* TODO: support bytestream mode and set property to writable */ break; case PROP_KEEPALIVE_CONNCHECK: agent->keepalive_conncheck = g_value_get_boolean (value); break; case PROP_FORCE_RELAY: agent->force_relay = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } agent_unlock_and_emit (agent); } static void agent_signal_socket_writable (NiceAgent *agent, NiceComponent *component) { g_cancellable_cancel (component->tcp_writable_cancellable); agent_queue_signal (agent, signals[SIGNAL_RELIABLE_TRANSPORT_WRITABLE], component->stream->id, component->id); } static void pseudo_tcp_socket_create (NiceAgent *agent, NiceStream *stream, NiceComponent *component) { PseudoTcpCallbacks tcp_callbacks = {component, pseudo_tcp_socket_opened, pseudo_tcp_socket_readable, pseudo_tcp_socket_writable, pseudo_tcp_socket_closed, pseudo_tcp_socket_write_packet}; component->tcp = pseudo_tcp_socket_new (0, &tcp_callbacks); component->tcp_writable_cancellable = g_cancellable_new (); nice_debug ("Agent %p: Create Pseudo Tcp Socket for component %d", agent, component->id); } static void priv_pseudo_tcp_error (NiceAgent *agent, NiceStream *stream, NiceComponent *component) { if (component->tcp_writable_cancellable) { g_cancellable_cancel (component->tcp_writable_cancellable); g_clear_object (&component->tcp_writable_cancellable); } if (component->tcp) { agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_FAILED); nice_component_detach_all_sockets (component); pseudo_tcp_socket_close (component->tcp, TRUE); } if (component->tcp_clock) { g_source_destroy (component->tcp_clock); g_source_unref (component->tcp_clock); component->tcp_clock = NULL; } } static void pseudo_tcp_socket_opened (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; NiceStream *stream = component->stream; nice_debug ("Agent %p: s%d:%d pseudo Tcp socket Opened", agent, stream->id, component->id); agent_signal_socket_writable (agent, component); } /* Will attempt to queue all @n_messages into the pseudo-TCP transmission * buffer. This is always used in reliable mode, so essentially treats @messages * as a massive flat array of buffers. * * Returns the number of messages successfully sent on success (which may be * zero if sending the first buffer of the message would have blocked), or * a negative number on error. If "allow_partial" is TRUE, then it returns * the number of bytes sent */ static gint pseudo_tcp_socket_send_messages (PseudoTcpSocket *self, const NiceOutputMessage *messages, guint n_messages, gboolean allow_partial, GError **error) { guint i; gint bytes_sent = 0; for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; guint j; /* If allow_partial is FALSE and there’s not enough space for the * entire message, bail now before queuing anything. This doesn’t * gel with the fact this function is only used in reliable mode, * and there is no concept of a ‘message’, but is necessary * because the calling API has no way of returning to the client * and indicating that a message was partially sent. */ if (!allow_partial && output_message_get_size (message) > pseudo_tcp_socket_get_available_send_space (self)) { return i; } for (j = 0; (message->n_buffers >= 0 && j < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[j].buffer != NULL); j++) { const GOutputVector *buffer = &message->buffers[j]; gssize ret; /* Send on the pseudo-TCP socket. */ ret = pseudo_tcp_socket_send (self, buffer->buffer, buffer->size); /* In case of -1, the error is either EWOULDBLOCK or ENOTCONN, which both * need the user to wait for the reliable-transport-writable signal */ if (ret < 0) { if (pseudo_tcp_socket_get_error (self) == EWOULDBLOCK) goto out; if (pseudo_tcp_socket_get_error (self) == ENOTCONN || pseudo_tcp_socket_get_error (self) == EPIPE) g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "TCP connection is not yet established."); else g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Error writing data to pseudo-TCP socket."); return -1; } else { bytes_sent += ret; } } } out: return allow_partial ? bytes_sent : (gint) i; } /* Will fill up @messages from the first free byte onwards (as determined using * @iter). This is always used in reliable mode, so it essentially treats * @messages as a massive flat array of buffers. * * Updates @iter in place. @iter and @messages are left in invalid states if * an error is returned. * * Returns the number of valid messages in @messages on success (which may be * zero if no data is pending and the peer has disconnected), or a negative * number on error (including if the request would have blocked returning no * messages). */ static gint pseudo_tcp_socket_recv_messages (PseudoTcpSocket *self, NiceInputMessage *messages, guint n_messages, NiceInputMessageIter *iter, GError **error) { for (; iter->message < n_messages; iter->message++) { NiceInputMessage *message = &messages[iter->message]; if (iter->buffer == 0 && iter->offset == 0) { message->length = 0; } for (; (message->n_buffers >= 0 && iter->buffer < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[iter->buffer].buffer != NULL); iter->buffer++) { GInputVector *buffer = &message->buffers[iter->buffer]; do { gssize len; len = pseudo_tcp_socket_recv (self, (gchar *) buffer->buffer + iter->offset, buffer->size - iter->offset); nice_debug_verbose ("%s: Received %" G_GSSIZE_FORMAT " bytes into " "buffer %p (offset %" G_GSIZE_FORMAT ", length %" G_GSIZE_FORMAT ").", G_STRFUNC, len, buffer->buffer, iter->offset, buffer->size); if (len == 0) { /* Reached EOS. */ len = 0; goto done; } else if (len < 0 && pseudo_tcp_socket_get_error (self) == EWOULDBLOCK) { /* EWOULDBLOCK. If we’ve already received something, return that; * otherwise, error. */ if (nice_input_message_iter_get_n_valid_messages (iter) > 0) { goto done; } g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "Error reading data from pseudo-TCP socket: would block."); return len; } else if (len < 0 && pseudo_tcp_socket_get_error (self) == ENOTCONN) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "Error reading data from pseudo-TCP socket: not connected."); return len; } else if (len < 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Error reading data from pseudo-TCP socket."); return len; } else { /* Got some data! */ message->length += len; iter->offset += len; } } while (iter->offset < buffer->size); iter->offset = 0; } iter->buffer = 0; } done: return nice_input_message_iter_get_n_valid_messages (iter); } /* This is called with the agent lock held. */ static void pseudo_tcp_socket_readable (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; NiceStream *stream = component->stream; gboolean has_io_callback; guint stream_id = stream->id; guint component_id = component->id; g_object_ref (agent); nice_debug_verbose ("Agent %p: s%d:%d pseudo Tcp socket readable", agent, stream->id, component->id); component->tcp_readable = TRUE; has_io_callback = nice_component_has_io_callback (component); /* Only dequeue pseudo-TCP data if we can reliably inform the client. The * agent lock is held here, so has_io_callback can only change during * nice_component_emit_io_callback(), after which it’s re-queried. This ensures * no data loss of packets already received and dequeued. */ if (has_io_callback) { do { guint8 buf[MAX_BUFFER_SIZE]; gssize len; /* FIXME: Why copy into a temporary buffer here? Why can’t the I/O * callbacks be emitted directly from the pseudo-TCP receive buffer? */ len = pseudo_tcp_socket_recv (sock, (gchar *) buf, sizeof(buf)); nice_debug ("%s: I/O callback case: Received %" G_GSSIZE_FORMAT " bytes", G_STRFUNC, len); if (len == 0) { /* Reached EOS. */ component->tcp_readable = FALSE; pseudo_tcp_socket_close (component->tcp, FALSE); break; } else if (len < 0) { /* Handle errors. */ if (pseudo_tcp_socket_get_error (sock) != EWOULDBLOCK) { nice_debug ("%s: calling priv_pseudo_tcp_error()", G_STRFUNC); priv_pseudo_tcp_error (agent, stream, component); } if (component->recv_buf_error != NULL) { GIOErrorEnum error_code; if (pseudo_tcp_socket_get_error (sock) == ENOTCONN) error_code = G_IO_ERROR_BROKEN_PIPE; else if (pseudo_tcp_socket_get_error (sock) == EWOULDBLOCK) error_code = G_IO_ERROR_WOULD_BLOCK; else error_code = G_IO_ERROR_FAILED; g_set_error (component->recv_buf_error, G_IO_ERROR, error_code, "Error reading data from pseudo-TCP socket."); } break; } nice_component_emit_io_callback (component, buf, len); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { nice_debug ("Stream or Component disappeared during the callback"); goto out; } if (pseudo_tcp_socket_is_closed (component->tcp)) { nice_debug ("PseudoTCP socket got destroyed in readable callback!"); goto out; } has_io_callback = nice_component_has_io_callback (component); } while (has_io_callback); } else if (component->recv_messages != NULL) { gint n_valid_messages; GError *child_error = NULL; /* Fill up every buffer in every message until the connection closes or an * error occurs. Copy the data directly into the client’s receive message * array without making any callbacks. Update component->recv_messages_iter * as we go. */ n_valid_messages = pseudo_tcp_socket_recv_messages (sock, component->recv_messages, component->n_recv_messages, &component->recv_messages_iter, &child_error); nice_debug_verbose ("%s: Client buffers case: Received %d valid messages:", G_STRFUNC, n_valid_messages); nice_debug_input_message_composition (component->recv_messages, component->n_recv_messages); if (n_valid_messages < 0) { g_propagate_error (component->recv_buf_error, child_error); } else { g_clear_error (&child_error); } if (n_valid_messages < 0 && g_error_matches (child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { component->tcp_readable = FALSE; } else if (n_valid_messages < 0) { nice_debug ("%s: calling priv_pseudo_tcp_error()", G_STRFUNC); priv_pseudo_tcp_error (agent, stream, component); } else if (n_valid_messages == 0) { /* Reached EOS. */ component->tcp_readable = FALSE; pseudo_tcp_socket_close (component->tcp, FALSE); } } else { nice_debug ("%s: no data read", G_STRFUNC); } if (stream && component) adjust_tcp_clock (agent, stream, component); out: g_object_unref (agent); } static void pseudo_tcp_socket_writable (PseudoTcpSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; NiceStream *stream = component->stream; nice_debug_verbose ("Agent %p: s%d:%d pseudo Tcp socket writable", agent, stream->id, component->id); agent_signal_socket_writable (agent, component); } static void pseudo_tcp_socket_closed (PseudoTcpSocket *sock, guint32 err, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; NiceStream *stream = component->stream; nice_debug ("Agent %p: s%d:%d pseudo Tcp socket closed. " "Calling priv_pseudo_tcp_error().", agent, stream->id, component->id); priv_pseudo_tcp_error (agent, stream, component); } static PseudoTcpWriteResult pseudo_tcp_socket_write_packet (PseudoTcpSocket *psocket, const gchar *buffer, guint32 len, gpointer user_data) { NiceComponent *component = user_data; if (component->selected_pair.local != NULL) { NiceSocket *sock; NiceAddress *addr; sock = component->selected_pair.local->sockptr; addr = &component->selected_pair.remote->addr; if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (addr, tmpbuf); nice_debug_verbose ( "Agent %p : s%d:%d: sending %d bytes on socket %p (FD %d) to [%s]:%d", component->agent, component->stream->id, component->id, len, sock->fileno, g_socket_get_fd (sock->fileno), tmpbuf, nice_address_get_port (addr)); } /* Send the segment. nice_socket_send() returns 0 on EWOULDBLOCK; in that * case the segment is not sent on the wire, but we return WR_SUCCESS * anyway. This effectively drops the segment. The pseudo-TCP state machine * will eventually pick up this loss and go into recovery mode, reducing * its transmission rate and, hopefully, the usage of system resources * which caused the EWOULDBLOCK in the first place. */ if (nice_socket_send (sock, addr, len, buffer) >= 0) { return WR_SUCCESS; } } else { nice_debug ("%s: WARNING: Failed to send pseudo-TCP packet from agent %p " "as no pair has been selected yet.", G_STRFUNC, component->agent); } return WR_FAIL; } static gboolean notify_pseudo_tcp_socket_clock (gpointer user_data) { NiceComponent *component = user_data; NiceStream *stream; NiceAgent *agent; agent_lock(); stream = component->stream; agent = component->agent; if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Source was destroyed. " "Avoided race condition in notify_pseudo_tcp_socket_clock"); agent_unlock (); return FALSE; } pseudo_tcp_socket_notify_clock (component->tcp); adjust_tcp_clock (agent, stream, component); agent_unlock_and_emit (agent); return G_SOURCE_CONTINUE; } static void adjust_tcp_clock (NiceAgent *agent, NiceStream *stream, NiceComponent *component) { if (!pseudo_tcp_socket_is_closed (component->tcp)) { guint64 timeout = component->last_clock_timeout; if (pseudo_tcp_socket_get_next_clock (component->tcp, &timeout)) { if (timeout != component->last_clock_timeout) { component->last_clock_timeout = timeout; if (component->tcp_clock) { g_source_set_ready_time (component->tcp_clock, timeout * 1000); } if (!component->tcp_clock) { long interval = timeout - (guint32) (g_get_monotonic_time () / 1000); /* Prevent integer overflows */ if (interval < 0 || interval > G_MAXINT) interval = G_MAXINT; agent_timeout_add_with_context (agent, &component->tcp_clock, "Pseudo-TCP clock", interval, notify_pseudo_tcp_socket_clock, component); } } } else { nice_debug ("Agent %p: component %d pseudo-TCP socket should be " "destroyed. Calling priv_pseudo_tcp_error().", agent, component->id); priv_pseudo_tcp_error (agent, stream, component); } } } void _tcp_sock_is_writable (NiceSocket *sock, gpointer user_data) { NiceComponent *component = user_data; NiceAgent *agent = component->agent; NiceStream *stream = component->stream; agent_lock (); /* Don't signal writable if the socket that has become writable is not * the selected pair */ if (component->selected_pair.local == NULL || !nice_socket_is_based_on (component->selected_pair.local->sockptr, sock)) { agent_unlock (); return; } nice_debug ("Agent %p: s%d:%d Tcp socket writable", agent, stream->id, component->id); agent_signal_socket_writable (agent, component); agent_unlock_and_emit (agent); } static const gchar * _transport_to_string (NiceCandidateTransport type) { switch(type) { case NICE_CANDIDATE_TRANSPORT_UDP: return "UDP"; case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: return "TCP-ACT"; case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: return "TCP-PASS"; case NICE_CANDIDATE_TRANSPORT_TCP_SO: return "TCP-SO"; default: return "???"; } } void agent_gathering_done (NiceAgent *agent) { GSList *i, *j, *k, *l, *m; for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; for (j = stream->components; j; j = j->next) { NiceComponent *component = j->data; for (k = component->local_candidates; k; k = k->next) { NiceCandidate *local_candidate = k->data; if (agent->force_relay && local_candidate->type != NICE_CANDIDATE_TYPE_RELAYED) continue; if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (&local_candidate->addr, tmpbuf); nice_debug ("Agent %p: gathered %s local candidate : [%s]:%u" " for s%d/c%d. U/P '%s'/'%s'", agent, _transport_to_string (local_candidate->transport), tmpbuf, nice_address_get_port (&local_candidate->addr), local_candidate->stream_id, local_candidate->component_id, local_candidate->username, local_candidate->password); } for (l = component->remote_candidates; l; l = l->next) { NiceCandidate *remote_candidate = l->data; for (m = stream->conncheck_list; m; m = m->next) { CandidateCheckPair *p = m->data; if (p->local == local_candidate && p->remote == remote_candidate) break; } if (m == NULL) { conn_check_add_for_candidate_pair (agent, stream->id, component, local_candidate, remote_candidate); } } } } } #ifdef HAVE_GUPNP if (agent->discovery_timer_source == NULL && agent->upnp_timer_source == NULL) { agent_signal_gathering_done (agent); } #else if (agent->discovery_timer_source == NULL) agent_signal_gathering_done (agent); #endif } void agent_signal_gathering_done (NiceAgent *agent) { GSList *i; for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; if (stream->gathering) { stream->gathering = FALSE; agent_queue_signal (agent, signals[SIGNAL_CANDIDATE_GATHERING_DONE], stream->id); } } } void agent_signal_initial_binding_request_received (NiceAgent *agent, NiceStream *stream) { if (stream->initial_binding_request_received != TRUE) { stream->initial_binding_request_received = TRUE; agent_queue_signal (agent, signals[SIGNAL_INITIAL_BINDING_REQUEST_RECEIVED], stream->id); } } /* If the Component now has a selected_pair, and has pending TCP packets which * it couldn’t receive before due to not being able to send out ACKs (or * SYNACKs, for the initial SYN packet), handle them now. * * Must be called with the agent lock held. */ static void process_queued_tcp_packets (NiceAgent *agent, NiceStream *stream, NiceComponent *component) { GOutputVector *vec; guint stream_id = stream->id; guint component_id = component->id; g_assert (agent->reliable); if (component->selected_pair.local == NULL || pseudo_tcp_socket_is_closed (component->tcp) || nice_socket_is_reliable (component->selected_pair.local->sockptr)) { return; } nice_debug_verbose ("%s: Sending outstanding packets for agent %p.", G_STRFUNC, agent); while ((vec = g_queue_peek_head (&component->queued_tcp_packets)) != NULL) { gboolean retval; nice_debug ("%s: Sending %" G_GSIZE_FORMAT " bytes.", G_STRFUNC, vec->size); retval = pseudo_tcp_socket_notify_packet (component->tcp, vec->buffer, vec->size); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { nice_debug ("Stream or Component disappeared during " "pseudo_tcp_socket_notify_packet()"); return; } if (pseudo_tcp_socket_is_closed (component->tcp)) { nice_debug ("PseudoTCP socket got destroyed in" " pseudo_tcp_socket_notify_packet()!"); return; } adjust_tcp_clock (agent, stream, component); if (!retval) { /* Failed to send; try again later. */ break; } g_queue_pop_head (&component->queued_tcp_packets); g_free ((gpointer) vec->buffer); g_slice_free (GOutputVector, vec); } } void agent_signal_new_selected_pair (NiceAgent *agent, guint stream_id, guint component_id, NiceCandidate *lcandidate, NiceCandidate *rcandidate) { NiceComponent *component; NiceStream *stream; if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return; if (((NiceSocket *)lcandidate->sockptr)->type == NICE_SOCKET_TYPE_UDP_TURN) { nice_udp_turn_socket_set_peer (lcandidate->sockptr, &rcandidate->addr); } if(agent->reliable && !nice_socket_is_reliable (lcandidate->sockptr)) { if (!component->tcp) pseudo_tcp_socket_create (agent, stream, component); process_queued_tcp_packets (agent, stream, component); pseudo_tcp_socket_connect (component->tcp); pseudo_tcp_socket_notify_mtu (component->tcp, MAX_TCP_MTU); adjust_tcp_clock (agent, stream, component); } if (nice_debug_is_enabled ()) { gchar ip[100]; guint port; port = nice_address_get_port (&lcandidate->addr); nice_address_to_string (&lcandidate->addr, ip); nice_debug ("Agent %p: Local selected pair: %d:%d %s %s %s:%d %s", agent, stream_id, component_id, lcandidate->foundation, lcandidate->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE ? "TCP-ACT" : lcandidate->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE ? "TCP-PASS" : lcandidate->transport == NICE_CANDIDATE_TRANSPORT_UDP ? "UDP" : "???", ip, port, lcandidate->type == NICE_CANDIDATE_TYPE_HOST ? "HOST" : lcandidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE ? "SRV-RFLX" : lcandidate->type == NICE_CANDIDATE_TYPE_RELAYED ? "RELAYED" : lcandidate->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE ? "PEER-RFLX" : "???"); port = nice_address_get_port (&rcandidate->addr); nice_address_to_string (&rcandidate->addr, ip); nice_debug ("Agent %p: Remote selected pair: %d:%d %s %s %s:%d %s", agent, stream_id, component_id, rcandidate->foundation, rcandidate->transport == NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE ? "TCP-ACT" : rcandidate->transport == NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE ? "TCP-PASS" : rcandidate->transport == NICE_CANDIDATE_TRANSPORT_UDP ? "UDP" : "???", ip, port, rcandidate->type == NICE_CANDIDATE_TYPE_HOST ? "HOST" : rcandidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE ? "SRV-RFLX" : rcandidate->type == NICE_CANDIDATE_TYPE_RELAYED ? "RELAYED" : rcandidate->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE ? "PEER-RFLX" : "???"); } agent_queue_signal (agent, signals[SIGNAL_NEW_SELECTED_PAIR_FULL], stream_id, component_id, lcandidate, rcandidate); agent_queue_signal (agent, signals[SIGNAL_NEW_SELECTED_PAIR], stream_id, component_id, lcandidate->foundation, rcandidate->foundation); if(agent->reliable && nice_socket_is_reliable (lcandidate->sockptr)) { agent_signal_socket_writable (agent, component); } } void agent_signal_new_candidate (NiceAgent *agent, NiceCandidate *candidate) { agent_queue_signal (agent, signals[SIGNAL_NEW_CANDIDATE_FULL], candidate); agent_queue_signal (agent, signals[SIGNAL_NEW_CANDIDATE], candidate->stream_id, candidate->component_id, candidate->foundation); } void agent_signal_new_remote_candidate (NiceAgent *agent, NiceCandidate *candidate) { agent_queue_signal (agent, signals[SIGNAL_NEW_REMOTE_CANDIDATE_FULL], candidate); agent_queue_signal (agent, signals[SIGNAL_NEW_REMOTE_CANDIDATE], candidate->stream_id, candidate->component_id, candidate->foundation); } NICEAPI_EXPORT const gchar * nice_component_state_to_string (NiceComponentState state) { switch (state) { case NICE_COMPONENT_STATE_DISCONNECTED: return "disconnected"; case NICE_COMPONENT_STATE_GATHERING: return "gathering"; case NICE_COMPONENT_STATE_CONNECTING: return "connecting"; case NICE_COMPONENT_STATE_CONNECTED: return "connected"; case NICE_COMPONENT_STATE_READY: return "ready"; case NICE_COMPONENT_STATE_FAILED: return "failed"; case NICE_COMPONENT_STATE_LAST: default: return "invalid"; } } void agent_signal_component_state_change (NiceAgent *agent, guint stream_id, guint component_id, NiceComponentState new_state) { NiceComponentState old_state; NiceComponent *component; NiceStream *stream; g_return_if_fail (new_state < NICE_COMPONENT_STATE_LAST); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) return; /* Validate the state change. */ old_state = component->state; if (new_state == old_state) { return; } nice_debug ("Agent %p : stream %u component %u STATE-CHANGE %s -> %s.", agent, stream_id, component_id, nice_component_state_to_string (old_state), nice_component_state_to_string (new_state)); /* Check whether it’s a valid state transition. */ #define TRANSITION(OLD, NEW) \ (old_state == NICE_COMPONENT_STATE_##OLD && \ new_state == NICE_COMPONENT_STATE_##NEW) g_assert (/* Can (almost) always transition to FAILED (including * DISCONNECTED → FAILED which happens if one component fails * before another leaves DISCONNECTED): */ TRANSITION (DISCONNECTED, FAILED) || TRANSITION (GATHERING, FAILED) || TRANSITION (CONNECTING, FAILED) || TRANSITION (CONNECTED, FAILED) || TRANSITION (READY, FAILED) || /* Standard progression towards a ready connection: */ TRANSITION (DISCONNECTED, GATHERING) || TRANSITION (GATHERING, CONNECTING) || TRANSITION (CONNECTING, CONNECTED) || TRANSITION (CONNECTED, READY) || /* priv_conn_check_add_for_candidate_pair_matched(): */ TRANSITION (READY, CONNECTED) || /* If set_remote_candidates() is called with new candidates after * reaching FAILED: */ TRANSITION (FAILED, CONNECTING) || /* if new relay servers are added to a failed connection */ TRANSITION (FAILED, GATHERING) || /* Possible by calling set_remote_candidates() without calling * nice_agent_gather_candidates(): */ TRANSITION (DISCONNECTED, CONNECTING)); #undef TRANSITION component->state = new_state; if (agent->reliable) process_queued_tcp_packets (agent, stream, component); agent_queue_signal (agent, signals[SIGNAL_COMPONENT_STATE_CHANGED], stream_id, component_id, new_state); } guint64 agent_candidate_pair_priority (NiceAgent *agent, NiceCandidate *local, NiceCandidate *remote) { if (agent->controlling_mode) return nice_candidate_pair_priority (local->priority, remote->priority); else return nice_candidate_pair_priority (remote->priority, local->priority); } static void priv_add_new_candidate_discovery_stun (NiceAgent *agent, NiceSocket *nicesock, NiceAddress server, NiceStream *stream, guint component_id) { CandidateDiscovery *cdisco; /* note: no need to check for redundant candidates, as this is * done later on in the process */ cdisco = g_slice_new0 (CandidateDiscovery); cdisco->type = NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE; cdisco->nicesock = nicesock; cdisco->server = server; cdisco->stream = stream; cdisco->component = nice_stream_find_component_by_id (stream, component_id); cdisco->agent = agent; stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, (agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) ? STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES : 0); nice_debug ("Agent %p : Adding new srv-rflx candidate discovery %p", agent, cdisco); agent->discovery_list = g_slist_append (agent->discovery_list, cdisco); ++agent->discovery_unsched_items; } static void priv_add_new_candidate_discovery_turn (NiceAgent *agent, NiceSocket *nicesock, TurnServer *turn, NiceStream *stream, guint component_id, gboolean turn_tcp) { CandidateDiscovery *cdisco; NiceComponent *component = nice_stream_find_component_by_id (stream, component_id); NiceAddress local_address; /* note: no need to check for redundant candidates, as this is * done later on in the process */ cdisco = g_slice_new0 (CandidateDiscovery); cdisco->type = NICE_CANDIDATE_TYPE_RELAYED; if (turn->type == NICE_RELAY_TYPE_TURN_UDP) { if (agent->use_ice_udp == FALSE || turn_tcp == TRUE) { g_slice_free (CandidateDiscovery, cdisco); return; } if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { NiceAddress addr = nicesock->addr; NiceSocket *new_socket; nice_address_set_port (&addr, 0); new_socket = nice_udp_bsd_socket_new (&addr); if (new_socket) { _priv_set_socket_tos (agent, new_socket, stream->tos); nice_component_attach_socket (component, new_socket); nicesock = new_socket; } } cdisco->nicesock = nicesock; } else { NiceAddress proxy_server; gboolean reliable_tcp = FALSE; /* MS-TURN will allocate a transport with the same protocol it received * the allocate request. So if we are connecting in TCP, then the candidate * will be TCP-ACT/TCP-PASS which means it will be reliable all the way * to the peer. * [MS-TURN] : The transport address has the same transport protocol * over which the Allocate request was received; a request that is * received over TCP returns a TCP allocated transport address. */ if (turn_tcp) reliable_tcp = TRUE; /* Ignore tcp candidates if we disabled ice-tcp */ if ((agent->use_ice_udp == FALSE && reliable_tcp == FALSE) || (agent->use_ice_tcp == FALSE && reliable_tcp == TRUE)) { g_slice_free (CandidateDiscovery, cdisco); return; } /* TURN-TCP is currently unsupport unless it's OC2007 compatibliity */ /* TODO: Add support for TURN-TCP */ if (((agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && reliable_tcp == FALSE) || (!(agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) && reliable_tcp == TRUE)) { g_slice_free (CandidateDiscovery, cdisco); return; } local_address = nicesock->addr; nice_address_set_port (&local_address, 0); nicesock = NULL; /* TODO: add support for turn-tcp RFC 6062 */ if (agent->proxy_type != NICE_PROXY_TYPE_NONE && agent->proxy_ip != NULL && nice_address_set_from_string (&proxy_server, agent->proxy_ip)) { nice_address_set_port (&proxy_server, agent->proxy_port); nicesock = nice_tcp_bsd_socket_new (agent->main_context, &local_address, &proxy_server, reliable_tcp); if (nicesock) { _priv_set_socket_tos (agent, nicesock, stream->tos); if (agent->proxy_type == NICE_PROXY_TYPE_SOCKS5) { nicesock = nice_socks5_socket_new (nicesock, &turn->server, agent->proxy_username, agent->proxy_password); } else if (agent->proxy_type == NICE_PROXY_TYPE_HTTP){ nicesock = nice_http_socket_new (nicesock, &turn->server, agent->proxy_username, agent->proxy_password); } else { nice_socket_free (nicesock); nicesock = NULL; } } } if (nicesock == NULL) { nicesock = nice_tcp_bsd_socket_new (agent->main_context, &local_address, &turn->server, reliable_tcp); if (nicesock) _priv_set_socket_tos (agent, nicesock, stream->tos); } /* The TURN server may be invalid or not listening */ if (nicesock == NULL) return; if (agent->reliable) nice_socket_set_writable_callback (nicesock, _tcp_sock_is_writable, component); if (turn->type == NICE_RELAY_TYPE_TURN_TLS && agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { nicesock = nice_pseudossl_socket_new (nicesock, NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_GOOGLE); } else if (turn->type == NICE_RELAY_TYPE_TURN_TLS && (agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2)) { nicesock = nice_pseudossl_socket_new (nicesock, NICE_PSEUDOSSL_SOCKET_COMPATIBILITY_MSOC); } cdisco->nicesock = nice_udp_turn_over_tcp_socket_new (nicesock, agent_to_turn_socket_compatibility (agent)); nice_component_attach_socket (component, cdisco->nicesock); } cdisco->turn = turn_server_ref (turn); cdisco->server = turn->server; cdisco->stream = stream; cdisco->component = nice_stream_find_component_by_id (stream, component_id); cdisco->agent = agent; if (agent->compatibility == NICE_COMPATIBILITY_GOOGLE) { stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS | STUN_AGENT_USAGE_IGNORE_CREDENTIALS); } else if (agent->compatibility == NICE_COMPATIBILITY_MSN || agent->compatibility == NICE_COMPATIBILITY_WLM2009) { stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS); } else if (agent->compatibility == NICE_COMPATIBILITY_OC2007 || agent->compatibility == NICE_COMPATIBILITY_OC2007R2) { stun_agent_init (&cdisco->stun_agent, STUN_MSOC_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_OC2007, STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS | STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES); } else { stun_agent_init (&cdisco->stun_agent, STUN_ALL_KNOWN_ATTRIBUTES, STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_ADD_SOFTWARE | STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS); } stun_agent_set_software (&cdisco->stun_agent, agent->software_attribute); nice_debug ("Agent %p : Adding new relay-rflx candidate discovery %p", agent, cdisco); agent->discovery_list = g_slist_append (agent->discovery_list, cdisco); ++agent->discovery_unsched_items; } NICEAPI_EXPORT guint nice_agent_add_stream ( NiceAgent *agent, guint n_components) { NiceStream *stream; guint ret = 0; guint i; g_return_val_if_fail (NICE_IS_AGENT (agent), 0); g_return_val_if_fail (n_components >= 1, 0); agent_lock(); stream = nice_stream_new (n_components, agent); agent->streams = g_slist_append (agent->streams, stream); stream->id = agent->next_stream_id++; nice_debug ("Agent %p : allocating stream id %u (%p)", agent, stream->id, stream); if (agent->reliable) { nice_debug ("Agent %p : reliable stream", agent); for (i = 0; i < n_components; i++) { NiceComponent *component = nice_stream_find_component_by_id (stream, i + 1); if (component) { pseudo_tcp_socket_create (agent, stream, component); } else { nice_debug ("Agent %p: couldn't find component %d", agent, i+1); } } } nice_stream_initialize_credentials (stream, agent->rng); ret = stream->id; agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT gboolean nice_agent_set_relay_info(NiceAgent *agent, guint stream_id, guint component_id, const gchar *server_ip, guint server_port, const gchar *username, const gchar *password, NiceRelayType type) { NiceComponent *component = NULL; NiceStream *stream = NULL; gboolean ret = TRUE; TurnServer *turn; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); g_return_val_if_fail (component_id >= 1, FALSE); g_return_val_if_fail (server_ip, FALSE); g_return_val_if_fail (server_port, FALSE); g_return_val_if_fail (username, FALSE); g_return_val_if_fail (password, FALSE); g_return_val_if_fail (type <= NICE_RELAY_TYPE_TURN_TLS, FALSE); agent_lock(); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { ret = FALSE; goto done; } turn = turn_server_new (server_ip, server_port, username, password, type); if (!turn) { ret = FALSE; goto done; } nice_debug ("Agent %p: added relay server [%s]:%d of type %d to s/c %d/%d " "with user/pass : %s -- %s", agent, server_ip, server_port, type, stream_id, component_id, username, password); component->turn_servers = g_list_append (component->turn_servers, turn); if (stream->gathering_started) { GSList *i; stream->gathering = TRUE; for (i = component->local_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; if (candidate->type == NICE_CANDIDATE_TYPE_HOST && candidate->transport != NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE && nice_address_ip_version (&candidate->addr) == nice_address_ip_version (&turn->server)) priv_add_new_candidate_discovery_turn (agent, candidate->sockptr, turn, stream, component_id, candidate->transport != NICE_CANDIDATE_TRANSPORT_UDP); } if (agent->discovery_unsched_items) discovery_schedule (agent); } done: agent_unlock_and_emit (agent); return ret; } #ifdef HAVE_GUPNP static void agent_check_upnp_gathering_done (NiceAgent *agent); static gboolean priv_upnp_timeout_cb (gpointer user_data) { NiceAgent *agent = (NiceAgent*)user_data; agent_lock(); /* If the source has been destroyed, we have already freed all mappings. */ if (g_source_is_destroyed (g_main_current_source ())) { agent_unlock (); return FALSE; } nice_debug ("Agent %p : UPnP port mapping timed out", agent); /* We cannot free priv->upnp here as it may be holding mappings open which * we are using (e.g. if some mappings were successful and others errored). */ g_slist_free_full (agent->upnp_mapping, (GDestroyNotify) nice_address_free); agent->upnp_mapping = NULL; agent_check_upnp_gathering_done (agent); agent_unlock_and_emit (agent); return FALSE; } /* Check whether UPnP gathering is done, which is true when the list of pending * mappings (upnp_mapping) is empty. When it is empty, we have heard back from * gupnp-igd about each of the mappings we added, either successfully or not. * * Note that upnp_mapping has to be a list, rather than a counter, as the * mapped-external-port and error-mapping-port signals could be emitted multiple * times for each mapping. */ static void agent_check_upnp_gathering_done (NiceAgent *agent) { if (agent->upnp_mapping != NULL) return; if (agent->upnp_timer_source != NULL) { g_source_destroy (agent->upnp_timer_source); g_source_unref (agent->upnp_timer_source); agent->upnp_timer_source = NULL; } agent_gathering_done (agent); } static void _upnp_mapped_external_port (GUPnPSimpleIgd *self, gchar *proto, gchar *external_ip, gchar *replaces_external_ip, guint external_port, gchar *local_ip, guint local_port, gchar *description, gpointer user_data) { NiceAgent *agent = (NiceAgent*)user_data; NiceAddress localaddr; NiceAddress externaddr; NiceCandidateTransport transport; GSList *i, *j, *k; agent_lock(); if (agent->upnp_timer_source == NULL) goto end; nice_debug ("Agent %p : Successfully mapped %s:%d to %s:%d", agent, local_ip, local_port, external_ip, external_port); if (!nice_address_set_from_string (&localaddr, local_ip)) goto end; nice_address_set_port (&localaddr, local_port); if (g_strcmp0 (proto, "TCP") == 0) transport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; else transport = NICE_CANDIDATE_TRANSPORT_UDP; for (i = agent->upnp_mapping; i; i = i->next) { NiceAddress *addr = i->data; if (nice_address_equal (&localaddr, addr)) { agent->upnp_mapping = g_slist_remove (agent->upnp_mapping, addr); nice_address_free (addr); break; } } if (!nice_address_set_from_string (&externaddr, external_ip)) goto end; nice_address_set_port (&externaddr, external_port); for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; for (j = stream->components; j; j = j->next) { NiceComponent *component = j->data; for (k = component->local_candidates; k; k = k->next) { NiceCandidate *local_candidate = k->data; if (agent->force_relay && local_candidate->type != NICE_CANDIDATE_TYPE_RELAYED) continue; if (nice_address_equal (&localaddr, &local_candidate->base_addr)) { discovery_add_server_reflexive_candidate ( agent, stream->id, component->id, &externaddr, transport, local_candidate->sockptr, TRUE); goto end; } } } } end: agent_check_upnp_gathering_done (agent); agent_unlock_and_emit (agent); } static void _upnp_error_mapping_port (GUPnPSimpleIgd *self, GError *error, gchar *proto, guint external_port, gchar *local_ip, guint local_port, gchar *description, gpointer user_data) { NiceAgent *agent = (NiceAgent*)user_data; NiceAddress localaddr; GSList *i; agent_lock(); nice_debug ("Agent %p : Error mapping %s:%d to %d (%d) : %s", agent, local_ip, local_port, external_port, error->domain, error->message); if (nice_address_set_from_string (&localaddr, local_ip)) { nice_address_set_port (&localaddr, local_port); for (i = agent->upnp_mapping; i; i = i->next) { NiceAddress *addr = i->data; if (nice_address_equal (&localaddr, addr)) { agent->upnp_mapping = g_slist_remove (agent->upnp_mapping, addr); nice_address_free (addr); break; } } agent_check_upnp_gathering_done (agent); } agent_unlock_and_emit (agent); } #endif NICEAPI_EXPORT gboolean nice_agent_gather_candidates ( NiceAgent *agent, guint stream_id) { guint cid; GSList *i; NiceStream *stream; GSList *local_addresses = NULL; gboolean ret = TRUE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); agent_lock(); stream = agent_find_stream (agent, stream_id); if (stream == NULL) { agent_unlock_and_emit (agent); return FALSE; } if (stream->gathering_started) { /* Stream is already gathering, ignore this call */ agent_unlock_and_emit (agent); return TRUE; } nice_debug ("Agent %p : In %s mode, starting candidate gathering.", agent, agent->full_mode ? "ICE-FULL" : "ICE-LITE"); #ifdef HAVE_GUPNP if (agent->upnp_enabled && agent->upnp == NULL && !agent->force_relay) { agent->upnp = gupnp_simple_igd_thread_new (); if (agent->upnp) { g_signal_connect (agent->upnp, "mapped-external-port", G_CALLBACK (_upnp_mapped_external_port), agent); g_signal_connect (agent->upnp, "error-mapping-port", G_CALLBACK (_upnp_error_mapping_port), agent); } else { nice_debug ("Agent %p : Error creating UPnP Simple IGD agent", agent); } } else { nice_debug ("Agent %p : UPnP property Disabled", agent); } #else nice_debug ("Agent %p : libnice compiled without UPnP support", agent); #endif /* if no local addresses added, generate them ourselves */ if (agent->local_addresses == NULL) { GList *addresses = nice_interfaces_get_local_ips (FALSE); GList *item; for (item = addresses; item; item = g_list_next (item)) { const gchar *addr_string = item->data; NiceAddress *addr = nice_address_new (); if (nice_address_set_from_string (addr, addr_string)) { local_addresses = g_slist_append (local_addresses, addr); } else { nice_debug ("Error: Failed to parse local address ‘%s’.", addr_string); nice_address_free (addr); } } g_list_foreach (addresses, (GFunc) g_free, NULL); g_list_free (addresses); } else { for (i = agent->local_addresses; i; i = i->next) { NiceAddress *addr = i->data; NiceAddress *dupaddr = nice_address_dup (addr); local_addresses = g_slist_append (local_addresses, dupaddr); } } for (cid = 1; cid <= stream->n_components; cid++) { NiceComponent *component = nice_stream_find_component_by_id (stream, cid); gboolean found_local_address = FALSE; enum { ADD_HOST_MIN = 0, ADD_HOST_UDP = ADD_HOST_MIN, ADD_HOST_TCP_ACTIVE, ADD_HOST_TCP_PASSIVE, ADD_HOST_MAX = ADD_HOST_TCP_PASSIVE } add_type; if (component == NULL) continue; /* generate a local host candidate for each local address */ for (i = local_addresses; i; i = i->next) { NiceAddress *addr = i->data; NiceCandidate *host_candidate; #ifdef HAVE_GUPNP gchar local_ip[NICE_ADDRESS_STRING_LEN]; nice_address_to_string (addr, local_ip); #endif for (add_type = ADD_HOST_MIN; add_type <= ADD_HOST_MAX; add_type++) { NiceCandidateTransport transport; guint current_port; guint start_port; HostCandidateResult res = HOST_CANDIDATE_CANT_CREATE_SOCKET; if ((agent->use_ice_udp == FALSE && add_type == ADD_HOST_UDP) || (agent->use_ice_tcp == FALSE && add_type != ADD_HOST_UDP)) continue; switch (add_type) { default: case ADD_HOST_UDP: transport = NICE_CANDIDATE_TRANSPORT_UDP; break; case ADD_HOST_TCP_ACTIVE: transport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; break; case ADD_HOST_TCP_PASSIVE: transport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; break; } start_port = component->min_port; if(component->min_port != 0) { start_port = nice_rng_generate_int(agent->rng, component->min_port, component->max_port+1); } current_port = start_port; host_candidate = NULL; while (res == HOST_CANDIDATE_CANT_CREATE_SOCKET) { nice_debug ("Agent %p: Trying to create host candidate on port %d", agent, current_port); nice_address_set_port (addr, current_port); res = discovery_add_local_host_candidate (agent, stream->id, cid, addr, transport, &host_candidate); if (current_port > 0) current_port++; if (current_port > component->max_port) current_port = component->min_port; if (current_port == 0 || current_port == start_port) break; } if (res == HOST_CANDIDATE_REDUNDANT) { nice_debug ("Agent %p: Ignoring local candidate, it's redundant", agent); continue; } else if (res == HOST_CANDIDATE_FAILED) { nice_debug ("Agent %p: Could ot retrieive component %d/%d", agent, stream->id, cid); continue; } else if (res == HOST_CANDIDATE_CANT_CREATE_SOCKET) { if (nice_debug_is_enabled ()) { gchar ip[NICE_ADDRESS_STRING_LEN]; nice_address_to_string (addr, ip); nice_debug ("Agent %p: Unable to add local host candidate %s for" " s%d:%d. Invalid interface?", agent, ip, stream->id, component->id); } continue; } found_local_address = TRUE; nice_address_set_port (addr, 0); if (agent->reliable) nice_socket_set_writable_callback (host_candidate->sockptr, _tcp_sock_is_writable, component); #ifdef HAVE_GUPNP if (agent->upnp_enabled && agent->upnp && transport != NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE) { NiceAddress *base_addr = nice_address_dup (&host_candidate->base_addr); nice_debug ("Agent %p: Adding UPnP port %s:%d", agent, local_ip, nice_address_get_port (base_addr)); gupnp_simple_igd_add_port (GUPNP_SIMPLE_IGD (agent->upnp), transport == NICE_CANDIDATE_TRANSPORT_UDP ? "UDP" : "TCP", 0, local_ip, nice_address_get_port (base_addr), 0, PACKAGE_STRING); agent->upnp_mapping = g_slist_prepend (agent->upnp_mapping, base_addr); agent_timeout_add_with_context (agent, &agent->upnp_timer_source, "UPnP timeout", agent->upnp_timeout, priv_upnp_timeout_cb, agent); } #endif /* TODO: Add server-reflexive support for TCP candidates */ if (agent->full_mode && agent->stun_server_ip && !agent->force_relay && transport == NICE_CANDIDATE_TRANSPORT_UDP) { NiceAddress stun_server; if (nice_address_set_from_string (&stun_server, agent->stun_server_ip)) { nice_address_set_port (&stun_server, agent->stun_server_port); priv_add_new_candidate_discovery_stun (agent, host_candidate->sockptr, stun_server, stream, cid); } } if (agent->full_mode && component && transport != NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE) { GList *item; int host_ip_version = nice_address_ip_version (&host_candidate->addr); for (item = component->turn_servers; item; item = item->next) { TurnServer *turn = item->data; if (host_ip_version != nice_address_ip_version (&turn->server)) { continue; } priv_add_new_candidate_discovery_turn (agent, host_candidate->sockptr, turn, stream, cid, host_candidate->transport != NICE_CANDIDATE_TRANSPORT_UDP); } } } } /* Go to error if we could not find a local address for a given * component */ if (!found_local_address) { ret = FALSE; goto error; } } stream->gathering = TRUE; stream->gathering_started = TRUE; /* Only signal the new candidates after we're sure that the gathering was * succesfful. But before sending gathering-done */ for (cid = 1; cid <= stream->n_components; cid++) { NiceComponent *component = nice_stream_find_component_by_id (stream, cid); for (i = component->local_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; if (agent->force_relay && candidate->type != NICE_CANDIDATE_TYPE_RELAYED) continue; agent_signal_new_candidate (agent, candidate); } } /* note: no async discoveries pending, signal that we are ready */ if (agent->discovery_unsched_items == 0 && #ifdef HAVE_GUPNP agent->upnp_mapping == NULL) { #else TRUE) { #endif nice_debug ("Agent %p: Candidate gathering FINISHED, no scheduled items.", agent); agent_gathering_done (agent); } else if (agent->discovery_unsched_items) { discovery_schedule (agent); } error: for (i = local_addresses; i; i = i->next) nice_address_free (i->data); g_slist_free (local_addresses); if (ret == FALSE) { priv_stop_upnp (agent); for (cid = 1; cid <= stream->n_components; cid++) { NiceComponent *component = nice_stream_find_component_by_id (stream, cid); nice_component_free_socket_sources (component); for (i = component->local_candidates; i; i = i->next) { NiceCandidate *candidate = i->data; agent_remove_local_candidate (agent, candidate); nice_candidate_free (candidate); } g_slist_free (component->local_candidates); component->local_candidates = NULL; } discovery_prune_stream (agent, stream_id); } agent_unlock_and_emit (agent); return ret; } void agent_remove_local_candidate (NiceAgent *agent, NiceCandidate *candidate) { #ifdef HAVE_GUPNP gchar local_ip[NICE_ADDRESS_STRING_LEN]; if (agent->upnp == NULL) return; if (candidate->type != NICE_CANDIDATE_TYPE_HOST) return; if (nice_address_get_port (&candidate->addr) == 0) return; nice_address_to_string (&candidate->addr, local_ip); gupnp_simple_igd_remove_port_local (GUPNP_SIMPLE_IGD (agent->upnp), "UDP", local_ip, nice_address_get_port (&candidate->addr)); #endif } static void priv_stop_upnp (NiceAgent *agent) { #ifdef HAVE_GUPNP if (!agent->upnp) return; g_slist_free_full (agent->upnp_mapping, (GDestroyNotify) nice_address_free); agent->upnp_mapping = NULL; if (agent->upnp_timer_source != NULL) { g_source_destroy (agent->upnp_timer_source); g_source_unref (agent->upnp_timer_source); agent->upnp_timer_source = NULL; } #endif } static void priv_remove_keepalive_timer (NiceAgent *agent) { if (agent->keepalive_timer_source != NULL) { g_source_destroy (agent->keepalive_timer_source); g_source_unref (agent->keepalive_timer_source); agent->keepalive_timer_source = NULL; } } NICEAPI_EXPORT void nice_agent_remove_stream ( NiceAgent *agent, guint stream_id) { guint stream_ids[] = { stream_id, 0 }; /* note that streams/candidates can be in use by other threads */ NiceStream *stream; g_return_if_fail (NICE_IS_AGENT (agent)); g_return_if_fail (stream_id >= 1); agent_lock(); stream = agent_find_stream (agent, stream_id); if (!stream) { agent_unlock_and_emit (agent); return; } /* note: remove items with matching stream_ids from both lists */ conn_check_prune_stream (agent, stream); discovery_prune_stream (agent, stream_id); refresh_prune_stream (agent, stream_id); /* Remove the stream and signal its removal. */ agent->streams = g_slist_remove (agent->streams, stream); nice_stream_close (stream); if (!agent->streams) priv_remove_keepalive_timer (agent); agent_queue_signal (agent, signals[SIGNAL_STREAMS_REMOVED], g_memdup (stream_ids, sizeof(stream_ids))); agent_unlock_and_emit (agent); /* Actually free the stream. This should be done with the lock released, as * it could end up disposing of a NiceIOStream, which tries to take the * agent lock itself. */ g_object_unref (stream); return; } NICEAPI_EXPORT void nice_agent_set_port_range (NiceAgent *agent, guint stream_id, guint component_id, guint min_port, guint max_port) { NiceStream *stream; NiceComponent *component; g_return_if_fail (NICE_IS_AGENT (agent)); g_return_if_fail (stream_id >= 1); g_return_if_fail (component_id >= 1); agent_lock(); if (agent_find_component (agent, stream_id, component_id, &stream, &component)) { if (stream->gathering_started) { g_critical ("nice_agent_gather_candidates (stream_id=%u) already called for this stream", stream_id); } else { component->min_port = min_port; component->max_port = max_port; } } agent_unlock_and_emit (agent); } NICEAPI_EXPORT gboolean nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr) { NiceAddress *dupaddr; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (addr != NULL, FALSE); agent_lock(); dupaddr = nice_address_dup (addr); nice_address_set_port (dupaddr, 0); agent->local_addresses = g_slist_append (agent->local_addresses, dupaddr); agent_unlock_and_emit (agent); return TRUE; } static gboolean priv_add_remote_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceCandidateType type, const NiceAddress *addr, const NiceAddress *base_addr, NiceCandidateTransport transport, guint32 priority, const gchar *username, const gchar *password, const gchar *foundation) { NiceComponent *component; NiceCandidate *candidate; if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) return FALSE; /* step: check whether the candidate already exists */ candidate = nice_component_find_remote_candidate (component, addr, transport); /* If it was a discovered remote peer reflexive candidate, then it should * be updated according to RFC 5245 section 7.2.1.3 */ if (candidate && candidate->type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE && candidate->priority == priority) { nice_debug ("Agent %p : Updating existing peer-rfx remote candidate to %s", agent, _cand_type_to_sdp (type)); candidate->type = type; /* If it got there, the next one will also be ran, so the foundation * will be set. */ } if (candidate && candidate->type == type) { if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (addr, tmpbuf); nice_debug ("Agent %p : Updating existing remote candidate with addr [%s]:%u" " for s%d/c%d. U/P '%s'/'%s' prio: %u", agent, tmpbuf, nice_address_get_port (addr), stream_id, component_id, username, password, priority); } /* case 1: an existing candidate, update the attributes */ if (base_addr) candidate->base_addr = *base_addr; candidate->priority = priority; if (foundation) g_strlcpy(candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION); /* note: username and password must remain the same during * a session; see sect 9.1.2 in ICE ID-19 */ /* note: however, the user/pass in ID-19 is global, if the user/pass * are set in the candidate here, it means they need to be updated... * this is essential to overcome a race condition where we might receive * a valid binding request from a valid candidate that wasn't yet added to * our list of candidates.. this 'update' will make the peer-rflx a * server-rflx/host candidate again and restore that user/pass it needed * to have in the first place */ if (username) { g_free (candidate->username); candidate->username = g_strdup (username); } if (password) { g_free (candidate->password); candidate->password = g_strdup (password); } } else { /* case 2: add a new candidate */ if (type == NICE_CANDIDATE_TYPE_PEER_REFLEXIVE) { nice_debug("Agent %p : Warning: ignoring externally set peer-reflexive candidate!", agent); return FALSE; } candidate = nice_candidate_new (type); component->remote_candidates = g_slist_append (component->remote_candidates, candidate); candidate->stream_id = stream_id; candidate->component_id = component_id; candidate->type = type; if (addr) candidate->addr = *addr; if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN] = {0}; if (addr) nice_address_to_string (addr, tmpbuf); nice_debug ("Agent %p : Adding %s remote candidate with addr [%s]:%u" " for s%d/c%d. U/P '%s'/'%s' prio: %u", agent, _transport_to_string (transport), tmpbuf, addr? nice_address_get_port (addr) : 0, stream_id, component_id, username, password, priority); } if (base_addr) candidate->base_addr = *base_addr; candidate->transport = transport; candidate->priority = priority; candidate->username = g_strdup (username); candidate->password = g_strdup (password); if (foundation) g_strlcpy (candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION); } if (conn_check_add_for_candidate (agent, stream_id, component, candidate) < 0) { goto errors; } return TRUE; errors: nice_candidate_free (candidate); return FALSE; } NICEAPI_EXPORT gboolean nice_agent_set_remote_credentials ( NiceAgent *agent, guint stream_id, const gchar *ufrag, const gchar *pwd) { NiceStream *stream; gboolean ret = FALSE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); agent_lock(); stream = agent_find_stream (agent, stream_id); /* note: oddly enough, ufrag and pwd can be empty strings */ if (stream && ufrag && pwd) { g_strlcpy (stream->remote_ufrag, ufrag, NICE_STREAM_MAX_UFRAG); g_strlcpy (stream->remote_password, pwd, NICE_STREAM_MAX_PWD); ret = TRUE; goto done; } done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT gboolean nice_agent_set_local_credentials ( NiceAgent *agent, guint stream_id, const gchar *ufrag, const gchar *pwd) { NiceStream *stream; gboolean ret = FALSE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); agent_lock (); stream = agent_find_stream (agent, stream_id); /* note: oddly enough, ufrag and pwd can be empty strings */ if (stream && ufrag && pwd) { g_strlcpy (stream->local_ufrag, ufrag, NICE_STREAM_MAX_UFRAG); g_strlcpy (stream->local_password, pwd, NICE_STREAM_MAX_PWD); ret = TRUE; goto done; } done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT gboolean nice_agent_get_local_credentials ( NiceAgent *agent, guint stream_id, gchar **ufrag, gchar **pwd) { NiceStream *stream; gboolean ret = TRUE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); agent_lock(); stream = agent_find_stream (agent, stream_id); if (stream == NULL) { goto done; } if (!ufrag || !pwd) { goto done; } *ufrag = g_strdup (stream->local_ufrag); *pwd = g_strdup (stream->local_password); ret = TRUE; done: agent_unlock_and_emit (agent); return ret; } static int _set_remote_candidates_locked (NiceAgent *agent, NiceStream *stream, NiceComponent *component, const GSList *candidates) { const GSList *i; int added = 0; for (i = candidates; i && added >= 0; i = i->next) { NiceCandidate *d = (NiceCandidate*) i->data; if (nice_address_is_valid (&d->addr) == TRUE) { gboolean res = priv_add_remote_candidate (agent, stream->id, component->id, d->type, &d->addr, &d->base_addr, d->transport, d->priority, d->username, d->password, d->foundation); if (res) ++added; } } conn_check_remote_candidates_set(agent, stream, component); if (added > 0) { conn_check_schedule_next (agent); } return added; } NICEAPI_EXPORT int nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint component_id, const GSList *candidates) { int added = 0; NiceStream *stream; NiceComponent *component; g_return_val_if_fail (NICE_IS_AGENT (agent), 0); g_return_val_if_fail (stream_id >= 1, 0); g_return_val_if_fail (component_id >= 1, 0); nice_debug ("Agent %p: set_remote_candidates %d %d", agent, stream_id, component_id); agent_lock(); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { g_warning ("Could not find component %u in stream %u", component_id, stream_id); added = -1; goto done; } added = _set_remote_candidates_locked (agent, stream, component, candidates); done: agent_unlock_and_emit (agent); return added; } /* Return values for agent_recv_message_unlocked(). Needed purely because it * must differentiate between RECV_OOB and RECV_SUCCESS. */ typedef enum { RECV_ERROR = -2, RECV_WOULD_BLOCK = -1, RECV_OOB = 0, RECV_SUCCESS = 1, } RecvStatus; /* * agent_recv_message_unlocked: * @agent: a #NiceAgent * @stream: the stream to receive from * @component: the component to receive from * @socket: the socket to receive on * @message: the message to write into (must have at least 65536 bytes of buffer * space) * * Receive a single message of data from the given @stream, @component and * @socket tuple, in a non-blocking fashion. The caller must ensure that * @message contains enough buffers to provide at least 65536 bytes of buffer * space, but the buffers may be split as the caller sees fit. * * This must be called with the agent’s lock held. * * Returns: number of valid messages received on success (i.e. %RECV_SUCCESS or * 1), %RECV_OOB if data was successfully received but was handled out-of-band * (e.g. due to being a STUN control packet), %RECV_WOULD_BLOCK if no data is * available and the call would block, or %RECV_ERROR on error */ static RecvStatus agent_recv_message_unlocked ( NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *nicesock, NiceInputMessage *message) { NiceAddress from; GList *item; gint retval; gboolean is_turn = FALSE; /* We need an address for packet parsing, below. */ if (message->from == NULL) { message->from = &from; } /* ICE-TCP requires that all packets be framed with RFC4571 */ if (nice_socket_is_reliable (nicesock)) { /* In the case of OC2007 and OC2007R2 which uses UDP TURN for TCP-ACTIVE * and TCP-PASSIVE candidates, the recv_messages will be packetized and * always return an entire frame, so we must read it as is */ if (nicesock->type == NICE_SOCKET_TYPE_UDP_TURN_OVER_TCP || nicesock->type == NICE_SOCKET_TYPE_UDP_TURN) { GSList *cand_i; GInputVector *local_bufs; NiceInputMessage local_message; guint n_bufs = 0; guint16 rfc4571_frame; guint i; /* In case of ICE-TCP on UDP-TURN (OC2007 compat), we need to do the recv * on the UDP_TURN socket, but it's possible we receive the source event * on the UDP_TURN_OVER_TCP socket, so in that case, we need to replace * the socket we do the recv on to the topmost socket */ for (cand_i = component->local_candidates; cand_i; cand_i = cand_i->next) { NiceCandidate *cand = cand_i->data; if (cand->type == NICE_CANDIDATE_TYPE_RELAYED && cand->stream_id == stream->id && cand->component_id == component->id && nice_socket_is_based_on(cand->sockptr, nicesock)) { nice_debug ("Agent %p : Packet received from a TURN socket.", agent); nicesock = cand->sockptr; break; } } /* Count the number of buffers. */ if (message->n_buffers == -1) { for (i = 0; message->buffers[i].buffer != NULL; i++) n_bufs++; } else { n_bufs = message->n_buffers; } local_bufs = g_alloca ((n_bufs + 1) * sizeof (GInputVector)); local_message.buffers = local_bufs; local_message.n_buffers = n_bufs + 1; local_message.from = message->from; local_message.length = 0; local_bufs[0].buffer = &rfc4571_frame; local_bufs[0].size = sizeof (guint16); for (i = 0; i < n_bufs; i++) { local_bufs[i + 1].buffer = message->buffers[i].buffer; local_bufs[i + 1].size = message->buffers[i].size; } retval = nice_socket_recv_messages (nicesock, &local_message, 1); if (retval == 1) { message->length = ntohs (rfc4571_frame); } } else { if (nicesock->type == NICE_SOCKET_TYPE_TCP_PASSIVE) { NiceSocket *new_socket; /* Passive candidates when readable should accept and create a new * socket. When established, the connchecks will create a peer reflexive * candidate for it */ new_socket = nice_tcp_passive_socket_accept (nicesock); if (new_socket) { _priv_set_socket_tos (agent, new_socket, stream->tos); nice_component_attach_socket (component, new_socket); } retval = 0; } else { /* In the case of a real ICE-TCP connection, we can use the socket as a * bytestream and do the read here with caching of data being read */ gssize available = g_socket_get_available_bytes (nicesock->fileno); /* TODO: Support bytestream reads */ message->length = 0; retval = 0; if (available <= 0) { retval = available; /* If we don't call check_connect_result on an outbound connection, * then is_connected will always return FALSE. That's why we check * both conditions to make sure g_socket_is_connected returns the * correct result, otherwise we end up closing valid connections */ if (g_socket_check_connect_result (nicesock->fileno, NULL) == FALSE || g_socket_is_connected (nicesock->fileno) == FALSE) { /* If we receive a readable event on a TCP_BSD socket which is * not connected, it means that it failed to connect, so we must * return an error to make the socket fail/closed */ retval = -1; } else { gint flags = G_SOCKET_MSG_PEEK; /* If available bytes are 0, but the socket is still considered * connected, then either we're just trying to see if there's more * data available or the peer closed the connection. * The only way to know is to do a read, so we do here a peek and * check the return value, if it's 0, it means the peer has closed * the connection, so we must return an error instead of WOULD_BLOCK */ if (g_socket_receive_message (nicesock->fileno, NULL, NULL, 0, NULL, NULL, &flags, NULL, NULL) == 0) retval = -1; } } else if (agent->rfc4571_expecting_length == 0) { if ((gsize) available >= sizeof(guint16)) { guint16 rfc4571_frame; GInputVector local_buf = { &rfc4571_frame, sizeof(guint16)}; NiceInputMessage local_message = { &local_buf, 1, message->from, 0}; retval = nice_socket_recv_messages (nicesock, &local_message, 1); if (retval == 1) { agent->rfc4571_expecting_length = ntohs (rfc4571_frame); available = g_socket_get_available_bytes (nicesock->fileno); } } } if (agent->rfc4571_expecting_length > 0 && available >= agent->rfc4571_expecting_length) { GInputVector *local_bufs; NiceInputMessage local_message; gsize off; guint n_bufs = 0; guint i; /* Count the number of buffers. */ if (message->n_buffers == -1) { for (i = 0; message->buffers[i].buffer != NULL; i++) n_bufs++; } else { n_bufs = message->n_buffers; } local_bufs = g_alloca (n_bufs * sizeof (GInputVector)); local_message.buffers = local_bufs; local_message.from = message->from; local_message.length = 0; local_message.n_buffers = 0; /* Only read up to the expected number of bytes in the frame */ off = 0; for (i = 0; i < n_bufs; i++) { if (message->buffers[i].size < agent->rfc4571_expecting_length - off) { local_bufs[i].buffer = message->buffers[i].buffer; local_bufs[i].size = message->buffers[i].size; local_message.n_buffers++; off += message->buffers[i].size; } else { local_bufs[i].buffer = message->buffers[i].buffer; local_bufs[i].size = MIN (message->buffers[i].size, agent->rfc4571_expecting_length - off); local_message.n_buffers++; off += local_bufs[i].size; } } retval = nice_socket_recv_messages (nicesock, &local_message, 1); if (retval == 1) { message->length = local_message.length; agent->rfc4571_expecting_length -= local_message.length; } } } } } else { retval = nice_socket_recv_messages (nicesock, message, 1); } if (retval == 0) { retval = RECV_WOULD_BLOCK; /* EWOULDBLOCK */ nice_debug_verbose ("%s: Agent %p: no message available on read attempt", G_STRFUNC, agent); goto done; } else if (retval < 0) { nice_debug ("Agent %p: %s returned %d, errno (%d) : %s", agent, G_STRFUNC, retval, errno, g_strerror (errno)); retval = RECV_ERROR; goto done; } if (retval == RECV_OOB || message->length == 0) { retval = RECV_OOB; nice_debug_verbose ("%s: Agent %p: message handled out-of-band", G_STRFUNC, agent); goto done; } if (nice_debug_is_verbose ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (message->from, tmpbuf); nice_debug_verbose ("%s: Agent %p : Packet received on local socket %p " "(fd %d) from [%s]:%u (%" G_GSSIZE_FORMAT " octets).", G_STRFUNC, agent, nicesock, g_socket_get_fd (nicesock->fileno), tmpbuf, nice_address_get_port (message->from), message->length); } if (nicesock->type == NICE_SOCKET_TYPE_UDP_TURN) is_turn = TRUE; if (!is_turn && component->turn_candidate && nice_socket_is_based_on (component->turn_candidate->sockptr, nicesock) && nice_address_equal (message->from, &component->turn_candidate->turn->server)) { is_turn = TRUE; retval = nice_udp_turn_socket_parse_recv_message ( component->turn_candidate->sockptr, &nicesock, message); } for (item = component->turn_servers; item && !is_turn; item = g_list_next (item)) { TurnServer *turn = item->data; GSList *i = NULL; if (!nice_address_equal (message->from, &turn->server)) continue; nice_debug_verbose ("Agent %p : Packet received from TURN server candidate.", agent); is_turn = TRUE; for (i = component->local_candidates; i; i = i->next) { NiceCandidate *cand = i->data; if (cand->type == NICE_CANDIDATE_TYPE_RELAYED && cand->turn == turn && cand->stream_id == stream->id && nice_socket_is_based_on (cand->sockptr, nicesock)) { retval = nice_udp_turn_socket_parse_recv_message (cand->sockptr, &nicesock, message); break; } } break; } if (agent->force_relay && !is_turn) { /* Ignore messages not from TURN if TURN is required */ retval = RECV_WOULD_BLOCK; /* EWOULDBLOCK */ goto done; } if (retval == RECV_OOB) goto done; agent->media_after_tick = TRUE; /* If the message’s stated length is equal to its actual length, it’s probably * a STUN message; otherwise it’s probably data. */ if (stun_message_validate_buffer_length_fast ( (StunInputVector *) message->buffers, message->n_buffers, message->length, (agent->compatibility != NICE_COMPATIBILITY_OC2007 && agent->compatibility != NICE_COMPATIBILITY_OC2007R2)) == (ssize_t) message->length) { /* Slow path: If this message isn’t obviously *not* a STUN packet, compact * its buffers * into a single monolithic one and parse the packet properly. */ guint8 *big_buf; gsize big_buf_len; int validated_len; big_buf = compact_input_message (message, &big_buf_len); validated_len = stun_message_validate_buffer_length (big_buf, big_buf_len, (agent->compatibility != NICE_COMPATIBILITY_OC2007 && agent->compatibility != NICE_COMPATIBILITY_OC2007R2)); if (validated_len == (gint) big_buf_len) { gboolean handled; handled = conn_check_handle_inbound_stun (agent, stream, component, nicesock, message->from, (gchar *) big_buf, big_buf_len); if (handled) { /* Handled STUN message. */ nice_debug ("%s: Valid STUN packet received.", G_STRFUNC); retval = RECV_OOB; g_free (big_buf); goto done; } } nice_debug ("%s: Packet passed fast STUN validation but failed " "slow validation.", G_STRFUNC); g_free (big_buf); } /* Unhandled STUN; try handling TCP data, then pass to the client. */ if (message->length > 0 && agent->reliable) { if (!nice_socket_is_reliable (nicesock) && !pseudo_tcp_socket_is_closed (component->tcp)) { /* If we don’t yet have an underlying selected socket, queue up the * incoming data to handle later. This is because we can’t send ACKs (or, * more importantly for the first few packets, SYNACKs) without an * underlying socket. We’d rather wait a little longer for a pair to be * selected, then process the incoming packets and send out ACKs, than try * to process them now, fail to send the ACKs, and incur a timeout in our * pseudo-TCP state machine. */ if (component->selected_pair.local == NULL) { GOutputVector *vec = g_slice_new (GOutputVector); vec->buffer = compact_input_message (message, &vec->size); g_queue_push_tail (&component->queued_tcp_packets, vec); nice_debug ("%s: Queued %" G_GSSIZE_FORMAT " bytes for agent %p.", G_STRFUNC, vec->size, agent); return RECV_OOB; } else { process_queued_tcp_packets (agent, stream, component); } /* Received data on a reliable connection. */ nice_debug_verbose ("%s: notifying pseudo-TCP of packet, length %" G_GSIZE_FORMAT, G_STRFUNC, message->length); pseudo_tcp_socket_notify_message (component->tcp, message); adjust_tcp_clock (agent, stream, component); /* Success! Handled out-of-band. */ retval = RECV_OOB; goto done; } else if (pseudo_tcp_socket_is_closed (component->tcp)) { nice_debug ("Received data on a pseudo tcp FAILED component. Ignoring."); retval = RECV_OOB; goto done; } } done: /* Clear local modifications. */ if (message->from == &from) { message->from = NULL; } return retval; } /* Print the composition of an array of messages. No-op if debugging is * disabled. */ static void nice_debug_input_message_composition (const NiceInputMessage *messages, guint n_messages) { guint i; if (!nice_debug_is_verbose ()) return; for (i = 0; i < n_messages; i++) { const NiceInputMessage *message = &messages[i]; guint j; nice_debug_verbose ("Message %p (from: %p, length: %" G_GSIZE_FORMAT ")", message, message->from, message->length); for (j = 0; (message->n_buffers >= 0 && j < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[j].buffer != NULL); j++) { GInputVector *buffer = &message->buffers[j]; nice_debug_verbose ("\tBuffer %p (length: %" G_GSIZE_FORMAT ")", buffer->buffer, buffer->size); } } } static guint8 * compact_message (const NiceOutputMessage *message, gsize buffer_length) { guint8 *buffer; gsize offset = 0; guint i; buffer = g_malloc (buffer_length); for (i = 0; (message->n_buffers >= 0 && i < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[i].buffer != NULL); i++) { gsize len = MIN (buffer_length - offset, message->buffers[i].size); memcpy (buffer + offset, message->buffers[i].buffer, len); offset += len; } return buffer; } /* Concatenate all the buffers in the given @recv_message into a single, newly * allocated, monolithic buffer which is returned. The length of the new buffer * is returned in @buffer_length, and should be equal to the length field of * @recv_message. * * The return value must be freed with g_free(). */ guint8 * compact_input_message (const NiceInputMessage *message, gsize *buffer_length) { nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC); nice_debug_input_message_composition (message, 1); /* This works as long as NiceInputMessage is a subset of eNiceOutputMessage */ *buffer_length = message->length; return compact_message ((NiceOutputMessage *) message, *buffer_length); } /* Returns the number of bytes copied. Silently drops any data from @buffer * which doesn’t fit in @message. */ gsize memcpy_buffer_to_input_message (NiceInputMessage *message, const guint8 *buffer, gsize buffer_length) { guint i; nice_debug_verbose ("%s: **WARNING: SLOW PATH**", G_STRFUNC); message->length = 0; for (i = 0; buffer_length > 0 && ((message->n_buffers >= 0 && i < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[i].buffer != NULL)); i++) { gsize len; len = MIN (message->buffers[i].size, buffer_length); memcpy (message->buffers[i].buffer, buffer, len); buffer += len; buffer_length -= len; message->length += len; } nice_debug_input_message_composition (message, 1); if (buffer_length > 0) { g_warning ("Dropped %" G_GSIZE_FORMAT " bytes of data from the end of " "buffer %p (length: %" G_GSIZE_FORMAT ") due to not fitting in " "message %p", buffer_length, buffer - message->length, message->length + buffer_length, message); } return message->length; } /* Concatenate all the buffers in the given @message into a single, newly * allocated, monolithic buffer which is returned. The length of the new buffer * is returned in @buffer_length, and should be equal to the length field of * @recv_message. * * The return value must be freed with g_free(). */ guint8 * compact_output_message (const NiceOutputMessage *message, gsize *buffer_length) { nice_debug ("%s: **WARNING: SLOW PATH**", G_STRFUNC); *buffer_length = output_message_get_size (message); return compact_message (message, *buffer_length); } gsize output_message_get_size (const NiceOutputMessage *message) { guint i; gsize message_len = 0; /* Find the total size of the message */ for (i = 0; (message->n_buffers >= 0 && i < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[i].buffer != NULL); i++) message_len += message->buffers[i].size; return message_len; } static gsize input_message_get_size (const NiceInputMessage *message) { guint i; gsize message_len = 0; /* Find the total size of the message */ for (i = 0; (message->n_buffers >= 0 && i < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[i].buffer != NULL); i++) message_len += message->buffers[i].size; return message_len; } /* * nice_input_message_iter_reset: * @iter: a #NiceInputMessageIter * * Reset the given @iter to point to the beginning of the array of messages. * This may be used both to initialise it and to reset it after use. * * Since: 0.1.5 */ void nice_input_message_iter_reset (NiceInputMessageIter *iter) { iter->message = 0; iter->buffer = 0; iter->offset = 0; } /* * nice_input_message_iter_is_at_end: * @iter: a #NiceInputMessageIter * @messages: (array length=n_messages): an array of #NiceInputMessages * @n_messages: number of entries in @messages * * Determine whether @iter points to the end of the given @messages array. If it * does, the array is full: every buffer in every message is full of valid * bytes. * * Returns: %TRUE if the messages’ buffers are full, %FALSE otherwise * * Since: 0.1.5 */ gboolean nice_input_message_iter_is_at_end (NiceInputMessageIter *iter, NiceInputMessage *messages, guint n_messages) { return (iter->message == n_messages && iter->buffer == 0 && iter->offset == 0); } /* * nice_input_message_iter_get_n_valid_messages: * @iter: a #NiceInputMessageIter * * Calculate the number of valid messages in the messages array. A valid message * is one which contains at least one valid byte of data in its buffers. * * Returns: number of valid messages (may be zero) * * Since: 0.1.5 */ guint nice_input_message_iter_get_n_valid_messages (NiceInputMessageIter *iter) { if (iter->buffer == 0 && iter->offset == 0) return iter->message; else return iter->message + 1; } /** * nice_input_message_iter_compare: * @a: a #NiceInputMessageIter * @b: another #NiceInputMessageIter * * Compare two #NiceInputMessageIters for equality, returning %TRUE if they * point to the same place in the receive message array. * * Returns: %TRUE if the iters match, %FALSE otherwise * * Since: 0.1.5 */ gboolean nice_input_message_iter_compare (const NiceInputMessageIter *a, const NiceInputMessageIter *b) { return (a->message == b->message && a->buffer == b->buffer && a->offset == b->offset); } /* Will fill up @messages from the first free byte onwards (as determined using * @iter). This may be used in reliable or non-reliable mode; in non-reliable * mode it will always increment the message index after each buffer is * consumed. * * Updates @iter in place. No errors can occur. * * Returns the number of valid messages in @messages on success (which may be * zero if reading into the first buffer of the message would have blocked). * * Must be called with the io_mutex held. */ static gint pending_io_messages_recv_messages (NiceComponent *component, gboolean reliable, NiceInputMessage *messages, guint n_messages, NiceInputMessageIter *iter) { gsize len; IOCallbackData *data; NiceInputMessage *message = &messages[iter->message]; g_assert (component->io_callback_id == 0); data = g_queue_peek_head (&component->pending_io_messages); if (data == NULL) goto done; if (iter->buffer == 0 && iter->offset == 0) { message->length = 0; } for (; (message->n_buffers >= 0 && iter->buffer < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[iter->buffer].buffer != NULL); iter->buffer++) { GInputVector *buffer = &message->buffers[iter->buffer]; do { len = MIN (data->buf_len - data->offset, buffer->size - iter->offset); memcpy ((guint8 *) buffer->buffer + iter->offset, data->buf + data->offset, len); nice_debug ("%s: Unbuffered %" G_GSIZE_FORMAT " bytes into " "buffer %p (offset %" G_GSIZE_FORMAT ", length %" G_GSIZE_FORMAT ").", G_STRFUNC, len, buffer->buffer, iter->offset, buffer->size); message->length += len; iter->offset += len; data->offset += len; } while (iter->offset < buffer->size); iter->offset = 0; } /* Only if we managed to consume the whole buffer should it be popped off the * queue; otherwise we’ll have another go at it later. */ if (data->offset == data->buf_len) { g_queue_pop_head (&component->pending_io_messages); io_callback_data_free (data); /* If we’ve consumed an entire message from pending_io_messages, and * are in non-reliable mode, move on to the next message in * @messages. */ if (!reliable) { iter->offset = 0; iter->buffer = 0; iter->message++; } } done: return nice_input_message_iter_get_n_valid_messages (iter); } static gboolean nice_agent_recv_cancelled_cb (GCancellable *cancellable, gpointer user_data) { GError **error = user_data; return !g_cancellable_set_error_if_cancelled (cancellable, error); } static gint nice_agent_recv_messages_blocking_or_nonblocking (NiceAgent *agent, guint stream_id, guint component_id, gboolean blocking, NiceInputMessage *messages, guint n_messages, GCancellable *cancellable, GError **error) { GMainContext *context; NiceStream *stream; NiceComponent *component; gint n_valid_messages = -1; GSource *cancellable_source = NULL; gboolean received_enough = FALSE, error_reported = FALSE; gboolean all_sockets_would_block = FALSE; gboolean reached_eos = FALSE; GError *child_error = NULL; NiceInputMessage *messages_orig = NULL; guint i; g_return_val_if_fail (NICE_IS_AGENT (agent), -1); g_return_val_if_fail (stream_id >= 1, -1); g_return_val_if_fail (component_id >= 1, -1); g_return_val_if_fail (n_messages == 0 || messages != NULL, -1); g_return_val_if_fail ( cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1); g_return_val_if_fail (error == NULL || *error == NULL, -1); if (n_messages == 0) return 0; if (n_messages > G_MAXINT) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "The number of messages can't exceed G_MAXINT: %d", G_MAXINT); return -1; } /* Receive buffer size must be at least 1280 for STUN */ if (!agent->reliable) { for (i = 0; i < n_messages; i++) { if (input_message_get_size (&messages[i]) < 1280) { GInputVector *vec; if (messages_orig == NULL) messages_orig = g_memdup (messages, sizeof (NiceInputMessage) * n_messages); vec = g_slice_new (GInputVector); vec->buffer = g_slice_alloc (1280); vec->size = 1280; messages[i].buffers = vec; messages[i].n_buffers = 1; } } } agent_lock (); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE, "Invalid stream/component."); goto done; } nice_debug_verbose ("%s: %p: (%s):", G_STRFUNC, agent, blocking ? "blocking" : "non-blocking"); nice_debug_input_message_composition (messages, n_messages); /* Disallow re-entrant reads. */ g_assert (component->n_recv_messages == 0 && component->recv_messages == NULL); /* Set the component’s receive buffer. */ context = nice_component_dup_io_context (component); nice_component_set_io_callback (component, NULL, NULL, messages, n_messages, &child_error); /* Add the cancellable as a source. */ if (cancellable != NULL) { cancellable_source = g_cancellable_source_new (cancellable); g_source_set_callback (cancellable_source, (GSourceFunc) nice_agent_recv_cancelled_cb, &child_error, NULL); g_source_attach (cancellable_source, context); } /* Is there already pending data left over from having an I/O callback * attached and switching to using nice_agent_recv()? This is a horrifically * specific use case which I hope nobody ever tries. And yet, it still must be * supported. */ g_mutex_lock (&component->io_mutex); while (!received_enough && !g_queue_is_empty (&component->pending_io_messages)) { pending_io_messages_recv_messages (component, agent->reliable, component->recv_messages, component->n_recv_messages, &component->recv_messages_iter); nice_debug_verbose ("%s: %p: Received %d valid messages from pending I/O buffer.", G_STRFUNC, agent, nice_input_message_iter_get_n_valid_messages ( &component->recv_messages_iter)); received_enough = nice_input_message_iter_is_at_end (&component->recv_messages_iter, component->recv_messages, component->n_recv_messages); } g_mutex_unlock (&component->io_mutex); /* For a reliable stream, grab any data from the pseudo-TCP input buffer * before trying the sockets. */ if (agent->reliable && pseudo_tcp_socket_get_available_bytes (component->tcp) > 0) { pseudo_tcp_socket_recv_messages (component->tcp, component->recv_messages, component->n_recv_messages, &component->recv_messages_iter, &child_error); adjust_tcp_clock (agent, stream, component); nice_debug_verbose ("%s: %p: Received %d valid messages from pseudo-TCP read " "buffer.", G_STRFUNC, agent, nice_input_message_iter_get_n_valid_messages ( &component->recv_messages_iter)); received_enough = nice_input_message_iter_is_at_end (&component->recv_messages_iter, component->recv_messages, component->n_recv_messages); error_reported = (child_error != NULL); } /* Each iteration of the main context will either receive some data, a * cancellation error or a socket error. In non-reliable mode, the iter’s * @message counter will be incremented after each read. * * In blocking, reliable mode, iterate the loop enough to fill exactly * @n_messages messages. In blocking, non-reliable mode, iterate the loop to * receive @n_messages messages (which may not fill all the buffers). In * non-blocking mode, stop iterating the loop if all sockets would block (i.e. * if no data was received for an iteration; in which case @child_error will * be set to %G_IO_ERROR_WOULD_BLOCK). */ while (!received_enough && !error_reported && !all_sockets_would_block && !reached_eos) { NiceInputMessageIter prev_recv_messages_iter; g_clear_error (&child_error); memcpy (&prev_recv_messages_iter, &component->recv_messages_iter, sizeof (NiceInputMessageIter)); agent_unlock (); g_main_context_iteration (context, blocking); agent_lock (); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { g_clear_error (&child_error); g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE, "Component removed during call."); component = NULL; error_reported = TRUE; goto recv_error; } received_enough = nice_input_message_iter_is_at_end (&component->recv_messages_iter, component->recv_messages, component->n_recv_messages); error_reported = (child_error != NULL && !g_error_matches (child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); reached_eos = (agent->reliable && pseudo_tcp_socket_is_closed_remotely (component->tcp) && nice_input_message_iter_compare (&prev_recv_messages_iter, &component->recv_messages_iter)); all_sockets_would_block = (!blocking && !reached_eos && nice_input_message_iter_compare (&prev_recv_messages_iter, &component->recv_messages_iter)); } n_valid_messages = nice_input_message_iter_get_n_valid_messages ( &component->recv_messages_iter); /* grab before resetting the iter */ nice_component_set_io_callback (component, NULL, NULL, NULL, 0, NULL); recv_error: /* Tidy up. Below this point, @component may be %NULL. */ if (cancellable_source != NULL) { g_source_destroy (cancellable_source); g_source_unref (cancellable_source); } g_main_context_unref (context); /* Handle errors and cancellations. */ if (child_error != NULL) { n_valid_messages = -1; } else if (n_valid_messages == 0 && all_sockets_would_block) { g_set_error_literal (&child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, g_strerror (EAGAIN)); n_valid_messages = -1; } nice_debug_verbose ("%s: %p: n_valid_messages: %d, n_messages: %u", G_STRFUNC, agent, n_valid_messages, n_messages); done: g_assert ((child_error != NULL) == (n_valid_messages == -1)); g_assert (n_valid_messages < 0 || (guint) n_valid_messages <= n_messages); g_assert (n_valid_messages != 0 || reached_eos); if (child_error != NULL) g_propagate_error (error, child_error); agent_unlock_and_emit (agent); if (messages_orig) { for (i = 0; i < n_messages; i++) { if (messages[i].buffers != messages_orig[i].buffers) { g_assert_cmpint (messages[i].n_buffers, ==, 1); memcpy_buffer_to_input_message (&messages_orig[i], messages[i].buffers[0].buffer, messages[i].length); g_slice_free1 (1280, messages[i].buffers[0].buffer); g_slice_free (GInputVector, messages[i].buffers); messages[i].buffers = messages_orig[i].buffers; messages[i].n_buffers = messages_orig[i].n_buffers; messages[i].length = messages_orig[i].length; } } g_free (messages_orig); } return n_valid_messages; } NICEAPI_EXPORT gint nice_agent_recv_messages (NiceAgent *agent, guint stream_id, guint component_id, NiceInputMessage *messages, guint n_messages, GCancellable *cancellable, GError **error) { return nice_agent_recv_messages_blocking_or_nonblocking (agent, stream_id, component_id, TRUE, messages, n_messages, cancellable, error); } NICEAPI_EXPORT gssize nice_agent_recv (NiceAgent *agent, guint stream_id, guint component_id, guint8 *buf, gsize buf_len, GCancellable *cancellable, GError **error) { gint n_valid_messages; GInputVector local_bufs = { buf, buf_len }; NiceInputMessage local_messages = { &local_bufs, 1, NULL, 0 }; g_return_val_if_fail (NICE_IS_AGENT (agent), -1); g_return_val_if_fail (stream_id >= 1, -1); g_return_val_if_fail (component_id >= 1, -1); g_return_val_if_fail (buf != NULL || buf_len == 0, -1); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1); g_return_val_if_fail (error == NULL || *error == NULL, -1); if (buf_len > G_MAXSSIZE) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "The buffer length can't exceed G_MAXSSIZE: %" G_GSSIZE_FORMAT, G_MAXSSIZE); return -1; } n_valid_messages = nice_agent_recv_messages (agent, stream_id, component_id, &local_messages, 1, cancellable, error); if (n_valid_messages <= 0) return n_valid_messages; return local_messages.length; } NICEAPI_EXPORT gint nice_agent_recv_messages_nonblocking (NiceAgent *agent, guint stream_id, guint component_id, NiceInputMessage *messages, guint n_messages, GCancellable *cancellable, GError **error) { return nice_agent_recv_messages_blocking_or_nonblocking (agent, stream_id, component_id, FALSE, messages, n_messages, cancellable, error); } NICEAPI_EXPORT gssize nice_agent_recv_nonblocking (NiceAgent *agent, guint stream_id, guint component_id, guint8 *buf, gsize buf_len, GCancellable *cancellable, GError **error) { gint n_valid_messages; GInputVector local_bufs = { buf, buf_len }; NiceInputMessage local_messages = { &local_bufs, 1, NULL, 0 }; g_return_val_if_fail (NICE_IS_AGENT (agent), -1); g_return_val_if_fail (stream_id >= 1, -1); g_return_val_if_fail (component_id >= 1, -1); g_return_val_if_fail (buf != NULL || buf_len == 0, -1); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1); g_return_val_if_fail (error == NULL || *error == NULL, -1); if (buf_len > G_MAXSSIZE) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "The buffer length can't exceed G_MAXSSIZE: %" G_GSSIZE_FORMAT, G_MAXSSIZE); return -1; } n_valid_messages = nice_agent_recv_messages_nonblocking (agent, stream_id, component_id, &local_messages, 1, cancellable, error); if (n_valid_messages <= 0) return n_valid_messages; return local_messages.length; } /* nice_agent_send_messages_nonblocking_internal: * * Returns: number of bytes sent if allow_partial is %TRUE, the number * of messages otherwise. */ static gint nice_agent_send_messages_nonblocking_internal ( NiceAgent *agent, guint stream_id, guint component_id, const NiceOutputMessage *messages, guint n_messages, gboolean allow_partial, GError **error) { NiceStream *stream; NiceComponent *component; gint n_sent = -1; /* is in bytes if allow_partial is TRUE, otherwise in messages */ GError *child_error = NULL; g_assert (n_messages == 1 || !allow_partial); agent_lock (); if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE, "Invalid stream/component."); goto done; } /* FIXME: Cancellation isn’t yet supported, but it doesn’t matter because * we only deal with non-blocking writes. */ if (component->selected_pair.local != NULL) { if (nice_debug_is_enabled ()) { gchar tmpbuf[INET6_ADDRSTRLEN]; nice_address_to_string (&component->selected_pair.remote->addr, tmpbuf); nice_debug_verbose ("Agent %p : s%d:%d: sending %u messages to " "[%s]:%d", agent, stream_id, component_id, n_messages, tmpbuf, nice_address_get_port (&component->selected_pair.remote->addr)); } if(agent->reliable && !nice_socket_is_reliable (component->selected_pair.local->sockptr)) { if (!pseudo_tcp_socket_is_closed (component->tcp)) { /* Send on the pseudo-TCP socket. */ n_sent = pseudo_tcp_socket_send_messages (component->tcp, messages, n_messages, allow_partial, &child_error); adjust_tcp_clock (agent, stream, component); if (!pseudo_tcp_socket_can_send (component->tcp)) g_cancellable_reset (component->tcp_writable_cancellable); if (n_sent < 0 && !g_error_matches (child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { /* Signal errors */ priv_pseudo_tcp_error (agent, stream, component); } } else { g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_FAILED, "Pseudo-TCP socket not connected."); } } else { NiceSocket *sock; NiceAddress *addr; sock = component->selected_pair.local->sockptr; addr = &component->selected_pair.remote->addr; if (nice_socket_is_reliable (sock)) { guint i; /* ICE-TCP requires that all packets be framed with RFC4571 */ n_sent = 0; for (i = 0; i < n_messages; i++) { const NiceOutputMessage *message = &messages[i]; gsize message_len = output_message_get_size (message); gsize offset = 0; gsize current_offset = 0; gsize offset_in_buffer = 0; gint n_sent_framed; GOutputVector *local_bufs; NiceOutputMessage local_message; guint j; guint n_bufs = 0; /* Count the number of buffers. */ if (message->n_buffers == -1) { for (j = 0; message->buffers[j].buffer != NULL; j++) n_bufs++; } else { n_bufs = message->n_buffers; } local_bufs = g_malloc_n (n_bufs + 1, sizeof (GOutputVector)); local_message.buffers = local_bufs; while (message_len > 0) { guint16 packet_len; guint16 rfc4571_frame; /* Split long messages into 62KB packets, leaving enough space * for TURN overhead as well */ if (message_len > 0xF800) packet_len = 0xF800; else packet_len = (guint16) message_len; message_len -= packet_len; rfc4571_frame = htons (packet_len); local_bufs[0].buffer = &rfc4571_frame; local_bufs[0].size = sizeof (guint16); local_message.n_buffers = 1; /* If we had to split the message, we need to find which buffer * to start copying from and our offset within that buffer */ offset_in_buffer = 0; current_offset = 0; for (j = 0; j < n_bufs; j++) { if (message->buffers[j].size < offset - current_offset) { current_offset += message->buffers[j].size; continue; } else { offset_in_buffer = offset - current_offset; current_offset = offset; break; } } /* Keep j position in array and start copying from there */ for (; j < n_bufs; j++) { local_bufs[local_message.n_buffers].buffer = ((guint8 *) message->buffers[j].buffer) + offset_in_buffer; local_bufs[local_message.n_buffers].size = MIN (message->buffers[j].size, packet_len); packet_len -= local_bufs[local_message.n_buffers].size; offset += local_bufs[local_message.n_buffers++].size; offset_in_buffer = 0; } /* If we sent part of the message already, then send the rest * reliably so the message is sent as a whole even if it's split */ if (current_offset == 0) n_sent_framed = nice_socket_send_messages (sock, addr, &local_message, 1); else n_sent_framed = nice_socket_send_messages_reliable (sock, addr, &local_message, 1); if (component->tcp_writable_cancellable && !nice_socket_can_send (sock, addr)) g_cancellable_reset (component->tcp_writable_cancellable); if (n_sent_framed < 0 && n_sent == 0) n_sent = n_sent_framed; if (n_sent_framed != 1) break; /* This is the last split frame, increment n_sent */ if (message_len == 0) n_sent ++; } g_free (local_bufs); } } else { n_sent = nice_socket_send_messages (sock, addr, messages, n_messages); } if (n_sent < 0) { g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_FAILED, "Error writing data to socket."); } else if (n_sent > 0 && allow_partial) { g_assert (n_messages == 1); n_sent = output_message_get_size (messages); } } } else { /* Socket isn’t properly open yet. */ n_sent = 0; /* EWOULDBLOCK */ } /* Handle errors and cancellations. */ if (n_sent == 0) { g_set_error_literal (&child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, g_strerror (EAGAIN)); n_sent = -1; } nice_debug_verbose ("%s: n_sent: %d, n_messages: %u", G_STRFUNC, n_sent, n_messages); done: g_assert ((child_error != NULL) == (n_sent == -1)); g_assert (n_sent != 0); g_assert (n_sent < 0 || (!allow_partial && (guint) n_sent <= n_messages) || (allow_partial && n_messages == 1 && (gsize) n_sent <= output_message_get_size (&messages[0]))); if (child_error != NULL) g_propagate_error (error, child_error); agent_unlock_and_emit (agent); return n_sent; } NICEAPI_EXPORT gint nice_agent_send_messages_nonblocking ( NiceAgent *agent, guint stream_id, guint component_id, const NiceOutputMessage *messages, guint n_messages, GCancellable *cancellable, GError **error) { g_return_val_if_fail (NICE_IS_AGENT (agent), -1); g_return_val_if_fail (stream_id >= 1, -1); g_return_val_if_fail (component_id >= 1, -1); g_return_val_if_fail (n_messages == 0 || messages != NULL, -1); g_return_val_if_fail ( cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1); g_return_val_if_fail (error == NULL || *error == NULL, -1); if (g_cancellable_set_error_if_cancelled (cancellable, error)) return -1; return nice_agent_send_messages_nonblocking_internal (agent, stream_id, component_id, messages, n_messages, FALSE, error); } NICEAPI_EXPORT gint nice_agent_send ( NiceAgent *agent, guint stream_id, guint component_id, guint len, const gchar *buf) { GOutputVector local_buf = { buf, len }; NiceOutputMessage local_message = { &local_buf, 1 }; gint n_sent_bytes; g_return_val_if_fail (NICE_IS_AGENT (agent), -1); g_return_val_if_fail (stream_id >= 1, -1); g_return_val_if_fail (component_id >= 1, -1); g_return_val_if_fail (buf != NULL, -1); n_sent_bytes = nice_agent_send_messages_nonblocking_internal (agent, stream_id, component_id, &local_message, 1, TRUE, NULL); return n_sent_bytes; } NICEAPI_EXPORT GSList * nice_agent_get_local_candidates ( NiceAgent *agent, guint stream_id, guint component_id) { NiceComponent *component; GSList * ret = NULL; GSList * item = NULL; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (component_id >= 1, NULL); agent_lock(); if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) { goto done; } for (item = component->local_candidates; item; item = item->next) { NiceCandidate *cand = item->data; if (agent->force_relay && cand->type != NICE_CANDIDATE_TYPE_RELAYED) continue; ret = g_slist_append (ret, nice_candidate_copy (cand)); } done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT GSList * nice_agent_get_remote_candidates ( NiceAgent *agent, guint stream_id, guint component_id) { NiceComponent *component; GSList *ret = NULL, *item = NULL; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (component_id >= 1, NULL); agent_lock(); if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) { goto done; } for (item = component->remote_candidates; item; item = item->next) ret = g_slist_append (ret, nice_candidate_copy (item->data)); done: agent_unlock_and_emit (agent); return ret; } gboolean nice_agent_restart ( NiceAgent *agent) { GSList *i; agent_lock(); /* step: regenerate tie-breaker value */ priv_generate_tie_breaker (agent); for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; /* step: reset local credentials for the stream and * clean up the list of remote candidates */ nice_stream_restart (stream, agent); } agent_unlock_and_emit (agent); return TRUE; } gboolean nice_agent_restart_stream ( NiceAgent *agent, guint stream_id) { gboolean res = FALSE; NiceStream *stream; agent_lock(); stream = agent_find_stream (agent, stream_id); if (!stream) { g_warning ("Could not find stream %u", stream_id); goto done; } /* step: reset local credentials for the stream and * clean up the list of remote candidates */ nice_stream_restart (stream, agent); res = TRUE; done: agent_unlock_and_emit (agent); return res; } static void nice_agent_dispose (GObject *object) { GSList *i; QueuedSignal *sig; NiceAgent *agent = NICE_AGENT (object); /* step: free resources for the binding discovery timers */ discovery_free (agent); g_assert (agent->discovery_list == NULL); refresh_free (agent); g_assert (agent->refresh_list == NULL); /* step: free resources for the connectivity check timers */ conn_check_free (agent); priv_remove_keepalive_timer (agent); for (i = agent->local_addresses; i; i = i->next) { NiceAddress *a = i->data; nice_address_free (a); } g_slist_free (agent->local_addresses); agent->local_addresses = NULL; for (i = agent->streams; i; i = i->next) { NiceStream *s = i->data; nice_stream_close (s); g_object_unref (s); } g_slist_free (agent->streams); agent->streams = NULL; while ((sig = g_queue_pop_head (&agent->pending_signals))) { free_queued_signal (sig); } g_free (agent->stun_server_ip); agent->stun_server_ip = NULL; g_free (agent->proxy_ip); agent->proxy_ip = NULL; g_free (agent->proxy_username); agent->proxy_username = NULL; g_free (agent->proxy_password); agent->proxy_password = NULL; nice_rng_free (agent->rng); agent->rng = NULL; priv_stop_upnp (agent); #ifdef HAVE_GUPNP if (agent->upnp) { g_object_unref (agent->upnp); agent->upnp = NULL; } #endif g_free (agent->software_attribute); agent->software_attribute = NULL; if (agent->main_context != NULL) g_main_context_unref (agent->main_context); agent->main_context = NULL; if (G_OBJECT_CLASS (nice_agent_parent_class)->dispose) G_OBJECT_CLASS (nice_agent_parent_class)->dispose (object); } gboolean component_io_cb (GSocket *gsocket, GIOCondition condition, gpointer user_data) { SocketSource *socket_source = user_data; NiceComponent *component; NiceAgent *agent; NiceStream *stream; gboolean has_io_callback; gboolean remove_source = FALSE; agent_lock (); if (g_source_is_destroyed (g_main_current_source ())) { /* Silently return FALSE. */ nice_debug ("%s: source %p destroyed", G_STRFUNC, g_main_current_source ()); agent_unlock (); return G_SOURCE_REMOVE; } component = socket_source->component; agent = component->agent; stream = component->stream; g_object_ref (agent); /* Remove disconnected sockets when we get a HUP */ if (condition & G_IO_HUP) { nice_debug ("Agent %p: NiceSocket %p has received HUP", agent, socket_source->socket); if (component->selected_pair.local && component->selected_pair.local->sockptr == socket_source->socket && component->state == NICE_COMPONENT_STATE_READY) { nice_debug ("Agent %p: Selected pair socket %p has HUP, declaring failed", agent, socket_source->socket); agent_signal_component_state_change (agent, stream->id, component->id, NICE_COMPONENT_STATE_FAILED); } nice_component_remove_socket (component, socket_source->socket); agent_unlock (); g_object_unref (agent); return G_SOURCE_REMOVE; } has_io_callback = nice_component_has_io_callback (component); /* Choose which receive buffer to use. If we’re reading for * nice_agent_attach_recv(), use a local static buffer. If we’re reading for * nice_agent_recv_messages(), use the buffer provided by the client. * * has_io_callback cannot change throughout this function, as we operate * entirely with the agent lock held, and nice_component_set_io_callback() * would need to take the agent lock to change the Component’s * io_callback. */ g_assert (!has_io_callback || component->recv_messages == NULL); if (agent->reliable && !nice_socket_is_reliable (socket_source->socket)) { #define TCP_HEADER_SIZE 24 /* bytes */ guint8 local_header_buf[TCP_HEADER_SIZE]; /* FIXME: Currently, the critical path for reliable packet delivery has two * memcpy()s: one into the pseudo-TCP receive buffer, and one out of it. * This could moderately easily be reduced to one memcpy() in the common * case of in-order packet delivery, by replacing local_body_buf with a * pointer into the pseudo-TCP receive buffer. If it turns out the packet * is out-of-order (which we can only know after parsing its header), the * data will need to be moved in the buffer. If the packet *is* in order, * however, the only memcpy() then needed is from the pseudo-TCP receive * buffer to the client’s message buffers. * * In fact, in the case of a reliable agent with I/O callbacks, zero * memcpy()s can be achieved (for in-order packet delivery) by emittin the * I/O callback directly from the pseudo-TCP receive buffer. */ guint8 local_body_buf[MAX_BUFFER_SIZE]; GInputVector local_bufs[] = { { local_header_buf, sizeof (local_header_buf) }, { local_body_buf, sizeof (local_body_buf) }, }; NiceInputMessage local_message = { local_bufs, G_N_ELEMENTS (local_bufs), NULL, 0 }; RecvStatus retval = 0; if (pseudo_tcp_socket_is_closed (component->tcp)) { nice_debug ("Agent %p: not handling incoming packet for s%d:%d " "because pseudo-TCP socket does not exist in reliable mode.", agent, stream->id, component->id); remove_source = TRUE; goto done; } while (has_io_callback || (component->recv_messages != NULL && !nice_input_message_iter_is_at_end (&component->recv_messages_iter, component->recv_messages, component->n_recv_messages))) { /* Receive a single message. This will receive it into the given * @local_bufs then, for pseudo-TCP, emit I/O callbacks or copy it into * component->recv_messages in pseudo_tcp_socket_readable(). STUN packets * will be parsed in-place. */ retval = agent_recv_message_unlocked (agent, stream, component, socket_source->socket, &local_message); nice_debug_verbose ("%s: %p: received %d valid messages with %" G_GSSIZE_FORMAT " bytes", G_STRFUNC, agent, retval, local_message.length); /* Don’t expect any valid messages to escape pseudo_tcp_socket_readable() * when in reliable mode. */ g_assert_cmpint (retval, !=, RECV_SUCCESS); if (retval == RECV_WOULD_BLOCK) { /* EWOULDBLOCK. */ break; } else if (retval == RECV_ERROR) { /* Other error. */ nice_debug ("%s: error receiving message", G_STRFUNC); remove_source = TRUE; break; } has_io_callback = nice_component_has_io_callback (component); } } else if (has_io_callback) { while (has_io_callback) { guint8 local_buf[MAX_BUFFER_SIZE]; GInputVector local_bufs = { local_buf, sizeof (local_buf) }; NiceInputMessage local_message = { &local_bufs, 1, NULL, 0 }; RecvStatus retval; /* Receive a single message. */ retval = agent_recv_message_unlocked (agent, stream, component, socket_source->socket, &local_message); if (retval == RECV_WOULD_BLOCK) { /* EWOULDBLOCK. */ nice_debug_verbose ("%s: %p: no message available on read attempt", G_STRFUNC, agent); break; } else if (retval == RECV_ERROR) { /* Other error. */ nice_debug ("%s: %p: error receiving message", G_STRFUNC, agent); remove_source = TRUE; break; } if (retval == RECV_SUCCESS) { nice_debug_verbose ("%s: %p: received a valid message with %" G_GSSIZE_FORMAT " bytes", G_STRFUNC, agent, local_message.length); if (local_message.length > 0) { nice_component_emit_io_callback (component, local_buf, local_message.length); } } if (g_source_is_destroyed (g_main_current_source ())) { nice_debug ("Component IO source disappeared during the callback"); goto out; } has_io_callback = nice_component_has_io_callback (component); } } else if (component->recv_messages != NULL) { RecvStatus retval; /* Don’t want to trample over partially-valid buffers. */ g_assert (component->recv_messages_iter.buffer == 0); g_assert (component->recv_messages_iter.offset == 0); while (!nice_input_message_iter_is_at_end (&component->recv_messages_iter, component->recv_messages, component->n_recv_messages)) { /* Receive a single message. This will receive it into the given * user-provided #NiceInputMessage, which it’s the user’s responsibility * to ensure is big enough to avoid data loss (since we’re in non-reliable * mode). Iterate to receive as many messages as possible. * * STUN packets will be parsed in-place. */ retval = agent_recv_message_unlocked (agent, stream, component, socket_source->socket, &component->recv_messages[component->recv_messages_iter.message]); nice_debug_verbose ("%s: %p: received %d valid messages", G_STRFUNC, agent, retval); if (retval == RECV_SUCCESS) { /* Successfully received a single message. */ component->recv_messages_iter.message++; g_clear_error (component->recv_buf_error); } else if (retval == RECV_WOULD_BLOCK) { /* EWOULDBLOCK. */ if (component->recv_messages_iter.message == 0 && component->recv_buf_error != NULL && *component->recv_buf_error == NULL) { g_set_error_literal (component->recv_buf_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, g_strerror (EAGAIN)); } break; } else if (retval == RECV_ERROR) { /* Other error. */ remove_source = TRUE; break; } /* else if (retval == RECV_OOB) { ignore me and continue; } */ } } done: if (remove_source) nice_component_remove_socket (component, socket_source->socket); /* If we’re in the middle of a read, don’t emit any signals, or we could cause * re-entrancy by (e.g.) emitting component-state-changed and having the * client perform a read. */ if (component->n_recv_messages == 0 && component->recv_messages == NULL) { agent_unlock_and_emit (agent); } else { agent_unlock (); } g_object_unref (agent); return !remove_source; out: g_object_unref (agent); agent_unlock_and_emit (agent); return G_SOURCE_REMOVE; } NICEAPI_EXPORT gboolean nice_agent_attach_recv ( NiceAgent *agent, guint stream_id, guint component_id, GMainContext *ctx, NiceAgentRecvFunc func, gpointer data) { NiceComponent *component = NULL; NiceStream *stream = NULL; gboolean ret = FALSE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); g_return_val_if_fail (component_id >= 1, FALSE); agent_lock(); /* attach candidates */ /* step: check that params specify an existing pair */ if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { g_warning ("Could not find component %u in stream %u", component_id, stream_id); goto done; } if (ctx == NULL) ctx = g_main_context_default (); /* Set the component’s I/O context. */ nice_component_set_io_context (component, ctx); nice_component_set_io_callback (component, func, data, NULL, 0, NULL); ret = TRUE; if (func) { /* If we got detached, maybe our readable callback didn't finish reading * all available data in the pseudotcp, so we need to make sure we free * our recv window, so the readable callback can be triggered again on the * next incoming data. * but only do this if we know we're already readable, otherwise we might * trigger an error in the initial, pre-connection attach. */ if (agent->reliable && !pseudo_tcp_socket_is_closed (component->tcp) && component->tcp_readable) pseudo_tcp_socket_readable (component->tcp, component); } done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT gboolean nice_agent_set_selected_pair ( NiceAgent *agent, guint stream_id, guint component_id, const gchar *lfoundation, const gchar *rfoundation) { NiceComponent *component; NiceStream *stream; CandidatePair pair; gboolean ret = FALSE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); g_return_val_if_fail (component_id >= 1, FALSE); g_return_val_if_fail (lfoundation, FALSE); g_return_val_if_fail (rfoundation, FALSE); agent_lock(); /* step: check that params specify an existing pair */ if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { goto done; } if (!nice_component_find_pair (component, agent, lfoundation, rfoundation, &pair)){ goto done; } /* step: stop connectivity checks (note: for the whole stream) */ conn_check_prune_stream (agent, stream); if (agent->reliable && !nice_socket_is_reliable (pair.local->sockptr) && pseudo_tcp_socket_is_closed (component->tcp)) { nice_debug ("Agent %p: not setting selected pair for s%d:%d because " "pseudo tcp socket does not exist in reliable mode", agent, stream->id, component->id); goto done; } /* step: change component state; we could be in STATE_DISCONNECTED; skip * STATE_GATHERING and continue through the states to give client code a nice * logical progression. See http://phabricator.freedesktop.org/D218 for * discussion. */ if (component->state < NICE_COMPONENT_STATE_CONNECTING || component->state == NICE_COMPONENT_STATE_FAILED) agent_signal_component_state_change (agent, stream_id, component_id, NICE_COMPONENT_STATE_CONNECTING); if (component->state < NICE_COMPONENT_STATE_CONNECTED) agent_signal_component_state_change (agent, stream_id, component_id, NICE_COMPONENT_STATE_CONNECTED); agent_signal_component_state_change (agent, stream_id, component_id, NICE_COMPONENT_STATE_READY); /* step: set the selected pair */ nice_component_update_selected_pair (component, &pair); agent_signal_new_selected_pair (agent, stream_id, component_id, pair.local, pair.remote); ret = TRUE; done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT gboolean nice_agent_get_selected_pair (NiceAgent *agent, guint stream_id, guint component_id, NiceCandidate **local, NiceCandidate **remote) { NiceComponent *component; NiceStream *stream; gboolean ret = FALSE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); g_return_val_if_fail (component_id >= 1, FALSE); g_return_val_if_fail (local != NULL, FALSE); g_return_val_if_fail (remote != NULL, FALSE); agent_lock(); /* step: check that params specify an existing pair */ if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) goto done; if (component->selected_pair.local && component->selected_pair.remote) { *local = component->selected_pair.local; *remote = component->selected_pair.remote; ret = TRUE; } done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT GSocket * nice_agent_get_selected_socket (NiceAgent *agent, guint stream_id, guint component_id) { NiceComponent *component; NiceStream *stream; NiceSocket *nice_socket; GSocket *g_socket = NULL; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (component_id >= 1, NULL); agent_lock(); /* Reliable streams are pseudotcp or MUST use RFC 4571 framing */ if (agent->reliable) goto done; /* step: check that params specify an existing pair */ if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) goto done; if (!component->selected_pair.local || !component->selected_pair.remote) goto done; if (component->selected_pair.local->type == NICE_CANDIDATE_TYPE_RELAYED) goto done; /* ICE-TCP requires RFC4571 framing, even if unreliable */ if (component->selected_pair.local->transport != NICE_CANDIDATE_TRANSPORT_UDP) goto done; nice_socket = (NiceSocket *)component->selected_pair.local->sockptr; if (nice_socket->fileno) g_socket = g_object_ref (nice_socket->fileno); done: agent_unlock_and_emit (agent); return g_socket; } /* Create a new timer GSource with the given @name, @interval, callback * @function and @data, and assign it to @out, destroying and freeing any * existing #GSource in @out first. * * This guarantees that a timer won’t be overwritten without being destroyed. */ void agent_timeout_add_with_context (NiceAgent *agent, GSource **out, const gchar *name, guint interval, GSourceFunc function, gpointer data) { GSource *source; g_return_if_fail (function != NULL); g_return_if_fail (out != NULL); /* Destroy any existing source. */ if (*out != NULL) { g_source_destroy (*out); g_source_unref (*out); *out = NULL; } /* Create the new source. */ source = g_timeout_source_new (interval); g_source_set_name (source, name); g_source_set_callback (source, function, data, NULL); g_source_attach (source, agent->main_context); /* Return it! */ *out = source; } NICEAPI_EXPORT gboolean nice_agent_set_selected_remote_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceCandidate *candidate) { NiceComponent *component; NiceStream *stream; NiceCandidate *lcandidate = NULL; gboolean ret = FALSE; NiceCandidate *local = NULL, *remote = NULL; guint64 priority; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id != 0, FALSE); g_return_val_if_fail (component_id != 0, FALSE); g_return_val_if_fail (candidate != NULL, FALSE); agent_lock(); /* step: check if the component exists*/ if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) { goto done; } /* step: stop connectivity checks (note: for the whole stream) */ conn_check_prune_stream (agent, stream); /* Store previous selected pair */ local = component->selected_pair.local; remote = component->selected_pair.remote; priority = component->selected_pair.priority; /* step: set the selected pair */ lcandidate = nice_component_set_selected_remote_candidate (component, agent, candidate); if (!lcandidate) goto done; if (agent->reliable && !nice_socket_is_reliable (lcandidate->sockptr) && pseudo_tcp_socket_is_closed (component->tcp)) { nice_debug ("Agent %p: not setting selected remote candidate s%d:%d because" " pseudo tcp socket does not exist in reliable mode", agent, stream->id, component->id); /* Revert back to previous selected pair */ /* FIXME: by doing this, we lose the keepalive tick */ component->selected_pair.local = local; component->selected_pair.remote = remote; component->selected_pair.priority = priority; goto done; } /* step: change component state; we could be in STATE_DISCONNECTED; skip * STATE_GATHERING and continue through the states to give client code a nice * logical progression. See http://phabricator.freedesktop.org/D218 for * discussion. */ if (component->state < NICE_COMPONENT_STATE_CONNECTING || component->state == NICE_COMPONENT_STATE_FAILED) agent_signal_component_state_change (agent, stream_id, component_id, NICE_COMPONENT_STATE_CONNECTING); if (component->state < NICE_COMPONENT_STATE_CONNECTED) agent_signal_component_state_change (agent, stream_id, component_id, NICE_COMPONENT_STATE_CONNECTED); agent_signal_component_state_change (agent, stream_id, component_id, NICE_COMPONENT_STATE_READY); agent_signal_new_selected_pair (agent, stream_id, component_id, lcandidate, candidate); ret = TRUE; done: agent_unlock_and_emit (agent); return ret; } void _priv_set_socket_tos (NiceAgent *agent, NiceSocket *sock, gint tos) { if (sock->fileno == NULL) return; if (setsockopt (g_socket_get_fd (sock->fileno), IPPROTO_IP, IP_TOS, (const char *) &tos, sizeof (tos)) < 0) { nice_debug ("Agent %p: Could not set socket ToS: %s", agent, g_strerror (errno)); } #ifdef IPV6_TCLASS if (setsockopt (g_socket_get_fd (sock->fileno), IPPROTO_IPV6, IPV6_TCLASS, (const char *) &tos, sizeof (tos)) < 0) { nice_debug ("Agent %p: Could not set IPV6 socket ToS: %s", agent, g_strerror (errno)); } #endif } NICEAPI_EXPORT void nice_agent_set_stream_tos (NiceAgent *agent, guint stream_id, gint tos) { GSList *i, *j; NiceStream *stream; g_return_if_fail (NICE_IS_AGENT (agent)); g_return_if_fail (stream_id >= 1); agent_lock(); stream = agent_find_stream (agent, stream_id); if (stream == NULL) goto done; stream->tos = tos; for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; for (j = component->local_candidates; j; j = j->next) { NiceCandidate *local_candidate = j->data; _priv_set_socket_tos (agent, local_candidate->sockptr, tos); } } done: agent_unlock_and_emit (agent); } NICEAPI_EXPORT void nice_agent_set_software (NiceAgent *agent, const gchar *software) { g_return_if_fail (NICE_IS_AGENT (agent)); agent_lock(); g_free (agent->software_attribute); if (software) agent->software_attribute = g_strdup_printf ("%s/%s", software, PACKAGE_STRING); nice_agent_reset_all_stun_agents (agent, TRUE); agent_unlock_and_emit (agent); } NICEAPI_EXPORT gboolean nice_agent_set_stream_name (NiceAgent *agent, guint stream_id, const gchar *name) { NiceStream *stream_to_name = NULL; GSList *i; gboolean ret = FALSE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); g_return_val_if_fail (name, FALSE); if (strcmp (name, "audio") && strcmp (name, "video") && strcmp (name, "text") && strcmp (name, "application") && strcmp (name, "message") && strcmp (name, "image")) { g_critical ("Stream name %s will produce invalid SDP, only \"audio\"," " \"video\", \"text\", \"application\", \"image\" and \"message\"" " are valid", name); } agent_lock(); for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; if (stream->id != stream_id && g_strcmp0 (stream->name, name) == 0) goto done; else if (stream->id == stream_id) stream_to_name = stream; } if (stream_to_name == NULL) goto done; if (stream_to_name->name) g_free (stream_to_name->name); stream_to_name->name = g_strdup (name); ret = TRUE; done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT const gchar * nice_agent_get_stream_name (NiceAgent *agent, guint stream_id) { NiceStream *stream; gchar *name = NULL; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); agent_lock(); stream = agent_find_stream (agent, stream_id); if (stream == NULL) goto done; name = stream->name; done: agent_unlock_and_emit (agent); return name; } static NiceCandidate * _get_default_local_candidate_locked (NiceAgent *agent, NiceStream *stream, NiceComponent *component) { GSList *i; NiceCandidate *default_candidate = NULL; NiceCandidate *default_rtp_candidate = NULL; if (component->id != NICE_COMPONENT_TYPE_RTP) { NiceComponent *rtp_component; if (!agent_find_component (agent, stream->id, NICE_COMPONENT_TYPE_RTP, NULL, &rtp_component)) goto done; default_rtp_candidate = _get_default_local_candidate_locked (agent, stream, rtp_component); if (default_rtp_candidate == NULL) goto done; } for (i = component->local_candidates; i; i = i->next) { NiceCandidate *local_candidate = i->data; if (agent->force_relay && local_candidate->type != NICE_CANDIDATE_TYPE_RELAYED) continue; /* Only check for ipv4 candidates */ if (nice_address_ip_version (&local_candidate->addr) != 4) continue; if (component->id == NICE_COMPONENT_TYPE_RTP) { if (default_candidate == NULL || local_candidate->priority < default_candidate->priority) { default_candidate = local_candidate; } } else if (strncmp (local_candidate->foundation, default_rtp_candidate->foundation, NICE_CANDIDATE_MAX_FOUNDATION) == 0) { default_candidate = local_candidate; break; } } done: return default_candidate; } NICEAPI_EXPORT NiceCandidate * nice_agent_get_default_local_candidate (NiceAgent *agent, guint stream_id, guint component_id) { NiceStream *stream = NULL; NiceComponent *component = NULL; NiceCandidate *default_candidate = NULL; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (component_id >= 1, NULL); agent_lock (); /* step: check if the component exists*/ if (!agent_find_component (agent, stream_id, component_id, &stream, &component)) goto done; default_candidate = _get_default_local_candidate_locked (agent, stream, component); if (default_candidate) default_candidate = nice_candidate_copy (default_candidate); done: agent_unlock_and_emit (agent); return default_candidate; } static const gchar * _cand_type_to_sdp (NiceCandidateType type) { switch(type) { case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: return "srflx"; case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: return "prflx"; case NICE_CANDIDATE_TYPE_RELAYED: return "relay"; case NICE_CANDIDATE_TYPE_HOST: default: return "host"; } } static const gchar * _transport_to_sdp (NiceCandidateTransport type) { switch(type) { case NICE_CANDIDATE_TRANSPORT_UDP: return "UDP"; case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: case NICE_CANDIDATE_TRANSPORT_TCP_SO: return "TCP"; default: return "???"; } } static const gchar * _transport_to_sdp_tcptype (NiceCandidateTransport type) { switch(type) { case NICE_CANDIDATE_TRANSPORT_UDP: return ""; case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: return "active"; case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: return "passive"; case NICE_CANDIDATE_TRANSPORT_TCP_SO: return "so"; default: return ""; } } static void _generate_candidate_sdp (NiceAgent *agent, NiceCandidate *candidate, GString *sdp) { gchar ip4[INET6_ADDRSTRLEN]; guint16 port; nice_address_to_string (&candidate->addr, ip4); port = nice_address_get_port (&candidate->addr); g_string_append_printf (sdp, "a=candidate:%.*s %d %s %d %s %d", NICE_CANDIDATE_MAX_FOUNDATION, candidate->foundation, candidate->component_id, _transport_to_sdp (candidate->transport), candidate->priority, ip4, port == 0 ? 9 : port); g_string_append_printf (sdp, " typ %s", _cand_type_to_sdp (candidate->type)); if (nice_address_is_valid (&candidate->base_addr) && !nice_address_equal (&candidate->addr, &candidate->base_addr)) { port = nice_address_get_port (&candidate->addr); nice_address_to_string (&candidate->base_addr, ip4); g_string_append_printf (sdp, " raddr %s rport %d", ip4, port == 0 ? 9 : port); } if (candidate->transport != NICE_CANDIDATE_TRANSPORT_UDP) { g_string_append_printf (sdp, " tcptype %s", _transport_to_sdp_tcptype (candidate->transport)); } } static void _generate_stream_sdp (NiceAgent *agent, NiceStream *stream, GString *sdp, gboolean include_non_ice) { GSList *i, *j; if (include_non_ice) { NiceAddress rtp, rtcp; gchar ip4[INET6_ADDRSTRLEN] = ""; nice_address_init (&rtp); nice_address_set_ipv4 (&rtp, 0); nice_address_init (&rtcp); nice_address_set_ipv4 (&rtcp, 0); /* Find default candidates */ for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; NiceCandidate *default_candidate; if (component->id == NICE_COMPONENT_TYPE_RTP) { default_candidate = _get_default_local_candidate_locked (agent, stream, component); if (default_candidate) rtp = default_candidate->addr; } else if (component->id == NICE_COMPONENT_TYPE_RTCP) { default_candidate = _get_default_local_candidate_locked (agent, stream, component); if (default_candidate) rtcp = default_candidate->addr; } } nice_address_to_string (&rtp, ip4); g_string_append_printf (sdp, "m=%s %d ICE/SDP\n", stream->name ? stream->name : "-", nice_address_get_port (&rtp)); g_string_append_printf (sdp, "c=IN IP4 %s\n", ip4); if (nice_address_get_port (&rtcp) != 0) g_string_append_printf (sdp, "a=rtcp:%d\n", nice_address_get_port (&rtcp)); } g_string_append_printf (sdp, "a=ice-ufrag:%s\n", stream->local_ufrag); g_string_append_printf (sdp, "a=ice-pwd:%s\n", stream->local_password); for (i = stream->components; i; i = i->next) { NiceComponent *component = i->data; for (j = component->local_candidates; j; j = j->next) { NiceCandidate *candidate = j->data; if (agent->force_relay && candidate->type != NICE_CANDIDATE_TYPE_RELAYED) continue; _generate_candidate_sdp (agent, candidate, sdp); g_string_append (sdp, "\n"); } } } NICEAPI_EXPORT gchar * nice_agent_generate_local_sdp (NiceAgent *agent) { GString * sdp = g_string_new (NULL); GSList *i; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); agent_lock(); for (i = agent->streams; i; i = i->next) { NiceStream *stream = i->data; _generate_stream_sdp (agent, stream, sdp, TRUE); } agent_unlock_and_emit (agent); return g_string_free (sdp, FALSE); } NICEAPI_EXPORT gchar * nice_agent_generate_local_stream_sdp (NiceAgent *agent, guint stream_id, gboolean include_non_ice) { GString *sdp = NULL; gchar *ret = NULL; NiceStream *stream; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); agent_lock(); stream = agent_find_stream (agent, stream_id); if (stream == NULL) goto done; sdp = g_string_new (NULL); _generate_stream_sdp (agent, stream, sdp, include_non_ice); ret = g_string_free (sdp, FALSE); done: agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT gchar * nice_agent_generate_local_candidate_sdp (NiceAgent *agent, NiceCandidate *candidate) { GString *sdp = NULL; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (candidate != NULL, NULL); agent_lock(); sdp = g_string_new (NULL); _generate_candidate_sdp (agent, candidate, sdp); agent_unlock_and_emit (agent); return g_string_free (sdp, FALSE); } NICEAPI_EXPORT gint nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp) { NiceStream *current_stream = NULL; gchar **sdp_lines = NULL; GSList *l, *stream_item = NULL; gint i; gint ret = 0; g_return_val_if_fail (NICE_IS_AGENT (agent), -1); g_return_val_if_fail (sdp != NULL, -1); agent_lock(); for (l = agent->streams; l; l = l->next) { NiceStream *stream = l->data; if (stream->name == NULL) { ret = -1; goto done; } } sdp_lines = g_strsplit (sdp, "\n", 0); for (i = 0; sdp_lines && sdp_lines[i]; i++) { if (g_str_has_prefix (sdp_lines[i], "m=")) { if (stream_item == NULL) stream_item = agent->streams; else stream_item = stream_item->next; if (!stream_item) { g_critical("More streams in SDP than in agent"); ret = -1; goto done; } current_stream = stream_item->data; } else if (g_str_has_prefix (sdp_lines[i], "a=ice-ufrag:")) { if (current_stream == NULL) { ret = -1; goto done; } g_strlcpy (current_stream->remote_ufrag, sdp_lines[i] + 12, NICE_STREAM_MAX_UFRAG); } else if (g_str_has_prefix (sdp_lines[i], "a=ice-pwd:")) { if (current_stream == NULL) { ret = -1; goto done; } g_strlcpy (current_stream->remote_password, sdp_lines[i] + 10, NICE_STREAM_MAX_PWD); } else if (g_str_has_prefix (sdp_lines[i], "a=candidate:")) { NiceCandidate *candidate = NULL; NiceComponent *component = NULL; GSList *cands = NULL; gint added; if (current_stream == NULL) { ret = -1; goto done; } candidate = nice_agent_parse_remote_candidate_sdp (agent, current_stream->id, sdp_lines[i]); if (candidate == NULL) { ret = -1; goto done; } if (!agent_find_component (agent, candidate->stream_id, candidate->component_id, NULL, &component)) { nice_candidate_free (candidate); ret = -1; goto done; } cands = g_slist_prepend (cands, candidate); added = _set_remote_candidates_locked (agent, current_stream, component, cands); g_slist_free_full(cands, (GDestroyNotify)&nice_candidate_free); if (added > 0) ret++; } } done: if (sdp_lines) g_strfreev(sdp_lines); agent_unlock_and_emit (agent); return ret; } NICEAPI_EXPORT GSList * nice_agent_parse_remote_stream_sdp (NiceAgent *agent, guint stream_id, const gchar *sdp, gchar **ufrag, gchar **pwd) { NiceStream *stream = NULL; gchar **sdp_lines = NULL; GSList *candidates = NULL; gint i; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (sdp != NULL, NULL); agent_lock(); stream = agent_find_stream (agent, stream_id); if (stream == NULL) { goto done; } sdp_lines = g_strsplit (sdp, "\n", 0); for (i = 0; sdp_lines && sdp_lines[i]; i++) { if (ufrag && g_str_has_prefix (sdp_lines[i], "a=ice-ufrag:")) { *ufrag = g_strdup (sdp_lines[i] + 12); } else if (pwd && g_str_has_prefix (sdp_lines[i], "a=ice-pwd:")) { *pwd = g_strdup (sdp_lines[i] + 10); } else if (g_str_has_prefix (sdp_lines[i], "a=candidate:")) { NiceCandidate *candidate = NULL; candidate = nice_agent_parse_remote_candidate_sdp (agent, stream->id, sdp_lines[i]); if (candidate == NULL) { g_slist_free_full(candidates, (GDestroyNotify)&nice_candidate_free); candidates = NULL; break; } candidates = g_slist_prepend (candidates, candidate); } } done: if (sdp_lines) g_strfreev(sdp_lines); agent_unlock_and_emit (agent); return candidates; } NICEAPI_EXPORT NiceCandidate * nice_agent_parse_remote_candidate_sdp (NiceAgent *agent, guint stream_id, const gchar *sdp) { NiceCandidate *candidate = NULL; int ntype = -1; gchar **tokens = NULL; const gchar *foundation = NULL; guint component_id = 0; const gchar *transport = NULL; guint32 priority = 0; const gchar *addr = NULL; guint16 port = 0; const gchar *type = NULL; const gchar *tcptype = NULL; const gchar *raddr = NULL; guint16 rport = 0; static const gchar *type_names[] = {"host", "srflx", "prflx", "relay"}; NiceCandidateTransport ctransport; guint i; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (sdp != NULL, NULL); if (!g_str_has_prefix (sdp, "a=candidate:")) goto done; tokens = g_strsplit (sdp + 12, " ", 0); for (i = 0; tokens && tokens[i]; i++) { switch (i) { case 0: foundation = tokens[i]; break; case 1: component_id = (guint) g_ascii_strtoull (tokens[i], NULL, 10); break; case 2: transport = tokens[i]; break; case 3: priority = (guint32) g_ascii_strtoull (tokens[i], NULL, 10); break; case 4: addr = tokens[i]; break; case 5: port = (guint16) g_ascii_strtoull (tokens[i], NULL, 10); break; default: if (tokens[i + 1] == NULL) goto done; if (g_strcmp0 (tokens[i], "typ") == 0) { type = tokens[i + 1]; } else if (g_strcmp0 (tokens[i], "raddr") == 0) { raddr = tokens[i + 1]; } else if (g_strcmp0 (tokens[i], "rport") == 0) { rport = (guint16) g_ascii_strtoull (tokens[i + 1], NULL, 10); } else if (g_strcmp0 (tokens[i], "tcptype") == 0) { tcptype = tokens[i + 1]; } i++; break; } } if (type == NULL) goto done; ntype = -1; for (i = 0; i < G_N_ELEMENTS (type_names); i++) { if (g_strcmp0 (type, type_names[i]) == 0) { ntype = i; break; } } if (ntype == -1) goto done; if (g_ascii_strcasecmp (transport, "UDP") == 0) ctransport = NICE_CANDIDATE_TRANSPORT_UDP; else if (g_ascii_strcasecmp (transport, "TCP-SO") == 0) ctransport = NICE_CANDIDATE_TRANSPORT_TCP_SO; else if (g_ascii_strcasecmp (transport, "TCP-ACT") == 0) ctransport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; else if (g_ascii_strcasecmp (transport, "TCP-PASS") == 0) ctransport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; else if (g_ascii_strcasecmp (transport, "TCP") == 0) { if (g_ascii_strcasecmp (tcptype, "so") == 0) ctransport = NICE_CANDIDATE_TRANSPORT_TCP_SO; else if (g_ascii_strcasecmp (tcptype, "active") == 0) ctransport = NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE; else if (g_ascii_strcasecmp (tcptype, "passive") == 0) ctransport = NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE; else goto done; } else goto done; candidate = nice_candidate_new(ntype); candidate->component_id = component_id; candidate->stream_id = stream_id; candidate->transport = ctransport; g_strlcpy(candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION); candidate->priority = priority; if (!nice_address_set_from_string (&candidate->addr, addr)) { nice_candidate_free (candidate); candidate = NULL; goto done; } nice_address_set_port (&candidate->addr, port); if (raddr && rport) { if (!nice_address_set_from_string (&candidate->base_addr, raddr)) { nice_candidate_free (candidate); candidate = NULL; goto done; } nice_address_set_port (&candidate->base_addr, rport); } done: if (tokens) g_strfreev(tokens); return candidate; } NICEAPI_EXPORT GIOStream * nice_agent_get_io_stream (NiceAgent *agent, guint stream_id, guint component_id) { GIOStream *iostream = NULL; NiceComponent *component; g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (component_id >= 1, NULL); g_return_val_if_fail (agent->reliable, NULL); agent_lock (); if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) goto done; if (component->iostream == NULL) component->iostream = nice_io_stream_new (agent, stream_id, component_id); iostream = g_object_ref (component->iostream); done: agent_unlock_and_emit (agent); return iostream; } NICEAPI_EXPORT gboolean nice_agent_forget_relays (NiceAgent *agent, guint stream_id, guint component_id) { NiceComponent *component; gboolean ret = TRUE; g_return_val_if_fail (NICE_IS_AGENT (agent), FALSE); g_return_val_if_fail (stream_id >= 1, FALSE); g_return_val_if_fail (component_id >= 1, FALSE); agent_lock (); if (!agent_find_component (agent, stream_id, component_id, NULL, &component)) { ret = FALSE; goto done; } nice_component_clean_turn_servers (component); done: agent_unlock_and_emit (agent); return ret; } /* Helper function to allow us to send connchecks reliably. * If the transport is reliable, then we request a reliable send, which will * either send the data, or queue it in the case of unestablished http/socks5 * proxies or tcp-turn. If the transport is not reliable, then it could be an * unreliable tcp-bsd, so we still try a reliable send to see if it can succeed * meaning the message was queued, or if it failed, then it was either udp-bsd * or turn and so we retry with a non reliable send and let the retransmissions * take care of the rest. * This is in order to avoid having to retransmit something if the underlying * socket layer can queue the message and send it once a connection is * established. */ gssize agent_socket_send (NiceSocket *sock, const NiceAddress *addr, gsize len, const gchar *buf) { if (nice_socket_is_reliable (sock)) { guint16 rfc4571_frame = htons (len); GOutputVector local_buf[2] = {{&rfc4571_frame, 2}, { buf, len }}; NiceOutputMessage local_message = { local_buf, 2}; gint ret; /* ICE-TCP requires that all packets be framed with RFC4571 */ ret = nice_socket_send_messages_reliable (sock, addr, &local_message, 1); if (ret == 1) return len; return ret; } else { gssize ret = nice_socket_send_reliable (sock, addr, len, buf); if (ret < 0) ret = nice_socket_send (sock, addr, len, buf); return ret; } } NiceComponentState nice_agent_get_component_state (NiceAgent *agent, guint stream_id, guint component_id) { NiceComponentState state = NICE_COMPONENT_STATE_FAILED; NiceComponent *component; agent_lock (); if (agent_find_component (agent, stream_id, component_id, NULL, &component)) state = component->state; agent_unlock (); return state; } libnice-0.1.14/agent/iostream.h0000664000076400007640000000554712415560725013251 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __NICE_IO_STREAM_H__ #define __NICE_IO_STREAM_H__ #include #include G_BEGIN_DECLS /* TYPE MACROS */ /* IO Stream */ #define NICE_TYPE_IO_STREAM \ (nice_io_stream_get_type ()) #define NICE_IO_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), NICE_TYPE_IO_STREAM, \ NiceIOStream)) #define NICE_IO_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), NICE_TYPE_IO_STREAM, \ NiceIOStreamClass)) #define NICE_IS_IO_STREAM(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj), NICE_TYPE_IO_STREAM)) #define NICE_IS_IO_STREAM_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass), NICE_TYPE_IO_STREAM)) #define NICE_IO_STREAM_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), NICE_TYPE_IO_STREAM, \ NiceIOStreamClass)) /* IO Stream */ typedef struct _NiceIOStreamPrivate NiceIOStreamPrivate; typedef struct _NiceIOStreamClass NiceIOStreamClass; typedef struct _NiceIOStream NiceIOStream; #include "agent.h" #include "inputstream.h" #include "outputstream.h" /* IO Stream */ GType nice_io_stream_get_type (void); struct _NiceIOStreamClass { GIOStreamClass parent_class; }; struct _NiceIOStream { GIOStream parent_instance; NiceIOStreamPrivate *priv; }; GIOStream *nice_io_stream_new (NiceAgent *agent, guint stream_id, guint component_id); G_END_DECLS #endif /* __NICE_IO_STREAM_H__ */ libnice-0.1.14/agent/iostream.c0000664000076400007640000002556712520743534013246 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /*** * SECTION:nice_io_stream * @short_description: #GIOStream implementation for libnice * @see_also: #NiceAgent * @include: iostream.h * @stability: Stable * * #NiceIOStream is a #GIOStream wrapper for a single reliable stream and * component of a #NiceAgent. Given an existing reliable #NiceAgent, plus the * IDs of an existing stream and component in the agent, it will provide a * streaming input and output interface for communication over the given * component. * * A single #NiceIOStream can only be used with a single agent, stream and * component triple, and will be closed as soon as that stream is removed from * the agent (e.g. if nice_agent_remove_stream() is called from another thread). * If g_io_stream_close() is called on a #NiceIOStream, the I/O stream and * underlying #NiceAgent stream will be closed in both directions, but the * underlying stream will not be removed. Use nice_agent_remove_stream() to do * that, but only do so after g_io_stream_close() has completed, or the stream * will return broken pipe errors. * * Since: 0.1.5 */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "iostream.h" #include "inputstream.h" #include "outputstream.h" G_DEFINE_TYPE (NiceIOStream, nice_io_stream, G_TYPE_IO_STREAM); enum { PROP_AGENT = 1, PROP_STREAM_ID, PROP_COMPONENT_ID, }; struct _NiceIOStreamPrivate { GWeakRef/**/ agent_ref; guint stream_id; guint component_id; GInputStream *input_stream; /* owned */ GOutputStream *output_stream; /* owned */ }; static void nice_io_stream_dispose (GObject *object); static void nice_io_stream_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void nice_io_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static GInputStream *nice_io_stream_get_input_stream (GIOStream *stream); static GOutputStream *nice_io_stream_get_output_stream (GIOStream *stream); static void streams_removed_cb (NiceAgent *agent, guint *stream_ids, gpointer user_data); static void nice_io_stream_class_init (NiceIOStreamClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass); g_type_class_add_private (klass, sizeof (NiceIOStreamPrivate)); gobject_class->set_property = nice_io_stream_set_property; gobject_class->get_property = nice_io_stream_get_property; gobject_class->dispose = nice_io_stream_dispose; stream_class->get_input_stream = nice_io_stream_get_input_stream; stream_class->get_output_stream = nice_io_stream_get_output_stream; /* * NiceIOStream:agent: * * The #NiceAgent to wrap with an I/O stream. This must be an existing * reliable agent. * * A reference is not held on the #NiceAgent. If the agent is destroyed before * the #NiceIOStream, %G_IO_ERROR_CLOSED will be returned for all subsequent * operations on the stream. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_AGENT, g_param_spec_object ("agent", "NiceAgent", "The underlying NiceAgent", NICE_TYPE_AGENT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /* * NiceIOStream:stream-id: * * ID of the stream to use in the #NiceIOStream:agent. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_STREAM_ID, g_param_spec_uint ( "stream-id", "Agent’s stream ID", "The ID of the agent’s stream to wrap.", 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /* * NiceIOStream:component-id: * * ID of the component to use in the #NiceIOStream:agent. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_COMPONENT_ID, g_param_spec_uint ( "component-id", "Agent’s component ID", "The ID of the agent’s component to wrap.", 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void nice_io_stream_init (NiceIOStream *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NICE_TYPE_IO_STREAM, NiceIOStreamPrivate); g_weak_ref_init (&self->priv->agent_ref, NULL); /* Invalidate the stream/component IDs to begin with. */ self->priv->stream_id = 0; self->priv->component_id = 0; } static void nice_io_stream_dispose (GObject *object) { NiceIOStream *self = NICE_IO_STREAM (object); NiceAgent *agent; /* Ensure the stream is closed before continuing. Otherwise, if the input or * output streams haven’t yet been lazily created, closing the stream in * g_io_stream_dispose() will lazily create them, but NiceAgent will be NULL * by that point and things will explode. */ if (!g_io_stream_is_closed (G_IO_STREAM (object))) g_io_stream_close (G_IO_STREAM (object), NULL, NULL); /* Clear everything away. */ if (self->priv->input_stream != NULL) g_object_unref (self->priv->input_stream); self->priv->input_stream = NULL; if (self->priv->output_stream != NULL) g_object_unref (self->priv->output_stream); self->priv->output_stream = NULL; agent = g_weak_ref_get (&self->priv->agent_ref); if (agent != NULL) { g_signal_handlers_disconnect_by_func (agent, streams_removed_cb, self); g_object_unref (agent); } g_weak_ref_clear (&self->priv->agent_ref); G_OBJECT_CLASS (nice_io_stream_parent_class)->dispose (object); } static void nice_io_stream_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NiceIOStream *self = NICE_IO_STREAM (object); switch (prop_id) { case PROP_AGENT: g_value_take_object (value, g_weak_ref_get (&self->priv->agent_ref)); break; case PROP_STREAM_ID: g_value_set_uint (value, self->priv->stream_id); break; case PROP_COMPONENT_ID: g_value_set_uint (value, self->priv->component_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void nice_io_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NiceIOStream *self = NICE_IO_STREAM (object); switch (prop_id) { case PROP_AGENT: { /* Construct only. */ NiceAgent *agent = g_value_dup_object (value); g_weak_ref_set (&self->priv->agent_ref, agent); g_signal_connect (agent, "streams-removed", (GCallback) streams_removed_cb, self); g_object_unref (agent); break; } case PROP_STREAM_ID: /* Construct only. */ self->priv->stream_id = g_value_get_uint (value); break; case PROP_COMPONENT_ID: /* Construct only. */ self->priv->component_id = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } /*** * nice_io_stream_new: * @agent: A #NiceAgent * @stream_id: The ID of the agent’s stream to wrap * @component_id: The ID of the agent’s component to wrap * * Create a new #NiceIOStream wrapping the given stream/component from @agent, * which must be a reliable #NiceAgent. * * The constructed #NiceIOStream will not hold a reference to @agent. If @agent * is destroyed before the I/O stream, %G_IO_ERROR_CLOSED will be returned for * all subsequent operations on the stream. * * Returns: The new #NiceIOStream object * * Since: 0.1.5 */ GIOStream * nice_io_stream_new (NiceAgent *agent, guint stream_id, guint component_id) { g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id > 0, NULL); g_return_val_if_fail (component_id > 0, NULL); return g_object_new (NICE_TYPE_IO_STREAM, "agent", agent, "stream-id", stream_id, "component-id", component_id, NULL); } static GInputStream * nice_io_stream_get_input_stream (GIOStream *stream) { NiceIOStream *self = NICE_IO_STREAM (stream); if (G_UNLIKELY (self->priv->input_stream == NULL)) { NiceAgent *agent; /* Note that agent may be NULL here. NiceInputStream must support * construction with a NULL agent. */ agent = g_weak_ref_get (&self->priv->agent_ref); self->priv->input_stream = G_INPUT_STREAM (nice_input_stream_new ( agent, self->priv->stream_id, self->priv->component_id)); if (agent != NULL) g_object_unref (agent); } return self->priv->input_stream; } static GOutputStream * nice_io_stream_get_output_stream (GIOStream *stream) { NiceIOStream *self = NICE_IO_STREAM (stream); if (G_UNLIKELY (self->priv->output_stream == NULL)) { NiceAgent *agent; /* Note that agent may be NULL here. NiceOutputStream must support * construction with a NULL agent. */ agent = g_weak_ref_get (&self->priv->agent_ref); self->priv->output_stream = g_object_new (NICE_TYPE_OUTPUT_STREAM, "agent", agent, "stream-id", self->priv->stream_id, "component-id", self->priv->component_id, NULL); if (agent != NULL) g_object_unref (agent); } return self->priv->output_stream; } static void streams_removed_cb (NiceAgent *agent, guint *stream_ids, gpointer user_data) { NiceIOStream *self = NICE_IO_STREAM (user_data); guint i; for (i = 0; stream_ids[i] != 0; i++) { if (stream_ids[i] == self->priv->stream_id) { /* The socket has been closed. */ g_io_stream_close (G_IO_STREAM (self), NULL, NULL); break; } } } libnice-0.1.14/agent/debug.c0000664000076400007640000001177412721653252012504 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008 Collabora Ltd. * Contact: Youness Alaoui * (C) 2008 Nokia Corporation. All rights reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "debug.h" #include "stunagent.h" #include "pseudotcp.h" #include "agent-priv.h" static int debug_enabled = 0; static int debug_verbose_enabled = 0; #define NICE_DEBUG_STUN 1 #define NICE_DEBUG_NICE 2 #define NICE_DEBUG_PSEUDOTCP 4 #define NICE_DEBUG_PSEUDOTCP_VERBOSE 8 #define NICE_DEBUG_NICE_VERBOSE 16 static const GDebugKey keys[] = { { (gchar *)"stun", NICE_DEBUG_STUN }, { (gchar *)"nice", NICE_DEBUG_NICE }, { (gchar *)"pseudotcp", NICE_DEBUG_PSEUDOTCP }, { (gchar *)"pseudotcp-verbose", NICE_DEBUG_PSEUDOTCP_VERBOSE }, { (gchar *)"nice-verbose", NICE_DEBUG_NICE_VERBOSE }, { NULL, 0}, }; static const GDebugKey gkeys[] = { { (gchar *)"libnice-stun", NICE_DEBUG_STUN }, { (gchar *)"libnice", NICE_DEBUG_NICE }, { (gchar *)"libnice-pseudotcp", NICE_DEBUG_PSEUDOTCP }, { (gchar *)"libnice-pseudotcp-verbose", NICE_DEBUG_PSEUDOTCP_VERBOSE }, { (gchar *)"libnice-verbose", NICE_DEBUG_NICE_VERBOSE }, { NULL, 0}, }; static void stun_handler (const char *format, va_list ap) G_GNUC_PRINTF (1, 0); static void stun_handler (const char *format, va_list ap) { g_logv ("libnice-stun", G_LOG_LEVEL_DEBUG, format, ap); } void nice_debug_init (void) { static gboolean debug_initialized = FALSE; const gchar *flags_string; const gchar *gflags_string; guint flags = 0; if (!debug_initialized) { debug_initialized = TRUE; flags_string = g_getenv ("NICE_DEBUG"); gflags_string = g_getenv ("G_MESSAGES_DEBUG"); if (flags_string) flags = g_parse_debug_string (flags_string, keys, 4); if (gflags_string) flags |= g_parse_debug_string (gflags_string, gkeys, 4); if (gflags_string && strstr (gflags_string, "libnice-pseudotcp-verbose")) flags |= NICE_DEBUG_PSEUDOTCP_VERBOSE; if (gflags_string && strstr (gflags_string, "libnice-nice-verbose")) { flags |= NICE_DEBUG_NICE_VERBOSE; } stun_set_debug_handler (stun_handler); debug_enabled = !!(flags & NICE_DEBUG_NICE); if (flags & NICE_DEBUG_STUN) stun_debug_enable (); else stun_debug_disable (); if (flags & NICE_DEBUG_NICE_VERBOSE) debug_verbose_enabled = TRUE; /* Set verbose before normal so that if we use 'all', then only normal debug is enabled, we'd need to set pseudotcp-verbose without the pseudotcp flag in order to actually enable verbose pseudotcp */ if (flags & NICE_DEBUG_PSEUDOTCP_VERBOSE) pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE); else if (flags & NICE_DEBUG_PSEUDOTCP) pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_NORMAL); } } #ifndef NDEBUG gboolean nice_debug_is_enabled (void) { return debug_enabled; } gboolean nice_debug_is_verbose (void) { return debug_verbose_enabled; } #else /* Defined in agent-priv.h. */ #endif void nice_debug_enable (gboolean with_stun) { nice_debug_init (); debug_enabled = 1; if (with_stun) stun_debug_enable (); } void nice_debug_disable (gboolean with_stun) { nice_debug_init (); debug_enabled = 0; if (with_stun) stun_debug_disable (); } #ifndef NDEBUG void nice_debug (const char *fmt, ...) { va_list ap; if (debug_enabled) { va_start (ap, fmt); g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, fmt, ap); va_end (ap); } } void nice_debug_verbose (const char *fmt, ...) { va_list ap; if (debug_verbose_enabled) { va_start (ap, fmt); g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, fmt, ap); va_end (ap); } } #else /* Defined in agent-priv.h. */ #endif libnice-0.1.14/agent/interfaces.h0000664000076400007640000000470612520743534013543 00000000000000/* * interfaces.h - Source for interface discovery code * * Farsight Helper functions * Copyright (C) 2006 Youness Alaoui * Copyright (C) 2008-2009 Collabora, Nokia * Contact: Youness Alaoui * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LIBNICE_INTERFACES_H__ #define __LIBNICE_INTERFACES_H__ /** * SECTION:interfaces * @short_description: Utility functions to discover local network interfaces * @include: interfaces.h * @stability: Stable * * These utility functions allow the discovery of local network interfaces * in a portable manner, they also allow finding the local ip addresses or * the address allocated to a network interface. */ #include G_BEGIN_DECLS /** * nice_interfaces_get_ip_for_interface: * @interface_name: name of local interface * * Retrieves the IP address of an interface by its name. If this fails, %NULL * is returned. * * Returns: (nullable) (transfer full): a newly-allocated string with the IP * address */ gchar * nice_interfaces_get_ip_for_interface (gchar *interface_name); /** * nice_interfaces_get_local_ips: * @include_loopback: Include any loopback devices * * Get a list of local ipv4 interface addresses * * Returns: (element-type utf8) (transfer full): a newly-allocated #GList of * strings. The caller must free it. */ GList * nice_interfaces_get_local_ips (gboolean include_loopback); /** * nice_interfaces_get_local_interfaces: * * Get the list of local interfaces * * Returns: (element-type utf8) (transfer full): a newly-allocated #GList of * strings. The caller must free it. */ GList * nice_interfaces_get_local_interfaces (void); G_END_DECLS #endif /* __LIBNICE_INTERFACES_H__ */ libnice-0.1.14/agent/address.c0000664000076400007640000002233012564721761013037 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #else #define NICEAPI_EXPORT #endif #include #ifdef HAVE_NETDB_H #include #endif #include "address.h" #ifdef G_OS_WIN32 #define inet_ntop inet_ntop_win32 /* Defined in recent versions of mingw: * https://github.com/mirror/mingw-w64/commit/0f4899473c4ba2e34fa447b1931a04e38c1f105e */ #ifndef IN6_ARE_ADDR_EQUAL #define IN6_ARE_ADDR_EQUAL(a, b) \ (memcmp ((const void *) (a), (const void *) (b), sizeof (struct in6_addr)) == 0) #endif static const char * inet_ntop_win32 (int af, const void *src, char *dst, socklen_t cnt) { if (af == AF_INET) { struct sockaddr_in in; memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; memcpy(&in.sin_addr, src, sizeof(struct in_addr)); getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); return dst; } else if (af == AF_INET6) { struct sockaddr_in6 in; memset(&in, 0, sizeof(in)); in.sin6_family = AF_INET6; memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); return dst; } return NULL; } #endif NICEAPI_EXPORT void nice_address_init (NiceAddress *addr) { addr->s.addr.sa_family = AF_UNSPEC; memset (&addr->s, 0, sizeof(addr->s)); } NICEAPI_EXPORT NiceAddress * nice_address_new (void) { NiceAddress *addr = g_slice_new0 (NiceAddress); nice_address_init (addr); return addr; } NICEAPI_EXPORT void nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4) { addr->s.ip4.sin_family = AF_INET; #ifdef HAVE_SA_LEN addr->s.ip4.sin_len = sizeof (addr->sa.ip4); #endif addr->s.ip4.sin_addr.s_addr = addr_ipv4 ? htonl (addr_ipv4) : INADDR_ANY; addr->s.ip4.sin_port = 0; } NICEAPI_EXPORT void nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6) { addr->s.ip6.sin6_family = AF_INET6; #ifdef HAVE_SA_LEN addr->s.ip6.sin6_len = sizeof (addr->sa.ip6); #endif memcpy (addr->s.ip6.sin6_addr.s6_addr, addr_ipv6, 16); addr->s.ip6.sin6_port = 0; addr->s.ip6.sin6_scope_id = 0; } NICEAPI_EXPORT void nice_address_set_port (NiceAddress *addr, guint port) { g_assert (addr); switch (addr->s.addr.sa_family) { case AF_INET: addr->s.ip4.sin_port = htons (port); break; case AF_INET6: addr->s.ip6.sin6_port = htons (port); break; default: g_return_if_reached (); } } guint nice_address_get_port (const NiceAddress *addr) { if (!addr) return 0; switch (addr->s.addr.sa_family) { case AF_INET: return ntohs (addr->s.ip4.sin_port); case AF_INET6: return ntohs (addr->s.ip6.sin6_port); default: g_return_val_if_reached (0); } } NICEAPI_EXPORT gboolean nice_address_set_from_string (NiceAddress *addr, const gchar *str) { struct addrinfo hints; struct addrinfo *res; memset (&hints, 0, sizeof (hints)); /* AI_NUMERICHOST prevents getaddrinfo() from doing DNS resolution. */ hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_NUMERICHOST; if (getaddrinfo (str, NULL, &hints, &res) != 0) return FALSE; /* invalid address */ nice_address_set_from_sockaddr (addr, res->ai_addr); freeaddrinfo (res); return TRUE; } NICEAPI_EXPORT void nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sa) { switch (sa->sa_family) { case AF_INET: memcpy(&addr->s.ip4, sa, sizeof (addr->s.ip4)); break; case AF_INET6: memcpy(&addr->s.ip6, sa, sizeof (addr->s.ip6)); break; default: g_return_if_reached (); } } NICEAPI_EXPORT void nice_address_copy_to_sockaddr (const NiceAddress *addr, struct sockaddr *_sa) { union { struct sockaddr *addr; struct sockaddr_in *in; struct sockaddr_in6 *in6; } sa; sa.addr = _sa; g_assert (_sa); switch (addr->s.addr.sa_family) { case AF_INET: memcpy (sa.in, &addr->s.ip4, sizeof (*sa.in)); break; case AF_INET6: memcpy (sa.in6, &addr->s.ip6, sizeof (*sa.in6)); break; default: g_return_if_reached (); } } NICEAPI_EXPORT void nice_address_to_string (const NiceAddress *addr, gchar *dst) { switch (addr->s.addr.sa_family) { case AF_INET: inet_ntop (AF_INET, &addr->s.ip4.sin_addr, dst, INET_ADDRSTRLEN); break; case AF_INET6: inet_ntop (AF_INET6, &addr->s.ip6.sin6_addr, dst, INET6_ADDRSTRLEN); break; default: g_return_if_reached (); } } NICEAPI_EXPORT gboolean nice_address_equal (const NiceAddress *a, const NiceAddress *b) { if (a->s.addr.sa_family != b->s.addr.sa_family) return FALSE; switch (a->s.addr.sa_family) { case AF_INET: return (a->s.ip4.sin_addr.s_addr == b->s.ip4.sin_addr.s_addr) && (a->s.ip4.sin_port == b->s.ip4.sin_port); case AF_INET6: return IN6_ARE_ADDR_EQUAL (&a->s.ip6.sin6_addr, &b->s.ip6.sin6_addr) && (a->s.ip6.sin6_port == b->s.ip6.sin6_port) && (a->s.ip6.sin6_scope_id == 0 || b->s.ip6.sin6_scope_id == 0 || (a->s.ip6.sin6_scope_id == b->s.ip6.sin6_scope_id)); default: g_return_val_if_reached (FALSE); } } NICEAPI_EXPORT NiceAddress * nice_address_dup (const NiceAddress *a) { NiceAddress *dup = g_slice_new0 (NiceAddress); *dup = *a; return dup; } NICEAPI_EXPORT void nice_address_free (NiceAddress *addr) { g_slice_free (NiceAddress, addr); } /* "private" in the sense of "not routable on the Internet" */ static gboolean ipv4_address_is_private (guint32 addr) { addr = ntohl (addr); /* http://tools.ietf.org/html/rfc3330 */ return ( /* 10.0.0.0/8 */ ((addr & 0xff000000) == 0x0a000000) || /* 172.16.0.0/12 */ ((addr & 0xfff00000) == 0xac100000) || /* 192.168.0.0/16 */ ((addr & 0xffff0000) == 0xc0a80000) || /* 127.0.0.0/8 */ ((addr & 0xff000000) == 0x7f000000)); } static gboolean ipv6_address_is_private (const guchar *addr) { return ( /* fe80::/10 */ ((addr[0] == 0xfe) && ((addr[1] & 0xc0) == 0x80)) || /* fc00::/7 */ ((addr[0] & 0xfe) == 0xfc) || /* ::1 loopback */ ((memcmp (addr, "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x01", 16) == 0))); } NICEAPI_EXPORT gboolean nice_address_is_private (const NiceAddress *a) { switch (a->s.addr.sa_family) { case AF_INET: return ipv4_address_is_private (a->s.ip4.sin_addr.s_addr); case AF_INET6: return ipv6_address_is_private (a->s.ip6.sin6_addr.s6_addr); default: g_return_val_if_reached (FALSE); } } NICEAPI_EXPORT gboolean nice_address_is_valid (const NiceAddress *a) { switch (a->s.addr.sa_family) { case AF_INET: case AF_INET6: return TRUE; default: return FALSE; } } NICEAPI_EXPORT int nice_address_ip_version (const NiceAddress *addr) { switch (addr->s.addr.sa_family) { case AF_INET: return 4; case AF_INET6: return 6; default: return 0; } } NICEAPI_EXPORT gboolean nice_address_equal_no_port (const NiceAddress *a, const NiceAddress *b) { if (a->s.addr.sa_family != b->s.addr.sa_family) return FALSE; switch (a->s.addr.sa_family) { case AF_INET: return (a->s.ip4.sin_addr.s_addr == b->s.ip4.sin_addr.s_addr); case AF_INET6: return IN6_ARE_ADDR_EQUAL (&a->s.ip6.sin6_addr, &b->s.ip6.sin6_addr) && (a->s.ip6.sin6_scope_id == 0 || b->s.ip6.sin6_scope_id == 0 || (a->s.ip6.sin6_scope_id == b->s.ip6.sin6_scope_id)); default: g_return_val_if_reached (FALSE); } } libnice-0.1.14/agent/candidate.h0000664000076400007640000001653512721653731013341 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __LIBNICE_CANDIDATE_H__ #define __LIBNICE_CANDIDATE_H__ #include #include /** * SECTION:candidate * @short_description: ICE candidate representation * @see_also: #NiceAddress * @stability: Stable * * A representation of an ICE candidate. Make sure you read the ICE drafts[1] to * understand correctly the concept of ICE candidates. * * [1] http://tools.ietf.org/wg/mmusic/draft-ietf-mmusic-ice/ */ G_BEGIN_DECLS /* Constants for determining candidate priorities */ #define NICE_CANDIDATE_TYPE_PREF_HOST 120 #define NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE 110 #define NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED 105 #define NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE 100 #define NICE_CANDIDATE_TYPE_PREF_RELAYED_UDP 30 #define NICE_CANDIDATE_TYPE_PREF_RELAYED 20 /* Priority preference constants for MS-ICE compatibility */ #define NICE_CANDIDATE_TRANSPORT_MS_PREF_UDP 15 #define NICE_CANDIDATE_TRANSPORT_MS_PREF_TCP 6 #define NICE_CANDIDATE_DIRECTION_MS_PREF_PASSIVE 2 #define NICE_CANDIDATE_DIRECTION_MS_PREF_ACTIVE 5 /* Max foundation size '1*32ice-char' plus terminating NULL, ICE ID-19 */ /** * NICE_CANDIDATE_MAX_FOUNDATION: * * The maximum size a candidate foundation can have. */ #define NICE_CANDIDATE_MAX_FOUNDATION (32+1) /** * NiceCandidateType: * @NICE_CANDIDATE_TYPE_HOST: A host candidate * @NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: A server reflexive candidate * @NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: A peer reflexive candidate * @NICE_CANDIDATE_TYPE_RELAYED: A relay candidate * * An enum represneting the type of a candidate */ typedef enum { NICE_CANDIDATE_TYPE_HOST, NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE, NICE_CANDIDATE_TYPE_PEER_REFLEXIVE, NICE_CANDIDATE_TYPE_RELAYED, } NiceCandidateType; /** * NiceCandidateTransport: * @NICE_CANDIDATE_TRANSPORT_UDP: UDP transport * @NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: TCP Active transport * @NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: TCP Passive transport * @NICE_CANDIDATE_TRANSPORT_TCP_SO: TCP Simultaneous-Open transport * * An enum representing the type of transport to use */ typedef enum { NICE_CANDIDATE_TRANSPORT_UDP, NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE, NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE, NICE_CANDIDATE_TRANSPORT_TCP_SO, } NiceCandidateTransport; /** * NiceRelayType: * @NICE_RELAY_TYPE_TURN_UDP: A TURN relay using UDP * @NICE_RELAY_TYPE_TURN_TCP: A TURN relay using TCP * @NICE_RELAY_TYPE_TURN_TLS: A TURN relay using TLS over TCP * * An enum representing the type of relay to use */ typedef enum { NICE_RELAY_TYPE_TURN_UDP, NICE_RELAY_TYPE_TURN_TCP, NICE_RELAY_TYPE_TURN_TLS } NiceRelayType; typedef struct _NiceCandidate NiceCandidate; typedef struct _TurnServer TurnServer; /** * TurnServer: * @ref_count: Reference count for the structure. * @server: The #NiceAddress of the TURN server * @username: The TURN username * @password: The TURN password * @type: The #NiceRelayType of the server * * A structure to store the TURN relay settings */ struct _TurnServer { gint ref_count; NiceAddress server; gchar *username; gchar *password; NiceRelayType type; }; /** * NiceCandidate: * @type: The type of candidate * @transport: The transport being used for the candidate * @addr: The #NiceAddress of the candidate * @base_addr: The #NiceAddress of the base address used by the candidate * @priority: The priority of the candidate see note * @stream_id: The ID of the stream to which belongs the candidate * @component_id: The ID of the component to which belongs the candidate * @foundation: The foundation of the candidate * @username: The candidate-specific username to use (overrides the one set * by nice_agent_set_local_credentials() or nice_agent_set_remote_credentials()) * @password: The candidate-specific password to use (overrides the one set * by nice_agent_set_local_credentials() or nice_agent_set_remote_credentials()) * @turn: The #TurnServer settings if the candidate is * of type %NICE_CANDIDATE_TYPE_RELAYED * @sockptr: The underlying socket * * A structure to represent an ICE candidate The @priority is an integer as specified in the ICE draft 19. If you are using the MSN or the GOOGLE compatibility mode (which are based on ICE draft 6, which uses a floating point qvalue as priority), then the @priority value will represent the qvalue multiplied by 1000. */ struct _NiceCandidate { NiceCandidateType type; NiceCandidateTransport transport; NiceAddress addr; NiceAddress base_addr; guint32 priority; guint stream_id; guint component_id; gchar foundation[NICE_CANDIDATE_MAX_FOUNDATION]; gchar *username; /* pointer to a nul-terminated username string */ gchar *password; /* pointer to a nul-terminated password string */ TurnServer *turn; gpointer sockptr; }; /** * nice_candidate_new: * @type: The #NiceCandidateType of the candidate to create * * Creates a new candidate. Must be freed with nice_candidate_free() * * Returns: A new #NiceCandidate */ NiceCandidate * nice_candidate_new (NiceCandidateType type); /** * nice_candidate_free: * @candidate: The candidate to free * * Frees a #NiceCandidate */ void nice_candidate_free (NiceCandidate *candidate); /** * nice_candidate_copy: * @candidate: The candidate to copy * * Makes a copy of a #NiceCandidate * * Returns: A new #NiceCandidate, a copy of @candidate */ NiceCandidate * nice_candidate_copy (const NiceCandidate *candidate); GType nice_candidate_get_type (void); /** * NICE_TYPE_CANDIDATE: * * A boxed type for a #NiceCandidate. */ #define NICE_TYPE_CANDIDATE nice_candidate_get_type () G_END_DECLS #endif /* __LIBNICE_CANDIDATE_H__ */ libnice-0.1.14/agent/candidate.c0000664000076400007640000002511113070472030013307 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * @file candidate.c * @brief ICE candidate functions */ #ifdef HAVE_CONFIG_H # include #else #define NICEAPI_EXPORT #endif #include #include "agent.h" #include "component.h" #include "interfaces.h" G_DEFINE_BOXED_TYPE (NiceCandidate, nice_candidate, nice_candidate_copy, nice_candidate_free); /* (ICE 4.1.1 "Gathering Candidates") ""Every candidate is a transport * address. It also has a type and a base. Three types are defined and * gathered by this specification - host candidates, server reflexive * candidates, and relayed candidates."" (ID-19) */ NICEAPI_EXPORT NiceCandidate * nice_candidate_new (NiceCandidateType type) { NiceCandidate *candidate; candidate = g_slice_new0 (NiceCandidate); candidate->type = type; return candidate; } NICEAPI_EXPORT void nice_candidate_free (NiceCandidate *candidate) { /* better way of checking if socket is allocated? */ if (candidate->username) g_free (candidate->username); if (candidate->password) g_free (candidate->password); if (candidate->turn) turn_server_unref (candidate->turn); g_slice_free (NiceCandidate, candidate); } guint32 nice_candidate_jingle_priority (NiceCandidate *candidate) { switch (candidate->type) { case NICE_CANDIDATE_TYPE_HOST: return 1000; case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: return 900; case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: return 900; case NICE_CANDIDATE_TYPE_RELAYED: return 500; default: return 0; } } guint32 nice_candidate_msn_priority (NiceCandidate *candidate) { switch (candidate->type) { case NICE_CANDIDATE_TYPE_HOST: return 830; case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: return 550; case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: return 550; case NICE_CANDIDATE_TYPE_RELAYED: return 450; default: return 0; } } /* * ICE 4.1.2.1. "Recommended Formula" (ID-19): * returns number between 1 and 0x7effffff */ guint32 nice_candidate_ice_priority_full ( // must be ∈ (0, 126) (max 2^7 - 2) guint type_preference, // must be ∈ (0, 65535) (max 2^16 - 1) guint local_preference, // must be ∈ (0, 255) (max 2 ^ 8 - 1) guint component_id) { return ( 0x1000000 * type_preference + 0x100 * local_preference + (0x100 - component_id)); } static guint32 nice_candidate_ice_local_preference_full (guint direction_preference, guint other_preference) { return (0x2000 * direction_preference + other_preference); } static guint8 nice_candidate_ip_local_preference (const NiceCandidate *candidate) { guint8 preference = 0; gchar ip_string[INET6_ADDRSTRLEN]; GList/**/ *ips = NULL; GList/**/ *iter; /* Ensure otherwise identical host candidates with only different IP addresses * (multihomed host) get assigned different priorities. Position of the IP in * the list obtained from nice_interfaces_get_local_ips() serves here as the * distinguishing value of other_preference. Reflexive and relayed candidates * are likewise differentiated by their base address. * * This is required by RFC 5245 Section 4.1.2.1: * https://tools.ietf.org/html/rfc5245#section-4.1.2.1 */ if (candidate->type == NICE_CANDIDATE_TYPE_HOST) { nice_address_to_string (&candidate->addr, ip_string); } else { nice_address_to_string (&candidate->base_addr, ip_string); } ips = nice_interfaces_get_local_ips (TRUE); for (iter = ips; iter; iter = g_list_next (iter)) { if (g_strcmp0 (ip_string, iter->data) == 0) { break; } ++preference; } g_list_free_full (ips, g_free); return preference; } static guint16 nice_candidate_ice_local_preference (const NiceCandidate *candidate) { guint direction_preference; switch (candidate->transport) { case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || candidate->type == NICE_CANDIDATE_TYPE_HOST) direction_preference = 4; else direction_preference = 6; break; case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || candidate->type == NICE_CANDIDATE_TYPE_HOST) direction_preference = 2; else direction_preference = 4; break; case NICE_CANDIDATE_TRANSPORT_TCP_SO: if (candidate->type == NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE || candidate->type == NICE_CANDIDATE_TYPE_HOST) direction_preference = 6; else direction_preference = 2; break; case NICE_CANDIDATE_TRANSPORT_UDP: default: return 1; break; } return nice_candidate_ice_local_preference_full (direction_preference, nice_candidate_ip_local_preference (candidate)); } static guint32 nice_candidate_ms_ice_local_preference_full (guint transport_preference, guint direction_preference, guint other_preference) { return 0x1000 * transport_preference + 0x200 * direction_preference + 0x1 * other_preference; } static guint32 nice_candidate_ms_ice_local_preference (const NiceCandidate *candidate) { guint8 transport_preference = 0; guint8 direction_preference = 0; switch (candidate->transport) { case NICE_CANDIDATE_TRANSPORT_TCP_SO: case NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE: transport_preference = NICE_CANDIDATE_TRANSPORT_MS_PREF_TCP; direction_preference = NICE_CANDIDATE_DIRECTION_MS_PREF_ACTIVE; break; case NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE: transport_preference = NICE_CANDIDATE_TRANSPORT_MS_PREF_TCP; direction_preference = NICE_CANDIDATE_DIRECTION_MS_PREF_PASSIVE; break; case NICE_CANDIDATE_TRANSPORT_UDP: default: transport_preference = NICE_CANDIDATE_TRANSPORT_MS_PREF_UDP; break; } return nice_candidate_ms_ice_local_preference_full(transport_preference, direction_preference, nice_candidate_ip_local_preference (candidate)); } static guint8 nice_candidate_ice_type_preference (const NiceCandidate *candidate, gboolean reliable, gboolean nat_assisted) { guint8 type_preference; switch (candidate->type) { case NICE_CANDIDATE_TYPE_HOST: type_preference = NICE_CANDIDATE_TYPE_PREF_HOST; break; case NICE_CANDIDATE_TYPE_PEER_REFLEXIVE: type_preference = NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE; break; case NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: if (nat_assisted) type_preference = NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED; else type_preference = NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE; break; case NICE_CANDIDATE_TYPE_RELAYED: if (candidate->turn->type == NICE_RELAY_TYPE_TURN_UDP) type_preference = NICE_CANDIDATE_TYPE_PREF_RELAYED_UDP; else type_preference = NICE_CANDIDATE_TYPE_PREF_RELAYED; break; default: type_preference = 0; break; } if ((reliable && candidate->transport == NICE_CANDIDATE_TRANSPORT_UDP) || (!reliable && candidate->transport != NICE_CANDIDATE_TRANSPORT_UDP)) { type_preference = type_preference / 2; } return type_preference; } guint32 nice_candidate_ice_priority (const NiceCandidate *candidate, gboolean reliable, gboolean nat_assisted) { guint8 type_preference; guint16 local_preference; type_preference = nice_candidate_ice_type_preference (candidate, reliable, nat_assisted); local_preference = nice_candidate_ice_local_preference (candidate); return nice_candidate_ice_priority_full (type_preference, local_preference, candidate->component_id); } guint32 nice_candidate_ms_ice_priority (const NiceCandidate *candidate, gboolean reliable, gboolean nat_assisted) { guint8 type_preference; guint16 local_preference; type_preference = nice_candidate_ice_type_preference (candidate, reliable, nat_assisted); local_preference = nice_candidate_ms_ice_local_preference (candidate); return nice_candidate_ice_priority_full (type_preference, local_preference, candidate->component_id); } /* * Calculates the pair priority as specified in ICE * sect 5.7.2. "Computing Pair Priority and Ordering Pairs" (ID-19). */ guint64 nice_candidate_pair_priority (guint32 o_prio, guint32 a_prio) { guint32 max = o_prio > a_prio ? o_prio : a_prio; guint32 min = o_prio < a_prio ? o_prio : a_prio; /* These two constants are here explictly to make some version of GCC happy */ const guint64 one = 1; const guint64 thirtytwo = 32; return (one << thirtytwo) * min + 2 * max + (o_prio > a_prio ? 1 : 0); } /* * Copies a candidate */ NICEAPI_EXPORT NiceCandidate * nice_candidate_copy (const NiceCandidate *candidate) { NiceCandidate *copy; g_return_val_if_fail (candidate != NULL, NULL); copy = nice_candidate_new (candidate->type); memcpy (copy, candidate, sizeof(NiceCandidate)); copy->turn = NULL; copy->username = g_strdup (copy->username); copy->password = g_strdup (copy->password); return copy; } libnice-0.1.14/agent/inputstream.c0000664000076400007640000003563712661700132013766 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /*** * SECTION:nice_input_stream * @short_description: #GInputStream implementation for libnice * @see_also: #NiceAgent * @include: inputstream.h * @stability: Stable * * #NiceInputStream is a #GInputStream wrapper for a single reliable stream and * component of a #NiceAgent. Given an existing reliable #NiceAgent, plus the * IDs of an existing stream and component in the agent, it will provide a * streaming input interface for reading from the given component. * * A single #NiceInputStream can only be used with a single agent, stream and * component triple, and will be closed as soon as that stream is removed from * the agent (e.g. if nice_agent_remove_stream() is called from another thread). * If g_input_stream_close() is called on a #NiceInputStream, the input stream * and underlying #NiceAgent stream will be closed, but the underlying stream * will not be removed. Use nice_agent_remove_stream() to do that. * * Since: 0.1.5 */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "inputstream.h" #include "agent-priv.h" static void streams_removed_cb (NiceAgent *agent, guint *stream_ids, gpointer user_data); static void nice_input_stream_init_pollable ( GPollableInputStreamInterface *iface); G_DEFINE_TYPE_WITH_CODE (NiceInputStream, nice_input_stream, G_TYPE_INPUT_STREAM, G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, nice_input_stream_init_pollable)); enum { PROP_AGENT = 1, PROP_STREAM_ID, PROP_COMPONENT_ID, }; struct _NiceInputStreamPrivate { GWeakRef/**/ agent_ref; guint stream_id; guint component_id; }; static void nice_input_stream_dispose (GObject *object); static void nice_input_stream_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void nice_input_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static gssize nice_input_stream_read (GInputStream *stream, void *buffer, gsize count, GCancellable *cancellable, GError **error); static gboolean nice_input_stream_close (GInputStream *stream, GCancellable *cancellable, GError **error); static gboolean nice_input_stream_is_readable (GPollableInputStream *stream); static gssize nice_input_stream_read_nonblocking (GPollableInputStream *stream, void *buffer, gsize count, GError **error); static GSource *nice_input_stream_create_source (GPollableInputStream *stream, GCancellable *cancellable); static void nice_input_stream_class_init (NiceInputStreamClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass); g_type_class_add_private (klass, sizeof (NiceInputStreamPrivate)); gobject_class->set_property = nice_input_stream_set_property; gobject_class->get_property = nice_input_stream_get_property; gobject_class->dispose = nice_input_stream_dispose; stream_class->read_fn = nice_input_stream_read; stream_class->close_fn = nice_input_stream_close; /*** * NiceInputStream:agent: * * The #NiceAgent to wrap with an input stream. This must be an existing * reliable agent. * * A reference is not held on the #NiceAgent. If the agent is destroyed before * the #NiceInputStream, %G_IO_ERROR_CLOSED will be returned for all * subsequent operations on the stream. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_AGENT, g_param_spec_object ("agent", "NiceAgent", "The underlying NiceAgent", NICE_TYPE_AGENT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /*** * NiceInputStream:stream-id: * * ID of the stream to use in the #NiceInputStream:agent. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_STREAM_ID, g_param_spec_uint ( "stream-id", "Agent’s stream ID", "The ID of the agent’s stream to wrap.", 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /*** * NiceInputStream:component-id: * * ID of the component to use in the #NiceInputStream:agent. * * Since: 0.1.5 */ g_object_class_install_property (gobject_class, PROP_COMPONENT_ID, g_param_spec_uint ( "component-id", "Agent’s component ID", "The ID of the agent’s component to wrap.", 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void nice_input_stream_dispose (GObject *object) { NiceInputStream *self = NICE_INPUT_STREAM (object); NiceAgent *agent; /* Ensure the stream is closed first, otherwise the agent can’t be found in * the close handler called by the parent implementation. */ if (!g_input_stream_is_closed (G_INPUT_STREAM (object))) g_input_stream_close (G_INPUT_STREAM (object), NULL, NULL); agent = g_weak_ref_get (&self->priv->agent_ref); if (agent != NULL) { g_signal_handlers_disconnect_by_func (agent, streams_removed_cb, self); g_object_unref (agent); } g_weak_ref_clear (&self->priv->agent_ref); G_OBJECT_CLASS (nice_input_stream_parent_class)->dispose (object); } static void nice_input_stream_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NiceInputStream *self = NICE_INPUT_STREAM (object); switch (prop_id) { case PROP_AGENT: g_value_take_object (value, g_weak_ref_get (&self->priv->agent_ref)); break; case PROP_STREAM_ID: g_value_set_uint (value, self->priv->stream_id); break; case PROP_COMPONENT_ID: g_value_set_uint (value, self->priv->component_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void nice_input_stream_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NiceInputStream *self = NICE_INPUT_STREAM (object); switch (prop_id) { case PROP_AGENT: { /* Construct only. */ NiceAgent *agent = g_value_dup_object (value); g_weak_ref_set (&self->priv->agent_ref, agent); /* agent may be NULL if the stream is being constructed by * nice_io_stream_get_input_stream() after the NiceIOStream’s agent has * already been finalised. */ if (agent != NULL) { g_signal_connect (agent, "streams-removed", (GCallback) streams_removed_cb, self); g_object_unref (agent); } break; } case PROP_STREAM_ID: /* Construct only. */ self->priv->stream_id = g_value_get_uint (value); break; case PROP_COMPONENT_ID: /* Construct only. */ self->priv->component_id = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void nice_input_stream_init (NiceInputStream *stream) { stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, NICE_TYPE_INPUT_STREAM, NiceInputStreamPrivate); g_weak_ref_init (&stream->priv->agent_ref, NULL); } static void nice_input_stream_init_pollable (GPollableInputStreamInterface *iface) { iface->is_readable = nice_input_stream_is_readable; iface->read_nonblocking = nice_input_stream_read_nonblocking; iface->create_source = nice_input_stream_create_source; } /*** * nice_input_stream_new: * @agent: A #NiceAgent * @stream_id: The ID of the agent’s stream to wrap * @component_id: The ID of the agent’s component to wrap * * Create a new #NiceInputStream wrapping the given stream/component from * @agent, which must be a reliable #NiceAgent. * * The constructed #NiceInputStream will not hold a reference to @agent. If * @agent is destroyed before the input stream, %G_IO_ERROR_CLOSED will be * returned for all subsequent operations on the stream. * * Returns: The new #NiceInputStream object * * Since: 0.1.5 */ NiceInputStream * nice_input_stream_new (NiceAgent *agent, guint stream_id, guint component_id) { g_return_val_if_fail (NICE_IS_AGENT (agent), NULL); g_return_val_if_fail (stream_id >= 1, NULL); g_return_val_if_fail (component_id >= 1, NULL); return g_object_new (NICE_TYPE_INPUT_STREAM, "agent", agent, "stream-id", stream_id, "component-id", component_id, NULL); } static gssize nice_input_stream_read (GInputStream *stream, void *buffer, gsize count, GCancellable *cancellable, GError **error) { NiceInputStreamPrivate *priv = NICE_INPUT_STREAM (stream)->priv; NiceAgent *agent; /* owned */ gssize len; /* Closed streams are not readable. */ if (g_input_stream_is_closed (stream)) { return 0; } /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Stream is closed due to the NiceAgent being finalised."); return -1; } len = nice_agent_recv (agent, priv->stream_id, priv->component_id, buffer, count, cancellable, error); g_object_unref (agent); return len; } static gboolean nice_input_stream_close (GInputStream *stream, GCancellable *cancellable, GError **error) { NiceInputStreamPrivate *priv = NICE_INPUT_STREAM (stream)->priv; NiceComponent *component = NULL; NiceStream *_stream = NULL; NiceAgent *agent; /* owned */ /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) return TRUE; agent_lock (); /* Shut down the read side of the pseudo-TCP stream, if it still exists. */ if (agent_find_component (agent, priv->stream_id, priv->component_id, &_stream, &component) && agent->reliable && !pseudo_tcp_socket_is_closed (component->tcp)) { pseudo_tcp_socket_shutdown (component->tcp, PSEUDO_TCP_SHUTDOWN_RD); } agent_unlock (); g_object_unref (agent); return TRUE; } static gboolean nice_input_stream_is_readable (GPollableInputStream *stream) { NiceInputStreamPrivate *priv = NICE_INPUT_STREAM (stream)->priv; NiceComponent *component = NULL; NiceStream *_stream = NULL; gboolean retval = FALSE; GSList *i; NiceAgent *agent; /* owned */ /* Closed streams are not readable. */ if (g_input_stream_is_closed (G_INPUT_STREAM (stream))) return FALSE; /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) return FALSE; agent_lock (); if (!agent_find_component (agent, priv->stream_id, priv->component_id, &_stream, &component)) { g_warning ("Could not find component %u in stream %u", priv->component_id, priv->stream_id); goto done; } /* If it’s a reliable agent, see if there’s any pending data in the pseudo-TCP * buffer. */ if (agent->reliable && pseudo_tcp_socket_get_available_bytes (component->tcp) > 0) { retval = TRUE; goto done; } /* Check whether any of the component’s FDs are pollable. */ for (i = component->socket_sources; i != NULL; i = i->next) { SocketSource *socket_source = i->data; NiceSocket *nicesock = socket_source->socket; if (g_socket_condition_check (nicesock->fileno, G_IO_IN) != 0) { retval = TRUE; break; } } done: agent_unlock (); g_object_unref (agent); return retval; } static gssize nice_input_stream_read_nonblocking (GPollableInputStream *stream, void *buffer, gsize count, GError **error) { NiceInputStreamPrivate *priv = NICE_INPUT_STREAM (stream)->priv; NiceAgent *agent; /* owned */ gssize len; /* Closed streams are not readable. */ if (g_input_stream_is_closed (G_INPUT_STREAM (stream))) { return 0; } /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Stream is closed due to the NiceAgent being finalised."); return -1; } len = nice_agent_recv_nonblocking (agent, priv->stream_id, priv->component_id, (guint8 *) buffer, count, NULL, error); g_object_unref (agent); return len; } static GSource * nice_input_stream_create_source (GPollableInputStream *stream, GCancellable *cancellable) { NiceInputStreamPrivate *priv = NICE_INPUT_STREAM (stream)->priv; GSource *component_source = NULL; NiceAgent *agent; /* owned */ /* Closed streams cannot have sources. */ if (g_input_stream_is_closed (G_INPUT_STREAM (stream))) goto dummy_source; /* Has the agent disappeared? */ agent = g_weak_ref_get (&priv->agent_ref); if (agent == NULL) goto dummy_source; component_source = nice_component_input_source_new (agent, priv->stream_id, priv->component_id, stream, cancellable); g_object_unref (agent); return component_source; dummy_source: component_source = g_pollable_source_new (G_OBJECT (stream)); if (cancellable) { GSource *cancellable_source = g_cancellable_source_new (cancellable); g_source_set_dummy_callback (cancellable_source); g_source_add_child_source (component_source, cancellable_source); g_source_unref (cancellable_source); } return component_source; } static void streams_removed_cb (NiceAgent *agent, guint *stream_ids, gpointer user_data) { NiceInputStream *self = NICE_INPUT_STREAM (user_data); guint i; for (i = 0; stream_ids[i] != 0; i++) { if (stream_ids[i] == self->priv->stream_id) { /* The socket has been closed. */ g_input_stream_close (G_INPUT_STREAM (self), NULL, NULL); break; } } } libnice-0.1.14/agent/pseudotcp.h0000664000076400007640000004271612724403337013431 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __LIBNICE_PSEUDOTCP_H__ #define __LIBNICE_PSEUDOTCP_H__ /** * SECTION:pseudotcp * @short_description: Pseudo TCP implementation * @include: pseudotcp.h * @stability: Stable * * The #PseudoTcpSocket is an object implementing a Pseudo Tcp Socket for use * over UDP. * The socket will implement a subset of the TCP stack to allow for a reliable * transport over non-reliable sockets (such as UDP). * * See the file tests/test-pseudotcp.c in the source package for an example * of how to use the object. * * Since: 0.0.11 */ #include #ifndef __GTK_DOC_IGNORE__ #ifdef G_OS_WIN32 # include #ifndef ECONNABORTED # define ECONNABORTED WSAECONNABORTED #endif #ifndef ENOTCONN # define ENOTCONN WSAENOTCONN #endif #ifndef EWOULDBLOCK # define EWOULDBLOCK WSAEWOULDBLOCK #endif #ifndef ECONNRESET # define ECONNRESET WSAECONNRESET #endif #endif #endif #include "agent.h" G_BEGIN_DECLS /** * PseudoTcpSocket: * * The #PseudoTcpSocket is the GObject implementing the Pseudo TCP Socket * * Since: 0.0.11 */ typedef struct _PseudoTcpSocket PseudoTcpSocket; typedef struct _PseudoTcpSocketClass PseudoTcpSocketClass; GType pseudo_tcp_socket_get_type (void); /* TYPE MACROS */ #define PSEUDO_TCP_SOCKET_TYPE \ (pseudo_tcp_socket_get_type ()) #define PSEUDO_TCP_SOCKET(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), PSEUDO_TCP_SOCKET_TYPE, \ PseudoTcpSocket)) #define PSEUDO_TCP_SOCKET_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass), PSEUDO_TCP_SOCKET_TYPE, \ PseudoTcpSocketClass)) #define IS_PSEUDO_TCP_SOCKET(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj), PSEUDO_TCP_SOCKET_TYPE)) #define IS_PSEUDO_TCP_SOCKET_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass), PSEUDO_TCP_SOCKET_TYPE)) #define PSEUDOTCP_SOCKET_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), PSEUDO_TCP_SOCKET_TYPE, \ PseudoTcpSocketClass)) /** * PseudoTcpDebugLevel: * @PSEUDO_TCP_DEBUG_NONE: Disable debug messages * @PSEUDO_TCP_DEBUG_NORMAL: Enable basic debug messages * @PSEUDO_TCP_DEBUG_VERBOSE: Enable verbose debug messages * * Valid values of debug levels to be set. * * Since: 0.0.11 */ typedef enum { PSEUDO_TCP_DEBUG_NONE = 0, PSEUDO_TCP_DEBUG_NORMAL, PSEUDO_TCP_DEBUG_VERBOSE, } PseudoTcpDebugLevel; /** * PseudoTcpState: * @TCP_LISTEN: The socket's initial state. The socket isn't connected and is * listening for an incoming connection * @TCP_SYN_SENT: The socket has sent a connection request (SYN) packet and is * waiting for an answer * @TCP_SYN_RECEIVED: The socket has received a connection request (SYN) packet. * @TCP_ESTABLISHED: The socket is connected * @TCP_CLOSED: The socket has been closed * @TCP_FIN_WAIT_1: The socket has been closed locally but not remotely * (Since: 0.1.8) * @TCP_FIN_WAIT_2: The socket has been closed locally but not remotely * (Since: 0.1.8) * @TCP_CLOSING: The socket has been closed locally and remotely * (Since: 0.1.8) * @TCP_TIME_WAIT: The socket has been closed locally and remotely * (Since: 0.1.8) * @TCP_CLOSE_WAIT: The socket has been closed remotely but not locally * (Since: 0.1.8) * @TCP_LAST_ACK: The socket has been closed locally and remotely * (Since: 0.1.8) * * An enum representing the state of the #PseudoTcpSocket. These states * correspond to the TCP states in RFC 793. * See also: #PseudoTcpSocket:state * * Since: 0.0.11 */ typedef enum { TCP_LISTEN, TCP_SYN_SENT, TCP_SYN_RECEIVED, TCP_ESTABLISHED, TCP_CLOSED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, TCP_CLOSING, TCP_TIME_WAIT, TCP_CLOSE_WAIT, TCP_LAST_ACK, } PseudoTcpState; /** * PseudoTcpWriteResult: * @WR_SUCCESS: The write operation was successful * @WR_TOO_LARGE: The socket type requires that message be sent atomically * and the size of the message to be sent made this impossible. * @WR_FAIL: There was an error sending the message * * An enum representing the result value of the write operation requested by * the #PseudoTcpSocket. * See also: %PseudoTcpCallbacks:WritePacket * * Since: 0.0.11 */ typedef enum { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL } PseudoTcpWriteResult; /** * PseudoTcpShutdown: * @PSEUDO_TCP_SHUTDOWN_RD: Shut down the local reader only * @PSEUDO_TCP_SHUTDOWN_WR: Shut down the local writer only * @PSEUDO_TCP_SHUTDOWN_RDWR: Shut down both reading and writing * * Options for which parts of a connection to shut down when calling * pseudo_tcp_socket_shutdown(). These correspond to the values passed to POSIX * shutdown(). * * Since: 0.1.8 */ typedef enum { PSEUDO_TCP_SHUTDOWN_RD, PSEUDO_TCP_SHUTDOWN_WR, PSEUDO_TCP_SHUTDOWN_RDWR, } PseudoTcpShutdown; /** * PseudoTcpCallbacks: * @user_data: A user defined pointer to be passed to the callbacks * @PseudoTcpOpened: The #PseudoTcpSocket is now connected * @PseudoTcpReadable: The socket is readable * @PseudoTcpWritable: The socket is writable * @PseudoTcpClosed: The socket was closed (both sides) * @WritePacket: This callback is called when the socket needs to send data. * * A structure containing callbacks functions that will be called by the * #PseudoTcpSocket when some events happen. * See also: #PseudoTcpWriteResult * * Since: 0.0.11 */ typedef struct { gpointer user_data; void (*PseudoTcpOpened) (PseudoTcpSocket *tcp, gpointer data); void (*PseudoTcpReadable) (PseudoTcpSocket *tcp, gpointer data); void (*PseudoTcpWritable) (PseudoTcpSocket *tcp, gpointer data); void (*PseudoTcpClosed) (PseudoTcpSocket *tcp, guint32 error, gpointer data); PseudoTcpWriteResult (*WritePacket) (PseudoTcpSocket *tcp, const gchar * buffer, guint32 len, gpointer data); } PseudoTcpCallbacks; /** * pseudo_tcp_socket_new: * @conversation: The conversation id for the socket. * @callbacks: A pointer to the #PseudoTcpCallbacks structure for getting * notified of the #PseudoTcpSocket events. * * Creates a new #PseudoTcpSocket for the specified conversation * The @callbacks must be non-NULL, in order to get notified of packets the socket needs to send. If the @callbacks structure was dynamicly allocated, it can be freed after the call @pseudo_tcp_socket_new * * Returns: The new #PseudoTcpSocket object, %NULL on error * * Since: 0.0.11 */ PseudoTcpSocket *pseudo_tcp_socket_new (guint32 conversation, PseudoTcpCallbacks *callbacks); /** * pseudo_tcp_socket_connect: * @self: The #PseudoTcpSocket object. * * Connects the #PseudoTcpSocket to the peer with the same conversation id. * The connection will only be successful after the * %PseudoTcpCallbacks:PseudoTcpOpened callback is called * * Returns: %TRUE on success, %FALSE on failure (not in %TCP_LISTEN state) * See also: pseudo_tcp_socket_get_error() * * Since: 0.0.11 */ gboolean pseudo_tcp_socket_connect(PseudoTcpSocket *self); /** * pseudo_tcp_socket_recv: * @self: The #PseudoTcpSocket object. * @buffer: The buffer to fill with received data * @len: The length of @buffer * * Receive data from the socket. * Only call this on the %PseudoTcpCallbacks:PseudoTcpReadable callback. This function should be called in a loop. If this function does not return -1 with EWOULDBLOCK as the error, the %PseudoTcpCallbacks:PseudoTcpReadable callback will not be called again. * * Returns: The number of bytes received or -1 in case of error * See also: pseudo_tcp_socket_get_error() * * Since: 0.0.11 */ gint pseudo_tcp_socket_recv(PseudoTcpSocket *self, char * buffer, size_t len); /** * pseudo_tcp_socket_send: * @self: The #PseudoTcpSocket object. * @buffer: The buffer with data to send * @len: The length of @buffer * * Send data on the socket. * If this function return -1 with EWOULDBLOCK as the error, or if the return value is lower than @len, then the %PseudoTcpCallbacks:PseudoTcpWritable callback will be called when the socket will become writable. * * Returns: The number of bytes sent or -1 in case of error * See also: pseudo_tcp_socket_get_error() * * Since: 0.0.11 */ gint pseudo_tcp_socket_send(PseudoTcpSocket *self, const char * buffer, guint32 len); /** * pseudo_tcp_socket_close: * @self: The #PseudoTcpSocket object. * @force: %TRUE to close the socket forcefully, %FALSE to close it gracefully * * Close the socket for sending. If @force is set to %FALSE, the socket will * finish sending pending data before closing. If it is set to %TRUE, the socket * will discard pending data and close the connection immediately (sending a TCP * RST segment). * * The socket will be closed in both directions – sending and receiving – and * any pending received data must be read before calling this function, by * calling pseudo_tcp_socket_recv() until it blocks. If any pending data is in * the receive buffer when pseudo_tcp_socket_close() is called, a TCP RST * segment will be sent to the peer to notify it of the data loss. * The %PseudoTcpCallbacks:PseudoTcpClosed callback will not be called once the socket gets closed. It is only used for aborted connection. Instead, the socket gets closed when the pseudo_tcp_socket_get_next_clock() function returns FALSE. * * See also: pseudo_tcp_socket_get_next_clock() * * Since: 0.0.11 */ void pseudo_tcp_socket_close(PseudoTcpSocket *self, gboolean force); /** * pseudo_tcp_socket_shutdown: * @self: The #PseudoTcpSocket object. * @how: The directions of the connection to shut down. * * Shut down sending, receiving, or both on the socket, depending on the value * of @how. The behaviour of pseudo_tcp_socket_send() and * pseudo_tcp_socket_recv() will immediately change after this function returns * (depending on the value of @how), though the socket may continue to process * network traffic in the background even if sending or receiving data is * forbidden. * * This is equivalent to the POSIX shutdown() function. Setting @how to * %PSEUDO_TCP_SHUTDOWN_RDWR is equivalent to calling pseudo_tcp_socket_close(). * * Since: 0.1.8 */ void pseudo_tcp_socket_shutdown (PseudoTcpSocket *self, PseudoTcpShutdown how); /** * pseudo_tcp_socket_get_error: * @self: The #PseudoTcpSocket object. * * Return the last encountered error. * The return value can be : EINVAL (for pseudo_tcp_socket_connect()). EWOULDBLOCK or ENOTCONN (for pseudo_tcp_socket_recv() and pseudo_tcp_socket_send()). * * Returns: The error code * See also: pseudo_tcp_socket_connect() * See also: pseudo_tcp_socket_recv() * See also: pseudo_tcp_socket_send() * * Since: 0.0.11 */ int pseudo_tcp_socket_get_error(PseudoTcpSocket *self); /** * pseudo_tcp_socket_get_next_clock: * @self: The #PseudoTcpSocket object. * @timeout: A pointer to be filled with the new timeout. * * Call this to determine the timeout needed before the next time call * to pseudo_tcp_socket_notify_clock() should be made. * * Returns: %TRUE if @timeout was filled, %FALSE if the socket is closed and * ready to be destroyed. * * See also: pseudo_tcp_socket_notify_clock() * * Since: 0.0.11 */ gboolean pseudo_tcp_socket_get_next_clock(PseudoTcpSocket *self, guint64 *timeout); /** * pseudo_tcp_socket_notify_clock: * @self: The #PseudoTcpSocket object. * * Start the processing of receiving data, pending data or syn/acks. * Call this based on timeout value returned by * pseudo_tcp_socket_get_next_clock(). * It's ok to call this too frequently. * * See also: pseudo_tcp_socket_get_next_clock() * * Since: 0.0.11 */ void pseudo_tcp_socket_notify_clock(PseudoTcpSocket *self); /** * pseudo_tcp_socket_notify_mtu: * @self: The #PseudoTcpSocket object. * @mtu: The new MTU of the socket * * Set the MTU of the socket * * Since: 0.0.11 */ void pseudo_tcp_socket_notify_mtu(PseudoTcpSocket *self, guint16 mtu); /** * pseudo_tcp_socket_notify_packet: * @self: The #PseudoTcpSocket object. * @buffer: The buffer containing the received data * @len: The length of @buffer * * Notify the #PseudoTcpSocket when a new packet arrives * * Returns: %TRUE if the packet was processed successfully, %FALSE otherwise * * Since: 0.0.11 */ gboolean pseudo_tcp_socket_notify_packet(PseudoTcpSocket *self, const gchar * buffer, guint32 len); /** * pseudo_tcp_socket_notify_message: * @self: The #PseudoTcpSocket object. * @message: A #NiceInputMessage containing the received data. * * Notify the #PseudoTcpSocket that a new message has arrived, and enqueue the * data in its buffers to the #PseudoTcpSocket’s receive buffer. * * Returns: %TRUE if the packet was processed successfully, %FALSE otherwise * * Since: 0.1.5 */ gboolean pseudo_tcp_socket_notify_message (PseudoTcpSocket *self, NiceInputMessage *message); /** * pseudo_tcp_set_debug_level: * @level: The level of debug to set * * Sets the debug level to enable/disable normal/verbose debug messages. * * Since: 0.0.11 */ void pseudo_tcp_set_debug_level (PseudoTcpDebugLevel level); /** * pseudo_tcp_socket_get_available_bytes: * @self: The #PseudoTcpSocket object. * * Gets the number of bytes of data in the buffer that can be read without * receiving more packets from the network. * * Returns: The number of bytes or -1 if the connection is not established * * Since: 0.1.5 */ gint pseudo_tcp_socket_get_available_bytes (PseudoTcpSocket *self); /** * pseudo_tcp_socket_can_send: * @self: The #PseudoTcpSocket object. * * Returns if there is space in the send buffer to send any data. * * Returns: %TRUE if data can be sent, %FALSE otherwise * * Since: 0.1.5 */ gboolean pseudo_tcp_socket_can_send (PseudoTcpSocket *self); /** * pseudo_tcp_socket_get_available_send_space: * @self: The #PseudoTcpSocket object. * * Gets the number of bytes of space available in the transmission buffer. * * Returns: The number of bytes, or 0 if the connection is not established. * * Since: 0.1.5 */ gsize pseudo_tcp_socket_get_available_send_space (PseudoTcpSocket *self); /** * pseudo_tcp_socket_set_time: * @self: The #PseudoTcpSocket object. * @current_time: Current monotonic time, in milliseconds; or zero to use the * system monotonic clock. * * Sets the current monotonic time to be used by the TCP socket when calculating * timeouts and expiry times. If this function is not called, or is called with * @current_time as zero, g_get_monotonic_time() will be used. Otherwise, the * specified @current_time will be used until it is updated by calling this * function again. * * This function is intended for testing only, and should not be used in * production code. * * Since: 0.1.8 */ void pseudo_tcp_socket_set_time (PseudoTcpSocket *self, guint32 current_time); /** * pseudo_tcp_socket_is_closed: * @self: The #PseudoTcpSocket object. * * Gets whether the socket is closed, with the shutdown handshake completed, * and both peers no longer able to read or write data to the connection. * * Returns: %TRUE if the socket is closed in both directions, %FALSE otherwise * Since: 0.1.8 */ gboolean pseudo_tcp_socket_is_closed (PseudoTcpSocket *self); /** * pseudo_tcp_socket_is_closed_remotely: * @self: The #PseudoTcpSocket object. * * Gets whether the socket has been closed on the remote peer’s side of the * connection (i.e. whether pseudo_tcp_socket_close() has been called there). * This is guaranteed to return %TRUE if pseudo_tcp_socket_is_closed() returns * %TRUE. It will not return %TRUE after pseudo_tcp_socket_close() is called * until a FIN segment is received from the remote peer. * * Returns: %TRUE if the remote peer has closed its side of the connection, * %FALSE otherwise * Since: 0.1.8 */ gboolean pseudo_tcp_socket_is_closed_remotely (PseudoTcpSocket *self); G_END_DECLS #endif /* __LIBNICE_PSEUDOTCP_H__ */ libnice-0.1.14/agent/conncheck.h0000664000076400007640000001066413067571702013356 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _NICE_CONNCHECK_H #define _NICE_CONNCHECK_H /* note: this is a private header to libnice */ #include "agent.h" #include "stream.h" #include "stun/stunagent.h" #include "stun/usages/timer.h" #define NICE_CANDIDATE_PAIR_MAX_FOUNDATION NICE_CANDIDATE_MAX_FOUNDATION*2 /** * NiceCheckState: * @NICE_CHECK_WAITING: Waiting to be scheduled. * @NICE_CHECK_IN_PROGRESS: Connection checks started. * @NICE_CHECK_SUCCEEDED: Connection successfully checked. * @NICE_CHECK_FAILED: No connectivity; retransmissions ceased. * @NICE_CHECK_FROZEN: Waiting to be scheduled to %NICE_CHECK_WAITING. * @NICE_CHECK_CANCELLED: Check cancelled. * @NICE_CHECK_DISCOVERED: A valid candidate pair not on the check list. * * States for checking a candidate pair. */ typedef enum { NICE_CHECK_WAITING = 1, NICE_CHECK_IN_PROGRESS, NICE_CHECK_SUCCEEDED, NICE_CHECK_FAILED, NICE_CHECK_FROZEN, NICE_CHECK_CANCELLED, NICE_CHECK_DISCOVERED, } NiceCheckState; typedef struct _CandidateCheckPair CandidateCheckPair; struct _CandidateCheckPair { NiceAgent *agent; /* back pointer to owner */ guint stream_id; guint component_id; NiceCandidate *local; NiceCandidate *remote; NiceSocket *sockptr; gchar foundation[NICE_CANDIDATE_PAIR_MAX_FOUNDATION]; NiceCheckState state; gboolean nominated; gboolean controlling; gboolean timer_restarted; gboolean valid; guint64 priority; guint32 prflx_priority; GTimeVal next_tick; /* next tick timestamp */ StunTimer timer; uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE_IPV6]; StunMessage stun_message; }; int conn_check_add_for_candidate (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *remote); int conn_check_add_for_local_candidate (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local); gboolean conn_check_add_for_candidate_pair (NiceAgent *agent, guint stream_id, NiceComponent *component, NiceCandidate *local, NiceCandidate *remote); void conn_check_free (NiceAgent *agent); void conn_check_schedule_next (NiceAgent *agent); int conn_check_send (NiceAgent *agent, CandidateCheckPair *pair); void conn_check_prune_stream (NiceAgent *agent, NiceStream *stream); gboolean conn_check_handle_inbound_stun (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *udp_socket, const NiceAddress *from, gchar *buf, guint len); gint conn_check_compare (const CandidateCheckPair *a, const CandidateCheckPair *b); void conn_check_remote_candidates_set(NiceAgent *agent, NiceStream *stream, NiceComponent *component); NiceCandidateTransport conn_check_match_transport (NiceCandidateTransport transport); void conn_check_prune_socket (NiceAgent *agent, NiceStream *stream, NiceComponent *component, NiceSocket *sock); guint32 ensure_unique_priority (NiceComponent *component, guint32 priority); #endif /*_NICE_CONNCHECK_H */ libnice-0.1.14/agent/discovery.h0000664000076400007640000001172112661700132013413 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2008-2009 Collabora Ltd. * Contact: Youness Alaoui * (C) 2007-2009 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _NICE_DISCOVERY_H #define _NICE_DISCOVERY_H /* note: this is a private header to libnice */ #include "stream.h" #include "agent.h" typedef struct { NiceAgent *agent; /* back pointer to owner */ NiceCandidateType type; /* candidate type STUN or TURN */ NiceSocket *nicesock; /* XXX: should be taken from local cand: existing socket to use */ NiceAddress server; /* STUN/TURN server address */ GTimeVal next_tick; /* next tick timestamp */ gboolean pending; /* is discovery in progress? */ gboolean done; /* is discovery complete? */ NiceStream *stream; NiceComponent *component; TurnServer *turn; StunAgent stun_agent; StunTimer timer; uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE_IPV6]; StunMessage stun_message; uint8_t stun_resp_buffer[STUN_MAX_MESSAGE_SIZE]; StunMessage stun_resp_msg; } CandidateDiscovery; typedef struct { NiceAgent *agent; /* back pointer to owner */ NiceSocket *nicesock; /* existing socket to use */ NiceAddress server; /* STUN/TURN server address */ NiceCandidate *candidate; /* candidate to refresh */ NiceStream *stream; NiceComponent *component; StunAgent stun_agent; GSource *timer_source; GSource *tick_source; StunTimer timer; uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE_IPV6]; StunMessage stun_message; uint8_t stun_resp_buffer[STUN_MAX_MESSAGE_SIZE]; StunMessage stun_resp_msg; } CandidateRefresh; void refresh_free (NiceAgent *agent); void refresh_prune_stream (NiceAgent *agent, guint stream_id); void refresh_prune_candidate (NiceAgent *agent, NiceCandidate *candidate); void refresh_prune_socket (NiceAgent *agent, NiceSocket *sock); void refresh_cancel (CandidateRefresh *refresh); void discovery_free (NiceAgent *agent); void discovery_prune_stream (NiceAgent *agent, guint stream_id); void discovery_prune_socket (NiceAgent *agent, NiceSocket *sock); void discovery_schedule (NiceAgent *agent); typedef enum { HOST_CANDIDATE_SUCCESS, HOST_CANDIDATE_FAILED, HOST_CANDIDATE_CANT_CREATE_SOCKET, HOST_CANDIDATE_REDUNDANT } HostCandidateResult; HostCandidateResult discovery_add_local_host_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceCandidateTransport transport, NiceCandidate **candidate); NiceCandidate* discovery_add_relay_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceCandidateTransport transport, NiceSocket *base_socket, TurnServer *turn); NiceCandidate* discovery_add_server_reflexive_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceCandidateTransport transport, NiceSocket *base_socket, gboolean nat_assisted); void discovery_discover_tcp_server_reflexive_candidates ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceSocket *base_socket); NiceCandidate* discovery_add_peer_reflexive_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceAddress *address, NiceSocket *base_socket, NiceCandidate *local, NiceCandidate *remote); NiceCandidate * discovery_learn_remote_peer_reflexive_candidate ( NiceAgent *agent, NiceStream *stream, NiceComponent *component, guint32 priority, const NiceAddress *remote_address, NiceSocket *udp_socket, NiceCandidate *local, NiceCandidate *remote); #endif /*_NICE_CONNCHECK_H */ libnice-0.1.14/agent/component.h0000664000076400007640000002532212723144650013416 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2010 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2010 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _NICE_COMPONENT_H #define _NICE_COMPONENT_H #include typedef struct _NiceComponent NiceComponent; #include "agent.h" #include "agent-priv.h" #include "candidate.h" #include "stun/stunagent.h" #include "stun/usages/timer.h" #include "pseudotcp.h" #include "stream.h" #include "socket.h" G_BEGIN_DECLS /* (ICE §4.1.1.1, ID-19) * ""For RTP-based media streams, the RTP itself has a component * ID of 1, and RTCP a component ID of 2. If an agent is using RTCP it MUST * obtain a candidate for it. If an agent is using both RTP and RTCP, it * would end up with 2*K host candidates if an agent has K interfaces."" */ typedef struct _CandidatePair CandidatePair; typedef struct _CandidatePairKeepalive CandidatePairKeepalive; typedef struct _IncomingCheck IncomingCheck; struct _CandidatePairKeepalive { NiceAgent *agent; GSource *tick_source; guint stream_id; guint component_id; StunTimer timer; uint8_t stun_buffer[STUN_MAX_MESSAGE_SIZE_IPV6]; StunMessage stun_message; }; struct _CandidatePair { NiceCandidate *local; NiceCandidate *remote; guint64 priority; /* candidate pair priority */ guint32 prflx_priority; CandidatePairKeepalive keepalive; }; struct _IncomingCheck { NiceAddress from; NiceSocket *local_socket; guint32 priority; gboolean use_candidate; uint8_t *username; uint16_t username_len; }; void incoming_check_free (IncomingCheck *icheck); /* A pair of a socket and the GSource which polls it from the main loop. All * GSources in a Component must be attached to the same main context: * component->ctx. * * Socket must be non-NULL, but source may be NULL if it has been detached. * * The Component is stored so this may be used as the user data for a GSource * callback. */ typedef struct { NiceSocket *socket; GSource *source; NiceComponent *component; } SocketSource; /* A message which has been received and processed (so is guaranteed not * to be a STUN packet, or to contain pseudo-TCP header bytes, for example), but * which hasn’t yet been sent to the client in an I/O callback. This could be * due to the main context not being run, or due to the I/O callback being * detached. * * The @offset member gives the byte offset into @buf which has already been * sent to the client. #IOCallbackData buffers remain in the * #Component::pending_io_messages queue until all of their bytes have been sent * to the client. * * @offset is guaranteed to be smaller than @buf_len. */ typedef struct { guint8 *buf; /* owned */ gsize buf_len; gsize offset; } IOCallbackData; IOCallbackData * io_callback_data_new (const guint8 *buf, gsize buf_len); void io_callback_data_free (IOCallbackData *data); #define NICE_TYPE_COMPONENT nice_component_get_type() #define NICE_COMPONENT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), NICE_TYPE_COMPONENT, NiceComponent)) #define NICE_COMPONENT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), NICE_TYPE_COMPONENT, NiceComponentClass)) #define NICE_IS_COMPONENT(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NICE_TYPE_COMPONENT)) #define NICE_IS_COMPONENT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), NICE_TYPE_COMPONENT)) #define NICE_COMPONENT_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), NICE_TYPE_COMPONENT, NiceComponentClass)) struct _NiceComponent { /*< private >*/ GObject parent; NiceComponentType type; guint id; /* component id */ NiceComponentState state; GSList *local_candidates; /* list of NiceCandidate objs */ GSList *remote_candidates; /* list of NiceCandidate objs */ GSList *socket_sources; /* list of SocketSource objs; must only grow monotonically */ guint socket_sources_age; /* incremented when socket_sources changes */ GSList *incoming_checks; /* list of IncomingCheck objs */ GList *turn_servers; /* List of TurnServer objs */ CandidatePair selected_pair; /* independent from checklists, see ICE 11.1. "Sending Media" (ID-19) */ NiceCandidate *restart_candidate; /* for storing active remote candidate during a restart */ NiceCandidate *turn_candidate; /* for storing active turn candidate if turn servers have been cleared */ /* I/O handling. The main context must always be non-NULL, and is used for all * socket recv() operations. All io_callback emissions are invoked in this * context too. * * recv_messages and io_callback are mutually exclusive, but it is allowed for * both to be NULL if the Component is not currently ready to receive data. */ GMutex io_mutex; /* protects io_callback, io_user_data, pending_io_messages and io_callback_id. immutable: can be accessed without holding the agent lock; if the agent lock is to be taken, it must always be taken before this one */ NiceAgentRecvFunc io_callback; /* function called on io cb */ gpointer io_user_data; /* data passed to the io function */ GQueue pending_io_messages; /* queue of messages which have been received but not passed to the client in an I/O callback or recv() call yet. each element is an owned IOCallbackData */ guint io_callback_id; /* GSource ID of the I/O callback */ GMainContext *own_ctx; /* own context for GSources for this component */ GMainContext *ctx; /* context for GSources for this component (possibly set from the app) */ NiceInputMessage *recv_messages; /* unowned messages for receiving into */ guint n_recv_messages; /* length of recv_messages */ NiceInputMessageIter recv_messages_iter; /* current write position in recv_messages */ GError **recv_buf_error; /* error information about failed reads */ NiceAgent *agent; /* unowned, immutable: can be accessed without holding the * agent lock */ NiceStream *stream; /* unowned, immutable: can be accessed without holding * the agent lock */ StunAgent stun_agent; /* This stun agent is used to validate all stun requests */ GCancellable *stop_cancellable; GSource *stop_cancellable_source; /* owned */ PseudoTcpSocket *tcp; GSource* tcp_clock; guint64 last_clock_timeout; gboolean tcp_readable; GCancellable *tcp_writable_cancellable; GIOStream *iostream; guint min_port; guint max_port; /* Queue of messages received before a selected socket was available to send * ACKs on. The messages are dequeued to the pseudo-TCP socket once a selected * UDP socket is available. This is only used for reliable Components. */ GQueue queued_tcp_packets; }; typedef struct { GObjectClass parent_class; } NiceComponentClass; GType nice_component_get_type (void); NiceComponent * nice_component_new (guint component_id, NiceAgent *agent, NiceStream *stream); void nice_component_close (NiceComponent *component); gboolean nice_component_find_pair (NiceComponent *component, NiceAgent *agent, const gchar *lfoundation, const gchar *rfoundation, CandidatePair *pair); void nice_component_restart (NiceComponent *component); void nice_component_update_selected_pair (NiceComponent *component, const CandidatePair *pair); NiceCandidate * nice_component_find_remote_candidate (NiceComponent *component, const NiceAddress *addr, NiceCandidateTransport transport); NiceCandidate * nice_component_set_selected_remote_candidate (NiceComponent *component, NiceAgent *agent, NiceCandidate *candidate); void nice_component_attach_socket (NiceComponent *component, NiceSocket *nsocket); void nice_component_remove_socket (NiceComponent *component, NiceSocket *nsocket); void nice_component_detach_all_sockets (NiceComponent *component); void nice_component_free_socket_sources (NiceComponent *component); GSource * nice_component_input_source_new (NiceAgent *agent, guint stream_id, guint component_id, GPollableInputStream *pollable_istream, GCancellable *cancellable); GMainContext * nice_component_dup_io_context (NiceComponent *component); void nice_component_set_io_context (NiceComponent *component, GMainContext *context); void nice_component_set_io_callback (NiceComponent *component, NiceAgentRecvFunc func, gpointer user_data, NiceInputMessage *recv_messages, guint n_recv_messages, GError **error); void nice_component_emit_io_callback (NiceComponent *component, const guint8 *buf, gsize buf_len); gboolean nice_component_has_io_callback (NiceComponent *component); void nice_component_clean_turn_servers (NiceComponent *component); TurnServer * turn_server_new (const gchar *server_ip, guint server_port, const gchar *username, const gchar *password, NiceRelayType type); TurnServer * turn_server_ref (TurnServer *turn); void turn_server_unref (TurnServer *turn); G_END_DECLS #endif /* _NICE_COMPONENT_H */ libnice-0.1.14/agent/agent.h0000664000076400007640000015004312733070261012506 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2010 Collabora Ltd. * Contact: Youness Alaoui * (C) 2006-2010 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef __LIBNICE_AGENT_H__ #define __LIBNICE_AGENT_H__ /** * SECTION:agent * @short_description: ICE agent API implementation * @see_also: #NiceCandidate, #NiceAddress * @include: agent.h * @stability: Stable * * The #NiceAgent is your main object when using libnice. * It is the agent that will take care of everything relating to ICE. * It will take care of discovering your local candidates and do * connectivity checks to create a stream of data between you and your peer. * * A #NiceAgent must always be used with a #GMainLoop running the #GMainContext * passed into nice_agent_new() (or nice_agent_new_reliable()). Without the * #GMainContext being iterated, the agent’s timers will not fire, etc. * * Streams and their components are referenced by integer IDs (with respect to a * given #NiceAgent). These IDs are guaranteed to be positive (i.e. non-zero) * for valid streams/components. * * To complete the ICE connectivity checks, the user must either register * an I/O callback (with nice_agent_attach_recv()) or call nice_agent_recv_messages() * in a loop on a dedicated thread. * Technically, #NiceAgent does not poll the streams on its own, since * user data could arrive at any time; to receive STUN packets * required for establishing ICE connectivity, it is backpiggying * on the facility chosen by the user. #NiceAgent will handle all STUN * packets internally; they're never actually passed to the I/O callback * or returned from nice_agent_recv_messages() and related functions. * * Each stream can receive data in one of two ways: using * nice_agent_attach_recv() or nice_agent_recv_messages() (and the derived * #NiceInputStream and #NiceIOStream classes accessible using * nice_agent_get_io_stream()). nice_agent_attach_recv() is non-blocking: it * takes a user-provided callback function and attaches the stream’s socket to * the provided #GMainContext, invoking the callback in that context for every * packet received. nice_agent_recv_messages() instead blocks on receiving a * packet, and writes it directly into a user-provided buffer. This reduces the * number of callback invokations and (potentially) buffer copies required to * receive packets. nice_agent_recv_messages() (or #NiceInputStream) is designed * to be used in a blocking loop in a separate thread. * * * Simple example on how to use libnice * * guint stream_id; * gchar buffer[] = "hello world!"; * gchar *ufrag = NULL, *pwd = NULL; * gchar *remote_ufrag, *remote_pwd; * GSList *lcands = NULL; * * // Create a nice agent, passing in the global default GMainContext. * NiceAgent *agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); * spawn_thread_to_run_main_loop (g_main_loop_new (NULL, FALSE)); * * // Connect the signals * g_signal_connect (G_OBJECT (agent), "candidate-gathering-done", * G_CALLBACK (cb_candidate_gathering_done), NULL); * g_signal_connect (G_OBJECT (agent), "component-state-changed", * G_CALLBACK (cb_component_state_changed), NULL); * g_signal_connect (G_OBJECT (agent), "new-selected-pair", * G_CALLBACK (cb_new_selected_pair), NULL); * * // Create a new stream with one component and start gathering candidates * stream_id = nice_agent_add_stream (agent, 1); * nice_agent_gather_candidates (agent, stream_id); * * // Attach I/O callback the component to ensure that: * // 1) agent gets its STUN packets (not delivered to cb_nice_recv) * // 2) you get your own data * nice_agent_attach_recv (agent, stream_id, 1, NULL, * cb_nice_recv, NULL); * * // ... Wait until the signal candidate-gathering-done is fired ... * lcands = nice_agent_get_local_candidates(agent, stream_id, 1); * nice_agent_get_local_credentials(agent, stream_id, &ufrag, &pwd); * * // ... Send local candidates and credentials to the peer * * // Set the peer's remote credentials and remote candidates * nice_agent_set_remote_credentials (agent, stream_id, remote_ufrag, remote_pwd); * nice_agent_set_remote_candidates (agent, stream_id, 1, rcands); * * // ... Wait until the signal new-selected-pair is fired ... * // Send our message! * nice_agent_send (agent, stream_id, 1, sizeof(buffer), buffer); * * // Anything received will be received through the cb_nice_recv callback. * // You must be running a GMainLoop on the global default GMainContext in * // another thread for this to work. * * // Destroy the object * g_object_unref(agent); * * * * * Refer to the examples in the examples/ subdirectory of the libnice source for * more complete examples. * */ #include #include /** * NiceAgent: * * The #NiceAgent is the main GObject of the libnice library and represents * the ICE agent. */ typedef struct _NiceAgent NiceAgent; #include "address.h" #include "candidate.h" #include "debug.h" G_BEGIN_DECLS /** * NiceInputMessage: * @buffers: (array length=n_buffers): unowned array of #GInputVector buffers to * store data in for this message * @n_buffers: number of #GInputVectors in @buffers, or -1 to indicate @buffers * is %NULL-terminated * @from: (allow-none): return location to store the address of the peer who * transmitted the message, or %NULL * @length: total number of valid bytes contiguously stored in @buffers * * Represents a single message received off the network. For reliable * connections, this is essentially just an array of buffers (specifically, * @from can be ignored). for non-reliable connections, it represents a single * packet as received from the OS. * * @n_buffers may be -1 to indicate that @buffers is terminated by a * #GInputVector with a %NULL buffer pointer. * * By providing arrays of #NiceInputMessages to functions like * nice_agent_recv_messages(), multiple messages may be received with a single * call, which is more efficient than making multiple calls in a loop. In this * manner, nice_agent_recv_messages() is analogous to recvmmsg(); and * #NiceInputMessage to struct mmsghdr. * * Since: 0.1.5 */ typedef struct { GInputVector *buffers; gint n_buffers; /* may be -1 to indicate @buffers is NULL-terminated */ NiceAddress *from; /* return location for address of message sender */ gsize length; /* sum of the lengths of @buffers */ } NiceInputMessage; /** * NiceOutputMessage: * @buffers: (array length=n_buffers): unowned array of #GOutputVector buffers * which contain data to transmit for this message * @n_buffers: number of #GOutputVectors in @buffers, or -1 to indicate @buffers * is %NULL-terminated * * Represents a single message to transmit on the network. For * reliable connections, this is essentially just an array of * buffer. for non-reliable connections, it represents a single packet * to send to the OS. * * @n_buffers may be -1 to indicate that @buffers is terminated by a * #GOutputVector with a %NULL buffer pointer. * * By providing arrays of #NiceOutputMessages to functions like * nice_agent_send_messages_nonblocking(), multiple messages may be transmitted * with a single call, which is more efficient than making multiple calls in a * loop. In this manner, nice_agent_send_messages_nonblocking() is analogous to * sendmmsg(); and #NiceOutputMessage to struct mmsghdr. * * Since: 0.1.5 */ typedef struct { GOutputVector *buffers; gint n_buffers; } NiceOutputMessage; #define NICE_TYPE_AGENT nice_agent_get_type() #define NICE_AGENT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ NICE_TYPE_AGENT, NiceAgent)) #define NICE_AGENT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ NICE_TYPE_AGENT, NiceAgentClass)) #define NICE_IS_AGENT(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ NICE_TYPE_AGENT)) #define NICE_IS_AGENT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ NICE_TYPE_AGENT)) #define NICE_AGENT_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ NICE_TYPE_AGENT, NiceAgentClass)) typedef struct _NiceAgentClass NiceAgentClass; struct _NiceAgentClass { GObjectClass parent_class; }; GType nice_agent_get_type (void); /** * NICE_AGENT_MAX_REMOTE_CANDIDATES: * * A hard limit for the number of remote candidates. This * limit is enforced to protect against malevolent remote * clients. */ #define NICE_AGENT_MAX_REMOTE_CANDIDATES 25 /** * NiceComponentState: * @NICE_COMPONENT_STATE_DISCONNECTED: No activity scheduled * @NICE_COMPONENT_STATE_GATHERING: Gathering local candidates * @NICE_COMPONENT_STATE_CONNECTING: Establishing connectivity * @NICE_COMPONENT_STATE_CONNECTED: At least one working candidate pair * @NICE_COMPONENT_STATE_READY: ICE concluded, candidate pair selection * is now final * @NICE_COMPONENT_STATE_FAILED: Connectivity checks have been completed, * but connectivity was not established * @NICE_COMPONENT_STATE_LAST: Dummy state * * An enum representing the state of a component. * See also: #NiceAgent::component-state-changed */ typedef enum { NICE_COMPONENT_STATE_DISCONNECTED, NICE_COMPONENT_STATE_GATHERING, NICE_COMPONENT_STATE_CONNECTING, NICE_COMPONENT_STATE_CONNECTED, NICE_COMPONENT_STATE_READY, NICE_COMPONENT_STATE_FAILED, NICE_COMPONENT_STATE_LAST } NiceComponentState; /** * NiceComponentType: * @NICE_COMPONENT_TYPE_RTP: RTP Component type * @NICE_COMPONENT_TYPE_RTCP: RTCP Component type * * Convenience enum representing the type of a component for use as the * component_id for RTP/RTCP usages. Example of use. nice_agent_send (agent, stream_id, NICE_COMPONENT_TYPE_RTP, len, buf); */ typedef enum { NICE_COMPONENT_TYPE_RTP = 1, NICE_COMPONENT_TYPE_RTCP = 2 } NiceComponentType; /** * NiceCompatibility: * @NICE_COMPATIBILITY_RFC5245: Use compatibility with the RFC5245 ICE-UDP specs * and RFC6544 ICE-TCP specs * @NICE_COMPATIBILITY_GOOGLE: Use compatibility for Google Talk specs * @NICE_COMPATIBILITY_MSN: Use compatibility for MSN Messenger specs * @NICE_COMPATIBILITY_WLM2009: Use compatibility with Windows Live Messenger * 2009 * @NICE_COMPATIBILITY_OC2007: Use compatibility with Microsoft Office Communicator 2007 * @NICE_COMPATIBILITY_OC2007R2: Use compatibility with Microsoft Office Communicator 2007 R2 * @NICE_COMPATIBILITY_DRAFT19: Use compatibility for ICE Draft 19 specs * @NICE_COMPATIBILITY_LAST: Dummy last compatibility mode * * An enum to specify which compatible specifications the #NiceAgent should use. * Use with nice_agent_new() * * @NICE_COMPATIBILITY_DRAFT19 is deprecated and should not be used * in newly-written code. It is kept for compatibility reasons and * represents the same compatibility as @NICE_COMPATIBILITY_RFC5245 If @NICE_COMPATIBILITY_RFC5245 compatibility mode is used for a non-reliable agent, then ICE-UDP will be used with higher priority and ICE-TCP will also be used when the UDP connectivity fails. If it is used with a reliable agent, then ICE-UDP will be used with the TCP-Over-UDP (#PseudoTcpSocket) if ICE-TCP fails and ICE-UDP succeeds. * */ typedef enum { NICE_COMPATIBILITY_RFC5245 = 0, NICE_COMPATIBILITY_DRAFT19 = NICE_COMPATIBILITY_RFC5245, NICE_COMPATIBILITY_GOOGLE, NICE_COMPATIBILITY_MSN, NICE_COMPATIBILITY_WLM2009, NICE_COMPATIBILITY_OC2007, NICE_COMPATIBILITY_OC2007R2, NICE_COMPATIBILITY_LAST = NICE_COMPATIBILITY_OC2007R2, } NiceCompatibility; /** * NiceProxyType: * @NICE_PROXY_TYPE_NONE: Do not use a proxy * @NICE_PROXY_TYPE_SOCKS5: Use a SOCKS5 proxy * @NICE_PROXY_TYPE_HTTP: Use an HTTP proxy * @NICE_PROXY_TYPE_LAST: Dummy last proxy type * * An enum to specify which proxy type to use for relaying. * Note that the proxies will only be used with TCP TURN relaying. * See also: #NiceAgent:proxy-type * * Since: 0.0.4 */ typedef enum { NICE_PROXY_TYPE_NONE = 0, NICE_PROXY_TYPE_SOCKS5, NICE_PROXY_TYPE_HTTP, NICE_PROXY_TYPE_LAST = NICE_PROXY_TYPE_HTTP, } NiceProxyType; /** * NiceAgentRecvFunc: * @agent: The #NiceAgent Object * @stream_id: The id of the stream * @component_id: The id of the component of the stream * which received the data * @len: The length of the data * @buf: The buffer containing the data received * @user_data: The user data set in nice_agent_attach_recv() * * Callback function when data is received on a component * */ typedef void (*NiceAgentRecvFunc) ( NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data); /** * nice_agent_new: * @ctx: The Glib Mainloop Context to use for timers * @compat: The compatibility mode of the agent * * Create a new #NiceAgent. * The returned object must be freed with g_object_unref() * * Returns: The new agent GObject */ NiceAgent * nice_agent_new (GMainContext *ctx, NiceCompatibility compat); /** * nice_agent_new_reliable: * @ctx: The Glib Mainloop Context to use for timers * @compat: The compatibility mode of the agent * * Create a new #NiceAgent in reliable mode. If the connectivity is established * through ICE-UDP, then a #PseudoTcpSocket will be transparently used to * ensure reliability of the messages. * The returned object must be freed with g_object_unref() * See also: #NiceAgent::reliable-transport-writable * * Since: 0.0.11 * * Returns: The new agent GObject */ NiceAgent * nice_agent_new_reliable (GMainContext *ctx, NiceCompatibility compat); /** * nice_agent_add_local_address: * @agent: The #NiceAgent Object * @addr: The address to listen to * If the port is 0, then a random port will be chosen by the system * * Add a local address from which to derive local host candidates for * candidate gathering. * * Since 0.0.5, if this method is not called, libnice will automatically * discover the local addresses available * * * See also: nice_agent_gather_candidates() * Returns: %TRUE on success, %FALSE on fatal (memory allocation) errors */ gboolean nice_agent_add_local_address (NiceAgent *agent, NiceAddress *addr); /** * nice_agent_add_stream: * @agent: The #NiceAgent Object * @n_components: The number of components to add to the stream * * Adds a data stream to @agent containing @n_components components. The * returned stream ID is guaranteed to be positive on success. * * Returns: The ID of the new stream, 0 on failure **/ guint nice_agent_add_stream ( NiceAgent *agent, guint n_components); /** * nice_agent_remove_stream: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream to remove * * Remove and free a previously created data stream from @agent. If any I/O * streams have been created using nice_agent_get_io_stream(), they should be * closed completely using g_io_stream_close() before this is called, or they * will get broken pipe errors. * **/ void nice_agent_remove_stream ( NiceAgent *agent, guint stream_id); /** * nice_agent_set_port_range: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * @min_port: The minimum port to use * @max_port: The maximum port to use * * Sets a preferred port range for allocating host candidates. * * If a local host candidate cannot be created on that port * range, then the nice_agent_gather_candidates() call will fail. * * * This MUST be called before nice_agent_gather_candidates() * * */ void nice_agent_set_port_range ( NiceAgent *agent, guint stream_id, guint component_id, guint min_port, guint max_port); /** * nice_agent_set_relay_info: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * @server_ip: The IP address of the TURN server * @server_port: The port of the TURN server * @username: The TURN username to use for the allocate * @password: The TURN password to use for the allocate * @type: The type of relay to use * * Sets the settings for using a relay server during the candidate discovery. * This may be called multiple times to add multiple relay servers to the * discovery process; one TCP and one UDP, for example. * * Returns: %TRUE if the TURN settings were accepted. * %FALSE if the address was invalid. */ gboolean nice_agent_set_relay_info( NiceAgent *agent, guint stream_id, guint component_id, const gchar *server_ip, guint server_port, const gchar *username, const gchar *password, NiceRelayType type); /** * nice_agent_gather_candidates: * @agent: The #NiceAgent object * @stream_id: The ID of the stream to start * * Allocate and start listening on local candidate ports and start the remote * candidate gathering process. * Once done, #NiceAgent::candidate-gathering-done is called for the stream. * As soon as this function is called, #NiceAgent::new-candidate signals may be * emitted, even before this function returns. * * nice_agent_get_local_candidates() will only return non-empty results after * calling this function. * * See also: nice_agent_add_local_address() * See also: nice_agent_set_port_range() * * Returns: %FALSE if the stream ID is invalid or if a host candidate couldn't * be allocated on the requested interfaces/ports; %TRUE otherwise * Local addresses can be previously set with nice_agent_add_local_address() Since 0.0.5, If no local address was previously added, then the nice agent will automatically detect the local address using nice_interfaces_get_local_ips() */ gboolean nice_agent_gather_candidates ( NiceAgent *agent, guint stream_id); /** * nice_agent_set_remote_credentials: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @ufrag: nul-terminated string containing an ICE username fragment * (length must be between 22 and 256 chars) * @pwd: nul-terminated string containing an ICE password * (length must be between 4 and 256 chars) * * Sets the remote credentials for stream @stream_id. * Stream credentials do not override per-candidate credentials if set Due to the native of peer-reflexive candidates, any agent using a per-stream credentials (RFC5245, WLM2009, OC2007R2 and DRAFT19) instead of per-candidate credentials (GOOGLE, MSN, OC2007), must use the nice_agent_set_remote_credentials() API instead of setting the username and password on the candidates. * * Returns: %TRUE on success, %FALSE on error. */ gboolean nice_agent_set_remote_credentials ( NiceAgent *agent, guint stream_id, const gchar *ufrag, const gchar *pwd); /** * nice_agent_set_local_credentials: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @ufrag: nul-terminated string containing an ICE username fragment * (length must be between 22 and 256 chars) * @pwd: nul-terminated string containing an ICE password * (length must be between 4 and 256 chars) * * Sets the local credentials for stream @stream_id. * This is only effective before ICE negotiation has started. * * Since 0.1.11 * Returns: %TRUE on success, %FALSE on error. */ gboolean nice_agent_set_local_credentials ( NiceAgent *agent, guint stream_id, const gchar *ufrag, const gchar *pwd); /** * nice_agent_get_local_credentials: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @ufrag: (out callee-allocates): return location for a nul-terminated string * containing an ICE username fragment; must be freed with g_free() * @pwd: (out callee-allocates): return location for a nul-terminated string * containing an ICE password; must be freed with g_free() * * Gets the local credentials for stream @stream_id. This may be called any time * after creating a stream using nice_agent_add_stream(). * * An error will be returned if this is called for a non-existent stream, or if * either of @ufrag or @pwd are %NULL. * * Returns: %TRUE on success, %FALSE on error. */ gboolean nice_agent_get_local_credentials ( NiceAgent *agent, guint stream_id, gchar **ufrag, gchar **pwd); /** * nice_agent_set_remote_candidates: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream the candidates are for * @component_id: The ID of the component the candidates are for * @candidates: (element-type NiceCandidate) (transfer none): a #GSList of * #NiceCandidate items describing each candidate to add * * Sets, adds or updates the remote candidates for a component of a stream. * NICE_AGENT_MAX_REMOTE_CANDIDATES is the absolute maximum limit for remote candidates. You must first call nice_agent_gather_candidates() and wait for the #NiceAgent::candidate-gathering-done signale before calling nice_agent_set_remote_candidates() Since 0.1.3, there is no need to wait for the candidate-gathering-done signal. Remote candidates can be set even while gathering local candidates. Newly discovered local candidates will automatically be paired with existing remote candidates. * * Returns: The number of candidates added, negative on errors (memory * allocation error or invalid component) **/ int nice_agent_set_remote_candidates ( NiceAgent *agent, guint stream_id, guint component_id, const GSList *candidates); /** * nice_agent_send: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream to send to * @component_id: The ID of the component to send to * @len: The length of the buffer to send * @buf: The buffer of data to send * * Sends a data payload over a stream's component. * Component state MUST be NICE_COMPONENT_STATE_READY, or as a special case, in any state if component was in READY state before and was then restarted In reliable mode, the -1 error value means either that you are not yet connected or that the send buffer is full (equivalent to EWOULDBLOCK). In both cases, you simply need to wait for the #NiceAgent::reliable-transport-writable signal to be fired before resending the data. In non-reliable mode, it will virtually never happen with UDP sockets, but it might happen if the active candidate is a TURN-TCP connection that got disconnected. In both reliable and non-reliable mode, a -1 error code could also mean that the stream_id and/or component_id are invalid. * * Returns: The number of bytes sent, or negative error code */ gint nice_agent_send ( NiceAgent *agent, guint stream_id, guint component_id, guint len, const gchar *buf); /** * nice_agent_send_messages_nonblocking: * @agent: a #NiceAgent * @stream_id: the ID of the stream to send to * @component_id: the ID of the component to send to * @messages: (array length=n_messages): array of messages to send, of at least * @n_messages entries in length * @n_messages: number of entries in @messages * @cancellable: (allow-none): a #GCancellable to cancel the operation from * another thread, or %NULL * @error: (allow-none): return location for a #GError, or %NULL * * Sends multiple messages on the socket identified by the given * stream/component pair. Transmission is non-blocking, so a * %G_IO_ERROR_WOULD_BLOCK error may be returned if the send buffer is full. * * As with nice_agent_send(), the given component must be in * %NICE_COMPONENT_STATE_READY or, as a special case, in any state if it was * previously ready and was then restarted. * * On success, the number of messages written to the socket will be returned, * which may be less than @n_messages if transmission would have blocked * part-way through. Zero will be returned if @n_messages is zero, or if * transmission would have blocked on the first message. * * In reliable mode, it is instead recommended to use * nice_agent_send(). The return value can be less than @n_messages * or 0 even if it is still possible to send a partial message. In * this case, "nice-agent-writable" will never be triggered, so the * application would have to use nice_agent_sent() to fill the buffer or have * to retry sending at a later point. * * On failure, -1 will be returned and @error will be set. If the #NiceAgent is * reliable and the socket is not yet connected, %G_IO_ERROR_BROKEN_PIPE will be * returned; if the write buffer is full, %G_IO_ERROR_WOULD_BLOCK will be * returned. In both cases, wait for the #NiceAgent::reliable-transport-writable * signal before trying again. If the given @stream_id or @component_id are * invalid or not yet connected, %G_IO_ERROR_BROKEN_PIPE will be returned. * %G_IO_ERROR_FAILED will be returned for other errors. * * Returns: the number of messages sent (may be zero), or -1 on error * * Since: 0.1.5 */ gint nice_agent_send_messages_nonblocking ( NiceAgent *agent, guint stream_id, guint component_id, const NiceOutputMessage *messages, guint n_messages, GCancellable *cancellable, GError **error); /** * nice_agent_get_local_candidates: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * * Retrieve from the agent the list of all local candidates * for a stream's component * The caller owns the returned GSList as well as the candidates contained within it. To get full results, the client should wait for the #NiceAgent::candidate-gathering-done signal. * * Returns: (element-type NiceCandidate) (transfer full): a #GSList of * #NiceCandidate objects representing the local candidates of @agent **/ GSList * nice_agent_get_local_candidates ( NiceAgent *agent, guint stream_id, guint component_id); /** * nice_agent_get_remote_candidates: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * * Get a list of the remote candidates set on a stream's component * The caller owns the returned GSList as well as the candidates contained within it. The list of remote candidates can change during processing. The client should register for the #NiceAgent::new-remote-candidate signal to get notified of new remote candidates. * * Returns: (element-type NiceCandidate) (transfer full): a #GSList of * #NiceCandidates objects representing the remote candidates set on the @agent **/ GSList * nice_agent_get_remote_candidates ( NiceAgent *agent, guint stream_id, guint component_id); /** * nice_agent_restart: * @agent: The #NiceAgent Object * * Restarts the session as defined in ICE draft 19. This function * needs to be called both when initiating (ICE spec section 9.1.1.1. * "ICE Restarts"), as well as when reacting (spec section 9.2.1.1. * "Detecting ICE Restart") to a restart. * * Returns: %TRUE on success %FALSE on error **/ gboolean nice_agent_restart ( NiceAgent *agent); /** * nice_agent_restart_stream: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * * Restarts a single stream as defined in RFC 5245. This function * needs to be called both when initiating (ICE spec section 9.1.1.1. * "ICE Restarts"), as well as when reacting (spec section 9.2.1.1. * "Detecting ICE Restart") to a restart. * * Unlike nice_agent_restart(), this applies to a single stream. It also * does not generate a new tie breaker. * * Returns: %TRUE on success %FALSE on error * * Since: 0.1.6 **/ gboolean nice_agent_restart_stream ( NiceAgent *agent, guint stream_id); /** * nice_agent_attach_recv: (skip) * @agent: The #NiceAgent Object * @stream_id: The ID of stream * @component_id: The ID of the component * @ctx: The Glib Mainloop Context to use for listening on the component * @func: The callback function to be called when data is received on * the stream's component (will not be called for STUN messages that * should be handled by #NiceAgent itself) * @data: user data associated with the callback * * Attaches the stream's component's sockets to the Glib Mainloop Context in * order to be notified whenever data becomes available for a component, * and to enable #NiceAgent to receive STUN messages (during the * establishment of ICE connectivity). * * This must not be used in combination with nice_agent_recv_messages() (or * #NiceIOStream or #NiceInputStream) on the same stream/component pair. * * Calling nice_agent_attach_recv() with a %NULL @func will detach any existing * callback and cause reception to be paused for the given stream/component * pair. You must iterate the previously specified #GMainContext sufficiently to * ensure all pending I/O callbacks have been received before calling this * function to unset @func, otherwise data loss of received packets may occur. * * Returns: %TRUE on success, %FALSE if the stream or component IDs are invalid. */ gboolean nice_agent_attach_recv ( NiceAgent *agent, guint stream_id, guint component_id, GMainContext *ctx, NiceAgentRecvFunc func, gpointer data); /** * nice_agent_recv: * @agent: a #NiceAgent * @stream_id: the ID of the stream to receive on * @component_id: the ID of the component to receive on * @buf: (array length=buf_len) (out caller-allocates): caller-allocated buffer * to write the received data into, of length at least @buf_len * @buf_len: length of @buf * @cancellable: (allow-none): a #GCancellable to allow the operation to be * cancelled from another thread, or %NULL * @error: (allow-none): return location for a #GError, or %NULL * * A single-message version of nice_agent_recv_messages(). * * Returns: the number of bytes written to @buf on success (guaranteed to be * greater than 0 unless @buf_len is 0), 0 if in reliable mode and the remote * peer closed the stream, or -1 on error * * Since: 0.1.5 */ gssize nice_agent_recv ( NiceAgent *agent, guint stream_id, guint component_id, guint8 *buf, gsize buf_len, GCancellable *cancellable, GError **error); /** * nice_agent_recv_messages: * @agent: a #NiceAgent * @stream_id: the ID of the stream to receive on * @component_id: the ID of the component to receive on * @messages: (array length=n_messages) (out caller-allocates): caller-allocated * array of #NiceInputMessages to write the received messages into, of length at * least @n_messages * @n_messages: number of entries in @messages * @cancellable: (allow-none): a #GCancellable to allow the operation to be * cancelled from another thread, or %NULL * @error: (allow-none): return location for a #GError, or %NULL * * Block on receiving data from the given stream/component combination on * @agent, returning only once exactly @n_messages messages have been received * and written into @messages, the stream is closed by the other end or by * calling nice_agent_remove_stream(), or @cancellable is cancelled. * * Any STUN packets received will not be added to @messages; instead, * they'll be passed for processing to #NiceAgent itself. Since #NiceAgent * does not poll for messages on its own, it's therefore essential to keep * calling this function for ICE connection establishment to work. * * In the non-error case, in reliable mode, this will block until all buffers in * all @n_messages have been filled with received data (i.e. @messages is * treated as a large, flat array of buffers). In non-reliable mode, it will * block until @n_messages messages have been received, each of which does not * have to fill all the buffers in its #NiceInputMessage. In the non-reliable * case, each #NiceInputMessage must have enough buffers to contain an entire * message (65536 bytes), or any excess data may be silently dropped. * * For each received message, #NiceInputMessage::length will be set to the * number of valid bytes stored in the message’s buffers. The bytes are stored * sequentially in the buffers; there are no gaps apart from at the end of the * buffer array (in non-reliable mode). If non-%NULL on input, * #NiceInputMessage::from will have the address of the sending peer stored in * it. The base addresses, sizes, and number of buffers in each message will not * be modified in any case. * * This must not be used in combination with nice_agent_attach_recv() on the * same stream/component pair. * * If the stream/component pair doesn’t exist, or if a suitable candidate socket * hasn’t yet been selected for it, a %G_IO_ERROR_BROKEN_PIPE error will be * returned. A %G_IO_ERROR_CANCELLED error will be returned if the operation was * cancelled. %G_IO_ERROR_FAILED will be returned for other errors. * * Returns: the number of valid messages written to @messages on success * (guaranteed to be greater than 0 unless @n_messages is 0), 0 if the remote * peer closed the stream, or -1 on error * * Since: 0.1.5 */ gint nice_agent_recv_messages ( NiceAgent *agent, guint stream_id, guint component_id, NiceInputMessage *messages, guint n_messages, GCancellable *cancellable, GError **error); /** * nice_agent_recv_nonblocking: * @agent: a #NiceAgent * @stream_id: the ID of the stream to receive on * @component_id: the ID of the component to receive on * @buf: (array length=buf_len) (out caller-allocates): caller-allocated buffer * to write the received data into, of length at least @buf_len * @buf_len: length of @buf * @cancellable: (allow-none): a #GCancellable to allow the operation to be * cancelled from another thread, or %NULL * @error: (allow-none): return location for a #GError, or %NULL * * A single-message version of nice_agent_recv_messages_nonblocking(). * * Returns: the number of bytes received into @buf on success (guaranteed to be * greater than 0 unless @buf_len is 0), 0 if in reliable mode and the remote * peer closed the stream, or -1 on error * * Since: 0.1.5 */ gssize nice_agent_recv_nonblocking ( NiceAgent *agent, guint stream_id, guint component_id, guint8 *buf, gsize buf_len, GCancellable *cancellable, GError **error); /** * nice_agent_recv_messages_nonblocking: * @agent: a #NiceAgent * @stream_id: the ID of the stream to receive on * @component_id: the ID of the component to receive on * @messages: (array length=n_messages) (out caller-allocates): caller-allocated * array of #NiceInputMessages to write the received messages into, of length at * least @n_messages * @n_messages: number of entries in @messages * @cancellable: (allow-none): a #GCancellable to allow the operation to be * cancelled from another thread, or %NULL * @error: (allow-none): return location for a #GError, or %NULL * * Try to receive data from the given stream/component combination on @agent, * without blocking. If receiving data would block, -1 is returned and * %G_IO_ERROR_WOULD_BLOCK is set in @error. If any other error occurs, -1 is * returned and @error is set accordingly. Otherwise, 0 is returned if (and only * if) @n_messages is 0. In all other cases, the number of valid messages stored * in @messages is returned, and will be greater than 0. * * This function behaves similarly to nice_agent_recv_messages(), except that it * will not block on filling (in reliable mode) or receiving (in non-reliable * mode) exactly @n_messages messages. In reliable mode, it will receive bytes * into @messages until it would block; in non-reliable mode, it will receive * messages until it would block. * * Any STUN packets received will not be added to @messages; instead, * they'll be passed for processing to #NiceAgent itself. Since #NiceAgent * does not poll for messages on its own, it's therefore essential to keep * calling this function for ICE connection establishment to work. * * As this function is non-blocking, @cancellable is included only for parity * with nice_agent_recv_messages(). If @cancellable is cancelled before this * function is called, a %G_IO_ERROR_CANCELLED error will be returned * immediately. * * This must not be used in combination with nice_agent_attach_recv() on the * same stream/component pair. * * Returns: the number of valid messages written to @messages on success * (guaranteed to be greater than 0 unless @n_messages is 0), 0 if in reliable * mode and the remote peer closed the stream, or -1 on error * * Since: 0.1.5 */ gint nice_agent_recv_messages_nonblocking ( NiceAgent *agent, guint stream_id, guint component_id, NiceInputMessage *messages, guint n_messages, GCancellable *cancellable, GError **error); /** * nice_agent_set_selected_pair: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * @lfoundation: The local foundation of the candidate to use * @rfoundation: The remote foundation of the candidate to use * * Sets the selected candidate pair for media transmission * for a given stream's component. Calling this function will * disable all further ICE processing (connection check, * state machine updates, etc). Note that keepalives will * continue to be sent. * * Returns: %TRUE on success, %FALSE if the candidate pair cannot be found */ gboolean nice_agent_set_selected_pair ( NiceAgent *agent, guint stream_id, guint component_id, const gchar *lfoundation, const gchar *rfoundation); /** * nice_agent_get_selected_pair: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * @local: The local selected candidate * @remote: The remote selected candidate * * Retreive the selected candidate pair for media transmission * for a given stream's component. * * Returns: %TRUE on success, %FALSE if there is no selected candidate pair */ gboolean nice_agent_get_selected_pair ( NiceAgent *agent, guint stream_id, guint component_id, NiceCandidate **local, NiceCandidate **remote); /** * nice_agent_get_selected_socket: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * * Retreive the local socket associated with the selected candidate pair * for media transmission for a given stream's component. * * This is useful for adding ICE support to legacy applications that already * have a protocol that maintains a connection. If the socket is duplicated * before unrefing the agent, the application can take over and continue to use * it. New applications are encouraged to use the built in libnice stream * handling instead and let libnice handle the connection maintenance. * * Users of this method are encouraged to not use a TURN relay or any kind * of proxy, as in this case, the socket will not be available to the * application because the packets are encapsulated. * * Returns: (transfer full) (nullable): pointer to the #GSocket, or %NULL if * there is no selected candidate or if the selected candidate is a relayed * candidate. * * Since: 0.1.5 */ GSocket * nice_agent_get_selected_socket ( NiceAgent *agent, guint stream_id, guint component_id); /** * nice_agent_set_selected_remote_candidate: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * @candidate: The #NiceCandidate to select * * Sets the selected remote candidate for media transmission * for a given stream's component. This is used to force the selection of * a specific remote candidate even when connectivity checks are failing * (e.g. non-ICE compatible candidates). * Calling this function will disable all further ICE processing * (connection check, state machine updates, etc). Note that keepalives will * continue to be sent. * * Returns: %TRUE on success, %FALSE on failure */ gboolean nice_agent_set_selected_remote_candidate ( NiceAgent *agent, guint stream_id, guint component_id, NiceCandidate *candidate); /** * nice_agent_set_stream_tos: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @tos: The ToS to set * * Sets the IP_TOS and/or IPV6_TCLASS field on the stream's sockets' options * * Since: 0.0.9 */ void nice_agent_set_stream_tos ( NiceAgent *agent, guint stream_id, gint tos); /** * nice_agent_set_software: * @agent: The #NiceAgent Object * @software: The value of the SOFTWARE attribute to add. * * This function will set the value of the SOFTWARE attribute to be added to * STUN requests, responses and error responses sent during connectivity checks. * * The SOFTWARE attribute will only be added in the #NICE_COMPATIBILITY_RFC5245 * and #NICE_COMPATIBILITY_WLM2009 compatibility modes. * * * The @software argument will be appended with the libnice version before being sent. The @software argument must be in UTF-8 encoding and only the first 128 characters will be sent. * * Since: 0.0.10 * */ void nice_agent_set_software ( NiceAgent *agent, const gchar *software); /** * nice_agent_set_stream_name: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream to change * @name: The new name of the stream or %NULL * * This function will assign a media type to a stream. The only values * that can be used to produce a valid SDP are: "audio", "video", * "text", "application", "image" and "message". * * This is only useful when parsing and generating an SDP of the * candidates. * * See also: nice_agent_generate_local_sdp() * See also: nice_agent_parse_remote_sdp() * See also: nice_agent_get_stream_name() * * Returns: %TRUE if the name has been set. %FALSE in case of error * (invalid stream or duplicate name). * Since: 0.1.4 */ gboolean nice_agent_set_stream_name ( NiceAgent *agent, guint stream_id, const gchar *name); /** * nice_agent_get_stream_name: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream to change * * This function will return the name assigned to a stream. * See also: nice_agent_set_stream_name() * * Returns: The name of the stream. The name is only valid while the stream * exists or until it changes through a call to nice_agent_set_stream_name(). * * * Since: 0.1.4 */ const gchar *nice_agent_get_stream_name ( NiceAgent *agent, guint stream_id); /** * nice_agent_get_default_local_candidate: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * * This helper function will return the recommended default candidate to be * used for non-ICE compatible clients. This will usually be the candidate * with the lowest priority, since it will be the longest path but the one with * the most chances of success. * This function is only useful in order to manually generate the local SDP * * * Returns: The candidate to be used as the default candidate, or %NULL in case * of error. Must be freed with nice_candidate_free() once done. * */ NiceCandidate * nice_agent_get_default_local_candidate ( NiceAgent *agent, guint stream_id, guint component_id); /** * nice_agent_generate_local_sdp: * @agent: The #NiceAgent Object * * Generate an SDP string containing the local candidates and credentials for * all streams and components in the agent. * The SDP will not contain any codec lines and the 'm' line will not list any payload types. It is highly recommended to set names on the streams prior to calling this function. Unnamed streams will show up as '-' in the 'm' line, but the SDP will not be parseable with nice_agent_parse_remote_sdp() if a stream is unnamed. The default candidate in the SDP will be selected based on the lowest priority candidate for the first component. * * See also: nice_agent_set_stream_name() * See also: nice_agent_parse_remote_sdp() * See also: nice_agent_generate_local_stream_sdp() * See also: nice_agent_generate_local_candidate_sdp() * See also: nice_agent_get_default_local_candidate() * * Returns: A string representing the local SDP. Must be freed with g_free() * once done. * * Since: 0.1.4 **/ gchar * nice_agent_generate_local_sdp ( NiceAgent *agent); /** * nice_agent_generate_local_stream_sdp: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @include_non_ice: Whether or not to include non ICE specific lines * (m=, c= and a=rtcp: lines) * * Generate an SDP string containing the local candidates and credentials * for a stream. * The SDP will not contain any codec lines and the 'm' line will not list any payload types. It is highly recommended to set the name of the stream prior to calling this function. Unnamed streams will show up as '-' in the 'm' line. The default candidate in the SDP will be selected based on the lowest priority candidate. * * See also: nice_agent_set_stream_name() * See also: nice_agent_parse_remote_stream_sdp() * See also: nice_agent_generate_local_sdp() * See also: nice_agent_generate_local_candidate_sdp() * See also: nice_agent_get_default_local_candidate() * * Returns: A string representing the local SDP for the stream. Must be freed * with g_free() once done. * * Since: 0.1.4 **/ gchar * nice_agent_generate_local_stream_sdp ( NiceAgent *agent, guint stream_id, gboolean include_non_ice); /** * nice_agent_generate_local_candidate_sdp: * @agent: The #NiceAgent Object * @candidate: The candidate to generate * * Generate an SDP string representing a local candidate. * * See also: nice_agent_parse_remote_candidate_sdp() * See also: nice_agent_generate_local_sdp() * See also: nice_agent_generate_local_stream_sdp() * * Returns: A string representing the SDP for the candidate. Must be freed * with g_free() once done. * * Since: 0.1.4 **/ gchar * nice_agent_generate_local_candidate_sdp ( NiceAgent *agent, NiceCandidate *candidate); /** * nice_agent_parse_remote_sdp: * @agent: The #NiceAgent Object * @sdp: The remote SDP to parse * * Parse an SDP string and extracts candidates and credentials from it and sets * them on the agent. * This function will return an error if a stream has not been assigned a name with nice_agent_set_stream_name() as it becomes troublesome to assign the streams from the agent to the streams in the SDP. * * * See also: nice_agent_set_stream_name() * See also: nice_agent_generate_local_sdp() * See also: nice_agent_parse_remote_stream_sdp() * See also: nice_agent_parse_remote_candidate_sdp() * * Returns: The number of candidates added, negative on errors * * Since: 0.1.4 **/ int nice_agent_parse_remote_sdp ( NiceAgent *agent, const gchar *sdp); /** * nice_agent_parse_remote_stream_sdp: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream to parse * @sdp: The remote SDP to parse * @ufrag: Pointer to store the ice ufrag if non %NULL. Must be freed with * g_free() after use * @pwd: Pointer to store the ice password if non %NULL. Must be freed with * g_free() after use * * Parse an SDP string representing a single stream and extracts candidates * and credentials from it. * * See also: nice_agent_generate_local_stream_sdp() * See also: nice_agent_parse_remote_sdp() * See also: nice_agent_parse_remote_candidate_sdp() * * Returns: (element-type NiceCandidate) (transfer full): A #GSList of * candidates parsed from the SDP, or %NULL in case of errors * * Since: 0.1.4 **/ GSList * nice_agent_parse_remote_stream_sdp ( NiceAgent *agent, guint stream_id, const gchar *sdp, gchar **ufrag, gchar **pwd); /** * nice_agent_parse_remote_candidate_sdp: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream the candidate belongs to * @sdp: The remote SDP to parse * * Parse an SDP string and extracts the candidate from it. * * See also: nice_agent_generate_local_candidate_sdp() * See also: nice_agent_parse_remote_sdp() * See also: nice_agent_parse_remote_stream_sdp() * * Returns: The parsed candidate or %NULL if there was an error. * * Since: 0.1.4 **/ NiceCandidate * nice_agent_parse_remote_candidate_sdp ( NiceAgent *agent, guint stream_id, const gchar *sdp); /** * nice_agent_get_io_stream: * @agent: A #NiceAgent * @stream_id: The ID of the stream to wrap * @component_id: The ID of the component to wrap * * Gets a #GIOStream wrapper around the given stream and component in * @agent. The I/O stream will be valid for as long as @stream_id is valid. * The #GInputStream and #GOutputStream implement #GPollableInputStream and * #GPollableOutputStream. * * This function may only be called on reliable #NiceAgents. It is a * programming error to try and create an I/O stream wrapper for an * unreliable stream. * * Returns: (transfer full): A #GIOStream. * * Since: 0.1.5 */ GIOStream * nice_agent_get_io_stream ( NiceAgent *agent, guint stream_id, guint component_id); /** * nice_component_state_to_string: * @state: a #NiceComponentState * * Returns a string representation of the state, generally to use in debug * messages. * * Returns: (transfer none): a string representation of @state * Since: 0.1.6 */ const gchar * nice_component_state_to_string (NiceComponentState state); /** * nice_agent_forget_relays: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * * Forget all the relay servers previously added using * nice_agent_set_relay_info(). Currently connected streams will keep * using the relay as long as they have not been restarted and haven't * succesfully negotiated a different path. * * Returns: %FALSE if the component could not be found, %TRUE otherwise * * Since: 0.1.6 */ gboolean nice_agent_forget_relays (NiceAgent *agent, guint stream_id, guint component_id); /** * nice_agent_get_component_state: * @agent: The #NiceAgent Object * @stream_id: The ID of the stream * @component_id: The ID of the component * * Retrieves the current state of a component. * * Returns: the #NiceComponentState of the component and * %NICE_COMPONENT_STATE_FAILED if the component was invalid. * * Since: 0.1.8 */ NiceComponentState nice_agent_get_component_state (NiceAgent *agent, guint stream_id, guint component_id); G_END_DECLS #endif /* __LIBNICE_AGENT_H__ */ libnice-0.1.14/agent/pseudotcp.c0000664000076400007640000023342112732064221013411 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2010, 2014 Collabora Ltd. * Contact: Philip Withnall * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Youness Alaoui, Collabora Ltd. * Philip Withnall, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* Reproducing license from libjingle for copied code */ /* * libjingle * Copyright 2004--2005, Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #ifndef G_OS_WIN32 # include #endif #include "pseudotcp.h" #include "agent-priv.h" struct _PseudoTcpSocketClass { GObjectClass parent_class; }; typedef struct _PseudoTcpSocketPrivate PseudoTcpSocketPrivate; struct _PseudoTcpSocket { GObject parent; PseudoTcpSocketPrivate *priv; }; G_DEFINE_TYPE (PseudoTcpSocket, pseudo_tcp_socket, G_TYPE_OBJECT); ////////////////////////////////////////////////////////////////////// // Network Constants ////////////////////////////////////////////////////////////////////// // Standard MTUs const guint16 PACKET_MAXIMUMS[] = { 65535, // Theoretical maximum, Hyperchannel 32000, // Nothing 17914, // 16Mb IBM Token Ring 8166, // IEEE 802.4 //4464, // IEEE 802.5 (4Mb max) 4352, // FDDI //2048, // Wideband Network 2002, // IEEE 802.5 (4Mb recommended) //1536, // Expermental Ethernet Networks //1500, // Ethernet, Point-to-Point (default) 1492, // IEEE 802.3 1006, // SLIP, ARPANET //576, // X.25 Networks //544, // DEC IP Portal //512, // NETBIOS 508, // IEEE 802/Source-Rt Bridge, ARCNET 296, // Point-to-Point (low delay) //68, // Official minimum 0, // End of list marker }; // FIXME: This is a reasonable MTU, but we should get it from the lower layer #define DEF_MTU 1400 #define MAX_PACKET 65532 // Note: we removed lowest level because packet overhead was larger! #define MIN_PACKET 296 // (+ up to 40 bytes of options?) #define IP_HEADER_SIZE 20 #define ICMP_HEADER_SIZE 8 #define UDP_HEADER_SIZE 8 // TODO: Make JINGLE_HEADER_SIZE transparent to this code? // when relay framing is in use #define JINGLE_HEADER_SIZE 64 ////////////////////////////////////////////////////////////////////// // Global Constants and Functions ////////////////////////////////////////////////////////////////////// // // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 0 | Conversation Number | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 4 | Sequence Number | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 8 | Acknowledgment Number | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | | |U|A|P|R|S|F| | // 12 | Control | |R|C|S|S|Y|I| Window | // | | |G|K|H|T|N|N| | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 16 | Timestamp sending | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 20 | Timestamp receiving | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 24 | data | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // ////////////////////////////////////////////////////////////////////// #define MAX_SEQ 0xFFFFFFFF #define HEADER_SIZE 24 #define PACKET_OVERHEAD (HEADER_SIZE + UDP_HEADER_SIZE + \ IP_HEADER_SIZE + JINGLE_HEADER_SIZE) // MIN_RTO = 1 second (RFC6298, Sec 2.4) #define MIN_RTO 1000 #define DEF_RTO 1000 /* 1 seconds (RFC 6298 sect 2.1) */ #define MAX_RTO 60000 /* 60 seconds */ #define DEFAULT_ACK_DELAY 100 /* 100 milliseconds */ #define DEFAULT_NO_DELAY FALSE #define DEFAULT_RCV_BUF_SIZE (60 * 1024) #define DEFAULT_SND_BUF_SIZE (90 * 1024) /* NOTE: This must fit in 8 bits. This is used on the wire. */ typedef enum { /* Google-provided options: */ TCP_OPT_EOL = 0, /* end of list */ TCP_OPT_NOOP = 1, /* no-op */ TCP_OPT_MSS = 2, /* maximum segment size */ TCP_OPT_WND_SCALE = 3, /* window scale factor */ /* libnice extensions: */ TCP_OPT_FIN_ACK = 254, /* FIN-ACK support */ } TcpOption; /* #define FLAG_SYN 0x02 #define FLAG_ACK 0x10 */ /* NOTE: This must fit in 5 bits. This is used on the wire. */ typedef enum { FLAG_NONE = 0, FLAG_FIN = 1 << 0, FLAG_CTL = 1 << 1, FLAG_RST = 1 << 2, } TcpFlags; #define CTL_CONNECT 0 //#define CTL_REDIRECT 1 #define CTL_EXTRA 255 #define CTRL_BOUND 0x80000000 /* Maximum segment lifetime (1 minute). * RFC 793, §3.3 specifies 2 minutes; but Linux uses 1 minute, so let’s go with * that. */ #define TCP_MSL (60 * 1000) // If there are no pending clocks, wake up every 4 seconds #define DEFAULT_TIMEOUT 4000 // If the connection is closed, once per minute #define CLOSED_TIMEOUT (60 * 1000) /* Timeout after reaching the TIME_WAIT state, in milliseconds. * See: RFC 1122, §4.2.2.13. * * XXX: Since we can control the underlying layer’s channel ID, we can guarantee * delayed segments won’t affect subsequent connections, so can radically * shorten the TIME-WAIT timeout (to the extent that it basically doesn’t * exist). It would normally be (2 * TCP_MSL). */ #define TIME_WAIT_TIMEOUT 1 ////////////////////////////////////////////////////////////////////// // Helper Functions ////////////////////////////////////////////////////////////////////// #ifndef G_OS_WIN32 # define min(first, second) ((first) < (second) ? (first) : (second)) # define max(first, second) ((first) > (second) ? (first) : (second)) #endif static guint32 bound(guint32 lower, guint32 middle, guint32 upper) { return min (max (lower, middle), upper); } static gboolean time_is_between(guint32 later, guint32 middle, guint32 earlier) { if (earlier <= later) { return ((earlier <= middle) && (middle <= later)); } else { return !((later < middle) && (middle < earlier)); } } static gint32 time_diff(guint32 later, guint32 earlier) { guint32 LAST = 0xFFFFFFFF; guint32 HALF = 0x80000000; if (time_is_between(earlier + HALF, later, earlier)) { if (earlier <= later) { return (long)(later - earlier); } else { return (long)(later + (LAST - earlier) + 1); } } else { if (later <= earlier) { return -(long) (earlier - later); } else { return -(long)(earlier + (LAST - later) + 1); } } } //////////////////////////////////////////////////////// // PseudoTcpFifo works exactly like FifoBuffer in libjingle //////////////////////////////////////////////////////// typedef struct { guint8 *buffer; gsize buffer_length; gsize data_length; gsize read_position; } PseudoTcpFifo; static void pseudo_tcp_fifo_init (PseudoTcpFifo *b, gsize size) { b->buffer = g_slice_alloc (size); b->buffer_length = size; } static void pseudo_tcp_fifo_clear (PseudoTcpFifo *b) { if (b->buffer) g_slice_free1 (b->buffer_length, b->buffer); b->buffer = NULL; b->buffer_length = 0; } static gsize pseudo_tcp_fifo_get_buffered (PseudoTcpFifo *b) { return b->data_length; } static gboolean pseudo_tcp_fifo_set_capacity (PseudoTcpFifo *b, gsize size) { if (b->data_length > size) return FALSE; if (size != b->data_length) { guint8 *buffer = g_slice_alloc (size); gsize copy = b->data_length; gsize tail_copy = min (copy, b->buffer_length - b->read_position); memcpy (buffer, &b->buffer[b->read_position], tail_copy); memcpy (buffer + tail_copy, &b->buffer[0], copy - tail_copy); g_slice_free1 (b->buffer_length, b->buffer); b->buffer = buffer; b->buffer_length = size; b->read_position = 0; } return TRUE; } static void pseudo_tcp_fifo_consume_read_data (PseudoTcpFifo *b, gsize size) { g_assert (size <= b->data_length); b->read_position = (b->read_position + size) % b->buffer_length; b->data_length -= size; } static void pseudo_tcp_fifo_consume_write_buffer (PseudoTcpFifo *b, gsize size) { g_assert (size <= b->buffer_length - b->data_length); b->data_length += size; } static gsize pseudo_tcp_fifo_get_write_remaining (PseudoTcpFifo *b) { return b->buffer_length - b->data_length; } static gsize pseudo_tcp_fifo_read_offset (PseudoTcpFifo *b, guint8 *buffer, gsize bytes, gsize offset) { gsize available = b->data_length - offset; gsize read_position = (b->read_position + offset) % b->buffer_length; gsize copy = min (bytes, available); gsize tail_copy = min(copy, b->buffer_length - read_position); /* EOS */ if (offset >= b->data_length) return 0; memcpy(buffer, &b->buffer[read_position], tail_copy); memcpy(buffer + tail_copy, &b->buffer[0], copy - tail_copy); return copy; } static gsize pseudo_tcp_fifo_write_offset (PseudoTcpFifo *b, const guint8 *buffer, gsize bytes, gsize offset) { gsize available = b->buffer_length - b->data_length - offset; gsize write_position = (b->read_position + b->data_length + offset) % b->buffer_length; gsize copy = min (bytes, available); gsize tail_copy = min(copy, b->buffer_length - write_position); if (b->data_length + offset >= b->buffer_length) { return 0; } memcpy(&b->buffer[write_position], buffer, tail_copy); memcpy(&b->buffer[0], buffer + tail_copy, copy - tail_copy); return copy; } static gsize pseudo_tcp_fifo_read (PseudoTcpFifo *b, guint8 *buffer, gsize bytes) { gsize copy; copy = pseudo_tcp_fifo_read_offset (b, buffer, bytes, 0); b->read_position = (b->read_position + copy) % b->buffer_length; b->data_length -= copy; return copy; } static gsize pseudo_tcp_fifo_write (PseudoTcpFifo *b, const guint8 *buffer, gsize bytes) { gsize copy; copy = pseudo_tcp_fifo_write_offset (b, buffer, bytes, 0); b->data_length += copy; return copy; } ////////////////////////////////////////////////////////////////////// // PseudoTcp ////////////////////////////////////////////////////////////////////// /* Only used if FIN-ACK support is disabled. */ typedef enum { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } Shutdown; typedef enum { sfNone, sfDelayedAck, sfImmediateAck, sfFin, sfRst, sfDuplicateAck, } SendFlags; typedef struct { guint32 conv, seq, ack; TcpFlags flags; guint16 wnd; const gchar * data; guint32 len; guint32 tsval, tsecr; } Segment; typedef struct { guint32 seq, len; guint8 xmit; TcpFlags flags; } SSegment; typedef struct { guint32 seq, len; } RSegment; /** * ClosedownSource: * @CLOSEDOWN_LOCAL: Error detected locally, or connection forcefully closed * locally. * @CLOSEDOWN_REMOTE: RST segment received from the peer. * * Reasons for calling closedown(). * * Since: 0.1.8 */ typedef enum { CLOSEDOWN_LOCAL, CLOSEDOWN_REMOTE, } ClosedownSource; struct _PseudoTcpSocketPrivate { PseudoTcpCallbacks callbacks; Shutdown shutdown; /* only used if !support_fin_ack */ gboolean shutdown_reads; gint error; // TCB data PseudoTcpState state; guint32 conv; gboolean bReadEnable, bWriteEnable, bOutgoing; guint32 last_traffic; // Incoming data GList *rlist; guint32 rbuf_len, rcv_nxt, rcv_wnd, lastrecv; guint8 rwnd_scale; // Window scale factor PseudoTcpFifo rbuf; guint32 rcv_fin; /* sequence number of the received FIN octet, or 0 */ // Outgoing data GQueue slist; GQueue unsent_slist; guint32 sbuf_len, snd_nxt, snd_wnd, lastsend; guint32 snd_una; /* oldest unacknowledged sequence number */ guint8 swnd_scale; // Window scale factor PseudoTcpFifo sbuf; // Maximum segment size, estimated protocol level, largest segment sent guint32 mss, msslevel, largest, mtu_advise; // Retransmit timer guint32 rto_base; // Timestamp tracking guint32 ts_recent, ts_lastack; // Round-trip calculation guint32 rx_rttvar, rx_srtt, rx_rto; // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs guint32 ssthresh, cwnd; guint8 dup_acks; guint32 recover; gboolean fast_recovery; guint32 t_ack; /* time a delayed ack was scheduled; 0 if no acks scheduled */ guint32 last_acked_ts; gboolean use_nagling; guint32 ack_delay; // This is used by unit tests to test backward compatibility of // PseudoTcp implementations that don't support window scaling. gboolean support_wnd_scale; /* Current time. Typically only used for testing, when non-zero. When zero, * the system monotonic clock is used. Units: monotonic milliseconds. */ guint32 current_time; /* This is used by compatible implementations (with the TCP_OPT_FIN_ACK * option) to enable correct FIN-ACK connection termination. Defaults to * TRUE unless no compatible option is received. */ gboolean support_fin_ack; }; #define LARGER(a,b) (((a) - (b) - 1) < (G_MAXUINT32 >> 1)) #define LARGER_OR_EQUAL(a,b) (((a) - (b)) < (G_MAXUINT32 >> 1)) #define SMALLER(a,b) LARGER ((b),(a)) #define SMALLER_OR_EQUAL(a,b) LARGER_OR_EQUAL ((b),(a)) /* properties */ enum { PROP_CONVERSATION = 1, PROP_CALLBACKS, PROP_STATE, PROP_ACK_DELAY, PROP_NO_DELAY, PROP_RCV_BUF, PROP_SND_BUF, PROP_SUPPORT_FIN_ACK, LAST_PROPERTY }; static void pseudo_tcp_socket_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void pseudo_tcp_socket_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void pseudo_tcp_socket_finalize (GObject *object); static void queue_connect_message (PseudoTcpSocket *self); static guint32 queue (PseudoTcpSocket *self, const gchar *data, guint32 len, TcpFlags flags); static PseudoTcpWriteResult packet(PseudoTcpSocket *self, guint32 seq, TcpFlags flags, guint32 offset, guint32 len, guint32 now); static gboolean parse (PseudoTcpSocket *self, const guint8 *_header_buf, gsize header_buf_len, const guint8 *data_buf, gsize data_buf_len); static gboolean process(PseudoTcpSocket *self, Segment *seg); static int transmit(PseudoTcpSocket *self, SSegment *sseg, guint32 now); static void attempt_send(PseudoTcpSocket *self, SendFlags sflags); static void closedown (PseudoTcpSocket *self, guint32 err, ClosedownSource source); static void adjustMTU(PseudoTcpSocket *self); static void parse_options (PseudoTcpSocket *self, const guint8 *data, guint32 len); static void resize_send_buffer (PseudoTcpSocket *self, guint32 new_size); static void resize_receive_buffer (PseudoTcpSocket *self, guint32 new_size); static void set_state (PseudoTcpSocket *self, PseudoTcpState new_state); static void set_state_established (PseudoTcpSocket *self); static void set_state_closed (PseudoTcpSocket *self, guint32 err); static const gchar *pseudo_tcp_state_get_name (PseudoTcpState state); static gboolean pseudo_tcp_state_has_sent_fin (PseudoTcpState state); static gboolean pseudo_tcp_state_has_received_fin (PseudoTcpState state); static gboolean pseudo_tcp_state_has_received_fin_ack (PseudoTcpState state); // The following logging is for detailed (packet-level) pseudotcp analysis only. static PseudoTcpDebugLevel debug_level = PSEUDO_TCP_DEBUG_NONE; #define DEBUG(level, fmt, ...) \ if (debug_level >= level) \ g_log (level == PSEUDO_TCP_DEBUG_NORMAL ? "libnice-pseudotcp" : "libnice-pseudotcp-verbose", G_LOG_LEVEL_DEBUG, "PseudoTcpSocket %p %s: " fmt, \ self, pseudo_tcp_state_get_name (self->priv->state), ## __VA_ARGS__) void pseudo_tcp_set_debug_level (PseudoTcpDebugLevel level) { debug_level = level; } static guint32 get_current_time (PseudoTcpSocket *socket) { if (G_UNLIKELY (socket->priv->current_time != 0)) return socket->priv->current_time; return g_get_monotonic_time () / 1000; } void pseudo_tcp_socket_set_time (PseudoTcpSocket *self, guint32 current_time) { self->priv->current_time = current_time; } static void pseudo_tcp_socket_class_init (PseudoTcpSocketClass *cls) { GObjectClass *object_class = G_OBJECT_CLASS (cls); object_class->get_property = pseudo_tcp_socket_get_property; object_class->set_property = pseudo_tcp_socket_set_property; object_class->finalize = pseudo_tcp_socket_finalize; g_object_class_install_property (object_class, PROP_CONVERSATION, g_param_spec_uint ("conversation", "TCP Conversation ID", "The TCP Conversation ID", 0, G_MAXUINT32, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CALLBACKS, g_param_spec_pointer ("callbacks", "PseudoTcp socket callbacks", "Structure with the callbacks to call when PseudoTcp events happen", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, g_param_spec_uint ("state", "PseudoTcp State", "The current state (enum PseudoTcpState) of the PseudoTcp socket", TCP_LISTEN, TCP_CLOSED, TCP_LISTEN, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACK_DELAY, g_param_spec_uint ("ack-delay", "ACK Delay", "Delayed ACK timeout (in milliseconds)", 0, G_MAXUINT, DEFAULT_ACK_DELAY, G_PARAM_READWRITE| G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NO_DELAY, g_param_spec_boolean ("no-delay", "No Delay", "Disable the Nagle algorithm (like the TCP_NODELAY option)", DEFAULT_NO_DELAY, G_PARAM_READWRITE| G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RCV_BUF, g_param_spec_uint ("rcv-buf", "Receive Buffer", "Receive Buffer size", 1, G_MAXUINT, DEFAULT_RCV_BUF_SIZE, G_PARAM_READWRITE| G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SND_BUF, g_param_spec_uint ("snd-buf", "Send Buffer", "Send Buffer size", 1, G_MAXUINT, DEFAULT_SND_BUF_SIZE, G_PARAM_READWRITE| G_PARAM_STATIC_STRINGS)); /** * PseudoTcpSocket:support-fin-ack: * * Whether to support the FIN–ACK extension to the pseudo-TCP protocol for * this socket. The extension is only compatible with other libnice pseudo-TCP * stacks, and not with Jingle pseudo-TCP stacks. If enabled, support is * negotiatied on connection setup, so it is safe for a #PseudoTcpSocket with * support enabled to be used with one with it disabled, or with a Jingle * pseudo-TCP socket which doesn’t support it at all. * * Support is enabled by default. * * Since: 0.1.8 */ g_object_class_install_property (object_class, PROP_SUPPORT_FIN_ACK, g_param_spec_boolean ("support-fin-ack", "Support FIN–ACK", "Whether to enable the optional FIN–ACK support.", TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } static void pseudo_tcp_socket_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { PseudoTcpSocket *self = PSEUDO_TCP_SOCKET (object); switch (property_id) { case PROP_CONVERSATION: g_value_set_uint (value, self->priv->conv); break; case PROP_CALLBACKS: g_value_set_pointer (value, (gpointer) &self->priv->callbacks); break; case PROP_STATE: g_value_set_uint (value, self->priv->state); break; case PROP_ACK_DELAY: g_value_set_uint (value, self->priv->ack_delay); break; case PROP_NO_DELAY: g_value_set_boolean (value, !self->priv->use_nagling); break; case PROP_RCV_BUF: g_value_set_uint (value, self->priv->rbuf_len); break; case PROP_SND_BUF: g_value_set_uint (value, self->priv->sbuf_len); break; case PROP_SUPPORT_FIN_ACK: g_value_set_boolean (value, self->priv->support_fin_ack); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void pseudo_tcp_socket_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { PseudoTcpSocket *self = PSEUDO_TCP_SOCKET (object); switch (property_id) { case PROP_CONVERSATION: self->priv->conv = g_value_get_uint (value); break; case PROP_CALLBACKS: { PseudoTcpCallbacks *c = g_value_get_pointer (value); self->priv->callbacks = *c; } break; case PROP_ACK_DELAY: self->priv->ack_delay = g_value_get_uint (value); break; case PROP_NO_DELAY: self->priv->use_nagling = !g_value_get_boolean (value); break; case PROP_RCV_BUF: g_return_if_fail (self->priv->state == TCP_LISTEN); resize_receive_buffer (self, g_value_get_uint (value)); break; case PROP_SND_BUF: g_return_if_fail (self->priv->state == TCP_LISTEN); resize_send_buffer (self, g_value_get_uint (value)); break; case PROP_SUPPORT_FIN_ACK: self->priv->support_fin_ack = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void pseudo_tcp_socket_finalize (GObject *object) { PseudoTcpSocket *self = PSEUDO_TCP_SOCKET (object); PseudoTcpSocketPrivate *priv = self->priv; GList *i; SSegment *sseg; if (priv == NULL) return; while ((sseg = g_queue_pop_head (&priv->slist))) g_slice_free (SSegment, sseg); g_queue_clear (&priv->unsent_slist); for (i = priv->rlist; i; i = i->next) { RSegment *rseg = i->data; g_slice_free (RSegment, rseg); } g_list_free (priv->rlist); priv->rlist = NULL; pseudo_tcp_fifo_clear (&priv->rbuf); pseudo_tcp_fifo_clear (&priv->sbuf); g_free (priv); self->priv = NULL; if (G_OBJECT_CLASS (pseudo_tcp_socket_parent_class)->finalize) G_OBJECT_CLASS (pseudo_tcp_socket_parent_class)->finalize (object); } static void pseudo_tcp_socket_init (PseudoTcpSocket *obj) { /* Use g_new0, and do not use g_object_set_private because the size of * our private data is too big (150KB+) and the g_slice_allow cannot allocate * it. So we handle the private ourselves */ PseudoTcpSocketPrivate *priv = g_new0 (PseudoTcpSocketPrivate, 1); obj->priv = priv; priv->shutdown = SD_NONE; priv->error = 0; priv->rbuf_len = DEFAULT_RCV_BUF_SIZE; pseudo_tcp_fifo_init (&priv->rbuf, priv->rbuf_len); priv->sbuf_len = DEFAULT_SND_BUF_SIZE; pseudo_tcp_fifo_init (&priv->sbuf, priv->sbuf_len); priv->state = TCP_LISTEN; priv->conv = 0; g_queue_init (&priv->slist); g_queue_init (&priv->unsent_slist); priv->rcv_wnd = priv->rbuf_len; priv->rwnd_scale = priv->swnd_scale = 0; priv->snd_nxt = 0; priv->snd_wnd = 1; priv->snd_una = priv->rcv_nxt = 0; priv->bReadEnable = TRUE; priv->bWriteEnable = FALSE; priv->rcv_fin = 0; priv->t_ack = 0; priv->msslevel = 0; priv->largest = 0; priv->mss = MIN_PACKET - PACKET_OVERHEAD; priv->mtu_advise = DEF_MTU; priv->rto_base = 0; priv->cwnd = 2 * priv->mss; priv->ssthresh = priv->rbuf_len; priv->lastrecv = priv->lastsend = priv->last_traffic = 0; priv->bOutgoing = FALSE; priv->dup_acks = 0; priv->recover = 0; priv->last_acked_ts = 0; priv->ts_recent = priv->ts_lastack = 0; priv->rx_rto = DEF_RTO; priv->rx_srtt = priv->rx_rttvar = 0; priv->ack_delay = DEFAULT_ACK_DELAY; priv->use_nagling = !DEFAULT_NO_DELAY; priv->support_wnd_scale = TRUE; priv->support_fin_ack = TRUE; } PseudoTcpSocket *pseudo_tcp_socket_new (guint32 conversation, PseudoTcpCallbacks *callbacks) { return g_object_new (PSEUDO_TCP_SOCKET_TYPE, "conversation", conversation, "callbacks", callbacks, NULL); } static void queue_connect_message (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; guint8 buf[8]; gsize size = 0; buf[size++] = CTL_CONNECT; if (priv->support_wnd_scale) { buf[size++] = TCP_OPT_WND_SCALE; buf[size++] = 1; buf[size++] = priv->rwnd_scale; } if (priv->support_fin_ack) { buf[size++] = TCP_OPT_FIN_ACK; buf[size++] = 1; /* option length; zero is invalid (RFC 1122, §4.2.2.5) */ buf[size++] = 0; /* currently unused */ } priv->snd_wnd = size; queue (self, (char *) buf, size, FLAG_CTL); } static void queue_fin_message (PseudoTcpSocket *self) { g_assert (self->priv->support_fin_ack); /* FIN segments are always zero-length. */ queue (self, "", 0, FLAG_FIN); } static void queue_rst_message (PseudoTcpSocket *self) { g_assert (self->priv->support_fin_ack); /* RST segments are always zero-length. */ queue (self, "", 0, FLAG_RST); } gboolean pseudo_tcp_socket_connect(PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; if (priv->state != TCP_LISTEN) { priv->error = EINVAL; return FALSE; } set_state (self, TCP_SYN_SENT); queue_connect_message (self); attempt_send(self, sfNone); return TRUE; } void pseudo_tcp_socket_notify_mtu(PseudoTcpSocket *self, guint16 mtu) { PseudoTcpSocketPrivate *priv = self->priv; priv->mtu_advise = mtu; if (priv->state == TCP_ESTABLISHED) { adjustMTU(self); } } void pseudo_tcp_socket_notify_clock(PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; guint32 now = get_current_time (self); if (priv->state == TCP_CLOSED) return; /* If in the TIME-WAIT state, any delayed segments have passed and the * connection can be considered closed from both ends. * FIXME: This should probably actually compare a timestamp before * operating. */ if (priv->support_fin_ack && priv->state == TCP_TIME_WAIT) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Notified clock in TIME-WAIT state; closing connection."); set_state_closed (self, 0); } /* If in the LAST-ACK state, resend the FIN because it hasn’t been ACKed yet. * FIXME: This should probably actually compare a timestamp before * operating. */ if (priv->support_fin_ack && priv->state == TCP_LAST_ACK) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Notified clock in LAST-ACK state; resending FIN segment."); queue_fin_message (self); attempt_send (self, sfFin); } // Check if it's time to retransmit a segment if (priv->rto_base && (time_diff(priv->rto_base + priv->rx_rto, now) <= 0)) { if (g_queue_get_length (&priv->slist) == 0) { g_assert_not_reached (); } else { // Note: (priv->slist.front().xmit == 0)) { // retransmit segments guint32 nInFlight; guint32 rto_limit; int transmit_status; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "timeout retransmit (rto: %u) " "(rto_base: %u) (now: %u) (dup_acks: %u)", priv->rx_rto, priv->rto_base, now, (guint) priv->dup_acks); transmit_status = transmit(self, g_queue_peek_head (&priv->slist), now); if (transmit_status != 0) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Error transmitting segment. Closing down."); closedown (self, transmit_status, CLOSEDOWN_LOCAL); return; } nInFlight = priv->snd_nxt - priv->snd_una; priv->ssthresh = max(nInFlight / 2, 2 * priv->mss); DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "ssthresh: %u = (nInFlight: %u / 2) + " "2 * mss: %u", priv->ssthresh, nInFlight, priv->mss); //LOG(LS_INFO) << "priv->ssthresh: " << priv->ssthresh << " nInFlight: " << nInFlight << " priv->mss: " << priv->mss; priv->cwnd = priv->mss; // Back off retransmit timer. Note: the limit is lower when connecting. rto_limit = (priv->state < TCP_ESTABLISHED) ? DEF_RTO : MAX_RTO; priv->rx_rto = min(rto_limit, priv->rx_rto * 2); priv->rto_base = now; priv->recover = priv->snd_nxt; if (priv->dup_acks >= 3) { priv->dup_acks = 0; priv->fast_recovery = FALSE; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "exit recovery on timeout"); } } } // Check if it's time to probe closed windows if ((priv->snd_wnd == 0) && (time_diff(priv->lastsend + priv->rx_rto, now) <= 0)) { if (time_diff(now, priv->lastrecv) >= 15000) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Receive window closed. Closing down."); closedown (self, ECONNABORTED, CLOSEDOWN_LOCAL); return; } // probe the window packet(self, priv->snd_nxt - 1, 0, 0, 0, now); priv->lastsend = now; // back off retransmit timer priv->rx_rto = min(MAX_RTO, priv->rx_rto * 2); } // Check if it's time to send delayed acks if (priv->t_ack && (time_diff(priv->t_ack + priv->ack_delay, now) <= 0)) { packet(self, priv->snd_nxt, 0, 0, 0, now); } } gboolean pseudo_tcp_socket_notify_packet(PseudoTcpSocket *self, const gchar * buffer, guint32 len) { gboolean retval; if (len > MAX_PACKET) { //LOG_F(WARNING) << "packet too large"; self->priv->error = EMSGSIZE; return FALSE; } else if (len < HEADER_SIZE) { //LOG_F(WARNING) << "packet too small"; self->priv->error = EINVAL; return FALSE; } /* Hold a reference to the PseudoTcpSocket during parsing, since it may be * closed from within a callback. */ g_object_ref (self); retval = parse (self, (guint8 *) buffer, HEADER_SIZE, (guint8 *) buffer + HEADER_SIZE, len - HEADER_SIZE); g_object_unref (self); return retval; } /* Assume there are two buffers in the given #NiceInputMessage: a 24-byte one * containing the header, and a bigger one for the data. */ gboolean pseudo_tcp_socket_notify_message (PseudoTcpSocket *self, NiceInputMessage *message) { gboolean retval; g_assert_cmpuint (message->n_buffers, >, 0); if (message->n_buffers == 1) return pseudo_tcp_socket_notify_packet (self, message->buffers[0].buffer, message->buffers[0].size); g_assert_cmpuint (message->n_buffers, ==, 2); g_assert_cmpuint (message->buffers[0].size, ==, HEADER_SIZE); if (message->length > MAX_PACKET) { //LOG_F(WARNING) << "packet too large"; return FALSE; } else if (message->length < HEADER_SIZE) { //LOG_F(WARNING) << "packet too small"; return FALSE; } /* Hold a reference to the PseudoTcpSocket during parsing, since it may be * closed from within a callback. */ g_object_ref (self); retval = parse (self, message->buffers[0].buffer, message->buffers[0].size, message->buffers[1].buffer, message->length - message->buffers[0].size); g_object_unref (self); return retval; } gboolean pseudo_tcp_socket_get_next_clock(PseudoTcpSocket *self, guint64 *timeout) { PseudoTcpSocketPrivate *priv = self->priv; guint32 now = get_current_time (self); gsize snd_buffered; guint32 closed_timeout; if (priv->shutdown == SD_FORCEFUL) { if (priv->support_fin_ack) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "‘Forceful’ shutdown used when FIN-ACK support is enabled"); } /* Transition to the CLOSED state. */ closedown (self, 0, CLOSEDOWN_REMOTE); return FALSE; } snd_buffered = pseudo_tcp_fifo_get_buffered (&priv->sbuf); if ((priv->shutdown == SD_GRACEFUL) && ((priv->state != TCP_ESTABLISHED) || ((snd_buffered == 0) && (priv->t_ack == 0)))) { if (priv->support_fin_ack) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "‘Graceful’ shutdown used when FIN-ACK support is enabled"); } /* Transition to the CLOSED state. */ closedown (self, 0, CLOSEDOWN_REMOTE); return FALSE; } /* FIN-ACK support. The timeout for closing the socket if nothing is received * varies depending on whether the socket is waiting in the TIME-WAIT state * for delayed segments to pass. * * See: http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html */ closed_timeout = CLOSED_TIMEOUT; if (priv->support_fin_ack && priv->state == TCP_TIME_WAIT) closed_timeout = TIME_WAIT_TIMEOUT; if (priv->support_fin_ack && priv->state == TCP_CLOSED) { return FALSE; } if (*timeout == 0 || *timeout < now) *timeout = now + closed_timeout; if (priv->support_fin_ack && priv->state == TCP_TIME_WAIT) { *timeout = min (*timeout, now + TIME_WAIT_TIMEOUT); return TRUE; } if (priv->state == TCP_CLOSED && !priv->support_fin_ack) { *timeout = min (*timeout, now + CLOSED_TIMEOUT); return TRUE; } *timeout = min (*timeout, now + DEFAULT_TIMEOUT); if (priv->t_ack) { *timeout = min(*timeout, priv->t_ack + priv->ack_delay); } if (priv->rto_base) { *timeout = min(*timeout, priv->rto_base + priv->rx_rto); } if (priv->snd_wnd == 0) { *timeout = min(*timeout, priv->lastsend + priv->rx_rto); } return TRUE; } gint pseudo_tcp_socket_recv(PseudoTcpSocket *self, char * buffer, size_t len) { PseudoTcpSocketPrivate *priv = self->priv; gsize bytesread; gsize available_space; /* Received a FIN from the peer, so return 0. RFC 793, §3.5, Case 2. */ if (priv->support_fin_ack && priv->shutdown_reads) { return 0; } /* Return 0 if FIN-ACK is not supported but the socket has been closed. */ if (!priv->support_fin_ack && pseudo_tcp_socket_is_closed (self)) { return 0; } /* Return ENOTCONN if FIN-ACK is not supported and the connection is not * ESTABLISHED. */ if (!priv->support_fin_ack && priv->state != TCP_ESTABLISHED) { priv->error = ENOTCONN; return -1; } if (len == 0) return 0; bytesread = pseudo_tcp_fifo_read (&priv->rbuf, (guint8 *) buffer, len); // If there's no data in |m_rbuf|. if (bytesread == 0 && !(pseudo_tcp_state_has_received_fin (priv->state) || pseudo_tcp_state_has_received_fin_ack (priv->state))) { priv->bReadEnable = TRUE; priv->error = EWOULDBLOCK; return -1; } available_space = pseudo_tcp_fifo_get_write_remaining (&priv->rbuf); if (available_space - priv->rcv_wnd >= min (priv->rbuf_len / 2, priv->mss)) { // !?! Not sure about this was closed business gboolean bWasClosed = (priv->rcv_wnd == 0); priv->rcv_wnd = available_space; if (bWasClosed) { attempt_send(self, sfImmediateAck); } } return bytesread; } gint pseudo_tcp_socket_send(PseudoTcpSocket *self, const char * buffer, guint32 len) { PseudoTcpSocketPrivate *priv = self->priv; gint written; gsize available_space; if (priv->state != TCP_ESTABLISHED) { priv->error = pseudo_tcp_state_has_sent_fin (priv->state) ? EPIPE : ENOTCONN; return -1; } available_space = pseudo_tcp_fifo_get_write_remaining (&priv->sbuf); if (!available_space) { priv->bWriteEnable = TRUE; priv->error = EWOULDBLOCK; return -1; } written = queue (self, buffer, len, FLAG_NONE); attempt_send(self, sfNone); if (written > 0 && (guint32)written < len) { priv->bWriteEnable = TRUE; } return written; } void pseudo_tcp_socket_close(PseudoTcpSocket *self, gboolean force) { PseudoTcpSocketPrivate *priv = self->priv; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Closing socket %p %s", self, force ? "forcefully" : "gracefully"); /* Forced closure by sending an RST segment. RFC 1122, §4.2.2.13. */ if (force && priv->state != TCP_CLOSED) { closedown (self, ECONNABORTED, CLOSEDOWN_LOCAL); return; } /* Fall back to shutdown(). */ pseudo_tcp_socket_shutdown (self, PSEUDO_TCP_SHUTDOWN_RDWR); } void pseudo_tcp_socket_shutdown (PseudoTcpSocket *self, PseudoTcpShutdown how) { PseudoTcpSocketPrivate *priv = self->priv; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Shutting down socket %p: %u", self, how); /* FIN-ACK--only stuff below here. */ if (!priv->support_fin_ack) { if (priv->shutdown == SD_NONE) priv->shutdown = SD_GRACEFUL; return; } /* What needs shutting down? */ switch (how) { case PSEUDO_TCP_SHUTDOWN_RD: case PSEUDO_TCP_SHUTDOWN_RDWR: priv->shutdown_reads = TRUE; break; case PSEUDO_TCP_SHUTDOWN_WR: /* Handled below. */ break; default: DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid shutdown method: %u.", how); break; } if (how == PSEUDO_TCP_SHUTDOWN_RD) { return; } /* Unforced write closure. */ switch (priv->state) { case TCP_LISTEN: case TCP_SYN_SENT: /* Just abort the connection without completing the handshake. */ set_state_closed (self, 0); break; case TCP_SYN_RECEIVED: case TCP_ESTABLISHED: /* Local user initiating the close: RFC 793, §3.5, Cases 1 and 3. * If there is pending receive data, send RST instead of FIN; * see RFC 1122, §4.2.2.13. */ if (pseudo_tcp_socket_get_available_bytes (self) > 0) { closedown (self, ECONNABORTED, CLOSEDOWN_LOCAL); } else { queue_fin_message (self); attempt_send (self, sfFin); set_state (self, TCP_FIN_WAIT_1); } break; case TCP_CLOSE_WAIT: /* Remote user initiating the close: RFC 793, §3.5, Case 2. * We’ve previously received a FIN from the peer; now the user is closing * the local end of the connection. */ queue_fin_message (self); attempt_send (self, sfFin); set_state (self, TCP_LAST_ACK); break; case TCP_CLOSING: case TCP_CLOSED: /* Already closed on both sides. */ break; case TCP_FIN_WAIT_1: case TCP_FIN_WAIT_2: case TCP_TIME_WAIT: case TCP_LAST_ACK: /* Already closed locally. */ break; default: /* Do nothing. */ break; } } int pseudo_tcp_socket_get_error(PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; return priv->error; } // // Internal Implementation // static guint32 queue (PseudoTcpSocket *self, const gchar * data, guint32 len, TcpFlags flags) { PseudoTcpSocketPrivate *priv = self->priv; gsize available_space; available_space = pseudo_tcp_fifo_get_write_remaining (&priv->sbuf); if (len > available_space) { g_assert (flags == FLAG_NONE); len = available_space; } // We can concatenate data if the last segment is the same type // (control v. regular data), and has not been transmitted yet if (g_queue_get_length (&priv->slist) && (((SSegment *)g_queue_peek_tail (&priv->slist))->flags == flags) && (((SSegment *)g_queue_peek_tail (&priv->slist))->xmit == 0)) { ((SSegment *)g_queue_peek_tail (&priv->slist))->len += len; } else { SSegment *sseg = g_slice_new0 (SSegment); gsize snd_buffered = pseudo_tcp_fifo_get_buffered (&priv->sbuf); sseg->seq = priv->snd_una + snd_buffered; sseg->len = len; sseg->flags = flags; g_queue_push_tail (&priv->slist, sseg); g_queue_push_tail (&priv->unsent_slist, sseg); } //LOG(LS_INFO) << "PseudoTcp::queue - priv->slen = " << priv->slen; return pseudo_tcp_fifo_write (&priv->sbuf, (guint8*) data, len);; } // Creates a packet and submits it to the network. This method can either // send payload or just an ACK packet. // // |seq| is the sequence number of this packet. // |flags| is the flags for sending this packet. // |offset| is the offset to read from |m_sbuf|. // |len| is the number of bytes to read from |m_sbuf| as payload. If this // value is 0 then this is an ACK packet, otherwise this packet has payload. static PseudoTcpWriteResult packet(PseudoTcpSocket *self, guint32 seq, TcpFlags flags, guint32 offset, guint32 len, guint32 now) { PseudoTcpSocketPrivate *priv = self->priv; union { guint8 u8[MAX_PACKET]; guint16 u16[MAX_PACKET / 2]; guint32 u32[MAX_PACKET / 4]; } buffer; PseudoTcpWriteResult wres = WR_SUCCESS; g_assert(HEADER_SIZE + len <= MAX_PACKET); *buffer.u32 = htonl(priv->conv); *(buffer.u32 + 1) = htonl(seq); *(buffer.u32 + 2) = htonl(priv->rcv_nxt); buffer.u8[12] = 0; buffer.u8[13] = flags; *(buffer.u16 + 7) = htons((guint16)(priv->rcv_wnd >> priv->rwnd_scale)); // Timestamp computations *(buffer.u32 + 4) = htonl(now); *(buffer.u32 + 5) = htonl(priv->ts_recent); priv->ts_lastack = priv->rcv_nxt; if (len) { gsize bytes_read; bytes_read = pseudo_tcp_fifo_read_offset (&priv->sbuf, buffer.u8 + HEADER_SIZE, len, offset); g_assert (bytes_read == len); } DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "Sending " "", priv->conv, (unsigned)flags, seq, seq + len, priv->rcv_nxt, priv->rcv_wnd, now % 10000, priv->ts_recent % 10000, len); wres = priv->callbacks.WritePacket(self, (gchar *) buffer.u8, len + HEADER_SIZE, priv->callbacks.user_data); /* Note: When len is 0, this is an ACK packet. We don't read the return value for those, and thus we won't retry. So go ahead and treat the packet as a success (basically simulate as if it were dropped), which will prevent our timers from being messed up. */ if ((wres != WR_SUCCESS) && (0 != len)) return wres; priv->t_ack = 0; if (len > 0) { priv->lastsend = now; } priv->last_traffic = now; priv->bOutgoing = TRUE; return WR_SUCCESS; } static gboolean parse (PseudoTcpSocket *self, const guint8 *_header_buf, gsize header_buf_len, const guint8 *data_buf, gsize data_buf_len) { Segment seg; union { const guint8 *u8; const guint16 *u16; const guint32 *u32; } header_buf; header_buf.u8 = _header_buf; if (header_buf_len != 24) return FALSE; seg.conv = ntohl(*header_buf.u32); seg.seq = ntohl(*(header_buf.u32 + 1)); seg.ack = ntohl(*(header_buf.u32 + 2)); seg.flags = header_buf.u8[13]; seg.wnd = ntohs(*(header_buf.u16 + 7)); seg.tsval = ntohl(*(header_buf.u32 + 4)); seg.tsecr = ntohl(*(header_buf.u32 + 5)); seg.data = (const gchar *) data_buf; seg.len = data_buf_len; DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "Received " "", seg.conv, (unsigned)seg.flags, seg.seq, seg.seq + seg.len, seg.ack, seg.wnd, seg.tsval % 10000, seg.tsecr % 10000, seg.len); return process(self, &seg); } /* True iff the @state requires that a FIN has already been sent by this * host. */ static gboolean pseudo_tcp_state_has_sent_fin (PseudoTcpState state) { switch (state) { case TCP_LISTEN: case TCP_SYN_SENT: case TCP_SYN_RECEIVED: case TCP_ESTABLISHED: case TCP_CLOSE_WAIT: return FALSE; case TCP_CLOSED: case TCP_FIN_WAIT_1: case TCP_FIN_WAIT_2: case TCP_CLOSING: case TCP_TIME_WAIT: case TCP_LAST_ACK: return TRUE; default: return FALSE; } } /* True iff the @state requires that a FIN has already been received from the * peer. */ static gboolean pseudo_tcp_state_has_received_fin (PseudoTcpState state) { switch (state) { case TCP_LISTEN: case TCP_SYN_SENT: case TCP_SYN_RECEIVED: case TCP_ESTABLISHED: case TCP_FIN_WAIT_1: case TCP_FIN_WAIT_2: return FALSE; case TCP_CLOSED: case TCP_CLOSING: case TCP_TIME_WAIT: case TCP_CLOSE_WAIT: case TCP_LAST_ACK: return TRUE; default: return FALSE; } } /* True iff the @state requires that a FIN-ACK has already been received from * the peer. */ static gboolean pseudo_tcp_state_has_received_fin_ack (PseudoTcpState state) { switch (state) { case TCP_LISTEN: case TCP_SYN_SENT: case TCP_SYN_RECEIVED: case TCP_ESTABLISHED: case TCP_FIN_WAIT_1: case TCP_FIN_WAIT_2: case TCP_CLOSING: case TCP_CLOSE_WAIT: case TCP_LAST_ACK: return FALSE; case TCP_CLOSED: case TCP_TIME_WAIT: return TRUE; default: return FALSE; } } static gboolean process(PseudoTcpSocket *self, Segment *seg) { PseudoTcpSocketPrivate *priv = self->priv; guint32 now; SendFlags sflags = sfNone; gboolean bIgnoreData; gboolean bNewData; gboolean bConnect = FALSE; gsize snd_buffered; gsize available_space; guint32 kIdealRefillSize; gboolean is_valuable_ack, is_duplicate_ack, is_fin_ack = FALSE; gboolean received_fin = FALSE; /* If this is the wrong conversation, send a reset!?! (with the correct conversation?) */ if (seg->conv != priv->conv) { //if ((seg->flags & FLAG_RST) == 0) { // packet(sock, tcb, seg->ack, 0, FLAG_RST, 0, 0); //} DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "wrong conversation"); return FALSE; } now = get_current_time (self); priv->last_traffic = priv->lastrecv = now; priv->bOutgoing = FALSE; if (priv->state == TCP_CLOSED || (pseudo_tcp_state_has_received_fin_ack (priv->state) && seg->len > 0)) { /* Send an RST segment. See: RFC 1122, §4.2.2.13; RFC 793, §3.4, point 3, * page 37. We can only send RST if we know the peer knows we’re closed; * otherwise this could be a timeout retransmit from them, due to our * packets from data through to FIN being dropped. */ DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Segment received while closed; sending RST."); if ((seg->flags & FLAG_RST) == 0) { closedown (self, 0, CLOSEDOWN_LOCAL); } return FALSE; } // Check if this is a reset segment if (seg->flags & FLAG_RST) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Received RST segment; closing down."); closedown (self, ECONNRESET, CLOSEDOWN_REMOTE); return FALSE; } // Check for control data bConnect = FALSE; if (seg->flags & FLAG_CTL) { if (seg->len == 0) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Missing control code"); return FALSE; } else if (seg->data[0] == CTL_CONNECT) { bConnect = TRUE; parse_options (self, (guint8 *) &seg->data[1], seg->len - 1); if (priv->state == TCP_LISTEN) { set_state (self, TCP_SYN_RECEIVED); queue_connect_message (self); } else if (priv->state == TCP_SYN_SENT) { set_state_established (self); } } else { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Unknown control code: %u", seg->data[0]); return FALSE; } } // Update timestamp if (SMALLER_OR_EQUAL (seg->seq, priv->ts_lastack) && SMALLER (priv->ts_lastack, seg->seq + seg->len)) { priv->ts_recent = seg->tsval; } // Check if this is a valuable ack is_valuable_ack = (LARGER(seg->ack, priv->snd_una) && SMALLER_OR_EQUAL(seg->ack, priv->snd_nxt)); is_duplicate_ack = (seg->ack == priv->snd_una); if (is_valuable_ack) { guint32 nAcked; guint32 nFree; // Calculate round-trip time if (seg->tsecr) { long rtt = time_diff(now, seg->tsecr); if (rtt >= 0) { if (priv->rx_srtt == 0) { priv->rx_srtt = rtt; priv->rx_rttvar = rtt / 2; } else { priv->rx_rttvar = (3 * priv->rx_rttvar + labs((long)(rtt - priv->rx_srtt))) / 4; priv->rx_srtt = (7 * priv->rx_srtt + rtt) / 8; } priv->rx_rto = bound(MIN_RTO, priv->rx_srtt + max(1LU, 4 * priv->rx_rttvar), MAX_RTO); DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "rtt: %ld srtt: %u rttvar: %u rto: %u", rtt, priv->rx_srtt, priv->rx_rttvar, priv->rx_rto); } else { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid RTT: %ld", rtt); return FALSE; } priv->last_acked_ts = seg->tsecr; } priv->snd_wnd = seg->wnd << priv->swnd_scale; nAcked = seg->ack - priv->snd_una; priv->snd_una = seg->ack; priv->rto_base = (priv->snd_una == priv->snd_nxt) ? 0 : now; /* ACKs for FIN segments give an increment on nAcked, but there is no * corresponding byte to read because the FIN segment is empty (it just has * a sequence number). */ if (nAcked == priv->sbuf.data_length + 1 && pseudo_tcp_state_has_sent_fin (priv->state)) { is_fin_ack = TRUE; nAcked--; } pseudo_tcp_fifo_consume_read_data (&priv->sbuf, nAcked); for (nFree = nAcked; nFree > 0; ) { SSegment *data; g_assert(g_queue_get_length (&priv->slist) != 0); data = (SSegment *) g_queue_peek_head (&priv->slist); if (nFree < data->len) { data->len -= nFree; data->seq += nFree; nFree = 0; } else { if (data->len > priv->largest) { priv->largest = data->len; } nFree -= data->len; g_slice_free (SSegment, data); g_queue_pop_head (&priv->slist); } } if (priv->dup_acks >= 3) { if (LARGER_OR_EQUAL (priv->snd_una, priv->recover)) { // NewReno guint32 nInFlight = priv->snd_nxt - priv->snd_una; // (Fast Retransmit) priv->cwnd = min(priv->ssthresh, max (nInFlight, priv->mss) + priv->mss); DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "exit recovery cwnd=%d ssthresh=%d nInFlight=%d mss: %d", priv->cwnd, priv->ssthresh, nInFlight, priv->mss); priv->fast_recovery = FALSE; priv->dup_acks = 0; } else { int transmit_status; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "recovery retransmit"); transmit_status = transmit(self, g_queue_peek_head (&priv->slist), now); if (transmit_status != 0) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Error transmitting recovery retransmit segment. Closing down."); closedown (self, transmit_status, CLOSEDOWN_LOCAL); return FALSE; } priv->cwnd += (nAcked > priv->mss ? priv->mss : 0) - min(nAcked, priv->cwnd); } } else { priv->dup_acks = 0; // Slow start, congestion avoidance if (priv->cwnd < priv->ssthresh) { priv->cwnd += priv->mss; } else { priv->cwnd += max(1LU, priv->mss * priv->mss / priv->cwnd); } } } else if (is_duplicate_ack) { /* !?! Note, tcp says don't do this... but otherwise how does a closed window become open? */ priv->snd_wnd = seg->wnd << priv->swnd_scale; // Check duplicate acks if (seg->len > 0) { // it's a dup ack, but with a data payload, so don't modify priv->dup_acks } else if (priv->snd_una != priv->snd_nxt) { guint32 nInFlight; priv->dup_acks += 1; DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "Received dup ack (dups: %u)", priv->dup_acks); if (priv->dup_acks == 3) { // (Fast Retransmit) int transmit_status; if (LARGER_OR_EQUAL (priv->snd_una, priv->recover) || seg->tsecr == priv->last_acked_ts) { /* NewReno */ /* Invoke fast retransmit RFC3782 section 3 step 1A*/ DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "enter recovery"); DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "recovery retransmit"); transmit_status = transmit(self, g_queue_peek_head (&priv->slist), now); if (transmit_status != 0) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Error transmitting recovery retransmit segment. Closing down."); closedown (self, transmit_status, CLOSEDOWN_LOCAL); return FALSE; } priv->recover = priv->snd_nxt; nInFlight = priv->snd_nxt - priv->snd_una; priv->ssthresh = max(nInFlight / 2, 2 * priv->mss); DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "ssthresh: %u = max((nInFlight: %u / 2), 2 * mss: %u)", priv->ssthresh, nInFlight, priv->mss); priv->cwnd = priv->ssthresh + 3 * priv->mss; priv->fast_recovery = TRUE; } else { DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "Skipping fast recovery: recover: %u snd_una: %u", priv->recover, priv->snd_una); } } else if (priv->dup_acks > 3) { if (priv->fast_recovery) priv->cwnd += priv->mss; } } else { priv->dup_acks = 0; } } // !?! A bit hacky if ((priv->state == TCP_SYN_RECEIVED) && !bConnect) { set_state_established (self); } /* Check for connection closure. Only pay attention to FIN segments if they * are in sequence; otherwise we’ve missed a packet earlier in the stream and * need to request retransmission first. */ if (priv->support_fin_ack) { /* @received_fin is set when, and only when, all segments preceding the FIN * have been acknowledged. This is to handle the case where the FIN arrives * out of order with a preceding data segment. */ if (seg->flags & FLAG_FIN) { priv->rcv_fin = seg->seq; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Setting rcv_fin = %u", priv->rcv_fin); } /* For the moment, FIN segments must not contain data. */ if (seg->flags & FLAG_FIN && seg->len != 0) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "FIN segment contained data; ignored"); return FALSE; } received_fin = (priv->rcv_nxt != 0 && priv->rcv_nxt + seg->len == priv->rcv_fin); /* Update the state machine, implementing all transitions on ‘rcv FIN’ or * ‘rcv ACK of FIN’ from RFC 793, Figure 6; and RFC 1122, §4.2.2.8. */ switch (priv->state) { case TCP_ESTABLISHED: if (received_fin) { /* Received a FIN from the network, RFC 793, §3.5, Case 2. * The code below will send an ACK for the FIN. */ set_state (self, TCP_CLOSE_WAIT); } break; case TCP_CLOSING: if (is_fin_ack) { /* Handle the ACK of a locally-sent FIN flag. RFC 793, §3.5, Case 3. */ set_state (self, TCP_TIME_WAIT); } break; case TCP_LAST_ACK: if (is_fin_ack) { /* Handle the ACK of a locally-sent FIN flag. RFC 793, §3.5, Case 2. */ set_state_closed (self, 0); } break; case TCP_FIN_WAIT_1: if (is_fin_ack && received_fin) { /* Simultaneous close with an ACK for a FIN previously sent, * RFC 793, §3.5, Case 3. */ set_state (self, TCP_TIME_WAIT); } else if (is_fin_ack) { /* Handle the ACK of a locally-sent FIN flag. RFC 793, §3.5, Case 1. */ set_state (self, TCP_FIN_WAIT_2); } else if (received_fin) { /* Simultaneous close, RFC 793, §3.5, Case 3. */ set_state (self, TCP_CLOSING); } break; case TCP_FIN_WAIT_2: if (received_fin) { /* Local user closed the connection, RFC 793, §3.5, Case 1. */ set_state (self, TCP_TIME_WAIT); } break; case TCP_LISTEN: case TCP_SYN_SENT: case TCP_SYN_RECEIVED: case TCP_TIME_WAIT: case TCP_CLOSED: case TCP_CLOSE_WAIT: /* Shouldn’t ever hit these cases. */ if (received_fin) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Unexpected state %u when FIN received", priv->state); } else if (is_fin_ack) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Unexpected state %u when FIN-ACK received", priv->state); } break; default: DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid state %u when FIN received", priv->state); return FALSE; } } else if (seg->flags & FLAG_FIN) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid FIN received when FIN-ACK support is disabled"); } else if (is_fin_ack) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid FIN-ACK received when FIN-ACK support is disabled"); } // If we make room in the send queue, notify the user // The goal it to make sure we always have at least enough data to fill the // window. We'd like to notify the app when we are halfway to that point. kIdealRefillSize = (priv->sbuf_len + priv->rbuf_len) / 2; snd_buffered = pseudo_tcp_fifo_get_buffered (&priv->sbuf); if (priv->bWriteEnable && snd_buffered < kIdealRefillSize) { priv->bWriteEnable = FALSE; if (priv->callbacks.PseudoTcpWritable) priv->callbacks.PseudoTcpWritable(self, priv->callbacks.user_data); } /* Conditions where acks must be sent: * 1) Segment is too old (they missed an ACK) (immediately) * 2) Segment is too new (we missed a segment) (immediately) * 3) Segment has data (so we need to ACK!) (delayed) * ... so the only time we don't need to ACK, is an empty segment * that points to rcv_nxt! * 4) Segment has the FIN flag set (immediately) — note that the FIN flag * itself has to be included in the ACK as a numbered byte; * see RFC 793, §3.3. Also see: RFC 793, §3.5. */ if (seg->seq != priv->rcv_nxt) { sflags = sfDuplicateAck; // (Fast Recovery) } else if (seg->len != 0) { if (priv->ack_delay == 0) { sflags = sfImmediateAck; } else { sflags = sfDelayedAck; } } else if (received_fin) { /* FIN flags have a sequence number. Only acknowledge them after all * preceding octets have been acknowledged. */ sflags = sfImmediateAck; } if (sflags == sfDuplicateAck) { if (seg->seq > priv->rcv_nxt) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "too new"); } else if (SMALLER_OR_EQUAL(seg->seq + seg->len, priv->rcv_nxt)) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "too old"); } } // Adjust the incoming segment to fit our receive buffer if (SMALLER(seg->seq, priv->rcv_nxt)) { guint32 nAdjust = priv->rcv_nxt - seg->seq; if (nAdjust < seg->len) { seg->seq += nAdjust; seg->data += nAdjust; seg->len -= nAdjust; } else { seg->len = 0; } } available_space = pseudo_tcp_fifo_get_write_remaining (&priv->rbuf); if ((seg->seq + seg->len - priv->rcv_nxt) > available_space) { guint32 nAdjust = seg->seq + seg->len - priv->rcv_nxt - available_space; if (nAdjust < seg->len) { seg->len -= nAdjust; } else { seg->len = 0; } } bIgnoreData = (seg->flags & FLAG_CTL); if (!priv->support_fin_ack) bIgnoreData |= (priv->shutdown != SD_NONE); bNewData = FALSE; if (seg->len > 0) { if (bIgnoreData) { if (seg->seq == priv->rcv_nxt) { priv->rcv_nxt += seg->len; } } else { guint32 nOffset = seg->seq - priv->rcv_nxt; gsize res; res = pseudo_tcp_fifo_write_offset (&priv->rbuf, (guint8 *) seg->data, seg->len, nOffset); g_assert (res == seg->len); if (seg->seq == priv->rcv_nxt) { GList *iter = NULL; pseudo_tcp_fifo_consume_write_buffer (&priv->rbuf, seg->len); priv->rcv_nxt += seg->len; priv->rcv_wnd -= seg->len; bNewData = TRUE; iter = priv->rlist; while (iter && SMALLER_OR_EQUAL(((RSegment *)iter->data)->seq, priv->rcv_nxt)) { RSegment *data = (RSegment *)(iter->data); if (LARGER (data->seq + data->len, priv->rcv_nxt)) { guint32 nAdjust = (data->seq + data->len) - priv->rcv_nxt; sflags = sfImmediateAck; // (Fast Recovery) DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Recovered %u bytes (%u -> %u)", nAdjust, priv->rcv_nxt, priv->rcv_nxt + nAdjust); pseudo_tcp_fifo_consume_write_buffer (&priv->rbuf, nAdjust); priv->rcv_nxt += nAdjust; priv->rcv_wnd -= nAdjust; } g_slice_free (RSegment, priv->rlist->data); priv->rlist = g_list_delete_link (priv->rlist, priv->rlist); iter = priv->rlist; } } else { GList *iter = NULL; RSegment *rseg = g_slice_new0 (RSegment); DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Saving %u bytes (%u -> %u)", seg->len, seg->seq, seg->seq + seg->len); rseg->seq = seg->seq; rseg->len = seg->len; iter = priv->rlist; while (iter && SMALLER (((RSegment*)iter->data)->seq, rseg->seq)) { iter = g_list_next (iter); } priv->rlist = g_list_insert_before(priv->rlist, iter, rseg); } } } if (received_fin) { /* FIN flags have a sequence number. */ priv->rcv_nxt++; } attempt_send(self, sflags); // If we have new data, notify the user if (bNewData && priv->bReadEnable) { /* priv->bReadEnable = FALSE; — removed so that we’re always notified of * incoming pseudo-TCP data, rather than having to read the entire buffer * on each readable() callback before the next callback is enabled. * (When client-provided buffers are small, this is not possible.) */ if (priv->callbacks.PseudoTcpReadable) priv->callbacks.PseudoTcpReadable(self, priv->callbacks.user_data); } return TRUE; } static gboolean transmit(PseudoTcpSocket *self, SSegment *segment, guint32 now) { PseudoTcpSocketPrivate *priv = self->priv; guint32 nTransmit = min(segment->len, priv->mss); if (segment->xmit >= ((priv->state == TCP_ESTABLISHED) ? 15 : 30)) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "too many retransmits"); return ETIMEDOUT; } while (TRUE) { guint32 seq = segment->seq; guint8 flags = segment->flags; PseudoTcpWriteResult wres; /* The packet must not have already been acknowledged. */ g_assert_cmpuint (segment->seq - priv->snd_una, <=, 1024 * 1024 * 64); /* Write out the packet. */ wres = packet(self, seq, flags, segment->seq - priv->snd_una, nTransmit, now); if (wres == WR_SUCCESS) break; if (wres == WR_FAIL) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "packet failed"); return ECONNABORTED; /* FIXME: This error code doesn’t quite seem right */ } g_assert(wres == WR_TOO_LARGE); while (TRUE) { if (PACKET_MAXIMUMS[priv->msslevel + 1] == 0) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "MTU too small"); return EMSGSIZE; } /* !?! We need to break up all outstanding and pending packets and then retransmit!?! */ priv->mss = PACKET_MAXIMUMS[++priv->msslevel] - PACKET_OVERHEAD; // I added this... haven't researched actual formula priv->cwnd = 2 * priv->mss; if (priv->mss < nTransmit) { nTransmit = priv->mss; break; } } DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Adjusting mss to %u bytes ", priv->mss); } if (nTransmit < segment->len) { SSegment *subseg = g_slice_new0 (SSegment); subseg->seq = segment->seq + nTransmit; subseg->len = segment->len - nTransmit; subseg->flags = segment->flags; subseg->xmit = segment->xmit; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "mss reduced to %u", priv->mss); segment->len = nTransmit; g_queue_insert_after (&priv->slist, g_queue_find (&priv->slist, segment), subseg); if (subseg->xmit == 0) g_queue_insert_after (&priv->unsent_slist, g_queue_find (&priv->unsent_slist, segment), subseg); } if (segment->xmit == 0) { g_assert (g_queue_peek_head (&priv->unsent_slist) == segment); g_queue_pop_head (&priv->unsent_slist); priv->snd_nxt += segment->len; /* FIN flags require acknowledgement. */ if (segment->len == 0 && segment->flags & FLAG_FIN) priv->snd_nxt++; } segment->xmit += 1; if (priv->rto_base == 0) { priv->rto_base = now; } return 0; } static void attempt_send(PseudoTcpSocket *self, SendFlags sflags) { PseudoTcpSocketPrivate *priv = self->priv; guint32 now = get_current_time (self); gboolean bFirst = TRUE; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Attempting send with flags %u.", sflags); if (time_diff(now, priv->lastsend) > (long) priv->rx_rto) { priv->cwnd = priv->mss; } while (TRUE) { guint32 cwnd; guint32 nWindow; guint32 nInFlight; guint32 nUseable; guint32 nAvailable; gsize snd_buffered; GList *iter; SSegment *sseg; int transmit_status; cwnd = priv->cwnd; if ((priv->dup_acks == 1) || (priv->dup_acks == 2)) { // Limited Transmit cwnd += priv->dup_acks * priv->mss; } nWindow = min(priv->snd_wnd, cwnd); nInFlight = priv->snd_nxt - priv->snd_una; nUseable = (nInFlight < nWindow) ? (nWindow - nInFlight) : 0; snd_buffered = pseudo_tcp_fifo_get_buffered (&priv->sbuf); if (snd_buffered < nInFlight) /* iff a FIN has been sent */ nAvailable = 0; else nAvailable = min(snd_buffered - nInFlight, priv->mss); if (nAvailable > nUseable) { if (nUseable * 4 < nWindow) { // RFC 813 - avoid SWS nAvailable = 0; } else { nAvailable = nUseable; } } if (bFirst) { gsize available_space = pseudo_tcp_fifo_get_write_remaining (&priv->sbuf); bFirst = FALSE; DEBUG (PSEUDO_TCP_DEBUG_VERBOSE, "[cwnd: %u nWindow: %u nInFlight: %u " "nAvailable: %u nQueued: %" G_GSIZE_FORMAT " nEmpty: %" G_GSIZE_FORMAT " nWaiting: %zu ssthresh: %u]", priv->cwnd, nWindow, nInFlight, nAvailable, snd_buffered, available_space, snd_buffered - nInFlight, priv->ssthresh); } if (sflags == sfDuplicateAck) { packet(self, priv->snd_nxt, 0, 0, 0, now); sflags = sfNone; continue; } if (nAvailable == 0 && sflags != sfFin && sflags != sfRst) { if (sflags == sfNone) return; // If this is an immediate ack, or the second delayed ack if ((sflags == sfImmediateAck || sflags == sfDuplicateAck) || priv->t_ack) { packet(self, priv->snd_nxt, 0, 0, 0, now); } else { priv->t_ack = now; } return; } // Nagle algorithm // If there is data already in-flight, and we haven't a full segment of // data ready to send then hold off until we get more to send, or the // in-flight data is acknowledged. if (priv->use_nagling && sflags != sfFin && sflags != sfRst && (priv->snd_nxt > priv->snd_una) && (nAvailable < priv->mss)) { return; } // Find the next segment to transmit iter = g_queue_peek_head_link (&priv->unsent_slist); if (iter == NULL) return; sseg = iter->data; // If the segment is too large, break it into two if (sseg->len > nAvailable && sflags != sfFin && sflags != sfRst) { SSegment *subseg = g_slice_new0 (SSegment); subseg->seq = sseg->seq + nAvailable; subseg->len = sseg->len - nAvailable; subseg->flags = sseg->flags; sseg->len = nAvailable; g_queue_insert_after (&priv->unsent_slist, iter, subseg); g_queue_insert_after (&priv->slist, g_queue_find (&priv->slist, sseg), subseg); } transmit_status = transmit(self, sseg, now); if (transmit_status != 0) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "transmit failed"); // TODO: Is this the right thing ? closedown (self, transmit_status, CLOSEDOWN_REMOTE); return; } if (sflags == sfImmediateAck || sflags == sfDelayedAck) sflags = sfNone; } } /* If @source is %CLOSEDOWN_REMOTE, don’t send an RST packet, since closedown() * has been called as a result of an RST segment being received. * See: RFC 1122, §4.2.2.13. */ static void closedown (PseudoTcpSocket *self, guint32 err, ClosedownSource source) { PseudoTcpSocketPrivate *priv = self->priv; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Closing down socket %p with %s error %u.", self, (source == CLOSEDOWN_LOCAL) ? "local" : "remote", err); if (source == CLOSEDOWN_LOCAL && priv->support_fin_ack) { queue_rst_message (self); attempt_send (self, sfRst); } else if (source == CLOSEDOWN_LOCAL) { priv->shutdown = SD_FORCEFUL; } /* ‘Cute’ little navigation through the state machine to avoid breaking the * invariant that CLOSED can only be reached from TIME-WAIT or LAST-ACK. */ switch (priv->state) { case TCP_LISTEN: case TCP_SYN_SENT: break; case TCP_SYN_RECEIVED: case TCP_ESTABLISHED: set_state (self, TCP_FIN_WAIT_1); /* Fall through. */ case TCP_FIN_WAIT_1: set_state (self, TCP_FIN_WAIT_2); /* Fall through. */ case TCP_FIN_WAIT_2: case TCP_CLOSING: set_state (self, TCP_TIME_WAIT); break; case TCP_CLOSE_WAIT: set_state (self, TCP_LAST_ACK); break; case TCP_LAST_ACK: case TCP_TIME_WAIT: case TCP_CLOSED: default: break; } set_state_closed (self, err); } static void adjustMTU(PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; // Determine our current mss level, so that we can adjust appropriately later for (priv->msslevel = 0; PACKET_MAXIMUMS[priv->msslevel + 1] > 0; ++priv->msslevel) { if (((guint16)PACKET_MAXIMUMS[priv->msslevel]) <= priv->mtu_advise) { break; } } priv->mss = priv->mtu_advise - PACKET_OVERHEAD; // !?! Should we reset priv->largest here? DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Adjusting mss to %u bytes", priv->mss); // Enforce minimums on ssthresh and cwnd priv->ssthresh = max(priv->ssthresh, 2 * priv->mss); priv->cwnd = max(priv->cwnd, priv->mss); } static void apply_window_scale_option (PseudoTcpSocket *self, guint8 scale_factor) { PseudoTcpSocketPrivate *priv = self->priv; priv->swnd_scale = scale_factor; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Setting scale factor to %u", scale_factor); } static void apply_fin_ack_option (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; priv->support_fin_ack = TRUE; } static void apply_option (PseudoTcpSocket *self, guint8 kind, const guint8 *data, guint32 len) { switch (kind) { case TCP_OPT_MSS: DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Peer specified MSS option which is not supported."); // TODO: Implement. break; case TCP_OPT_WND_SCALE: // Window scale factor. // http://www.ietf.org/rfc/rfc1323.txt if (len != 1) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid window scale option received."); return; } apply_window_scale_option(self, data[0]); break; case TCP_OPT_FIN_ACK: // FIN-ACK support. DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "FIN-ACK support enabled."); apply_fin_ack_option (self); break; case TCP_OPT_EOL: case TCP_OPT_NOOP: /* Nothing to do. */ break; default: DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid TCP option %u", kind); break; } } static void parse_options (PseudoTcpSocket *self, const guint8 *data, guint32 len) { PseudoTcpSocketPrivate *priv = self->priv; gboolean has_window_scaling_option = FALSE; gboolean has_fin_ack_option = FALSE; guint32 pos = 0; // See http://www.freesoft.org/CIE/Course/Section4/8.htm for // parsing the options list. while (pos < len) { guint8 kind = TCP_OPT_EOL; guint8 opt_len; if (len < pos + 1) return; kind = data[pos]; pos++; if (kind == TCP_OPT_EOL) { // End of option list. break; } else if (kind == TCP_OPT_NOOP) { // No op. continue; } if (len < pos + 1) return; // Length of this option. opt_len = data[pos]; pos++; if (len < pos + opt_len) return; // Content of this option. if (opt_len <= len - pos) { apply_option (self, kind, data + pos, opt_len); pos += opt_len; } else { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Invalid option length received."); return; } if (kind == TCP_OPT_WND_SCALE) has_window_scaling_option = TRUE; else if (kind == TCP_OPT_FIN_ACK) has_fin_ack_option = TRUE; } if (!has_window_scaling_option) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Peer doesn't support window scaling"); if (priv->rwnd_scale > 0) { // Peer doesn't support TCP options and window scaling. // Revert receive buffer size to default value. resize_receive_buffer (self, DEFAULT_RCV_BUF_SIZE); priv->swnd_scale = 0; } } if (!has_fin_ack_option) { DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "Peer doesn't support FIN-ACK"); priv->support_fin_ack = FALSE; } } static void resize_send_buffer (PseudoTcpSocket *self, guint32 new_size) { PseudoTcpSocketPrivate *priv = self->priv; priv->sbuf_len = new_size; pseudo_tcp_fifo_set_capacity (&priv->sbuf, new_size); } static void resize_receive_buffer (PseudoTcpSocket *self, guint32 new_size) { PseudoTcpSocketPrivate *priv = self->priv; guint8 scale_factor = 0; gboolean result; gsize available_space; if (priv->rbuf_len == new_size) return; // Determine the scale factor such that the scaled window size can fit // in a 16-bit unsigned integer. while (new_size > 0xFFFF) { ++scale_factor; new_size >>= 1; } // Determine the proper size of the buffer. new_size <<= scale_factor; result = pseudo_tcp_fifo_set_capacity (&priv->rbuf, new_size); // Make sure the new buffer is large enough to contain data in the old // buffer. This should always be true because this method is called either // before connection is established or when peers are exchanging connect // messages. g_assert(result); priv->rbuf_len = new_size; priv->rwnd_scale = scale_factor; priv->ssthresh = new_size; available_space = pseudo_tcp_fifo_get_write_remaining (&priv->rbuf); priv->rcv_wnd = available_space; } gint pseudo_tcp_socket_get_available_bytes (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; return pseudo_tcp_fifo_get_buffered (&priv->rbuf); } gboolean pseudo_tcp_socket_can_send (PseudoTcpSocket *self) { return (pseudo_tcp_socket_get_available_send_space (self) > 0); } gsize pseudo_tcp_socket_get_available_send_space (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; gsize ret; if (!pseudo_tcp_state_has_sent_fin (priv->state)) { ret = pseudo_tcp_fifo_get_write_remaining (&priv->sbuf); } else { ret = 0; } if (ret == 0) priv->bWriteEnable = TRUE; return ret; } /* State names are capitalised and formatted as in RFC 793. */ static const gchar * pseudo_tcp_state_get_name (PseudoTcpState state) { switch (state) { case TCP_LISTEN: return "LISTEN"; case TCP_SYN_SENT: return "SYN-SENT"; case TCP_SYN_RECEIVED: return "SYN-RECEIVED"; case TCP_ESTABLISHED: return "ESTABLISHED"; case TCP_CLOSED: return "CLOSED"; case TCP_FIN_WAIT_1: return "FIN-WAIT-1"; case TCP_FIN_WAIT_2: return "FIN-WAIT-2"; case TCP_CLOSING: return "CLOSING"; case TCP_TIME_WAIT: return "TIME-WAIT"; case TCP_CLOSE_WAIT: return "CLOSE-WAIT"; case TCP_LAST_ACK: return "LAST-ACK"; default: return "UNKNOWN"; } } static void set_state (PseudoTcpSocket *self, PseudoTcpState new_state) { PseudoTcpSocketPrivate *priv = self->priv; PseudoTcpState old_state = priv->state; if (new_state == old_state) return; DEBUG (PSEUDO_TCP_DEBUG_NORMAL, "State %s → %s.", pseudo_tcp_state_get_name (old_state), pseudo_tcp_state_get_name (new_state)); /* Check whether it’s a valid state transition. */ #define TRANSITION(OLD, NEW) \ (old_state == TCP_##OLD && \ new_state == TCP_##NEW) /* Valid transitions. See: RFC 793, p23; RFC 1122, §4.2.2.8. */ g_assert (/* RFC 793, p23. */ TRANSITION (CLOSED, SYN_SENT) || TRANSITION (SYN_SENT, CLOSED) || TRANSITION (CLOSED, LISTEN) || TRANSITION (LISTEN, CLOSED) || TRANSITION (LISTEN, SYN_SENT) || TRANSITION (LISTEN, SYN_RECEIVED) || TRANSITION (SYN_SENT, SYN_RECEIVED) || TRANSITION (SYN_RECEIVED, ESTABLISHED) || TRANSITION (SYN_SENT, ESTABLISHED) || TRANSITION (SYN_RECEIVED, FIN_WAIT_1) || TRANSITION (ESTABLISHED, FIN_WAIT_1) || TRANSITION (ESTABLISHED, CLOSE_WAIT) || TRANSITION (FIN_WAIT_1, FIN_WAIT_2) || TRANSITION (FIN_WAIT_1, CLOSING) || TRANSITION (CLOSE_WAIT, LAST_ACK) || TRANSITION (FIN_WAIT_2, TIME_WAIT) || TRANSITION (CLOSING, TIME_WAIT) || TRANSITION (LAST_ACK, CLOSED) || TRANSITION (TIME_WAIT, CLOSED) || /* RFC 1122, §4.2.2.8. */ TRANSITION (SYN_RECEIVED, LISTEN) || TRANSITION (FIN_WAIT_1, TIME_WAIT)); #undef TRANSITION priv->state = new_state; } static void set_state_established (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; set_state (self, TCP_ESTABLISHED); adjustMTU (self); if (priv->callbacks.PseudoTcpOpened) priv->callbacks.PseudoTcpOpened (self, priv->callbacks.user_data); } /* (err == 0) means no error. */ static void set_state_closed (PseudoTcpSocket *self, guint32 err) { PseudoTcpSocketPrivate *priv = self->priv; set_state (self, TCP_CLOSED); /* Only call the callback if there was an error. */ if (priv->callbacks.PseudoTcpClosed && err != 0) priv->callbacks.PseudoTcpClosed (self, err, priv->callbacks.user_data); } gboolean pseudo_tcp_socket_is_closed (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; return (priv->state == TCP_CLOSED); } gboolean pseudo_tcp_socket_is_closed_remotely (PseudoTcpSocket *self) { PseudoTcpSocketPrivate *priv = self->priv; return pseudo_tcp_state_has_received_fin (priv->state); } libnice-0.1.14/agent/interfaces.c0000664000076400007640000004116212733070261013527 00000000000000/* * interfaces.c - Source for interface discovery code * * Copyright (C) 2006 Youness Alaoui * Copyright (C) 2007 Collabora, Nokia * Contact: Youness Alaoui * Copyright (C) 2008 Haakon Sporsheim * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * Philip Withnall, Collabora Ltd. * Haakon Sporsheim * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "interfaces.h" #include "agent-priv.h" #ifdef G_OS_UNIX #include #include #include #include #include #include #include #include #include #include #ifdef __sun #include #endif #ifdef HAVE_GETIFADDRS #include #endif #include #include #endif /* G_OS_UNIX */ #if (defined(G_OS_UNIX) && defined(HAVE_GETIFADDRS)) || defined(G_OS_WIN32) /* Works on both UNIX and Windows. Magic! */ static gchar * sockaddr_to_string (const struct sockaddr *addr) { char addr_as_string[INET6_ADDRSTRLEN+1]; size_t addr_len; switch (addr->sa_family) { case AF_INET: addr_len = sizeof (struct sockaddr_in); break; case AF_INET6: addr_len = sizeof (struct sockaddr_in6); break; default: return NULL; } if (getnameinfo (addr, addr_len, addr_as_string, sizeof (addr_as_string), NULL, 0, NI_NUMERICHOST) != 0) { return NULL; } return g_strdup (addr_as_string); } #endif #ifdef G_OS_UNIX #ifdef HAVE_GETIFADDRS GList * nice_interfaces_get_local_interfaces (void) { GList *interfaces = NULL; struct ifaddrs *ifa, *results; if (getifaddrs (&results) < 0) { return NULL; } /* Loop and get each interface the system has, one by one... */ for (ifa = results; ifa; ifa = ifa->ifa_next) { /* no ip address from interface that is down */ if ((ifa->ifa_flags & IFF_UP) == 0) continue; if (ifa->ifa_addr == NULL) continue; if (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6) { nice_debug ("Found interface : %s", ifa->ifa_name); interfaces = g_list_prepend (interfaces, g_strdup (ifa->ifa_name)); } } freeifaddrs (results); return interfaces; } #else /* ! HAVE_GETIFADDRS */ GList * nice_interfaces_get_local_interfaces (void) { GList *interfaces = NULL; gint sockfd; gint size = 0; struct ifreq *ifr; struct ifconf ifc; if ((sockfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { nice_debug ("error : Cannot open socket to retreive interface list"); return NULL; } ifc.ifc_len = 0; ifc.ifc_req = NULL; /* Loop and get each interface the system has, one by one... */ do { size += sizeof (struct ifreq); /* realloc buffer size until no overflow occurs */ if (NULL == (ifc.ifc_req = realloc (ifc.ifc_req, size))) { nice_debug ("Error : Out of memory while allocation interface" "configuration structure"); close (sockfd); return NULL; } ifc.ifc_len = size; if (ioctl (sockfd, SIOCGIFCONF, &ifc)) { perror ("ioctl SIOCFIFCONF"); close (sockfd); free (ifc.ifc_req); return NULL; } } while (size <= ifc.ifc_len); /* Loop throught the interface list and get the IP address of each IF */ for (ifr = ifc.ifc_req; (gchar *) ifr < (gchar *) ifc.ifc_req + ifc.ifc_len; ++ifr) { nice_debug ("Found interface : %s", ifr->ifr_name); interfaces = g_list_prepend (interfaces, g_strdup (ifr->ifr_name)); } free (ifc.ifc_req); close (sockfd); return interfaces; } #endif /* HAVE_GETIFADDRS */ static gboolean nice_interfaces_is_private_ip (const struct sockaddr *_sa) { union { const struct sockaddr *addr; const struct sockaddr_in *in; } sa; sa.addr = _sa; if (sa.addr->sa_family == AF_INET) { /* 10.x.x.x/8 */ if (sa.in->sin_addr.s_addr >> 24 == 0x0A) return TRUE; /* 172.16.0.0 - 172.31.255.255 = 172.16.0.0/10 */ if (sa.in->sin_addr.s_addr >> 20 == 0xAC1) return TRUE; /* 192.168.x.x/16 */ if (sa.in->sin_addr.s_addr >> 16 == 0xC0A8) return TRUE; /* 169.254.x.x/16 (for APIPA) */ if (sa.in->sin_addr.s_addr >> 16 == 0xA9FE) return TRUE; } return FALSE; } static GList * add_ip_to_list (GList *list, gchar *ip, gboolean append) { GList *i; for (i = list; i; i = i->next) { gchar *addr = (gchar *) i->data; if (g_strcmp0 (addr, ip) == 0) return list; } if (append) return g_list_append (list, ip); else return g_list_prepend (list, ip); } #ifdef HAVE_GETIFADDRS GList * nice_interfaces_get_local_ips (gboolean include_loopback) { GList *ips = NULL; struct ifaddrs *ifa, *results; GList *loopbacks = NULL; if (getifaddrs (&results) < 0) return NULL; /* Loop through the interface list and get the IP address of each IF */ for (ifa = results; ifa; ifa = ifa->ifa_next) { gchar *addr_string; /* no ip address from interface that is down */ if ((ifa->ifa_flags & IFF_UP) == 0) continue; if (ifa->ifa_addr == NULL) continue; /* Convert to a string. */ addr_string = sockaddr_to_string (ifa->ifa_addr); if (addr_string == NULL) { nice_debug ("Failed to convert address to string for interface ‘%s’.", ifa->ifa_name); continue; } nice_debug ("Interface: %s", ifa->ifa_name); nice_debug ("IP Address: %s", addr_string); if ((ifa->ifa_flags & IFF_LOOPBACK) == IFF_LOOPBACK) { if (include_loopback) { loopbacks = add_ip_to_list (loopbacks, addr_string, TRUE); } else { nice_debug ("Ignoring loopback interface"); g_free (addr_string); } } else { if (nice_interfaces_is_private_ip (ifa->ifa_addr)) ips = add_ip_to_list (ips, addr_string, TRUE); else ips = add_ip_to_list (ips, addr_string, FALSE); } } freeifaddrs (results); if (loopbacks) ips = g_list_concat (ips, loopbacks); return ips; } #else /* ! HAVE_GETIFADDRS */ GList * nice_interfaces_get_local_ips (gboolean include_loopback) { GList *ips = NULL; gint sockfd; gint size = 0; struct ifreq *ifr; struct ifconf ifc; struct sockaddr_in *sa; gchar *loopback = NULL; if ((sockfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { nice_debug ("Error : Cannot open socket to retreive interface list"); return NULL; } ifc.ifc_len = 0; ifc.ifc_req = NULL; /* Loop and get each interface the system has, one by one... */ do { size += sizeof (struct ifreq); /* realloc buffer size until no overflow occurs */ if (NULL == (ifc.ifc_req = realloc (ifc.ifc_req, size))) { nice_debug ("Error : Out of memory while allocation interface" " configuration structure"); close (sockfd); return NULL; } ifc.ifc_len = size; if (ioctl (sockfd, SIOCGIFCONF, &ifc)) { perror ("ioctl SIOCFIFCONF"); close (sockfd); free (ifc.ifc_req); return NULL; } } while (size <= ifc.ifc_len); /* Loop throught the interface list and get the IP address of each IF */ for (ifr = ifc.ifc_req; (gchar *) ifr < (gchar *) ifc.ifc_req + ifc.ifc_len; ++ifr) { if (ioctl (sockfd, SIOCGIFFLAGS, ifr)) { nice_debug ("Error : Unable to get IP information for interface %s." " Skipping...", ifr->ifr_name); continue; /* failed to get flags, skip it */ } sa = (struct sockaddr_in *) &ifr->ifr_addr; nice_debug ("Interface: %s", ifr->ifr_name); nice_debug ("IP Address: %s", inet_ntoa (sa->sin_addr)); if ((ifr->ifr_flags & IFF_LOOPBACK) == IFF_LOOPBACK){ if (include_loopback) loopback = g_strdup (inet_ntoa (sa->sin_addr)); else nice_debug ("Ignoring loopback interface"); } else { if (nice_interfaces_is_private_ip ((struct sockaddr *) sa)) { ips = add_ip_to_list (ips, g_strdup (inet_ntoa (sa->sin_addr)), TRUE); } else { ips = add_ip_to_list (ips, g_strdup (inet_ntoa (sa->sin_addr)), FALSE); } } } close (sockfd); free (ifc.ifc_req); if (loopback) ips = add_ip_to_list (ips, loopback, TRUE); return ips; } #endif /* HAVE_GETIFADDRS */ gchar * nice_interfaces_get_ip_for_interface (gchar *interface_name) { struct ifreq ifr; union { struct sockaddr *addr; struct sockaddr_in *in; } sa; gint sockfd; g_return_val_if_fail (interface_name != NULL, NULL); ifr.ifr_addr.sa_family = AF_INET; memset (ifr.ifr_name, 0, sizeof (ifr.ifr_name)); g_strlcpy (ifr.ifr_name, interface_name, sizeof (ifr.ifr_name)); if ((sockfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { nice_debug ("Error : Cannot open socket to retreive interface list"); return NULL; } if (ioctl (sockfd, SIOCGIFADDR, &ifr) < 0) { nice_debug ("Error : Unable to get IP information for interface %s", interface_name); close (sockfd); return NULL; } close (sockfd); sa.addr = &ifr.ifr_addr; nice_debug ("Address for %s: %s", interface_name, inet_ntoa (sa.in->sin_addr)); return g_strdup (inet_ntoa (sa.in->sin_addr)); } #else /* G_OS_UNIX */ #ifdef G_OS_WIN32 #include #include // Should be in Iphlpapi.h, but mingw doesn't seem to have these // Values copied directly from: // http://msdn.microsoft.com/en-us/library/aa366845(v=vs.85).aspx // (Title: MIB_IPADDRROW structure) #ifndef MIB_IPADDR_DISCONNECTED #define MIB_IPADDR_DISCONNECTED 0x0008 #endif #ifndef MIB_IPADDR_DELETED #define MIB_IPADDR_DELETED 0x0040 #endif #if 0 static gboolean started_wsa_engine = FALSE; /* * private function that initializes the WinSock engine and * returns a prebuilt socket */ SOCKET nice_interfaces_get_WSA_socket () { WORD wVersionRequested; WSADATA wsaData; int err; SOCKET sock; if (started_wsa_engine == FALSE) { wVersionRequested = MAKEWORD ( 2, 0 ); err = WSAStartup ( wVersionRequested, &wsaData ); if ( err != 0 ) { nice_debug ("Error : Could not start the winsocket engine"); return INVALID_SOCKET; } started_wsa_engine = TRUE; } if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) { nice_debug ("Error : Could not open socket to retreive interface list," " error no : %d", WSAGetLastError ()); return INVALID_SOCKET; } return sock; } #endif GList * nice_interfaces_get_local_interfaces (void) { ULONG size = 0; PMIB_IFTABLE if_table; GList * ret = NULL; GetIfTable(NULL, &size, TRUE); if (!size) return NULL; if_table = (PMIB_IFTABLE)g_malloc0(size); if (GetIfTable(if_table, &size, TRUE) == ERROR_SUCCESS) { DWORD i; for (i = 0; i < if_table->dwNumEntries; i++) { ret = g_list_prepend (ret, g_strdup ((gchar*)if_table->table[i].bDescr)); } } g_free(if_table); return ret; } GList * nice_interfaces_get_local_ips (gboolean include_loopback) { IP_ADAPTER_ADDRESSES *addresses = NULL, *a; ULONG status; guint iterations; ULONG addresses_size; DWORD pref = 0; GList *ret = NULL; /* As suggested on * http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365915%28v=vs.85%29.aspx */ #define MAX_TRIES 3 #define INITIAL_BUFFER_SIZE 15000 addresses_size = INITIAL_BUFFER_SIZE; iterations = 0; do { g_free (addresses); addresses = g_malloc0 (addresses_size); status = GetAdaptersAddresses (AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, NULL, addresses, &addresses_size); } while ((status == ERROR_BUFFER_OVERFLOW) && (iterations++ < MAX_TRIES)); nice_debug ("Queried addresses with status %lu.", status); #undef INITIAL_BUFFER_SIZE #undef MAX_TRIES /* Error? */ if (status != NO_ERROR) { nice_debug ("Error retrieving local addresses (error code %lu).", status); g_free (addresses); return NULL; } /* * Get the best interface for transport to 0.0.0.0. * This interface should be first in list! */ if (GetBestInterface (0, &pref) != NO_ERROR) pref = 0; /* Loop over the adapters. */ for (a = addresses; a != NULL; a = a->Next) { IP_ADAPTER_UNICAST_ADDRESS *unicast; nice_debug ("Interface ‘%S’:", a->FriendlyName); /* Various conditions for ignoring the interface. */ if (a->Flags & IP_ADAPTER_RECEIVE_ONLY || a->OperStatus == IfOperStatusDown || a->OperStatus == IfOperStatusNotPresent || a->OperStatus == IfOperStatusLowerLayerDown) { nice_debug ("Rejecting interface due to being down or read-only."); continue; } if (!include_loopback && a->IfType == IF_TYPE_SOFTWARE_LOOPBACK) { nice_debug ("Rejecting loopback interface ‘%S’.", a->FriendlyName); continue; } /* Grab the interface’s unicast addresses. */ for (unicast = a->FirstUnicastAddress; unicast != NULL; unicast = unicast->Next) { gchar *addr_string; addr_string = sockaddr_to_string (unicast->Address.lpSockaddr); if (addr_string == NULL) { nice_debug ("Failed to convert address to string for interface ‘%S’.", a->FriendlyName); continue; } nice_debug ("IP address: %s", addr_string); if (a->IfIndex == pref || a->Ipv6IfIndex == pref) ret = g_list_prepend (ret, addr_string); else ret = g_list_append (ret, addr_string); } } g_free (addresses); return ret; } /* * returns ip address as an utf8 string */ // Source for idx's type (Was IF_INDEX): // http://msdn.microsoft.com/en-us/library/aa366836(v=VS.85).aspx // (Title: MIB_IFROW structure) static gchar * win32_get_ip_for_interface (DWORD idx) { ULONG size = 0; PMIB_IPADDRTABLE ip_table; gchar * ret = NULL; GetIpAddrTable (NULL, &size, TRUE); if (!size) return NULL; ip_table = (PMIB_IPADDRTABLE)g_malloc0 (size); if (GetIpAddrTable (ip_table, &size, TRUE) == ERROR_SUCCESS) { DWORD i; for (i = 0; i < ip_table->dwNumEntries; i++) { PMIB_IPADDRROW ipaddr = &ip_table->table[i]; if (ipaddr->dwIndex == idx && !(ipaddr->wType & (MIB_IPADDR_DISCONNECTED | MIB_IPADDR_DELETED))) { ret = g_strdup_printf ("%lu.%lu.%lu.%lu", (ipaddr->dwAddr ) & 0xFF, (ipaddr->dwAddr >> 8) & 0xFF, (ipaddr->dwAddr >> 16) & 0xFF, (ipaddr->dwAddr >> 24) & 0xFF); break; } } } g_free (ip_table); return ret; } gchar * nice_interfaces_get_ip_for_interface (gchar *interface_name) { ULONG size = 0; PMIB_IFTABLE if_table; gchar * ret = NULL; GetIfTable (NULL, &size, TRUE); if (!size) return NULL; if_table = (PMIB_IFTABLE)g_malloc0 (size); if (GetIfTable (if_table, &size, TRUE) == ERROR_SUCCESS) { DWORD i; gchar * tmp_str; for (i = 0; i < if_table->dwNumEntries; i++) { tmp_str = g_utf16_to_utf8 ( if_table->table[i].wszName, MAX_INTERFACE_NAME_LEN, NULL, NULL, NULL); if (strlen (interface_name) == strlen (tmp_str) && g_ascii_strncasecmp (interface_name, tmp_str, strlen (interface_name)) == 0) { ret = win32_get_ip_for_interface (if_table->table[i].dwIndex); g_free (tmp_str); break; } g_free (tmp_str); } } g_free (if_table); return ret; } #else /* G_OS_WIN32 */ #error Can not use this method for retreiving ip list from OS other than unix or windows #endif /* G_OS_WIN32 */ #endif /* G_OS_UNIX */ libnice-0.1.14/gst/0000775000076400007640000000000013070512356011014 500000000000000libnice-0.1.14/gst/Makefile.in0000664000076400007640000010264013070512350012776 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = gst ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(gstplugindir)" \ "$(DESTDIR)$(gstplugin010dir)" LTLIBRARIES = $(gstplugin_LTLIBRARIES) $(gstplugin010_LTLIBRARIES) am__DEPENDENCIES_1 = @WITH_GSTREAMER_TRUE@libgstnice_la_DEPENDENCIES = $(COMMON_LIBADD) \ @WITH_GSTREAMER_TRUE@ $(am__DEPENDENCIES_1) am__libgstnice_la_SOURCES_DIST = gstnicesrc.h gstnicesrc.c \ gstnicesink.h gstnicesink.c gstnice.h gstnice.c @WITH_GSTREAMER_TRUE@am_libgstnice_la_OBJECTS = \ @WITH_GSTREAMER_TRUE@ libgstnice_la-gstnicesrc.lo \ @WITH_GSTREAMER_TRUE@ libgstnice_la-gstnicesink.lo \ @WITH_GSTREAMER_TRUE@ libgstnice_la-gstnice.lo libgstnice_la_OBJECTS = $(am_libgstnice_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgstnice_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgstnice_la_CFLAGS) \ $(CFLAGS) $(libgstnice_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_GSTREAMER_TRUE@am_libgstnice_la_rpath = -rpath $(gstplugindir) @WITH_GSTREAMER010_TRUE@libgstnice010_la_DEPENDENCIES = \ @WITH_GSTREAMER010_TRUE@ $(COMMON_LIBADD) $(am__DEPENDENCIES_1) am__libgstnice010_la_SOURCES_DIST = gstnicesrc.h gstnicesrc.c \ gstnicesink.h gstnicesink.c gstnice.h gstnice.c @WITH_GSTREAMER010_TRUE@am_libgstnice010_la_OBJECTS = \ @WITH_GSTREAMER010_TRUE@ libgstnice010_la-gstnicesrc.lo \ @WITH_GSTREAMER010_TRUE@ libgstnice010_la-gstnicesink.lo \ @WITH_GSTREAMER010_TRUE@ libgstnice010_la-gstnice.lo libgstnice010_la_OBJECTS = $(am_libgstnice010_la_OBJECTS) libgstnice010_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libgstnice010_la_CFLAGS) $(CFLAGS) \ $(libgstnice010_la_LDFLAGS) $(LDFLAGS) -o $@ @WITH_GSTREAMER010_TRUE@am_libgstnice010_la_rpath = -rpath \ @WITH_GSTREAMER010_TRUE@ $(gstplugin010dir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgstnice_la_SOURCES) $(libgstnice010_la_SOURCES) DIST_SOURCES = $(am__libgstnice_la_SOURCES_DIST) \ $(am__libgstnice010_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CFLAGS = $(LIBNICE_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/stun COMMON_LIBADD = \ $(top_builddir)/nice/libnice.la # libgstnice @WITH_GSTREAMER_TRUE@gstplugin_LTLIBRARIES = libgstnice.la @WITH_GSTREAMER_TRUE@libgstnice_la_CFLAGS = $(AM_CFLAGS) $(GST_CFLAGS) -DGST_USE_UNSTABLE_API @WITH_GSTREAMER_TRUE@libgstnice_la_SOURCES = \ @WITH_GSTREAMER_TRUE@ gstnicesrc.h \ @WITH_GSTREAMER_TRUE@ gstnicesrc.c \ @WITH_GSTREAMER_TRUE@ gstnicesink.h \ @WITH_GSTREAMER_TRUE@ gstnicesink.c \ @WITH_GSTREAMER_TRUE@ gstnice.h \ @WITH_GSTREAMER_TRUE@ gstnice.c @WITH_GSTREAMER_TRUE@libgstnice_la_LIBADD = $(COMMON_LIBADD) $(GST_LIBS) @WITH_GSTREAMER_TRUE@libgstnice_la_LDFLAGS = -module -avoid-version -no-undefined @WITH_GSTREAMER010_TRUE@gstplugin010_LTLIBRARIES = libgstnice010.la @WITH_GSTREAMER010_TRUE@libgstnice010_la_CFLAGS = $(AM_CFLAGS) $(GST010_CFLAGS) @WITH_GSTREAMER010_TRUE@libgstnice010_la_SOURCES = \ @WITH_GSTREAMER010_TRUE@ gstnicesrc.h \ @WITH_GSTREAMER010_TRUE@ gstnicesrc.c \ @WITH_GSTREAMER010_TRUE@ gstnicesink.h \ @WITH_GSTREAMER010_TRUE@ gstnicesink.c \ @WITH_GSTREAMER010_TRUE@ gstnice.h \ @WITH_GSTREAMER010_TRUE@ gstnice.c @WITH_GSTREAMER010_TRUE@libgstnice010_la_LIBADD = $(COMMON_LIBADD) $(GST010_LIBS) @WITH_GSTREAMER010_TRUE@libgstnice010_la_LDFLAGS = -module -avoid-version -no-undefined all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gst/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu gst/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-gstpluginLTLIBRARIES: $(gstplugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(gstplugin_LTLIBRARIES)'; test -n "$(gstplugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(gstplugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(gstplugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(gstplugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(gstplugindir)"; \ } uninstall-gstpluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(gstplugin_LTLIBRARIES)'; test -n "$(gstplugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(gstplugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(gstplugindir)/$$f"; \ done clean-gstpluginLTLIBRARIES: -test -z "$(gstplugin_LTLIBRARIES)" || rm -f $(gstplugin_LTLIBRARIES) @list='$(gstplugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-gstplugin010LTLIBRARIES: $(gstplugin010_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(gstplugin010_LTLIBRARIES)'; test -n "$(gstplugin010dir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(gstplugin010dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(gstplugin010dir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(gstplugin010dir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(gstplugin010dir)"; \ } uninstall-gstplugin010LTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(gstplugin010_LTLIBRARIES)'; test -n "$(gstplugin010dir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(gstplugin010dir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(gstplugin010dir)/$$f"; \ done clean-gstplugin010LTLIBRARIES: -test -z "$(gstplugin010_LTLIBRARIES)" || rm -f $(gstplugin010_LTLIBRARIES) @list='$(gstplugin010_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgstnice.la: $(libgstnice_la_OBJECTS) $(libgstnice_la_DEPENDENCIES) $(EXTRA_libgstnice_la_DEPENDENCIES) $(AM_V_CCLD)$(libgstnice_la_LINK) $(am_libgstnice_la_rpath) $(libgstnice_la_OBJECTS) $(libgstnice_la_LIBADD) $(LIBS) libgstnice010.la: $(libgstnice010_la_OBJECTS) $(libgstnice010_la_DEPENDENCIES) $(EXTRA_libgstnice010_la_DEPENDENCIES) $(AM_V_CCLD)$(libgstnice010_la_LINK) $(am_libgstnice010_la_rpath) $(libgstnice010_la_OBJECTS) $(libgstnice010_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstnice010_la-gstnice.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstnice010_la-gstnicesink.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstnice010_la-gstnicesrc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstnice_la-gstnice.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstnice_la-gstnicesink.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstnice_la-gstnicesrc.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgstnice_la-gstnicesrc.lo: gstnicesrc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice_la_CFLAGS) $(CFLAGS) -MT libgstnice_la-gstnicesrc.lo -MD -MP -MF $(DEPDIR)/libgstnice_la-gstnicesrc.Tpo -c -o libgstnice_la-gstnicesrc.lo `test -f 'gstnicesrc.c' || echo '$(srcdir)/'`gstnicesrc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstnice_la-gstnicesrc.Tpo $(DEPDIR)/libgstnice_la-gstnicesrc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstnicesrc.c' object='libgstnice_la-gstnicesrc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice_la_CFLAGS) $(CFLAGS) -c -o libgstnice_la-gstnicesrc.lo `test -f 'gstnicesrc.c' || echo '$(srcdir)/'`gstnicesrc.c libgstnice_la-gstnicesink.lo: gstnicesink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice_la_CFLAGS) $(CFLAGS) -MT libgstnice_la-gstnicesink.lo -MD -MP -MF $(DEPDIR)/libgstnice_la-gstnicesink.Tpo -c -o libgstnice_la-gstnicesink.lo `test -f 'gstnicesink.c' || echo '$(srcdir)/'`gstnicesink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstnice_la-gstnicesink.Tpo $(DEPDIR)/libgstnice_la-gstnicesink.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstnicesink.c' object='libgstnice_la-gstnicesink.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice_la_CFLAGS) $(CFLAGS) -c -o libgstnice_la-gstnicesink.lo `test -f 'gstnicesink.c' || echo '$(srcdir)/'`gstnicesink.c libgstnice_la-gstnice.lo: gstnice.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice_la_CFLAGS) $(CFLAGS) -MT libgstnice_la-gstnice.lo -MD -MP -MF $(DEPDIR)/libgstnice_la-gstnice.Tpo -c -o libgstnice_la-gstnice.lo `test -f 'gstnice.c' || echo '$(srcdir)/'`gstnice.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstnice_la-gstnice.Tpo $(DEPDIR)/libgstnice_la-gstnice.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstnice.c' object='libgstnice_la-gstnice.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice_la_CFLAGS) $(CFLAGS) -c -o libgstnice_la-gstnice.lo `test -f 'gstnice.c' || echo '$(srcdir)/'`gstnice.c libgstnice010_la-gstnicesrc.lo: gstnicesrc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice010_la_CFLAGS) $(CFLAGS) -MT libgstnice010_la-gstnicesrc.lo -MD -MP -MF $(DEPDIR)/libgstnice010_la-gstnicesrc.Tpo -c -o libgstnice010_la-gstnicesrc.lo `test -f 'gstnicesrc.c' || echo '$(srcdir)/'`gstnicesrc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstnice010_la-gstnicesrc.Tpo $(DEPDIR)/libgstnice010_la-gstnicesrc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstnicesrc.c' object='libgstnice010_la-gstnicesrc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice010_la_CFLAGS) $(CFLAGS) -c -o libgstnice010_la-gstnicesrc.lo `test -f 'gstnicesrc.c' || echo '$(srcdir)/'`gstnicesrc.c libgstnice010_la-gstnicesink.lo: gstnicesink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice010_la_CFLAGS) $(CFLAGS) -MT libgstnice010_la-gstnicesink.lo -MD -MP -MF $(DEPDIR)/libgstnice010_la-gstnicesink.Tpo -c -o libgstnice010_la-gstnicesink.lo `test -f 'gstnicesink.c' || echo '$(srcdir)/'`gstnicesink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstnice010_la-gstnicesink.Tpo $(DEPDIR)/libgstnice010_la-gstnicesink.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstnicesink.c' object='libgstnice010_la-gstnicesink.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice010_la_CFLAGS) $(CFLAGS) -c -o libgstnice010_la-gstnicesink.lo `test -f 'gstnicesink.c' || echo '$(srcdir)/'`gstnicesink.c libgstnice010_la-gstnice.lo: gstnice.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice010_la_CFLAGS) $(CFLAGS) -MT libgstnice010_la-gstnice.lo -MD -MP -MF $(DEPDIR)/libgstnice010_la-gstnice.Tpo -c -o libgstnice010_la-gstnice.lo `test -f 'gstnice.c' || echo '$(srcdir)/'`gstnice.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstnice010_la-gstnice.Tpo $(DEPDIR)/libgstnice010_la-gstnice.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstnice.c' object='libgstnice010_la-gstnice.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstnice010_la_CFLAGS) $(CFLAGS) -c -o libgstnice010_la-gstnice.lo `test -f 'gstnice.c' || echo '$(srcdir)/'`gstnice.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(gstplugindir)" "$(DESTDIR)$(gstplugin010dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-gstplugin010LTLIBRARIES \ clean-gstpluginLTLIBRARIES clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-gstplugin010LTLIBRARIES \ install-gstpluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-gstplugin010LTLIBRARIES \ uninstall-gstpluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-gstplugin010LTLIBRARIES clean-gstpluginLTLIBRARIES \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am \ install-gstplugin010LTLIBRARIES install-gstpluginLTLIBRARIES \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-gstplugin010LTLIBRARIES \ uninstall-gstpluginLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/gst/Makefile.am0000664000076400007640000000220612520743534012773 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. AM_CFLAGS = $(LIBNICE_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/stun COMMON_LIBADD = \ $(top_builddir)/nice/libnice.la # libgstnice if WITH_GSTREAMER gstplugin_LTLIBRARIES = libgstnice.la libgstnice_la_CFLAGS = $(AM_CFLAGS) $(GST_CFLAGS) -DGST_USE_UNSTABLE_API libgstnice_la_SOURCES = \ gstnicesrc.h \ gstnicesrc.c \ gstnicesink.h \ gstnicesink.c \ gstnice.h \ gstnice.c libgstnice_la_LIBADD = $(COMMON_LIBADD) $(GST_LIBS) libgstnice_la_LDFLAGS = -module -avoid-version -no-undefined endif if WITH_GSTREAMER010 gstplugin010_LTLIBRARIES = libgstnice010.la libgstnice010_la_CFLAGS = $(AM_CFLAGS) $(GST010_CFLAGS) libgstnice010_la_SOURCES = \ gstnicesrc.h \ gstnicesrc.c \ gstnicesink.h \ gstnicesink.c \ gstnice.h \ gstnice.c libgstnice010_la_LIBADD = $(COMMON_LIBADD) $(GST010_LIBS) libgstnice010_la_LDFLAGS = -module -avoid-version -no-undefined endif libnice-0.1.14/gst/gstnicesink.h0000664000076400007640000000541112520743534013432 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _GST_NICE_SINK_H #define _GST_NICE_SINK_H #include #include #include G_BEGIN_DECLS #define GST_TYPE_NICE_SINK \ (gst_nice_sink_get_type()) #define GST_NICE_SINK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NICE_SINK,GstNiceSink)) #define GST_NICE_SINK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NICE_SINK,GstNiceSinkClass)) #define GST_IS_NICE_SINK(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NICE_SINK)) #define GST_IS_NICE_SINK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NICE_SINK)) typedef struct _GstNiceSink GstNiceSink; struct _GstNiceSink { GstBaseSink parent; GstPad *sinkpad; NiceAgent *agent; guint stream_id; guint component_id; gboolean reliable; GCond writable_cond; gulong writable_id; gboolean flushing; #if GST_CHECK_VERSION (1,0,0) /* pre-allocated scrap space for render function */ GOutputVector *vecs; guint n_vecs; GstMapInfo *maps; guint n_maps; NiceOutputMessage *messages; guint n_messages; #endif }; typedef struct _GstNiceSinkClass GstNiceSinkClass; struct _GstNiceSinkClass { GstBaseSinkClass parent_class; }; GType gst_nice_sink_get_type (void); G_END_DECLS #endif libnice-0.1.14/gst/gstnice.h0000644000076400007640000000313411241364464012543 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #include "gstnicesrc.h" #include "gstnicesink.h" libnice-0.1.14/gst/gstnicesink.c0000664000076400007640000003570712520743534013440 00000000000000 /* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "gstnicesink.h" GST_DEBUG_CATEGORY_STATIC (nicesink_debug); #define GST_CAT_DEFAULT nicesink_debug static GstFlowReturn gst_nice_sink_render ( GstBaseSink *basesink, GstBuffer *buffer); #if GST_CHECK_VERSION (1,0,0) static GstFlowReturn gst_nice_sink_render_list ( GstBaseSink *basesink, GstBufferList *buffer_list); #endif static gboolean gst_nice_sink_unlock (GstBaseSink *basesink); static gboolean gst_nice_sink_unlock_stop (GstBaseSink *basesink); static void _reliable_transport_writable ( NiceAgent *agent, guint stream_id, guint component_id, GstNiceSink *sink); static void gst_nice_sink_set_property ( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_nice_sink_get_property ( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gst_nice_sink_dispose (GObject *object); #if GST_CHECK_VERSION (1,0,0) static void gst_nice_sink_finalize (GObject *object); #endif static GstStateChangeReturn gst_nice_sink_change_state ( GstElement * element, GstStateChange transition); static GstStaticPadTemplate gst_nice_sink_sink_template = GST_STATIC_PAD_TEMPLATE ( "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); G_DEFINE_TYPE (GstNiceSink, gst_nice_sink, GST_TYPE_BASE_SINK); enum { PROP_AGENT = 1, PROP_STREAM, PROP_COMPONENT }; static void gst_nice_sink_class_init (GstNiceSinkClass *klass) { GstBaseSinkClass *gstbasesink_class; GstElementClass *gstelement_class; GObjectClass *gobject_class; GST_DEBUG_CATEGORY_INIT (nicesink_debug, "nicesink", 0, "libnice sink"); gstbasesink_class = (GstBaseSinkClass *) klass; gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_nice_sink_render); #if GST_CHECK_VERSION (1,0,0) gstbasesink_class->render_list = GST_DEBUG_FUNCPTR (gst_nice_sink_render_list); #endif gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_nice_sink_unlock); gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_nice_sink_unlock_stop); gobject_class = (GObjectClass *) klass; gobject_class->set_property = gst_nice_sink_set_property; gobject_class->get_property = gst_nice_sink_get_property; gobject_class->dispose = gst_nice_sink_dispose; #if GST_CHECK_VERSION (1,0,0) gobject_class->finalize = gst_nice_sink_finalize; #endif gstelement_class = (GstElementClass *) klass; gstelement_class->change_state = gst_nice_sink_change_state; gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&gst_nice_sink_sink_template)); #if GST_CHECK_VERSION (1,0,0) gst_element_class_set_metadata (gstelement_class, #else gst_element_class_set_details_simple (gstelement_class, #endif "ICE sink", "Sink", "Interactive UDP connectivity establishment", "Dafydd Harries "); g_object_class_install_property (gobject_class, PROP_AGENT, g_param_spec_object ( "agent", "Agent", "The NiceAgent this source is bound to", NICE_TYPE_AGENT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_STREAM, g_param_spec_uint ( "stream", "Stream ID", "The ID of the stream to read from", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_COMPONENT, g_param_spec_uint ( "component", "Component ID", "The ID of the component to read from", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); } static void gst_nice_sink_init (GstNiceSink *sink) { #if GST_CHECK_VERSION (1,0,0) guint max_mem; #endif g_cond_init (&sink->writable_cond); #if GST_CHECK_VERSION (1,0,0) /* pre-allocate OutputVector, MapInfo and OutputMessage arrays * for use in the render and render_list functions */ max_mem = gst_buffer_get_max_memory (); sink->n_vecs = max_mem; sink->vecs = g_new (GOutputVector, sink->n_vecs); sink->n_maps = max_mem; sink->maps = g_new (GstMapInfo, sink->n_maps); sink->n_messages = 1; sink->messages = g_new (NiceOutputMessage, sink->n_messages); #endif } static void _reliable_transport_writable (NiceAgent *agent, guint stream_id, guint component_id, GstNiceSink *sink) { GST_OBJECT_LOCK (sink); if (stream_id == sink->stream_id && component_id == sink->component_id) { g_cond_broadcast (&sink->writable_cond); } GST_OBJECT_UNLOCK (sink); } #if GST_CHECK_VERSION (1,0,0) static gsize fill_vectors (GOutputVector * vecs, GstMapInfo * maps, guint n, GstBuffer * buf) { GstMemory *mem; gsize size = 0; guint i; g_assert (gst_buffer_n_memory (buf) == n); for (i = 0; i < n; ++i) { mem = gst_buffer_peek_memory (buf, i); if (gst_memory_map (mem, &maps[i], GST_MAP_READ)) { vecs[i].buffer = maps[i].data; vecs[i].size = maps[i].size; } else { GST_WARNING ("Failed to map memory %p for reading", mem); vecs[i].buffer = ""; vecs[i].size = 0; } size += vecs[i].size; } return size; } /* Buffer list code written by * Tim-Philipp Müller * taken from * gst-plugins-good/gst/udp/gstmultiudpsink.c */ static GstFlowReturn gst_nice_sink_render_buffers (GstNiceSink * sink, GstBuffer ** buffers, guint num_buffers, guint8 * mem_nums, guint total_mem_num) { NiceOutputMessage *msgs; GOutputVector *vecs; GstMapInfo *map_infos; guint i, mem; guint written = 0; gint ret; GstFlowReturn flow_ret = GST_FLOW_OK; GST_LOG_OBJECT (sink, "%u buffers, %u memories -> to be sent", num_buffers, total_mem_num); if (sink->n_vecs < total_mem_num) { sink->n_vecs = GST_ROUND_UP_16 (total_mem_num); g_free (sink->vecs); sink->vecs = g_new (GOutputVector, sink->n_vecs); } vecs = sink->vecs; if (sink->n_maps < total_mem_num) { sink->n_maps = GST_ROUND_UP_16 (total_mem_num); g_free (sink->maps); sink->maps = g_new (GstMapInfo, sink->n_maps); } map_infos = sink->maps; if (sink->n_messages < num_buffers) { sink->n_messages = GST_ROUND_UP_16 (num_buffers); g_free (sink->messages); sink->messages = g_new (NiceOutputMessage, sink->n_messages); } msgs = sink->messages; for (i = 0, mem = 0; i < num_buffers; ++i) { fill_vectors (&vecs[mem], &map_infos[mem], mem_nums[i], buffers[i]); msgs[i].buffers = &vecs[mem]; msgs[i].n_buffers = mem_nums[i]; mem += mem_nums[i]; } GST_OBJECT_LOCK (sink); do { ret = nice_agent_send_messages_nonblocking(sink->agent, sink->stream_id, sink->component_id, msgs + written, num_buffers - written, NULL, NULL); if (ret > 0) written += ret; if (sink->reliable && written < num_buffers) g_cond_wait (&sink->writable_cond, GST_OBJECT_GET_LOCK (sink)); if (sink->flushing) { flow_ret = GST_FLOW_FLUSHING; break; } } while (sink->reliable && written < num_buffers); GST_OBJECT_UNLOCK (sink); for (i = 0; i < mem; ++i) gst_memory_unmap (map_infos[i].memory, &map_infos[i]); return flow_ret; } #endif static GstFlowReturn gst_nice_sink_render (GstBaseSink *basesink, GstBuffer *buffer) { GstNiceSink *nicesink = GST_NICE_SINK (basesink); GstFlowReturn flow_ret = GST_FLOW_OK; #if GST_CHECK_VERSION (1,0,0) guint8 n_mem; n_mem = gst_buffer_n_memory (buffer); if (n_mem > 0) { flow_ret = gst_nice_sink_render_buffers (nicesink, &buffer, 1, &n_mem, n_mem); } #else guint written = 0; gint ret; gchar *data = NULL; guint size = 0; data = (gchar *) GST_BUFFER_DATA (buffer); size = GST_BUFFER_SIZE (buffer); GST_OBJECT_LOCK (nicesink); do { ret = nice_agent_send (nicesink->agent, nicesink->stream_id, nicesink->component_id, size - written, data + written); if (ret > 0) written += ret; if (nicesink->reliable && written < size) g_cond_wait (&nicesink->writable_cond, GST_OBJECT_GET_LOCK (nicesink)); if (nicesink->flushing) { flow_ret = GST_FLOW_WRONG_STATE; break; } } while (nicesink->reliable && written < size); GST_OBJECT_UNLOCK (nicesink); #endif return flow_ret; } #if GST_CHECK_VERSION (1,0,0) static GstFlowReturn gst_nice_sink_render_list (GstBaseSink *basesink, GstBufferList *buffer_list) { GstNiceSink *nicesink = GST_NICE_SINK (basesink); GstBuffer **buffers; GstFlowReturn flow_ret = GST_FLOW_OK; guint8 *mem_nums; guint total_mems; guint i, num_buffers; num_buffers = gst_buffer_list_length (buffer_list); if (num_buffers == 0) goto no_data; buffers = g_newa (GstBuffer *, num_buffers); mem_nums = g_newa (guint8, num_buffers); for (i = 0, total_mems = 0; i < num_buffers; ++i) { buffers[i] = gst_buffer_list_get (buffer_list, i); mem_nums[i] = gst_buffer_n_memory (buffers[i]); total_mems += mem_nums[i]; } flow_ret = gst_nice_sink_render_buffers (nicesink, buffers, num_buffers, mem_nums, total_mems); return flow_ret; no_data: { GST_LOG_OBJECT (nicesink, "empty buffer"); return GST_FLOW_OK; } return flow_ret; } #endif static gboolean gst_nice_sink_unlock (GstBaseSink *basesink) { GstNiceSink *nicesink = GST_NICE_SINK (basesink); GST_OBJECT_LOCK (nicesink); nicesink->flushing = TRUE; g_cond_broadcast (&nicesink->writable_cond); GST_OBJECT_UNLOCK (nicesink); return TRUE; } static gboolean gst_nice_sink_unlock_stop (GstBaseSink *basesink) { GstNiceSink *nicesink = GST_NICE_SINK (basesink); GST_OBJECT_LOCK (nicesink); nicesink->flushing = FALSE; GST_OBJECT_UNLOCK (nicesink); return TRUE; } static void gst_nice_sink_dispose (GObject *object) { GstNiceSink *sink = GST_NICE_SINK (object); if (sink->agent && sink->writable_id) g_signal_handler_disconnect (sink->agent, sink->writable_id); sink->writable_id = 0; g_clear_object (&sink->agent); g_cond_clear (&sink->writable_cond); G_OBJECT_CLASS (gst_nice_sink_parent_class)->dispose (object); } #if GST_CHECK_VERSION (1,0,0) static void gst_nice_sink_finalize (GObject *object) { GstNiceSink *sink = GST_NICE_SINK (object); g_free (sink->vecs); sink->vecs = NULL; sink->n_vecs = 0; g_free (sink->maps); sink->maps = NULL; sink->n_maps = 0; g_free (sink->messages); sink->messages = NULL; sink->n_messages = 0; G_OBJECT_CLASS (gst_nice_sink_parent_class)->finalize (object); } #endif static void gst_nice_sink_set_property ( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GstNiceSink *sink = GST_NICE_SINK (object); switch (prop_id) { case PROP_AGENT: if (sink->agent) { GST_ERROR_OBJECT (object, "Changing the agent on a nice sink not allowed"); } else { sink->agent = g_value_dup_object (value); g_object_get (sink->agent, "reliable", &sink->reliable, NULL); if (sink->reliable) sink->writable_id = g_signal_connect (sink->agent, "reliable-transport-writable", (GCallback) _reliable_transport_writable, sink); } break; case PROP_STREAM: GST_OBJECT_LOCK (sink); sink->stream_id = g_value_get_uint (value); GST_OBJECT_UNLOCK (sink); break; case PROP_COMPONENT: { guint new_component_id = g_value_get_uint (value); GST_OBJECT_LOCK (sink); if (sink->component_id != new_component_id) { sink->component_id = new_component_id; g_cond_broadcast (&sink->writable_cond); } GST_OBJECT_UNLOCK (sink); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gst_nice_sink_get_property ( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GstNiceSink *sink = GST_NICE_SINK (object); switch (prop_id) { case PROP_AGENT: g_value_set_object (value, sink->agent); break; case PROP_STREAM: GST_OBJECT_LOCK (sink); g_value_set_uint (value, sink->stream_id); GST_OBJECT_UNLOCK (sink); break; case PROP_COMPONENT: GST_OBJECT_LOCK (sink); g_value_set_uint (value, sink->component_id); GST_OBJECT_UNLOCK (sink); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static GstStateChangeReturn gst_nice_sink_change_state (GstElement * element, GstStateChange transition) { GstNiceSink *sink; GstStateChangeReturn ret; sink = GST_NICE_SINK (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (sink->agent == NULL) { GST_ERROR_OBJECT (element, "Trying to start Nice sink without an agent set"); return GST_STATE_CHANGE_FAILURE; } else if (sink->stream_id == 0) { GST_ERROR_OBJECT (element, "Trying to start Nice sink without a stream set"); return GST_STATE_CHANGE_FAILURE; } else if (sink->component_id == 0) { GST_ERROR_OBJECT (element, "Trying to start Nice sink without a component set"); return GST_STATE_CHANGE_FAILURE; } break; case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_READY_TO_NULL: default: break; } ret = GST_ELEMENT_CLASS (gst_nice_sink_parent_class)->change_state (element, transition); return ret; } libnice-0.1.14/gst/gstnicesrc.h0000664000076400007640000000507513067562400013261 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _GSTNICESRC_H #define _GSTNICESRC_H #include #include #include G_BEGIN_DECLS #define GST_TYPE_NICE_SRC \ (gst_nice_src_get_type()) #define GST_NICE_SRC(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NICE_SRC,GstNiceSrc)) #define GST_NICE_SRC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NICE_SRC,GstNiceSrcClass)) #define GST_IS_NICE_SRC(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NICE_SRC)) #define GST_IS_NICE_SRC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NICE_SRC)) typedef struct _GstNiceSrc GstNiceSrc; struct _GstNiceSrc { GstPushSrc parent; GstPad *srcpad; NiceAgent *agent; guint stream_id; guint component_id; GMainContext *mainctx; GMainLoop *mainloop; GQueue *outbufs; gboolean unlocked; GSource *idle_source; }; typedef struct _GstNiceSrcClass GstNiceSrcClass; struct _GstNiceSrcClass { GstPushSrcClass parent_class; }; GType gst_nice_src_get_type (void); G_END_DECLS #endif // _GSTNICESRC_H libnice-0.1.14/gst/gstnice.c0000664000076400007640000000436412262633251012543 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "gstnicesrc.h" #include "gstnicesink.h" static gboolean plugin_init (GstPlugin *plugin) { if (!gst_element_register (plugin, "nicesrc", GST_RANK_NONE, GST_TYPE_NICE_SRC)) return FALSE; if (!gst_element_register (plugin, "nicesink", GST_RANK_NONE, GST_TYPE_NICE_SINK)) return FALSE; return TRUE; } #if GST_CHECK_VERSION (1,0,0) #define PLUGIN_NAME nice #else #define PLUGIN_NAME "nice" #endif GST_PLUGIN_DEFINE ( GST_VERSION_MAJOR, GST_VERSION_MINOR, PLUGIN_NAME, "Interactive UDP connectivity establishment", plugin_init, VERSION, "LGPL", PACKAGE_NAME, "http://telepathy.freedesktop.org/wiki/"); libnice-0.1.14/gst/gstnicesrc.c0000664000076400007640000002743513067562400013260 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006, 2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006, 2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "gstnicesrc.h" GST_DEBUG_CATEGORY_STATIC (nicesrc_debug); #define GST_CAT_DEFAULT nicesrc_debug #define BUFFER_SIZE (65536) static GstFlowReturn gst_nice_src_create ( GstPushSrc *basesrc, GstBuffer **buffer); static gboolean gst_nice_src_unlock ( GstBaseSrc *basesrc); static gboolean gst_nice_src_unlock_stop ( GstBaseSrc *basesrc); static void gst_nice_src_set_property ( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_nice_src_get_property ( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gst_nice_src_dispose (GObject *object); static GstStateChangeReturn gst_nice_src_change_state ( GstElement * element, GstStateChange transition); static GstStaticPadTemplate gst_nice_src_src_template = GST_STATIC_PAD_TEMPLATE ( "src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); G_DEFINE_TYPE (GstNiceSrc, gst_nice_src, GST_TYPE_PUSH_SRC); enum { PROP_AGENT = 1, PROP_STREAM, PROP_COMPONENT }; static void gst_nice_src_class_init (GstNiceSrcClass *klass) { GstPushSrcClass *gstpushsrc_class; GstBaseSrcClass *gstbasesrc_class; GstElementClass *gstelement_class; GObjectClass *gobject_class; GST_DEBUG_CATEGORY_INIT (nicesrc_debug, "nicesrc", 0, "libnice source"); gstpushsrc_class = (GstPushSrcClass *) klass; gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_nice_src_create); gstbasesrc_class = (GstBaseSrcClass *) klass; gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_nice_src_unlock); gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_nice_src_unlock_stop); gobject_class = (GObjectClass *) klass; gobject_class->set_property = gst_nice_src_set_property; gobject_class->get_property = gst_nice_src_get_property; gobject_class->dispose = gst_nice_src_dispose; gstelement_class = (GstElementClass *) klass; gstelement_class->change_state = gst_nice_src_change_state; gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&gst_nice_src_src_template)); #if GST_CHECK_VERSION (1,0,0) gst_element_class_set_metadata (gstelement_class, #else gst_element_class_set_details_simple (gstelement_class, #endif "ICE source", "Source", "Interactive UDP connectivity establishment", "Dafydd Harries "); g_object_class_install_property (gobject_class, PROP_AGENT, g_param_spec_object ( "agent", "Agent", "The NiceAgent this source is bound to", NICE_TYPE_AGENT, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_STREAM, g_param_spec_uint ( "stream", "Stream ID", "The ID of the stream to read from", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_COMPONENT, g_param_spec_uint ( "component", "Component ID", "The ID of the component to read from", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); } static void gst_nice_src_init (GstNiceSrc *src) { gst_base_src_set_live (GST_BASE_SRC (src), TRUE); gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME); gst_base_src_set_do_timestamp (GST_BASE_SRC (src), TRUE); src->agent = NULL; src->stream_id = 0; src->component_id = 0; src->mainctx = g_main_context_new (); src->mainloop = g_main_loop_new (src->mainctx, FALSE); src->unlocked = FALSE; src->idle_source = NULL; src->outbufs = g_queue_new (); } static void gst_nice_src_read_callback (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data) { GstBaseSrc *basesrc = GST_BASE_SRC (data); GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc); GstBuffer *buffer = NULL; GST_LOG_OBJECT (agent, "Got buffer, getting out of the main loop"); #if GST_CHECK_VERSION (1,0,0) buffer = gst_buffer_new_allocate (NULL, len, NULL); gst_buffer_fill (buffer, 0, buf, len); #else buffer = gst_buffer_new_and_alloc (len); memcpy (GST_BUFFER_DATA (buffer), buf, len); #endif GST_OBJECT_LOCK (nicesrc); g_queue_push_tail (nicesrc->outbufs, buffer); g_main_loop_quit (nicesrc->mainloop); GST_OBJECT_UNLOCK (nicesrc); } static gboolean gst_nice_src_unlock_idler (gpointer data) { GstNiceSrc *nicesrc = GST_NICE_SRC (data); GST_OBJECT_LOCK (nicesrc); if (nicesrc->unlocked) g_main_loop_quit (nicesrc->mainloop); if (nicesrc->idle_source) { g_source_destroy (nicesrc->idle_source); g_source_unref (nicesrc->idle_source); nicesrc->idle_source = NULL; } GST_OBJECT_UNLOCK (nicesrc); return FALSE; } static gboolean gst_nice_src_unlock (GstBaseSrc *src) { GstNiceSrc *nicesrc = GST_NICE_SRC (src); GST_OBJECT_LOCK (src); nicesrc->unlocked = TRUE; g_main_loop_quit (nicesrc->mainloop); if (!nicesrc->idle_source) { nicesrc->idle_source = g_idle_source_new (); g_source_set_priority (nicesrc->idle_source, G_PRIORITY_HIGH); g_source_set_callback (nicesrc->idle_source, gst_nice_src_unlock_idler, src, NULL); g_source_attach (nicesrc->idle_source, g_main_loop_get_context (nicesrc->mainloop)); } GST_OBJECT_UNLOCK (src); return TRUE; } static gboolean gst_nice_src_unlock_stop (GstBaseSrc *src) { GstNiceSrc *nicesrc = GST_NICE_SRC (src); GST_OBJECT_LOCK (src); nicesrc->unlocked = FALSE; if (nicesrc->idle_source) { g_source_destroy (nicesrc->idle_source); g_source_unref(nicesrc->idle_source); } nicesrc->idle_source = NULL; GST_OBJECT_UNLOCK (src); return TRUE; } static GstFlowReturn gst_nice_src_create ( GstPushSrc *basesrc, GstBuffer **buffer) { GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc); GST_LOG_OBJECT (nicesrc, "create called"); GST_OBJECT_LOCK (basesrc); if (nicesrc->unlocked) { GST_OBJECT_UNLOCK (basesrc); #if GST_CHECK_VERSION (1,0,0) return GST_FLOW_FLUSHING; #else return GST_FLOW_WRONG_STATE; #endif } if (g_queue_is_empty (nicesrc->outbufs)) { GST_OBJECT_UNLOCK (basesrc); g_main_loop_run (nicesrc->mainloop); GST_OBJECT_LOCK (basesrc); } *buffer = g_queue_pop_head (nicesrc->outbufs); GST_OBJECT_UNLOCK (basesrc); if (*buffer != NULL) { GST_LOG_OBJECT (nicesrc, "Got buffer, pushing"); return GST_FLOW_OK; } else { GST_LOG_OBJECT (nicesrc, "Got interrupting, returning wrong-state"); #if GST_CHECK_VERSION (1,0,0) return GST_FLOW_FLUSHING; #else return GST_FLOW_WRONG_STATE; #endif } } static void gst_nice_src_dispose (GObject *object) { GstNiceSrc *src = GST_NICE_SRC (object); if (src->agent) g_object_unref (src->agent); src->agent = NULL; if (src->mainloop) g_main_loop_unref (src->mainloop); src->mainloop = NULL; if (src->mainctx) g_main_context_unref (src->mainctx); src->mainctx = NULL; if (src->outbufs) { g_queue_foreach (src->outbufs, (GFunc) gst_buffer_unref, NULL); g_queue_free (src->outbufs); } src->outbufs = NULL; G_OBJECT_CLASS (gst_nice_src_parent_class)->dispose (object); } static void gst_nice_src_set_property ( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GstNiceSrc *src = GST_NICE_SRC (object); switch (prop_id) { case PROP_AGENT: if (src->agent) GST_ERROR_OBJECT (object, "Changing the agent on a nice src not allowed"); else src->agent = g_value_dup_object (value); break; case PROP_STREAM: src->stream_id = g_value_get_uint (value); break; case PROP_COMPONENT: src->component_id = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gst_nice_src_get_property ( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GstNiceSrc *src = GST_NICE_SRC (object); switch (prop_id) { case PROP_AGENT: g_value_set_object (value, src->agent); break; case PROP_STREAM: g_value_set_uint (value, src->stream_id); break; case PROP_COMPONENT: g_value_set_uint (value, src->component_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static GstStateChangeReturn gst_nice_src_change_state (GstElement * element, GstStateChange transition) { GstNiceSrc *src; GstStateChangeReturn ret; src = GST_NICE_SRC (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (src->agent == NULL) { GST_ERROR_OBJECT (element, "Trying to start Nice source without an agent set"); return GST_STATE_CHANGE_FAILURE; } else if (src->stream_id == 0) { GST_ERROR_OBJECT (element, "Trying to start Nice source without a stream set"); return GST_STATE_CHANGE_FAILURE; } else if (src->component_id == 0) { GST_ERROR_OBJECT (element, "Trying to start Nice source without a component set"); return GST_STATE_CHANGE_FAILURE; } break; case GST_STATE_CHANGE_PAUSED_TO_READY: nice_agent_attach_recv (src->agent, src->stream_id, src->component_id, src->mainctx, NULL, NULL); GST_OBJECT_LOCK (src); g_queue_foreach (src->outbufs, (GFunc) gst_buffer_unref, NULL); g_queue_clear (src->outbufs); GST_OBJECT_UNLOCK (src); break; case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_NULL: default: break; } ret = GST_ELEMENT_CLASS (gst_nice_src_parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: nice_agent_attach_recv (src->agent, src->stream_id, src->component_id, src->mainctx, gst_nice_src_read_callback, (gpointer) src); break; case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_READY_TO_NULL: default: break; } return ret; } libnice-0.1.14/install-sh0000755000076400007640000003452313067560510012151 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2013-12-25.23; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnice-0.1.14/gtk-doc.make0000644000076400007640000002351413067560475012344 00000000000000# -*- mode: makefile -*- #################################### # Everything below here is generic # #################################### if GTK_DOC_USE_LIBTOOL GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) GTKDOC_RUN = $(LIBTOOL) --mode=execute else GTKDOC_CC = $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) GTKDOC_RUN = endif # We set GPATH here; this gives us semantics for GNU make # which are more like other make's VPATH, when it comes to # whether a source that is a target of one rule is then # searched for in VPATH/GPATH. # GPATH = $(srcdir) TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) SETUP_FILES = \ $(content_files) \ $(expand_content_files) \ $(DOC_MAIN_SGML_FILE) \ $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-overrides.txt EXTRA_DIST = \ $(HTML_IMAGES) \ $(SETUP_FILES) DOC_STAMPS=setup-build.stamp scan-build.stamp sgml-build.stamp \ html-build.stamp pdf-build.stamp \ sgml.stamp html.stamp pdf.stamp SCANOBJ_FILES = \ $(DOC_MODULE).args \ $(DOC_MODULE).hierarchy \ $(DOC_MODULE).interfaces \ $(DOC_MODULE).prerequisites \ $(DOC_MODULE).signals REPORT_FILES = \ $(DOC_MODULE)-undocumented.txt \ $(DOC_MODULE)-undeclared.txt \ $(DOC_MODULE)-unused.txt gtkdoc-check.test: Makefile $(AM_V_GEN)echo "#!/bin/sh -e" > $@; \ echo "$(GTKDOC_CHECK_PATH) || exit 1" >> $@; \ chmod +x $@ CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) gtkdoc-check.test if GTK_DOC_BUILD_HTML HTML_BUILD_STAMP=html-build.stamp else HTML_BUILD_STAMP= endif if GTK_DOC_BUILD_PDF PDF_BUILD_STAMP=pdf-build.stamp else PDF_BUILD_STAMP= endif all-gtk-doc: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) .PHONY: all-gtk-doc if ENABLE_GTK_DOC all-local: all-gtk-doc endif docs: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) $(REPORT_FILES): sgml-build.stamp #### setup #### GTK_DOC_V_SETUP=$(GTK_DOC_V_SETUP_$(V)) GTK_DOC_V_SETUP_=$(GTK_DOC_V_SETUP_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_SETUP_0=@echo " DOC Preparing build"; setup-build.stamp: -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \ if test "x$$files" != "x" ; then \ for file in $$files ; do \ destdir=`dirname $(abs_builddir)/$$file`; \ test -d "$$destdir" || mkdir -p "$$destdir"; \ test -f $(abs_srcdir)/$$file && \ cp -pf $(abs_srcdir)/$$file $(abs_builddir)/$$file || true; \ done; \ fi; \ fi $(AM_V_at)touch setup-build.stamp #### scan #### GTK_DOC_V_SCAN=$(GTK_DOC_V_SCAN_$(V)) GTK_DOC_V_SCAN_=$(GTK_DOC_V_SCAN_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_SCAN_0=@echo " DOC Scanning header files"; GTK_DOC_V_INTROSPECT=$(GTK_DOC_V_INTROSPECT_$(V)) GTK_DOC_V_INTROSPECT_=$(GTK_DOC_V_INTROSPECT_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_INTROSPECT_0=@echo " DOC Introspecting gobjects"; scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(GTK_DOC_V_SCAN)_source_dir='' ; \ for i in $(DOC_SOURCE_DIR) ; do \ _source_dir="$${_source_dir} --source-dir=$$i" ; \ done ; \ gtkdoc-scan --module=$(DOC_MODULE) --ignore-headers="$(IGNORE_HFILES)" $${_source_dir} $(SCAN_OPTIONS) $(EXTRA_HFILES) $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \ scanobj_options=""; \ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \ if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ scanobj_options="--verbose"; \ fi; \ fi; \ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \ gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \ else \ for i in $(SCANOBJ_FILES) ; do \ test -f $$i || touch $$i ; \ done \ fi $(AM_V_at)touch scan-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp @true #### xml #### GTK_DOC_V_XML=$(GTK_DOC_V_XML_$(V)) GTK_DOC_V_XML_=$(GTK_DOC_V_XML_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XML_0=@echo " DOC Building XML"; sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt $(expand_content_files) xml/gtkdocentities.ent $(GTK_DOC_V_XML)_source_dir='' ; \ for i in $(DOC_SOURCE_DIR) ; do \ _source_dir="$${_source_dir} --source-dir=$$i" ; \ done ; \ gtkdoc-mkdb --module=$(DOC_MODULE) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $${_source_dir} $(MKDB_OPTIONS) $(AM_V_at)touch sgml-build.stamp sgml.stamp: sgml-build.stamp @true xml/gtkdocentities.ent: Makefile $(GTK_DOC_V_XML)$(MKDIR_P) $(@D) && ( \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ ) > $@ #### html #### GTK_DOC_V_HTML=$(GTK_DOC_V_HTML_$(V)) GTK_DOC_V_HTML_=$(GTK_DOC_V_HTML_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_HTML_0=@echo " DOC Building HTML"; GTK_DOC_V_XREF=$(GTK_DOC_V_XREF_$(V)) GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references"; html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \ mkhtml_options=""; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \ if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkhtml_options="$$mkhtml_options --verbose"; \ fi; \ fi; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ if test "$$?" = "0"; then \ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \ fi; \ cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) -@test "x$(HTML_IMAGES)" = "x" || \ for file in $(HTML_IMAGES) ; do \ if test -f $(abs_srcdir)/$$file ; then \ cp $(abs_srcdir)/$$file $(abs_builddir)/html; \ fi; \ if test -f $(abs_builddir)/$$file ; then \ cp $(abs_builddir)/$$file $(abs_builddir)/html; \ fi; \ done; $(GTK_DOC_V_XREF)gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) $(AM_V_at)touch html-build.stamp #### pdf #### GTK_DOC_V_PDF=$(GTK_DOC_V_PDF_$(V)) GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_PDF_0=@echo " DOC Building PDF"; pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \ mkpdf_options=""; \ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \ if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkpdf_options="$$mkpdf_options --verbose"; \ fi; \ fi; \ if test "x$(HTML_IMAGES)" != "x"; then \ for img in $(HTML_IMAGES); do \ part=`dirname $$img`; \ echo $$mkpdf_options | grep >/dev/null "\-\-imgdir=$$part "; \ if test $$? != 0; then \ mkpdf_options="$$mkpdf_options --imgdir=$$part"; \ fi; \ done; \ fi; \ gtkdoc-mkpdf --path="$(abs_srcdir)" $$mkpdf_options $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) $(MKPDF_OPTIONS) $(AM_V_at)touch pdf-build.stamp ############## clean-local: @rm -f *~ *.bak @rm -rf .libs @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \ rm -f $(DOC_MODULE).types; \ fi @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \ rm -f $(DOC_MODULE)-sections.txt; \ fi distclean-local: @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ rm -f $(SETUP_FILES) $(DOC_MODULE).types; \ fi maintainer-clean-local: @rm -rf xml html install-data-local: @installfiles=`echo $(builddir)/html/*`; \ if test "$$installfiles" = '$(builddir)/html/*'; \ then echo 1>&2 'Nothing to install' ; \ else \ if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ $(mkinstalldirs) $${installdir} ; \ for i in $$installfiles; do \ echo ' $(INSTALL_DATA) '$$i ; \ $(INSTALL_DATA) $$i $${installdir}; \ done; \ if test -n "$(DOC_MODULE_VERSION)"; then \ mv -f $${installdir}/$(DOC_MODULE).devhelp2 \ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \ fi; \ $(GTKDOC_REBASE) --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir}; \ fi uninstall-local: @if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ rm -rf $${installdir} # # Require gtk-doc when making dist # if HAVE_GTK_DOC dist-check-gtkdoc: docs else dist-check-gtkdoc: @echo "*** gtk-doc is needed to run 'make dist'. ***" @echo "*** gtk-doc was not found when 'configure' ran. ***" @echo "*** please install gtk-doc and rerun 'configure'. ***" @false endif dist-hook: dist-check-gtkdoc all-gtk-doc dist-hook-local @mkdir $(distdir)/html @cp ./html/* $(distdir)/html @-cp ./$(DOC_MODULE).pdf $(distdir)/ @-cp ./$(DOC_MODULE).types $(distdir)/ @-cp ./$(DOC_MODULE)-sections.txt $(distdir)/ @cd $(distdir) && rm -f $(DISTCLEANFILES) @$(GTKDOC_REBASE) --online --relative --html-dir=$(distdir)/html .PHONY : dist-hook-local docs libnice-0.1.14/configure0000775000076400007640000207147413070512350012057 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for libnice 0.1.14. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libnice' PACKAGE_TARNAME='libnice' PACKAGE_VERSION='0.1.14' PACKAGE_STRING='libnice 0.1.14' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="agent/agent.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS HAVE_INTROSPECTION_FALSE HAVE_INTROSPECTION_TRUE INTROSPECTION_MAKEFILE INTROSPECTION_LIBS INTROSPECTION_CFLAGS INTROSPECTION_TYPELIBDIR INTROSPECTION_GIRDIR INTROSPECTION_GENERATE INTROSPECTION_COMPILER INTROSPECTION_SCANNER GTK_DOC_USE_REBASE_FALSE GTK_DOC_USE_REBASE_TRUE GTK_DOC_USE_LIBTOOL_FALSE GTK_DOC_USE_LIBTOOL_TRUE GTK_DOC_BUILD_PDF_FALSE GTK_DOC_BUILD_PDF_TRUE GTK_DOC_BUILD_HTML_FALSE GTK_DOC_BUILD_HTML_TRUE ENABLE_GTK_DOC_FALSE ENABLE_GTK_DOC_TRUE HAVE_GTK_DOC_FALSE HAVE_GTK_DOC_TRUE GTKDOC_DEPS_LIBS GTKDOC_DEPS_CFLAGS HTML_DIR GTKDOC_MKPDF GTKDOC_REBASE GTKDOC_CHECK_PATH GTKDOC_CHECK GST_PLUGIN_BUILD_STATIC_FALSE GST_PLUGIN_BUILD_STATIC_TRUE CCACHE_DISABLE UPNP_ENABLED HAVE_GUPNP GUPNP_PACKAGES GUPNP_PACKAGES_PRIVATE GUPNP_PACKAGES_PUBLIC GUPNP_LIBS GUPNP_CFLAGS WITH_GSTREAMER010_FALSE WITH_GSTREAMER010_TRUE HAVE_GST_CHECK_FALSE HAVE_GST_CHECK_TRUE WITH_GSTREAMER_FALSE WITH_GSTREAMER_TRUE gstplugin010dir gstplugindir GST010_LIBS GST010_CFLAGS GST_CHECK_LIBS GST_CHECK_CFLAGS GST_LIBS GST_CFLAGS NICE_PACKAGES_PRIVATE NICE_PACKAGES_PUBLIC GLIB_LIBS GLIB_CFLAGS GNUTLS_LIBS GNUTLS_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG LIBRT LIBNICE_CFLAGS WINDOWS_FALSE WINDOWS_TRUE LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP SED LIBTOOL OBJDUMP DLLTOOL AS ac_ct_AR AR EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC LIBNICE_LT_LDFLAGS AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_static enable_shared with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock enable_assert enable_compile_warnings with_gstreamer with_gstreamer_0_10 enable_gupnp enable_coverage enable_static_plugins with_html_dir enable_gtk_doc enable_gtk_doc_html enable_gtk_doc_pdf enable_introspection ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP LT_SYS_LIBRARY_PATH PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR GNUTLS_CFLAGS GNUTLS_LIBS GLIB_CFLAGS GLIB_LIBS GST_CFLAGS GST_LIBS GST_CHECK_CFLAGS GST_CHECK_LIBS GST010_CFLAGS GST010_LIBS GUPNP_CFLAGS GUPNP_LIBS GTKDOC_DEPS_CFLAGS GTKDOC_DEPS_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libnice 0.1.14 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libnice] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libnice 0.1.14:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-assert turn off assertions --enable-compile-warnings=[no/minimum/yes/maximum/error] Enable different levels of compiler warnings --disable-gupnp Disable GUPnP IGD support --enable-coverage build for test coverage (default disabled) --enable-static-plugins build static plugins [default=no] --enable-gtk-doc use gtk-doc to build documentation [[default=no]] --enable-gtk-doc-html build documentation in html format [[default=yes]] --enable-gtk-doc-pdf build documentation in pdf format [[default=no]] --enable-introspection=[no/auto/yes] Enable introspection for this build Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-gstreamer build GStreamer plugin --with-gstreamer-0.10 build GStreamer 0.10 plugin --with-html-dir=PATH path to installed docs Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor LT_SYS_LIBRARY_PATH User-defined run-time library search path. PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path GNUTLS_CFLAGS C compiler flags for GNUTLS, overriding pkg-config GNUTLS_LIBS linker flags for GNUTLS, overriding pkg-config GLIB_CFLAGS C compiler flags for GLIB, overriding pkg-config GLIB_LIBS linker flags for GLIB, overriding pkg-config GST_CFLAGS C compiler flags for GST, overriding pkg-config GST_LIBS linker flags for GST, overriding pkg-config GST_CHECK_CFLAGS C compiler flags for GST_CHECK, overriding pkg-config GST_CHECK_LIBS linker flags for GST_CHECK, overriding pkg-config GST010_CFLAGS C compiler flags for GST010, overriding pkg-config GST010_LIBS linker flags for GST010, overriding pkg-config GUPNP_CFLAGS C compiler flags for GUPNP, overriding pkg-config GUPNP_LIBS linker flags for GUPNP, overriding pkg-config GTKDOC_DEPS_CFLAGS C compiler flags for GTKDOC_DEPS, overriding pkg-config GTKDOC_DEPS_LIBS linker flags for GTKDOC_DEPS, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libnice configure 0.1.14 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libnice $as_me 0.1.14, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBNICE_RELEASE="yes" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- ac_config_headers="$ac_config_headers config.h" am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libnice' VERSION='0.1.14' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi ac_config_files="$ac_config_files Makefile agent/Makefile stun/Makefile stun/tests/Makefile stun/tools/Makefile socket/Makefile nice/Makefile nice/nice.pc random/Makefile gst/Makefile docs/Makefile docs/reference/Makefile docs/reference/libnice/Makefile tests/Makefile examples/Makefile" # Set the libtool C/A/R version info # If the source code was changed, but there were no interface changes: # Increment REVISION. # If there was a compatible interface change: # Increment CURRENT and AGE. Set REVISION to 0 # If there was an incompatible interface change: # Increment CURRENT. Set AGE and REVISION to 0 LIBNICE_CURRENT=17 LIBNICE_REVISION=0 LIBNICE_AGE=7 LIBNICE_LIBVERSION=${LIBNICE_CURRENT}:${LIBNICE_REVISION}:${LIBNICE_AGE} LIBNICE_LT_LDFLAGS="-version-info ${LIBNICE_LIBVERSION} -no-undefined" # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' # Checks for programs. DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" if test "x$ac_cv_header_minix_config_h" = xyes; then : MINIX=yes else MINIX= fi if test "$MINIX" = yes; then $as_echo "#define _POSIX_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h $as_echo "#define _MINIX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } if ${ac_cv_safe_to_define___extensions__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_safe_to_define___extensions__=yes else ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } test $ac_cv_safe_to_define___extensions__ = yes && $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h $as_echo "#define _ALL_SOURCE 1" >>confdefs.h $as_echo "#define _GNU_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=yes enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 $as_echo "$AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 $as_echo "$ac_ct_AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=no fi # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: # Check Operating System { $as_echo "$as_me:${as_lineno-$LINENO}: checking operating system" >&5 $as_echo_n "checking operating system... " >&6; } case "$host" in *-*-*mingw*|*-*-*cygwin*) platform=win32 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $platform" >&5 $as_echo "$platform" >&6; } ;; *) platform=linux/other { $as_echo "$as_me:${as_lineno-$LINENO}: result: $platform" >&5 $as_echo "$platform" >&6; } ;; esac if test "$platform" = "win32"; then WINDOWS_TRUE= WINDOWS_FALSE='#' else WINDOWS_TRUE='#' WINDOWS_FALSE= fi # Checks for compiler features { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5 $as_echo_n "checking for C/C++ restrict keyword... " >&6; } if ${ac_cv_c_restrict+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_restrict=no # The order here caters to the fact that C++ does not require restrict. for ac_kw in __restrict __restrict__ _Restrict restrict; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ typedef int * int_ptr; int foo (int_ptr $ac_kw ip) { return ip[0]; } int main () { int s[1]; int * $ac_kw t = s; t[0] = 0; return foo(t) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_restrict=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_restrict" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5 $as_echo "$ac_cv_c_restrict" >&6; } case $ac_cv_c_restrict in restrict) ;; no) $as_echo "#define restrict /**/" >>confdefs.h ;; *) cat >>confdefs.h <<_ACEOF #define restrict $ac_cv_c_restrict _ACEOF ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for variable-length arrays" >&5 $as_echo_n "checking for variable-length arrays... " >&6; } if ${ac_cv_c_vararrays+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { static int x; char a[++x]; a[sizeof a - 1] = 0; return a[0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_vararrays=yes else ac_cv_c_vararrays=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_vararrays" >&5 $as_echo "$ac_cv_c_vararrays" >&6; } if test $ac_cv_c_vararrays = yes; then $as_echo "#define HAVE_C_VARARRAYS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable assertions" >&5 $as_echo_n "checking whether to enable assertions... " >&6; } # Check whether --enable-assert was given. if test "${enable_assert+set}" = set; then : enableval=$enable_assert; ac_enable_assert=$enableval if test "x$enableval" = xno; then : $as_echo "#define NDEBUG 1" >>confdefs.h elif test "x$enableval" != xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: invalid argument supplied to --enable-assert" >&5 $as_echo "$as_me: WARNING: invalid argument supplied to --enable-assert" >&2;} ac_enable_assert=yes fi else ac_enable_assert=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_enable_assert" >&5 $as_echo "$ac_enable_assert" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi $as_echo "#define NICEAPI_EXPORT " >>confdefs.h for ac_header in arpa/inet.h net/in.h netdb.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in ifaddrs.h do : ac_fn_c_check_header_mongrel "$LINENO" "ifaddrs.h" "ac_cv_header_ifaddrs_h" "$ac_includes_default" if test "x$ac_cv_header_ifaddrs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IFADDRS_H 1 _ACEOF \ $as_echo "#define HAVE_GETIFADDRS 1" >>confdefs.h fi done ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SIZE_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" if test "x$ac_cv_type_ssize_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SSIZE_T 1 _ACEOF fi # Also put matching version in LIBNICE_CFLAGS GLIB_REQ=2.44 LIBNICE_CFLAGS="-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_44 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_44" # Check whether --enable-compile-warnings was given. if test "${enable_compile_warnings+set}" = set; then : enableval=$enable_compile_warnings; else if test "$LIBNICE_RELEASE" = "yes"; then : enable_compile_warnings="yes" else enable_compile_warnings="error" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -fno-strict-aliasing" >&5 $as_echo_n "checking to see if compiler understands -Werror -fno-strict-aliasing... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -fno-strict-aliasing" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -fno-strict-aliasing" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } if test "$enable_compile_warnings" != "no"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wall" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wall... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wall" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wall" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } fi if test "x$enable_compile_warnings" != "xno" -a \ "x$enable_compile_warnings" != "xminimum"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wextra" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wextra... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wextra" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wextra" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wundef" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wundef... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wundef" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wundef" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wnested-externs" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wnested-externs... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wnested-externs" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wnested-externs" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wwrite-strings" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wwrite-strings... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wwrite-strings" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wwrite-strings" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wpointer-arith" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wpointer-arith... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wpointer-arith" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wpointer-arith" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wmissing-declarations" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wmissing-declarations... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wmissing-declarations" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wmissing-declarations" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wmissing-prototypes" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wmissing-prototypes... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wmissing-prototypes" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wmissing-prototypes" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wstrict-prototypes" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wstrict-prototypes... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wstrict-prototypes" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wstrict-prototypes" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wredundant-decls" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wredundant-decls... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wredundant-decls" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wredundant-decls" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wno-unused-parameter" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wno-unused-parameter... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wno-unused-parameter" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wno-unused-parameter" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wno-missing-field-initializers" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wno-missing-field-initializers... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wno-missing-field-initializers" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wno-missing-field-initializers" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wdeclaration-after-statement" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wdeclaration-after-statement... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wdeclaration-after-statement" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wdeclaration-after-statement" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wformat=2" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wformat=2... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wformat=2" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wformat=2" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wold-style-definition" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wold-style-definition... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wold-style-definition" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wold-style-definition" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wcast-align" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wcast-align... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wcast-align" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wcast-align" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wformat-nonliteral" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wformat-nonliteral... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wformat-nonliteral" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wformat-nonliteral" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wformat-security" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wformat-security... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wformat-security" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wformat-security" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } fi if test "$enable_compile_warnings" = "yes" -o \ "$enable_compile_warnings" = "maximum" -o \ "$enable_compile_warnings" = "error"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wsign-compare" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wsign-compare... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wsign-compare" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wsign-compare" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wstrict-aliasing" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wstrict-aliasing... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wstrict-aliasing" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wstrict-aliasing" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wshadow" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wshadow... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wshadow" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wshadow" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Winline" >&5 $as_echo_n "checking to see if compiler understands -Werror -Winline... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Winline" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Winline" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wpacked" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wpacked... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wpacked" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wpacked" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wmissing-format-attribute" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wmissing-format-attribute... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wmissing-format-attribute" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wmissing-format-attribute" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Winit-self" >&5 $as_echo_n "checking to see if compiler understands -Werror -Winit-self... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Winit-self" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Winit-self" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wredundant-decls" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wredundant-decls... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wredundant-decls" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wredundant-decls" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wmissing-include-dirs" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wmissing-include-dirs... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wmissing-include-dirs" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wmissing-include-dirs" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wunused-but-set-variable" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wunused-but-set-variable... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wunused-but-set-variable" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wunused-but-set-variable" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Warray-bounds" >&5 $as_echo_n "checking to see if compiler understands -Werror -Warray-bounds... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Warray-bounds" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Warray-bounds" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } fi if test "$enable_compile_warnings" = "maximum" -o \ "$enable_compile_warnings" = "error"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wswitch-enum" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wswitch-enum... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wswitch-enum" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wswitch-enum" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wswitch-default" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wswitch-default... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wswitch-default" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wswitch-default" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Waggregate-return" >&5 $as_echo_n "checking to see if compiler understands -Werror -Waggregate-return... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Waggregate-return" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Waggregate-return" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } fi if test "x$enable_compile_warnings" = "xerror"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Werror" >&5 $as_echo_n "checking to see if compiler understands -Werror -Werror... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Werror" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -Werror -Wno-suggest-attribute=format" >&5 $as_echo_n "checking to see if compiler understands -Werror -Wno-suggest-attribute=format... " >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -Wno-suggest-attribute=format" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : flag_ok=yes else flag_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then LIBNICE_CFLAGS="$LIBNICE_CFLAGS -Wno-suggest-attribute=format" true else true fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5 $as_echo "$flag_ok" >&6; } fi # # Fixes for Solaris # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_pton" >&5 $as_echo_n "checking for library containing inet_pton... " >&6; } if ${ac_cv_search_inet_pton+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_pton (); int main () { return inet_pton (); ; return 0; } _ACEOF for ac_lib in '' nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_inet_pton=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_inet_pton+:} false; then : break fi done if ${ac_cv_search_inet_pton+:} false; then : else ac_cv_search_inet_pton=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_pton" >&5 $as_echo "$ac_cv_search_inet_pton" >&6; } ac_res=$ac_cv_search_inet_pton if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 $as_echo_n "checking for library containing socket... " >&6; } if ${ac_cv_search_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF for ac_lib in '' socket inet; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_socket=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_socket+:} false; then : break fi done if ${ac_cv_search_socket+:} false; then : else ac_cv_search_socket=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 $as_echo "$ac_cv_search_socket" >&6; } ac_res=$ac_cv_search_socket if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi case $host in *-*-solaris* ) $as_echo "#define _XOPEN_SOURCE 600" >>confdefs.h $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: set LIBNICE_CFLAGS to $LIBNICE_CFLAGS" >&5 $as_echo "$as_me: set LIBNICE_CFLAGS to $LIBNICE_CFLAGS" >&6;} # Checks for libraries. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if ${ac_cv_lib_rt_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : LIBRT="-lrt" else LIBRT="" fi for ac_func in poll do : ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" if test "x$ac_cv_func_poll" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_POLL 1 _ACEOF fi done # Dependencies GNUTLS_PACKAGES_PRIVATE="gnutls >= 2.12.0" if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNUTLS" >&5 $as_echo_n "checking for GNUTLS... " >&6; } if test -n "$GNUTLS_CFLAGS"; then pkg_cv_GNUTLS_CFLAGS="$GNUTLS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$GNUTLS_PACKAGES_PRIVATE\""; } >&5 ($PKG_CONFIG --exists --print-errors "$GNUTLS_PACKAGES_PRIVATE") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GNUTLS_CFLAGS=`$PKG_CONFIG --cflags "$GNUTLS_PACKAGES_PRIVATE" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GNUTLS_LIBS"; then pkg_cv_GNUTLS_LIBS="$GNUTLS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$GNUTLS_PACKAGES_PRIVATE\""; } >&5 ($PKG_CONFIG --exists --print-errors "$GNUTLS_PACKAGES_PRIVATE") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GNUTLS_LIBS=`$PKG_CONFIG --libs "$GNUTLS_PACKAGES_PRIVATE" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GNUTLS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$GNUTLS_PACKAGES_PRIVATE" 2>&1` else GNUTLS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$GNUTLS_PACKAGES_PRIVATE" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GNUTLS_PKG_ERRORS" >&5 as_fn_error $? "Package requirements ($GNUTLS_PACKAGES_PRIVATE) were not met: $GNUTLS_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GNUTLS_CFLAGS and GNUTLS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GNUTLS_CFLAGS and GNUTLS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GNUTLS_CFLAGS=$pkg_cv_GNUTLS_CFLAGS GNUTLS_LIBS=$pkg_cv_GNUTLS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi NICE_PACKAGES_PUBLIC="glib-2.0 >= $GLIB_REQ gio-2.0 >= $GLIB_REQ gobject-2.0 >= $GLIB_REQ" NICE_PACKAGES_PRIVATE="gthread-2.0" pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB" >&5 $as_echo_n "checking for GLIB... " >&6; } if test -n "$GLIB_CFLAGS"; then pkg_cv_GLIB_CFLAGS="$GLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$NICE_PACKAGES_PUBLIC \$NICE_PACKAGES_PRIVATE\""; } >&5 ($PKG_CONFIG --exists --print-errors "$NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB_CFLAGS=`$PKG_CONFIG --cflags "$NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GLIB_LIBS"; then pkg_cv_GLIB_LIBS="$GLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$NICE_PACKAGES_PUBLIC \$NICE_PACKAGES_PRIVATE\""; } >&5 ($PKG_CONFIG --exists --print-errors "$NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB_LIBS=`$PKG_CONFIG --libs "$NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE" 2>&1` else GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GLIB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements ($NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE) were not met: $GLIB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GLIB_CFLAGS and GLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GLIB_CFLAGS and GLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GLIB_CFLAGS=$pkg_cv_GLIB_CFLAGS GLIB_LIBS=$pkg_cv_GLIB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi NICE_PACKAGES_PRIVATE="$NICE_PACKAGES_PRIVATE $GNUTLS_PACKAGES_PRIVATE" # Check whether --with-gstreamer was given. if test "${with_gstreamer+set}" = set; then : withval=$with_gstreamer; with_gstreamer=${withval} else with_gstreamer=auto fi # Check whether --with-gstreamer-0.10 was given. if test "${with_gstreamer_0_10+set}" = set; then : withval=$with_gstreamer_0_10; with_gstreamer010=${withval} else with_gstreamer010=auto fi if test "$with_gstreamer" != no; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GST" >&5 $as_echo_n "checking for GST... " >&6; } if test -n "$GST_CFLAGS"; then pkg_cv_GST_CFLAGS="$GST_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GST_CFLAGS=`$PKG_CONFIG --cflags " gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GST_LIBS"; then pkg_cv_GST_LIBS="$GST_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GST_LIBS=`$PKG_CONFIG --libs " gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GST_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 " 2>&1` else GST_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 " 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GST_PKG_ERRORS" >&5 if test "$with_gstreamer" = yes; then : as_fn_error $? "GStreamer 1.0 support was requested but GStreamer 1.0 libraries are not available" "$LINENO" 5 fi with_gstreamer=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if test "$with_gstreamer" = yes; then : as_fn_error $? "GStreamer 1.0 support was requested but GStreamer 1.0 libraries are not available" "$LINENO" 5 fi with_gstreamer=no else GST_CFLAGS=$pkg_cv_GST_CFLAGS GST_LIBS=$pkg_cv_GST_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_gstreamer=yes GST_MAJORMINOR=1.0 gstplugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GST_CHECK" >&5 $as_echo_n "checking for GST_CHECK... " >&6; } if test -n "$GST_CHECK_CFLAGS"; then pkg_cv_GST_CHECK_CFLAGS="$GST_CHECK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-check-1.0 >= 0.11.91 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gstreamer-check-1.0 >= 0.11.91 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GST_CHECK_CFLAGS=`$PKG_CONFIG --cflags " gstreamer-check-1.0 >= 0.11.91 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GST_CHECK_LIBS"; then pkg_cv_GST_CHECK_LIBS="$GST_CHECK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-check-1.0 >= 0.11.91 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gstreamer-check-1.0 >= 0.11.91 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GST_CHECK_LIBS=`$PKG_CONFIG --libs " gstreamer-check-1.0 >= 0.11.91 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GST_CHECK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " gstreamer-check-1.0 >= 0.11.91 " 2>&1` else GST_CHECK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " gstreamer-check-1.0 >= 0.11.91 " 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GST_CHECK_PKG_ERRORS" >&5 have_gst_check=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_gst_check=no else GST_CHECK_CFLAGS=$pkg_cv_GST_CHECK_CFLAGS GST_CHECK_LIBS=$pkg_cv_GST_CHECK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_gst_check=yes fi fi if test "$with_gstreamer010" != no; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GST010" >&5 $as_echo_n "checking for GST010... " >&6; } if test -n "$GST010_CFLAGS"; then pkg_cv_GST010_CFLAGS="$GST010_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GST010_CFLAGS=`$PKG_CONFIG --cflags " gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GST010_LIBS"; then pkg_cv_GST010_LIBS="$GST010_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GST010_LIBS=`$PKG_CONFIG --libs " gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GST010_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 " 2>&1` else GST010_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 " 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GST010_PKG_ERRORS" >&5 if test "$with_gstreamer010" = yes; then : as_fn_error $? "GStreamer 0.10 support was requested but GStreamer 0.10 libraries are not available" "$LINENO" 5 fi with_gstreamer010=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if test "$with_gstreamer010" = yes; then : as_fn_error $? "GStreamer 0.10 support was requested but GStreamer 0.10 libraries are not available" "$LINENO" 5 fi with_gstreamer010=no else GST010_CFLAGS=$pkg_cv_GST010_CFLAGS GST010_LIBS=$pkg_cv_GST010_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } with_gstreamer010=yes GST_MAJORMINOR=0.10 gstplugin010dir="\$(libdir)/gstreamer-$GST_MAJORMINOR" fi fi if test "$with_gstreamer" = yes; then WITH_GSTREAMER_TRUE= WITH_GSTREAMER_FALSE='#' else WITH_GSTREAMER_TRUE='#' WITH_GSTREAMER_FALSE= fi if test "$have_gst_check" = yes; then HAVE_GST_CHECK_TRUE= HAVE_GST_CHECK_FALSE='#' else HAVE_GST_CHECK_TRUE='#' HAVE_GST_CHECK_FALSE= fi if test "$with_gstreamer010" = yes; then WITH_GSTREAMER010_TRUE= WITH_GSTREAMER010_FALSE='#' else WITH_GSTREAMER010_TRUE='#' WITH_GSTREAMER010_FALSE= fi GUPNP_IGD_REQUIRED=0.2.4 # Check whether --enable-gupnp was given. if test "${enable_gupnp+set}" = set; then : enableval=$enable_gupnp; case "${enableval}" in yes) WANT_GUPNP=yes ;; no) WANT_GUPNP=no ;; *) as_fn_error $? "bad value ${enableval} for --enable-gupnp" "$LINENO" 5 ;; esac else WANT_GUPNP=test fi GUPNP_PACKAGES_PUBLIC="" GUPNP_PACKAGES_PRIVATE="gupnp-igd-1.0 >= $GUPNP_IGD_REQUIRED" GUPNP_PACKAGES="$GUPNP_PACKAGES_PUBLIC $GUPNP_PACKAGES_PRIVATE" HAVE_GUPNP=no if test "x$WANT_GUPNP" != "xno"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GUPNP" >&5 $as_echo_n "checking for GUPNP... " >&6; } if test -n "$GUPNP_CFLAGS"; then pkg_cv_GUPNP_CFLAGS="$GUPNP_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$GUPNP_PACKAGES\""; } >&5 ($PKG_CONFIG --exists --print-errors "$GUPNP_PACKAGES") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GUPNP_CFLAGS=`$PKG_CONFIG --cflags "$GUPNP_PACKAGES" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GUPNP_LIBS"; then pkg_cv_GUPNP_LIBS="$GUPNP_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$GUPNP_PACKAGES\""; } >&5 ($PKG_CONFIG --exists --print-errors "$GUPNP_PACKAGES") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GUPNP_LIBS=`$PKG_CONFIG --libs "$GUPNP_PACKAGES" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GUPNP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$GUPNP_PACKAGES" 2>&1` else GUPNP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$GUPNP_PACKAGES" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GUPNP_PKG_ERRORS" >&5 HAVE_GUPNP=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } HAVE_GUPNP=no else GUPNP_CFLAGS=$pkg_cv_GUPNP_CFLAGS GUPNP_LIBS=$pkg_cv_GUPNP_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_GUPNP=yes fi fi if test "x$WANT_GUPNP" = "xyes" && test "x$HAVE_GUPNP" = "xno"; then as_fn_error $? "Requested GUPnP IGD, but it is not available" "$LINENO" 5 fi if test "x$HAVE_GUPNP" = "xyes"; then $as_echo "#define HAVE_GUPNP /**/" >>confdefs.h UPNP_ENABLED="true" else GUPNP_PACKAGES_PUBLIC="" GUPNP_PACKAGES_PRIVATE="" GUPNP_PACKAGES="" fi # Check whether --enable-coverage was given. if test "${enable_coverage+set}" = set; then : enableval=$enable_coverage; else enable_coverage="no" fi if test "${enable_coverage}" != "no"; then : CFLAGS="${CFLAGS} -g -O0 -fprofile-arcs -ftest-coverage" LDFLAGS="-lgcov" CCACHE_DISABLE=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static plugins or not" >&5 $as_echo_n "checking whether to build static plugins or not... " >&6; } # Check whether --enable-static-plugins was given. if test "${enable_static_plugins+set}" = set; then : enableval=$enable_static_plugins; case $enableval in #( no) : ;; #( yes) : ;; #( *) : as_fn_error $? "bad value \"$enableval\" for --enable-static-plugins" "$LINENO" 5 ;; esac else enable_static_plugins=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static_plugins" >&5 $as_echo "$enable_static_plugins" >&6; } if test "x$enable_static_plugins" = xyes; then $as_echo "#define GST_PLUGIN_BUILD_STATIC 1" >>confdefs.h fi if test "x$enable_static_plugins" = "xyes"; then GST_PLUGIN_BUILD_STATIC_TRUE= GST_PLUGIN_BUILD_STATIC_FALSE='#' else GST_PLUGIN_BUILD_STATIC_TRUE='#' GST_PLUGIN_BUILD_STATIC_FALSE= fi case $host_os in solaris*) LDFLAGS="$LDFLAGS -lsocket -lnsl" ;; *) ;; esac # check for gtk-doc gtk_doc_requires="gtk-doc >= 1.10" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk-doc" >&5 $as_echo_n "checking for gtk-doc... " >&6; } if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$gtk_doc_requires\""; } >&5 ($PKG_CONFIG --exists --print-errors "$gtk_doc_requires") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then have_gtk_doc=yes else have_gtk_doc=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gtk_doc" >&5 $as_echo "$have_gtk_doc" >&6; } if test "$have_gtk_doc" = "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You will not be able to create source packages with 'make dist' because $gtk_doc_requires is not found." >&5 $as_echo "$as_me: WARNING: You will not be able to create source packages with 'make dist' because $gtk_doc_requires is not found." >&2;} fi # Extract the first word of "gtkdoc-check", so it can be a program name with args. set dummy gtkdoc-check; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_GTKDOC_CHECK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$GTKDOC_CHECK"; then ac_cv_prog_GTKDOC_CHECK="$GTKDOC_CHECK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_GTKDOC_CHECK="gtkdoc-check.test" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi GTKDOC_CHECK=$ac_cv_prog_GTKDOC_CHECK if test -n "$GTKDOC_CHECK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_CHECK" >&5 $as_echo "$GTKDOC_CHECK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gtkdoc-check", so it can be a program name with args. set dummy gtkdoc-check; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GTKDOC_CHECK_PATH+:} false; then : $as_echo_n "(cached) " >&6 else case $GTKDOC_CHECK_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_GTKDOC_CHECK_PATH="$GTKDOC_CHECK_PATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GTKDOC_CHECK_PATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi GTKDOC_CHECK_PATH=$ac_cv_path_GTKDOC_CHECK_PATH if test -n "$GTKDOC_CHECK_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_CHECK_PATH" >&5 $as_echo "$GTKDOC_CHECK_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi for ac_prog in gtkdoc-rebase do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GTKDOC_REBASE+:} false; then : $as_echo_n "(cached) " >&6 else case $GTKDOC_REBASE in [\\/]* | ?:[\\/]*) ac_cv_path_GTKDOC_REBASE="$GTKDOC_REBASE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GTKDOC_REBASE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi GTKDOC_REBASE=$ac_cv_path_GTKDOC_REBASE if test -n "$GTKDOC_REBASE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_REBASE" >&5 $as_echo "$GTKDOC_REBASE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$GTKDOC_REBASE" && break done test -n "$GTKDOC_REBASE" || GTKDOC_REBASE="true" # Extract the first word of "gtkdoc-mkpdf", so it can be a program name with args. set dummy gtkdoc-mkpdf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GTKDOC_MKPDF+:} false; then : $as_echo_n "(cached) " >&6 else case $GTKDOC_MKPDF in [\\/]* | ?:[\\/]*) ac_cv_path_GTKDOC_MKPDF="$GTKDOC_MKPDF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GTKDOC_MKPDF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi GTKDOC_MKPDF=$ac_cv_path_GTKDOC_MKPDF if test -n "$GTKDOC_MKPDF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_MKPDF" >&5 $as_echo "$GTKDOC_MKPDF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Check whether --with-html-dir was given. if test "${with_html_dir+set}" = set; then : withval=$with_html_dir; else with_html_dir='${datadir}/gtk-doc/html' fi HTML_DIR="$with_html_dir" # Check whether --enable-gtk-doc was given. if test "${enable_gtk_doc+set}" = set; then : enableval=$enable_gtk_doc; else enable_gtk_doc=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build gtk-doc documentation" >&5 $as_echo_n "checking whether to build gtk-doc documentation... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gtk_doc" >&5 $as_echo "$enable_gtk_doc" >&6; } if test "x$enable_gtk_doc" = "xyes" && test "$have_gtk_doc" = "no"; then as_fn_error $? " You must have $gtk_doc_requires installed to build documentation for $PACKAGE_NAME. Please install gtk-doc or disable building the documentation by adding '--disable-gtk-doc' to '$0'." "$LINENO" 5 fi if test "x$PACKAGE_NAME" != "xglib"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTKDOC_DEPS" >&5 $as_echo_n "checking for GTKDOC_DEPS... " >&6; } if test -n "$GTKDOC_DEPS_CFLAGS"; then pkg_cv_GTKDOC_DEPS_CFLAGS="$GTKDOC_DEPS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTKDOC_DEPS_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTKDOC_DEPS_LIBS"; then pkg_cv_GTKDOC_DEPS_LIBS="$GTKDOC_DEPS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTKDOC_DEPS_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTKDOC_DEPS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>&1` else GTKDOC_DEPS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTKDOC_DEPS_PKG_ERRORS" >&5 : elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : else GTKDOC_DEPS_CFLAGS=$pkg_cv_GTKDOC_DEPS_CFLAGS GTKDOC_DEPS_LIBS=$pkg_cv_GTKDOC_DEPS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi fi # Check whether --enable-gtk-doc-html was given. if test "${enable_gtk_doc_html+set}" = set; then : enableval=$enable_gtk_doc_html; else enable_gtk_doc_html=yes fi # Check whether --enable-gtk-doc-pdf was given. if test "${enable_gtk_doc_pdf+set}" = set; then : enableval=$enable_gtk_doc_pdf; else enable_gtk_doc_pdf=no fi if test -z "$GTKDOC_MKPDF"; then enable_gtk_doc_pdf=no fi if test -z "$AM_DEFAULT_VERBOSITY"; then AM_DEFAULT_VERBOSITY=1 fi if test x$have_gtk_doc = xyes; then HAVE_GTK_DOC_TRUE= HAVE_GTK_DOC_FALSE='#' else HAVE_GTK_DOC_TRUE='#' HAVE_GTK_DOC_FALSE= fi if test x$enable_gtk_doc = xyes; then ENABLE_GTK_DOC_TRUE= ENABLE_GTK_DOC_FALSE='#' else ENABLE_GTK_DOC_TRUE='#' ENABLE_GTK_DOC_FALSE= fi if test x$enable_gtk_doc_html = xyes; then GTK_DOC_BUILD_HTML_TRUE= GTK_DOC_BUILD_HTML_FALSE='#' else GTK_DOC_BUILD_HTML_TRUE='#' GTK_DOC_BUILD_HTML_FALSE= fi if test x$enable_gtk_doc_pdf = xyes; then GTK_DOC_BUILD_PDF_TRUE= GTK_DOC_BUILD_PDF_FALSE='#' else GTK_DOC_BUILD_PDF_TRUE='#' GTK_DOC_BUILD_PDF_FALSE= fi if test -n "$LIBTOOL"; then GTK_DOC_USE_LIBTOOL_TRUE= GTK_DOC_USE_LIBTOOL_FALSE='#' else GTK_DOC_USE_LIBTOOL_TRUE='#' GTK_DOC_USE_LIBTOOL_FALSE= fi if test -n "$GTKDOC_REBASE"; then GTK_DOC_USE_REBASE_TRUE= GTK_DOC_USE_REBASE_FALSE='#' else GTK_DOC_USE_REBASE_TRUE='#' GTK_DOC_USE_REBASE_FALSE= fi # GObject introspection # Check whether --enable-introspection was given. if test "${enable_introspection+set}" = set; then : enableval=$enable_introspection; else enable_introspection=auto fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-introspection" >&5 $as_echo_n "checking for gobject-introspection... " >&6; } case $enable_introspection in #( no) : found_introspection="no (disabled, use --enable-introspection to enable)" ;; #( yes) : if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : else as_fn_error $? "gobject-introspection-1.0 is not installed" "$LINENO" 5 fi if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 1.30.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 1.30.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then found_introspection=yes else as_fn_error $? "You need to have gobject-introspection >= 1.30.0 installed to build libnice" "$LINENO" 5 fi ;; #( auto) : if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 1.30.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 1.30.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then found_introspection=yes else found_introspection=no fi enable_introspection=$found_introspection ;; #( *) : as_fn_error $? "invalid argument passed to --enable-introspection, should be one of [no/auto/yes]" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $found_introspection" >&5 $as_echo "$found_introspection" >&6; } INTROSPECTION_SCANNER= INTROSPECTION_COMPILER= INTROSPECTION_GENERATE= INTROSPECTION_GIRDIR= INTROSPECTION_TYPELIBDIR= if test "x$found_introspection" = "xyes"; then INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection fi if test "x$found_introspection" = "xyes"; then HAVE_INTROSPECTION_TRUE= HAVE_INTROSPECTION_FALSE='#' else HAVE_INTROSPECTION_TRUE='#' HAVE_INTROSPECTION_FALSE= fi cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WINDOWS_TRUE}" && test -z "${WINDOWS_FALSE}"; then as_fn_error $? "conditional \"WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_GSTREAMER_TRUE}" && test -z "${WITH_GSTREAMER_FALSE}"; then as_fn_error $? "conditional \"WITH_GSTREAMER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GST_CHECK_TRUE}" && test -z "${HAVE_GST_CHECK_FALSE}"; then as_fn_error $? "conditional \"HAVE_GST_CHECK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_GSTREAMER010_TRUE}" && test -z "${WITH_GSTREAMER010_FALSE}"; then as_fn_error $? "conditional \"WITH_GSTREAMER010\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GST_PLUGIN_BUILD_STATIC_TRUE}" && test -z "${GST_PLUGIN_BUILD_STATIC_FALSE}"; then as_fn_error $? "conditional \"GST_PLUGIN_BUILD_STATIC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GTK_DOC_TRUE}" && test -z "${HAVE_GTK_DOC_FALSE}"; then as_fn_error $? "conditional \"HAVE_GTK_DOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_GTK_DOC_TRUE}" && test -z "${ENABLE_GTK_DOC_FALSE}"; then as_fn_error $? "conditional \"ENABLE_GTK_DOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GTK_DOC_BUILD_HTML_TRUE}" && test -z "${GTK_DOC_BUILD_HTML_FALSE}"; then as_fn_error $? "conditional \"GTK_DOC_BUILD_HTML\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GTK_DOC_BUILD_PDF_TRUE}" && test -z "${GTK_DOC_BUILD_PDF_FALSE}"; then as_fn_error $? "conditional \"GTK_DOC_BUILD_PDF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GTK_DOC_USE_LIBTOOL_TRUE}" && test -z "${GTK_DOC_USE_LIBTOOL_FALSE}"; then as_fn_error $? "conditional \"GTK_DOC_USE_LIBTOOL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GTK_DOC_USE_REBASE_TRUE}" && test -z "${GTK_DOC_USE_REBASE_FALSE}"; then as_fn_error $? "conditional \"GTK_DOC_USE_REBASE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_INTROSPECTION_TRUE}" && test -z "${HAVE_INTROSPECTION_FALSE}"; then as_fn_error $? "conditional \"HAVE_INTROSPECTION\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libnice $as_me 0.1.14, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libnice config.status 0.1.14 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in AS \ DLLTOOL \ OBJDUMP \ SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "agent/Makefile") CONFIG_FILES="$CONFIG_FILES agent/Makefile" ;; "stun/Makefile") CONFIG_FILES="$CONFIG_FILES stun/Makefile" ;; "stun/tests/Makefile") CONFIG_FILES="$CONFIG_FILES stun/tests/Makefile" ;; "stun/tools/Makefile") CONFIG_FILES="$CONFIG_FILES stun/tools/Makefile" ;; "socket/Makefile") CONFIG_FILES="$CONFIG_FILES socket/Makefile" ;; "nice/Makefile") CONFIG_FILES="$CONFIG_FILES nice/Makefile" ;; "nice/nice.pc") CONFIG_FILES="$CONFIG_FILES nice/nice.pc" ;; "random/Makefile") CONFIG_FILES="$CONFIG_FILES random/Makefile" ;; "gst/Makefile") CONFIG_FILES="$CONFIG_FILES gst/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "docs/reference/Makefile") CONFIG_FILES="$CONFIG_FILES docs/reference/Makefile" ;; "docs/reference/libnice/Makefile") CONFIG_FILES="$CONFIG_FILES docs/reference/libnice/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Assembler program. AS=$lt_AS # DLL creation program. DLLTOOL=$lt_DLLTOOL # Object dumper program. OBJDUMP=$lt_OBJDUMP # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi libnice-0.1.14/config.h.in0000664000076400007640000001063113070512355012162 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if static plugins should be built */ #undef GST_PLUGIN_BUILD_STATIC /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Define to 1 if C supports variable-length arrays. */ #undef HAVE_C_VARARRAYS /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Whether getifaddrs() is available on the system */ #undef HAVE_GETIFADDRS /* Have the GUPnP IGD library */ #undef HAVE_GUPNP /* Define to 1 if you have the header file. */ #undef HAVE_IFADDRS_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IN_H /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if the system has the type `size_t'. */ #undef HAVE_SIZE_T /* Define to 1 if the system has the type `ssize_t'. */ #undef HAVE_SSIZE_T /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if assertions should be disabled. */ #undef NDEBUG /* Public library function implementation */ #undef NICEAPI_EXPORT /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Version number of package */ #undef VERSION /* Define to `2' to get GNU/libc warnings. */ /* Only define if -O1 or more is enabled */ #if defined __OPTIMIZE__ && __OPTIMIZE__ > 0 # define _FORTIFY_SOURCE 2 #endif /* Define to 1 if on MINIX. */ #undef _MINIX /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE /* Needed to get declarations for msg_control and msg_controllen on Solaris */ #undef _XOPEN_SOURCE /* Needed to get declarations for msg_control and msg_controllen on Solaris */ #undef __EXTENSIONS__ /* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported directly. */ #undef restrict /* Work around a bug in Sun C++: it does not support _Restrict or __restrict__, even though the corresponding Sun C compiler ends up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. Perhaps some future version of Sun C++ will work with restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ #if defined __SUNPRO_CC && !defined __RESTRICT # define _Restrict # define __restrict__ #endif libnice-0.1.14/config.guess0000755000076400007640000012367213067560510012471 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libnice-0.1.14/depcomp0000755000076400007640000005601613067560511011524 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnice-0.1.14/docs/0000775000076400007640000000000013070512356011147 500000000000000libnice-0.1.14/docs/Makefile.in0000664000076400007640000004721713070512350013141 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = docs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = reference EXTRA_DIST = design.txt all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu docs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/docs/Makefile.am0000644000076400007640000000005611241364464013125 00000000000000 SUBDIRS = reference EXTRA_DIST = design.txt libnice-0.1.14/docs/reference/0000775000076400007640000000000013070512356013105 500000000000000libnice-0.1.14/docs/reference/Makefile.in0000664000076400007640000004722313070512350015074 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = docs/reference ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = libnice all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/reference/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu docs/reference/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/docs/reference/Makefile.am0000644000076400007640000000002311241364464015055 00000000000000 SUBDIRS = libnice libnice-0.1.14/docs/reference/libnice/0000775000076400007640000000000013070512356014512 500000000000000libnice-0.1.14/docs/reference/libnice/libnice.types0000664000076400007640000000010713070512356017123 00000000000000nice_agent_get_type nice_candidate_get_type pseudo_tcp_socket_get_type libnice-0.1.14/docs/reference/libnice/Makefile.in0000664000076400007640000012177213070512350016503 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # -*- mode: makefile -*- #################################### # Everything below here is generic # #################################### VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = docs/reference/libnice ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/gtk-doc.make \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # We require automake 1.6 at least. AUTOMAKE_OPTIONS = 1.6 # The name of the module, e.g. 'glib'. DOC_MODULE = libnice # The top-level SGML file. You can change this if you want to. DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml # The directory containing the source code. Relative to $(srcdir). # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. # e.g. DOC_SOURCE_DIR=../../../gtk DOC_SOURCE_DIR = $(top_srcdir)/agent $(top_srcdir)/stun # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS = # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS = --rebuild-types # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml MKDB_OPTIONS = --xml-mode --output-format=xml --name-space=Nice # Extra options to supply to gtkdoc-mktmpl # e.g. MKTMPL_OPTIONS=--only-section-tmpl MKTMPL_OPTIONS = # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html FIXXREF_OPTIONS = # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB = $(top_srcdir)/agent/agent.h $(top_srcdir)/agent/address.h \ $(top_srcdir)/agent/debug.h $(top_srcdir)/agent/candidate.h \ $(top_srcdir)/agent/interfaces.h \ $(top_srcdir)/agent/pseudotcp.h \ $(top_srcdir)/stun/stunagent.h \ $(top_srcdir)/stun/stunmessage.h \ $(top_srcdir)/stun/debug.h \ $(top_srcdir)/stun/usages/bind.h \ $(top_srcdir)/stun/usages/ice.h \ $(top_srcdir)/stun/usages/timer.h \ $(top_srcdir)/stun/usages/turn.h CFILE_GLOB = $(top_srcdir)/agent/agent.c \ $(top_srcdir)/agent/pseudotcp.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES = conncheck.h discovery.h stream.h component.h agent-priv.h \ iostream.h inputstream.h outputstream.h \ gstnice.h gstnicesrc.h gstnicesink.h \ md5.h sha1.h stunhmac.h utils.h rand.h stun5389.h stuncrc32.h \ stund.h agent-signals-marshal.h win32_common.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES = states.png # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files = # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files # e.g. expand_content_files=running.sgml expand_content_files = # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) AM_CFLAGS = $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun GTKDOC_LIBS = $(top_builddir)/agent/libagent.la $(GLIB_LIBS) $(top_builddir)/stun/libstun.la \ $(GUPNP_LIBS) @GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_CC = $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_LD = $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) @GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) @GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_RUN = @GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_RUN = $(LIBTOOL) --mode=execute # We set GPATH here; this gives us semantics for GNU make # which are more like other make's VPATH, when it comes to # whether a source that is a target of one rule is then # searched for in VPATH/GPATH. # GPATH = $(srcdir) TARGET_DIR = $(HTML_DIR)/$(DOC_MODULE) SETUP_FILES = \ $(content_files) \ $(expand_content_files) \ $(DOC_MAIN_SGML_FILE) \ $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-overrides.txt # This includes the standard gtk-doc make rules, copied by gtkdocize. # Other files to distribute # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST = $(HTML_IMAGES) $(SETUP_FILES) states.gv DOC_STAMPS = setup-build.stamp scan-build.stamp sgml-build.stamp \ html-build.stamp pdf-build.stamp \ sgml.stamp html.stamp pdf.stamp SCANOBJ_FILES = \ $(DOC_MODULE).args \ $(DOC_MODULE).hierarchy \ $(DOC_MODULE).interfaces \ $(DOC_MODULE).prerequisites \ $(DOC_MODULE).signals REPORT_FILES = \ $(DOC_MODULE)-undocumented.txt \ $(DOC_MODULE)-undeclared.txt \ $(DOC_MODULE)-unused.txt CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) gtkdoc-check.test @GTK_DOC_BUILD_HTML_FALSE@HTML_BUILD_STAMP = @GTK_DOC_BUILD_HTML_TRUE@HTML_BUILD_STAMP = html-build.stamp @GTK_DOC_BUILD_PDF_FALSE@PDF_BUILD_STAMP = @GTK_DOC_BUILD_PDF_TRUE@PDF_BUILD_STAMP = pdf-build.stamp #### setup #### GTK_DOC_V_SETUP = $(GTK_DOC_V_SETUP_$(V)) GTK_DOC_V_SETUP_ = $(GTK_DOC_V_SETUP_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_SETUP_0 = @echo " DOC Preparing build"; #### scan #### GTK_DOC_V_SCAN = $(GTK_DOC_V_SCAN_$(V)) GTK_DOC_V_SCAN_ = $(GTK_DOC_V_SCAN_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_SCAN_0 = @echo " DOC Scanning header files"; GTK_DOC_V_INTROSPECT = $(GTK_DOC_V_INTROSPECT_$(V)) GTK_DOC_V_INTROSPECT_ = $(GTK_DOC_V_INTROSPECT_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_INTROSPECT_0 = @echo " DOC Introspecting gobjects"; #### xml #### GTK_DOC_V_XML = $(GTK_DOC_V_XML_$(V)) GTK_DOC_V_XML_ = $(GTK_DOC_V_XML_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XML_0 = @echo " DOC Building XML"; #### html #### GTK_DOC_V_HTML = $(GTK_DOC_V_HTML_$(V)) GTK_DOC_V_HTML_ = $(GTK_DOC_V_HTML_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_HTML_0 = @echo " DOC Building HTML"; GTK_DOC_V_XREF = $(GTK_DOC_V_XREF_$(V)) GTK_DOC_V_XREF_ = $(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XREF_0 = @echo " DOC Fixing cross-references"; #### pdf #### GTK_DOC_V_PDF = $(GTK_DOC_V_PDF_$(V)) GTK_DOC_V_PDF_ = $(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_PDF_0 = @echo " DOC Building PDF"; @ENABLE_GTK_DOC_TRUE@TESTS_ENVIRONMENT = \ @ENABLE_GTK_DOC_TRUE@ DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ @ENABLE_GTK_DOC_TRUE@ SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) @ENABLE_GTK_DOC_TRUE@TESTS = $(GTKDOC_CHECK) all: all-am .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/gtk-doc.make $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/reference/libnice/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu docs/reference/libnice/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/gtk-doc.make $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am @ENABLE_GTK_DOC_FALSE@all-local: all-am: Makefile all-local installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: check-am install-am install-strip .PHONY: all all-am all-local check check-TESTS check-am clean \ clean-generic clean-libtool clean-local cscopelist-am ctags-am \ dist-hook distclean distclean-generic distclean-libtool \ distclean-local distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic maintainer-clean-local mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags-am uninstall uninstall-am uninstall-local .PRECIOUS: Makefile gtkdoc-check.test: Makefile $(AM_V_GEN)echo "#!/bin/sh -e" > $@; \ echo "$(GTKDOC_CHECK_PATH) || exit 1" >> $@; \ chmod +x $@ all-gtk-doc: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) .PHONY: all-gtk-doc @ENABLE_GTK_DOC_TRUE@all-local: all-gtk-doc docs: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) $(REPORT_FILES): sgml-build.stamp setup-build.stamp: -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \ if test "x$$files" != "x" ; then \ for file in $$files ; do \ destdir=`dirname $(abs_builddir)/$$file`; \ test -d "$$destdir" || mkdir -p "$$destdir"; \ test -f $(abs_srcdir)/$$file && \ cp -pf $(abs_srcdir)/$$file $(abs_builddir)/$$file || true; \ done; \ fi; \ fi $(AM_V_at)touch setup-build.stamp scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(GTK_DOC_V_SCAN)_source_dir='' ; \ for i in $(DOC_SOURCE_DIR) ; do \ _source_dir="$${_source_dir} --source-dir=$$i" ; \ done ; \ gtkdoc-scan --module=$(DOC_MODULE) --ignore-headers="$(IGNORE_HFILES)" $${_source_dir} $(SCAN_OPTIONS) $(EXTRA_HFILES) $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \ scanobj_options=""; \ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \ if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ scanobj_options="--verbose"; \ fi; \ fi; \ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \ gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \ else \ for i in $(SCANOBJ_FILES) ; do \ test -f $$i || touch $$i ; \ done \ fi $(AM_V_at)touch scan-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp @true sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt $(expand_content_files) xml/gtkdocentities.ent $(GTK_DOC_V_XML)_source_dir='' ; \ for i in $(DOC_SOURCE_DIR) ; do \ _source_dir="$${_source_dir} --source-dir=$$i" ; \ done ; \ gtkdoc-mkdb --module=$(DOC_MODULE) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $${_source_dir} $(MKDB_OPTIONS) $(AM_V_at)touch sgml-build.stamp sgml.stamp: sgml-build.stamp @true xml/gtkdocentities.ent: Makefile $(GTK_DOC_V_XML)$(MKDIR_P) $(@D) && ( \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ echo ""; \ ) > $@ html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \ mkhtml_options=""; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \ if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkhtml_options="$$mkhtml_options --verbose"; \ fi; \ fi; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ if test "$$?" = "0"; then \ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \ fi; \ cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) -@test "x$(HTML_IMAGES)" = "x" || \ for file in $(HTML_IMAGES) ; do \ if test -f $(abs_srcdir)/$$file ; then \ cp $(abs_srcdir)/$$file $(abs_builddir)/html; \ fi; \ if test -f $(abs_builddir)/$$file ; then \ cp $(abs_builddir)/$$file $(abs_builddir)/html; \ fi; \ done; $(GTK_DOC_V_XREF)gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) $(AM_V_at)touch html-build.stamp pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \ mkpdf_options=""; \ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \ if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkpdf_options="$$mkpdf_options --verbose"; \ fi; \ fi; \ if test "x$(HTML_IMAGES)" != "x"; then \ for img in $(HTML_IMAGES); do \ part=`dirname $$img`; \ echo $$mkpdf_options | grep >/dev/null "\-\-imgdir=$$part "; \ if test $$? != 0; then \ mkpdf_options="$$mkpdf_options --imgdir=$$part"; \ fi; \ done; \ fi; \ gtkdoc-mkpdf --path="$(abs_srcdir)" $$mkpdf_options $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) $(MKPDF_OPTIONS) $(AM_V_at)touch pdf-build.stamp ############## clean-local: @rm -f *~ *.bak @rm -rf .libs @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \ rm -f $(DOC_MODULE).types; \ fi @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \ rm -f $(DOC_MODULE)-sections.txt; \ fi distclean-local: @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ rm -f $(SETUP_FILES) $(DOC_MODULE).types; \ fi maintainer-clean-local: @rm -rf xml html install-data-local: @installfiles=`echo $(builddir)/html/*`; \ if test "$$installfiles" = '$(builddir)/html/*'; \ then echo 1>&2 'Nothing to install' ; \ else \ if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ $(mkinstalldirs) $${installdir} ; \ for i in $$installfiles; do \ echo ' $(INSTALL_DATA) '$$i ; \ $(INSTALL_DATA) $$i $${installdir}; \ done; \ if test -n "$(DOC_MODULE_VERSION)"; then \ mv -f $${installdir}/$(DOC_MODULE).devhelp2 \ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \ fi; \ $(GTKDOC_REBASE) --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir}; \ fi uninstall-local: @if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ rm -rf $${installdir} # # Require gtk-doc when making dist # @HAVE_GTK_DOC_TRUE@dist-check-gtkdoc: docs @HAVE_GTK_DOC_FALSE@dist-check-gtkdoc: @HAVE_GTK_DOC_FALSE@ @echo "*** gtk-doc is needed to run 'make dist'. ***" @HAVE_GTK_DOC_FALSE@ @echo "*** gtk-doc was not found when 'configure' ran. ***" @HAVE_GTK_DOC_FALSE@ @echo "*** please install gtk-doc and rerun 'configure'. ***" @HAVE_GTK_DOC_FALSE@ @false dist-hook: dist-check-gtkdoc all-gtk-doc dist-hook-local @mkdir $(distdir)/html @cp ./html/* $(distdir)/html @-cp ./$(DOC_MODULE).pdf $(distdir)/ @-cp ./$(DOC_MODULE).types $(distdir)/ @-cp ./$(DOC_MODULE)-sections.txt $(distdir)/ @cd $(distdir) && rm -f $(DISTCLEANFILES) @$(GTKDOC_REBASE) --online --relative --html-dir=$(distdir)/html .PHONY : dist-hook-local docs # Files not to distribute # for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types # for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt #DISTCLEANFILES += # If we ever need to regenerate this diagram. # Since it’s not expected to change much, let’s not depend on GraphViz to # build the docs. states.png: states.gv dot -Tpng -Gsize=9.6,2.9\! -Gdpi=200 $^ > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/docs/reference/libnice/Makefile.am0000664000076400007640000000774113067561056016506 00000000000000## Process this file with automake to produce Makefile.in # We require automake 1.6 at least. AUTOMAKE_OPTIONS = 1.6 # The name of the module, e.g. 'glib'. DOC_MODULE=libnice # The top-level SGML file. You can change this if you want to. DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml # The directory containing the source code. Relative to $(srcdir). # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. # e.g. DOC_SOURCE_DIR=../../../gtk DOC_SOURCE_DIR=$(top_srcdir)/agent $(top_srcdir)/stun # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS= # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS=--rebuild-types # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml MKDB_OPTIONS=--xml-mode --output-format=xml --name-space=Nice # Extra options to supply to gtkdoc-mktmpl # e.g. MKTMPL_OPTIONS=--only-section-tmpl MKTMPL_OPTIONS= # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html FIXXREF_OPTIONS= # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB=$(top_srcdir)/agent/agent.h $(top_srcdir)/agent/address.h \ $(top_srcdir)/agent/debug.h $(top_srcdir)/agent/candidate.h \ $(top_srcdir)/agent/interfaces.h \ $(top_srcdir)/agent/pseudotcp.h \ $(top_srcdir)/stun/stunagent.h \ $(top_srcdir)/stun/stunmessage.h \ $(top_srcdir)/stun/debug.h \ $(top_srcdir)/stun/usages/bind.h \ $(top_srcdir)/stun/usages/ice.h \ $(top_srcdir)/stun/usages/timer.h \ $(top_srcdir)/stun/usages/turn.h CFILE_GLOB=$(top_srcdir)/agent/agent.c \ $(top_srcdir)/agent/pseudotcp.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES= conncheck.h discovery.h stream.h component.h agent-priv.h \ iostream.h inputstream.h outputstream.h \ gstnice.h gstnicesrc.h gstnicesink.h \ md5.h sha1.h stunhmac.h utils.h rand.h stun5389.h stuncrc32.h \ stund.h agent-signals-marshal.h win32_common.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES = states.png # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files= # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files # e.g. expand_content_files=running.sgml expand_content_files= # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) AM_CFLAGS = $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ -I $(top_srcdir) \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun GTKDOC_LIBS= $(top_builddir)/agent/libagent.la $(GLIB_LIBS) $(top_builddir)/stun/libstun.la \ $(GUPNP_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make # Other files to distribute # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += states.gv # Files not to distribute # for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types # for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt #DISTCLEANFILES += # If we ever need to regenerate this diagram. # Since it’s not expected to change much, let’s not depend on GraphViz to # build the docs. states.png: states.gv dot -Tpng -Gsize=9.6,2.9\! -Gdpi=200 $^ > $@ if ENABLE_GTK_DOC TESTS_ENVIRONMENT = \ DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) TESTS = $(GTKDOC_CHECK) endif libnice-0.1.14/docs/reference/libnice/states.gv0000664000076400007640000000220212661700132016263 00000000000000/* libnice state transition diagram for NiceComponentState. */ digraph NiceComponentState { rankdir=TB; node [shape = doublecircle]; DISCONNECTED; node [shape = circle]; /* Colour the normal control flow in green. */ DISCONNECTED -> GATHERING [ label = "nice_agent_gather_candidates()", color = chartreuse3 ]; GATHERING -> CONNECTING [ label = "nice_agent_set_remote_candidates()", color = chartreuse3 ]; CONNECTING -> CONNECTED [ label = "At least one candidate pair succeeds", color = chartreuse3 ]; CONNECTED -> READY [ label = "All candidate pairs checks finished", color = chartreuse3 ]; READY -> CONNECTED [ label = "Selected candidate pair fails" ]; FAILED -> CONNECTING [ label = "nice_agent_set_remote_candidates()" ]; DISCONNECTED -> CONNECTING [ label = "nice_agent_set_remote_candidates()" ]; /* Colour the failure paths in grey. */ DISCONNECTED -> FAILED [ label = "Failure", color = gray ]; GATHERING -> FAILED [ label = "Failure", color = gray ]; CONNECTING -> FAILED [ label = "Failure", color = gray ]; CONNECTED -> FAILED [ label = "Failure", color = gray ]; READY -> FAILED [ label = "Failure", color = gray ]; } libnice-0.1.14/docs/reference/libnice/html/0000775000076400007640000000000013070512356015456 500000000000000libnice-0.1.14/docs/reference/libnice/html/ix12.html0000664000076400007640000001346213070512356017055 00000000000000 Index of new symbols in 0.1.8: libnice Reference Manual libnice-0.1.14/docs/reference/libnice/html/pt02.html0000664000076400007640000000561113070512356017054 00000000000000 Part II. STUN Library: libnice Reference Manual

Part II. STUN Library

Table of Contents

StunAgent — STUN agent for building and validating STUN messages
StunMessage — STUN messages parsing and formatting functions
STUN Constants — STUN constants
STUN usages
Bind — STUN Binding Usage
ICE — STUN ICE Usage
TURN — TURN Allocation Usage
Timer — STUN timer Usage
libnice-0.1.14/docs/reference/libnice/html/libnice-STUN-Constants.html0000664000076400007640000003316513070512356022442 00000000000000 STUN Constants: libnice Reference Manual

STUN Constants

STUN Constants — STUN constants

Stability Level

Stable, unless otherwise indicated

Includes

#include <stun/constants.h>

Description

Various constants defining parts of the STUN and TURN protocols and on-the-wire packet formats.

Functions

Types and Values

STUN_AGENT_MAX_SAVED_IDS

#define STUN_AGENT_MAX_SAVED_IDS 200

Maximum number of simultaneously ongoing STUN transactions.


STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES

#define STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES 256

Maximum number of unknown attribute which can be handled in a single STUN message.


STUN_ATTRIBUTE_HEADER_LENGTH

#define STUN_ATTRIBUTE_HEADER_LENGTH STUN_ATTRIBUTE_VALUE_POS

Length of a single STUN attribute header (in bytes).


STUN_ATTRIBUTE_LENGTH_LEN

#define STUN_ATTRIBUTE_LENGTH_LEN 2

Length of the length field of a STUN attribute (in bytes).


STUN_ATTRIBUTE_LENGTH_POS

#define             STUN_ATTRIBUTE_LENGTH_POS

Offset of the length field of a STUN attribute (in bytes).


STUN_ATTRIBUTE_TYPE_LEN

#define STUN_ATTRIBUTE_TYPE_LEN 2

Length of the type field of a STUN attribute (in bytes).


STUN_ATTRIBUTE_TYPE_POS

#define STUN_ATTRIBUTE_TYPE_POS 0

Offset of the type field of a STUN attribute (in bytes).


STUN_ATTRIBUTE_VALUE_POS

#define             STUN_ATTRIBUTE_VALUE_POS

Offset of the value field of a STUN attribute (in bytes).


STUN_ID_LEN

#define STUN_ID_LEN 16

Length of the ID field of a STUN message (in bytes).


STUN_MAGIC_COOKIE

#define STUN_MAGIC_COOKIE 0x2112A442

Magic cookie value used to identify STUN messages.


STUN_MAX_MESSAGE_SIZE

#define STUN_MAX_MESSAGE_SIZE 65552

The Maximum size of a STUN message


STUN_MAX_MESSAGE_SIZE_IPV4

#define STUN_MAX_MESSAGE_SIZE_IPV4 576

Maximum size of a STUN message sent over IPv4 (in bytes).


STUN_MAX_MESSAGE_SIZE_IPV6

#define STUN_MAX_MESSAGE_SIZE_IPV6 1280

Maximum size of a STUN message sent over IPv6 (in bytes).


STUN_MESSAGE_ATTRIBUTES_POS

#define             STUN_MESSAGE_ATTRIBUTES_POS

Offset of the attributes of a STUN message (in bytes).


STUN_MESSAGE_HEADER_LENGTH

#define STUN_MESSAGE_HEADER_LENGTH STUN_MESSAGE_ATTRIBUTES_POS

Total length of a STUN message header (in bytes).


STUN_MESSAGE_LENGTH_LEN

#define STUN_MESSAGE_LENGTH_LEN 2

Length of the length field of a STUN message (in bytes).


STUN_MESSAGE_LENGTH_POS

#define             STUN_MESSAGE_LENGTH_POS

Offset of the length field of a STUN message (in bytes).


STUN_MESSAGE_TRANS_ID_LEN

#define STUN_MESSAGE_TRANS_ID_LEN 16

Length of the transaction ID field of a STUN message (in bytes).


STUN_MESSAGE_TRANS_ID_POS

#define             STUN_MESSAGE_TRANS_ID_POS

Offset of the transaction ID field of a STUN message (in bytes).


STUN_MESSAGE_TYPE_LEN

#define STUN_MESSAGE_TYPE_LEN 2

Length of the type field of a STUN message (in bytes).


STUN_MESSAGE_TYPE_POS

#define STUN_MESSAGE_TYPE_POS 0

Offset of the type field of a STUN message (in bytes).


TURN_MAGIC_COOKIE

#define TURN_MAGIC_COOKIE 0x72c64bc6

Magic cookie value used to identify TURN messages.

libnice-0.1.14/docs/reference/libnice/html/style.css0000644000076400007640000002115413070512356017251 00000000000000body { font-family: cantarell, sans-serif; } .synopsis, .classsynopsis { /* tango:aluminium 1/2 */ background: #eeeeec; background: rgba(238, 238, 236, 0.5); border: solid 1px rgb(238, 238, 236); padding: 0.5em; } .programlisting { /* tango:sky blue 0/1 */ /* fallback for no rgba support */ background: #e6f3ff; border: solid 1px #729fcf; background: rgba(114, 159, 207, 0.1); border: solid 1px rgba(114, 159, 207, 0.2); padding: 0.5em; } .variablelist { padding: 4px; margin-left: 3em; } .variablelist td:first-child { vertical-align: top; } div.gallery-float { float: left; padding: 10px; } div.gallery-float img { border-style: none; } div.gallery-spacer { clear: both; } a, a:visited { text-decoration: none; /* tango:sky blue 2 */ color: #3465a4; } a:hover { text-decoration: underline; /* tango:sky blue 1 */ color: #729fcf; } div.informaltable table { border-collapse: separate; border-spacing: 1em 0.3em; border: none; } div.informaltable table td, div.informaltable table th { vertical-align: top; } .function_type, .variable_type, .property_type, .signal_type, .parameter_name, .struct_member_name, .union_member_name, .define_keyword, .datatype_keyword, .typedef_keyword { text-align: right; } /* dim non-primary columns */ .c_punctuation, .function_type, .variable_type, .property_type, .signal_type, .define_keyword, .datatype_keyword, .typedef_keyword, .property_flags, .signal_flags, .parameter_annotations, .enum_member_annotations, .struct_member_annotations, .union_member_annotations { color: #888a85; } .function_type a, .function_type a:visited, .function_type a:hover, .property_type a, .property_type a:visited, .property_type a:hover, .signal_type a, .signal_type a:visited, .signal_type a:hover, .signal_flags a, .signal_flags a:visited, .signal_flags a:hover { color: #729fcf; } td p { margin: 0.25em; } div.table table { border-collapse: collapse; border-spacing: 0px; /* tango:aluminium 3 */ border: solid 1px #babdb6; } div.table table td, div.table table th { /* tango:aluminium 3 */ border: solid 1px #babdb6; padding: 3px; vertical-align: top; } div.table table th { /* tango:aluminium 2 */ background-color: #d3d7cf; } h4 { color: #555753; margin-top: 1em; margin-bottom: 1em; } hr { /* tango:aluminium 1 */ color: #d3d7cf; background: #d3d7cf; border: none 0px; height: 1px; clear: both; margin: 2.0em 0em 2.0em 0em; } dl.toc dt { padding-bottom: 0.25em; } dl.toc > dt { padding-top: 0.25em; padding-bottom: 0.25em; font-weight: bold; } dl.toc > dl { padding-bottom: 0.5em; } .parameter { font-style: normal; } .footer { padding-top: 3.5em; /* tango:aluminium 3 */ color: #babdb6; text-align: center; font-size: 80%; } .informalfigure, .figure { margin: 1em; } .informalexample, .example { margin-top: 1em; margin-bottom: 1em; } .warning { /* tango:orange 0/1 */ background: #ffeed9; background: rgba(252, 175, 62, 0.1); border-color: #ffb04f; border-color: rgba(252, 175, 62, 0.2); } .note { /* tango:chameleon 0/0.5 */ background: #d8ffb2; background: rgba(138, 226, 52, 0.1); border-color: #abf562; border-color: rgba(138, 226, 52, 0.2); } div.blockquote { border-color: #eeeeec; } .note, .warning, div.blockquote { padding: 0.5em; border-width: 1px; border-style: solid; margin: 2em; } .note p, .warning p { margin: 0; } div.warning h3.title, div.note h3.title { display: none; } p + div.section { margin-top: 1em; } div.refnamediv, div.refsynopsisdiv, div.refsect1, div.refsect2, div.toc, div.section { margin-bottom: 1em; } /* blob links */ h2 .extralinks, h3 .extralinks { float: right; /* tango:aluminium 3 */ color: #babdb6; font-size: 80%; font-weight: normal; } .lineart { color: #d3d7cf; font-weight: normal; } .annotation { /* tango:aluminium 5 */ color: #555753; font-weight: normal; } .structfield { font-style: normal; font-weight: normal; } acronym,abbr { border-bottom: 1px dotted gray; } /* code listings */ .listing_code .programlisting .normal, .listing_code .programlisting .normal a, .listing_code .programlisting .number, .listing_code .programlisting .cbracket, .listing_code .programlisting .symbol { color: #555753; } .listing_code .programlisting .comment, .listing_code .programlisting .linenum { color: #babdb6; } /* tango: aluminium 3 */ .listing_code .programlisting .function, .listing_code .programlisting .function a, .listing_code .programlisting .preproc { color: #204a87; } /* tango: sky blue 3 */ .listing_code .programlisting .string { color: #ad7fa8; } /* tango: plum */ .listing_code .programlisting .keyword, .listing_code .programlisting .usertype, .listing_code .programlisting .type, .listing_code .programlisting .type a { color: #4e9a06; } /* tango: chameleon 3 */ .listing_frame { /* tango:sky blue 1 */ border: solid 1px #729fcf; border: solid 1px rgba(114, 159, 207, 0.2); padding: 0px; } .listing_lines, .listing_code { margin-top: 0px; margin-bottom: 0px; padding: 0.5em; } .listing_lines { /* tango:sky blue 0.5 */ background: #a6c5e3; background: rgba(114, 159, 207, 0.2); /* tango:aluminium 6 */ color: #2e3436; } .listing_code { /* tango:sky blue 0 */ background: #e6f3ff; background: rgba(114, 159, 207, 0.1); } .listing_code .programlisting { /* override from previous */ border: none 0px; padding: 0px; background: none; } .listing_lines pre, .listing_code pre { margin: 0px; } @media screen { /* these have a as a first child, but since there are no parent selectors * we can't use that. */ a.footnote { position: relative; top: 0em ! important; } /* this is needed so that the local anchors are displayed below the naviagtion */ div.footnote a[name], div.refnamediv a[name], div.refsect1 a[name], div.refsect2 a[name], div.index a[name], div.glossary a[name], div.sect1 a[name] { display: inline-block; position: relative; top:-5em; } /* this seems to be a bug in the xsl style sheets when generating indexes */ div.index div.index { top: 0em; } /* make space for the fixed navigation bar and add space at the bottom so that * link targets appear somewhat close to top */ body { padding-top: 2.5em; padding-bottom: 500px; max-width: 60em; } p { max-width: 60em; } /* style and size the navigation bar */ table.navigation#top { position: fixed; background: #e2e2e2; border-bottom: solid 1px #babdb6; border-spacing: 5px; margin-top: 0; margin-bottom: 0; top: 0; left: 0; z-index: 10; } table.navigation#top td { padding-left: 6px; padding-right: 6px; } .navigation a, .navigation a:visited { /* tango:sky blue 3 */ color: #204a87; } .navigation a:hover { /* tango:sky blue 2 */ color: #3465a4; } td.shortcuts { /* tango:sky blue 2 */ color: #3465a4; font-size: 80%; white-space: nowrap; } td.shortcuts .dim { color: #babdb6; } .navigation .title { font-size: 80%; max-width: none; margin: 0px; font-weight: normal; } } @media screen and (min-width: 60em) { /* screen larger than 60em */ body { margin: auto; } } @media screen and (max-width: 60em) { /* screen less than 60em */ #nav_hierarchy { display: none; } #nav_interfaces { display: none; } #nav_prerequisites { display: none; } #nav_derived_interfaces { display: none; } #nav_implementations { display: none; } #nav_child_properties { display: none; } #nav_style_properties { display: none; } #nav_index { display: none; } #nav_glossary { display: none; } .gallery_image { display: none; } .property_flags { display: none; } .signal_flags { display: none; } .parameter_annotations { display: none; } .enum_member_annotations { display: none; } .struct_member_annotations { display: none; } .union_member_annotations { display: none; } /* now that a column is hidden, optimize space */ col.parameters_name { width: auto; } col.parameters_description { width: auto; } col.struct_members_name { width: auto; } col.struct_members_description { width: auto; } col.enum_members_name { width: auto; } col.enum_members_description { width: auto; } col.union_members_name { width: auto; } col.union_members_description { width: auto; } .listing_lines { display: none; } } @media print { table.navigation { visibility: collapse; display: none; } div.titlepage table.navigation { visibility: visible; display: table; background: #e2e2e2; border: solid 1px #babdb6; margin-top: 0; margin-bottom: 0; top: 0; left: 0; height: 3em; } } libnice-0.1.14/docs/reference/libnice/html/libnice-Bind.html0000664000076400007640000004720713070512356020555 00000000000000 Bind: libnice Reference Manual

Bind

Bind — STUN Binding Usage

Stability Level

Stable, unless otherwise indicated

Types and Values

Includes

#include <stun/usages/bind.h>

Description

The STUN Binding usage allows for easily creating and parsing STUN Binding requests and responses. It offers both an asynchronous and a synchronous API that uses the STUN timer usage.

Functions

stun_usage_bind_create ()

size_t
stun_usage_bind_create (StunAgent *agent,
                        StunMessage *msg,
                        uint8_t *buffer,
                        size_t buffer_len);

Create a new STUN binding request to use with a STUN server.

Parameters

agent

The StunAgent to use to create the binding request

 

msg

The StunMessage to build

 

buffer

The buffer to use for creating the StunMessage

 

buffer_len

The size of the buffer

 

Returns

The length of the built message.


stun_usage_bind_process ()

StunUsageBindReturn
stun_usage_bind_process (StunMessage *msg,
                         struct sockaddr *addr,
                         socklen_t *addrlen,
                         struct sockaddr *alternate_server,
                         socklen_t *alternate_server_len);

Process a STUN binding response and extracts the mapped address from the STUN message. Also checks for the ALTERNATE-SERVER attribute.

Parameters

msg

The StunMessage to process

 

addr

A pointer to a sockaddr structure to fill with the mapped address that the STUN server gives us

 

addrlen

The length of add . rMust be set to the size of the addr socket address and will be set to the actual length of the socket address.

 

alternate_server

A pointer to a sockaddr structure to fill with the address of an alternate server to which we should send our new STUN binding request, in case the currently used STUN server is requesting the use of an alternate server. This argument will only be filled if the return value of the function is STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER

 

alternate_server_len

The length of alternate_server . Must be set to the size of the alternate_server socket address and will be set to the actual length of the socket address.

 

Returns

A StunUsageBindReturn value. Note that STUN_USAGE_BIND_RETURN_TIMEOUT cannot be returned by this function


stun_usage_bind_keepalive ()

size_t
stun_usage_bind_keepalive (StunAgent *agent,
                           StunMessage *msg,
                           uint8_t *buf,
                           size_t len);

Creates a STUN binding indication that can be used for a keepalive. Since this is an indication message, no STUN response will be generated and it can only be used as a keepalive message.

Parameters

agent

The StunAgent to use to build the message

 

msg

The StunMessage to build

 

buf

The buffer to use for creating the StunMessage

 

len

The size of the buf

 

Returns

The length of the message to send


stun_usage_bind_run ()

StunUsageBindReturn
stun_usage_bind_run (const struct sockaddr *srv,
                     socklen_t srvlen,
                     struct sockaddr_storage *addr,
                     socklen_t *addrlen);

This is a convenience function that will do a synchronous Binding request to a server and wait for its answer. It will create the socket transports and use the StunTimer usage to send the request and handle the response.

Parameters

srv

A pointer to the sockaddr structure representing the STUN server's address

 

srvlen

The length of srv

 

addr

A pointer to a sockaddr structure to fill with the mapped address that the STUN server gives us

 

addrlen

The length of addr

 

Types and Values

enum StunUsageBindReturn

Return value of stun_usage_bind_process() and stun_usage_bind_run() which allows you to see what status the function call returned.

Members

STUN_USAGE_BIND_RETURN_SUCCESS

The binding usage succeeded

 

STUN_USAGE_BIND_RETURN_ERROR

There was an unknown error in the bind usage

 

STUN_USAGE_BIND_RETURN_INVALID

The message is invalid and should be ignored

 

STUN_USAGE_BIND_RETURN_ALTERNATE_SERVER

The binding request has an ALTERNATE-SERVER attribute

 

STUN_USAGE_BIND_RETURN_TIMEOUT

The binding was unsuccessful because it has timed out.

 
libnice-0.1.14/docs/reference/libnice/html/annotation-glossary.html0000664000076400007640000001365513070512356022311 00000000000000 Annotation Glossary: libnice Reference Manual

Annotation Glossary

A

allow-none

NULL is OK, both for passing and for returning.

array

Parameter points to an array of items.

E

element-type

Generics and defining elements of containers and arrays.

I

in

Parameter for input. Default is transfer none.

N

nullable

NULL may be passed as the value in, out, in-out; or as a return value.

O

out callee-allocates

Out parameter, where caller must allocate storage.

out caller-allocates

Out parameter, where caller must allocate storage.

S

skip

Exposed in C code, not necessarily available in other languages.

Stable

The intention of a Stable interface is to enable arbitrary third parties to develop applications to these interfaces, release them, and have confidence that they will run on all minor releases of the product (after the one in which the interface was introduced, and within the same major release). Even at a major release, incompatible changes are expected to be rare, and to have strong justifications.

T

transfer full

Free data after the code is done.

transfer none

Don't free data after the code is done.

U

Unstable

Unstable interfaces are experimental or transitional. They are typically used to give outside developers early access to new or rapidly changing technology, or to provide an interim solution to a problem where a more general solution is anticipated. No claims are made about either source or binary compatibility from one minor release to the next. The Unstable interface level is a warning that these interfaces are subject to change without warning and should not be used in unbundled products. Given such caveats, customer impact need not be a factor when considering incompatible changes to an Unstable interface in a major or minor release. Nonetheless, when such changes are introduced, the changes should still be mentioned in the release notes for the affected release.

libnice-0.1.14/docs/reference/libnice/html/libnice.devhelp20000664000076400007640000020070013070512356020435 00000000000000 libnice-0.1.14/docs/reference/libnice/html/up-insensitive.png0000644000076400007640000000056613070512356021073 00000000000000PNG  IHDRabKGD pHYs B(xtIMEwIIDAT8?/Qϙ?[u$VHTDۈBM+! ICE: libnice Reference Manual

ICE

ICE — STUN ICE Usage

Stability Level

Stable, unless otherwise indicated

Types and Values

Includes

#include <stun/usages/ice.h>

Description

The STUN ICE usage allows for easily creating and parsing STUN Binding requests and responses used for ICE connectivity checks. The API allows you to create a connectivity check message, parse a response or create a reply to an incoming connectivity check request.

Functions

stun_usage_ice_conncheck_create ()

size_t
stun_usage_ice_conncheck_create (StunAgent *agent,
                                 StunMessage *msg,
                                 uint8_t *buffer,
                                 size_t buffer_len,
                                 const uint8_t *username,
                                 const size_t username_len,
                                 const uint8_t *password,
                                 const size_t password_len,
                                 bool cand_use,
                                 bool controlling,
                                 uint32_t priority,
                                 uint64_t tie,
                                 const char *candidate_identifier,
                                 StunUsageIceCompatibility compatibility);

Builds an ICE connectivity check STUN message. If the compatibility is not STUN_USAGE_ICE_COMPATIBILITY_RFC5245, the cand_use , controlling , priority and tie arguments are not used. If the compatibility is not STUN_USAGE_ICE_COMPATIBILITY_MSICE2, the candidate_identifier argument is not used.

Parameters

agent

The StunAgent to use to build the request

 

msg

The StunMessage to build

 

buffer

The buffer to use for creating the StunMessage

 

buffer_len

The size of the buffer

 

username

The username to use in the request

 

username_len

The length of username

 

password

The key to use for building the MESSAGE-INTEGRITY

 

password_len

The length of password

 

cand_use

Set to TRUE to append the USE-CANDIDATE flag to the request

 

controlling

Set to TRUE if you are the controlling agent or set to FALSE if you are the controlled agent.

 

priority

The value of the PRIORITY attribute

 

tie

The value of the tie-breaker to put in the ICE-CONTROLLED or ICE-CONTROLLING attribute

 

candidate_identifier

The foundation value to put in the CANDIDATE-IDENTIFIER attribute

 

compatibility

The compatibility mode to use for building the conncheck request

 

Returns

The length of the message built.


stun_usage_ice_conncheck_process ()

StunUsageIceReturn
stun_usage_ice_conncheck_process (StunMessage *msg,
                                  struct sockaddr_storage *addr,
                                  socklen_t *addrlen,
                                  StunUsageIceCompatibility compatibility);

Process an ICE connectivity check STUN message and retreive the mapped address from the message

See also stun_usage_ice_conncheck_priority() and stun_usage_ice_conncheck_use_candidate()

Parameters

msg

The StunMessage to process

 

addr

A pointer to a sockaddr structure to fill with the mapped address that the STUN connectivity check response contains

 

addrlen

The length of addr

 

compatibility

The compatibility mode to use for processing the conncheck response

 

Returns

A StunUsageIceReturn value


stun_usage_ice_conncheck_create_reply ()

StunUsageIceReturn
stun_usage_ice_conncheck_create_reply (StunAgent *agent,
                                       StunMessage *req,
                                       StunMessage *msg,
                                       uint8_t *buf,
                                       size_t *plen,
                                       const struct sockaddr_storage *src,
                                       socklen_t srclen,
                                       bool *control,
                                       uint64_t tie,
                                       StunUsageIceCompatibility compatibility);

Tries to parse a STUN connectivity check request and builds a response accordingly.

In case of error, the msg is filled with the appropriate error response to be sent and the value of plen is set to the size of that message. If plen has a size of 0, then no error response should be sent.

Parameters

agent

The StunAgent to use to build the response

 

req

The original STUN request to reply to

 

msg

The StunMessage to build

 

buf

The buffer to use for creating the StunMessage

 

plen

A pointer containing the size of the buffer on input. Will contain the length of the message built on output.

 

src

A pointer to a sockaddr structure containing the source address from which the request was received. Will be used as the mapped address in the response

 

srclen

The length of addr

 

control

Set to TRUE if you are the controlling agent or set to FALSE if you are the controlled agent.

 

tie

The value of the tie-breaker to put in the ICE-CONTROLLED or ICE-CONTROLLING attribute

 

compatibility

The compatibility mode to use for building the conncheck response

 

Returns

A StunUsageIceReturn value


stun_usage_ice_conncheck_priority ()

uint32_t
stun_usage_ice_conncheck_priority (const StunMessage *msg);

Extracts the priority from a STUN message.

Parameters

msg

The StunMessage to parse

 

Returns

host byte order priority, or 0 if not specified.


stun_usage_ice_conncheck_use_candidate ()

bool
stun_usage_ice_conncheck_use_candidate
                               (const StunMessage *msg);

Extracts the USE-CANDIDATE attribute flag from a STUN message.

Parameters

msg

The StunMessage to parse

 

Returns

TRUE if the flag is set, FALSE if not.

Types and Values

enum StunUsageIceCompatibility

This enum defines which compatibility modes this ICE usage can use

STUN_USAGE_ICE_COMPATIBILITY_DRAFT19 and STUN_USAGE_ICE_COMPATIBILITY_WLM2009 are deprecated and should not be used in newly-written code. They are kept for compatibility reasons and represent the same compatibilities as STUN_USAGE_ICE_COMPATIBILITY_RFC5245 and STUN_USAGE_ICE_COMPATIBILITY_MSICE2 respectively.

Members

STUN_USAGE_ICE_COMPATIBILITY_RFC5245

The ICE compatibility with RFC 5245

 

STUN_USAGE_ICE_COMPATIBILITY_GOOGLE

The ICE compatibility with Google's implementation of ICE

 

STUN_USAGE_ICE_COMPATIBILITY_MSN

The ICE compatibility with MSN's implementation of ICE

 

STUN_USAGE_ICE_COMPATIBILITY_MSICE2

The ICE compatibility with [MS-ICE2] specification

 

STUN_USAGE_ICE_COMPATIBILITY_DRAFT19

The ICE compatibility with draft 19

 

STUN_USAGE_ICE_COMPATIBILITY_WLM2009

An alias for STUN_USAGE_ICE_COMPATIBILITY_MSICE2

 

enum StunUsageIceReturn

Return value of stun_usage_ice_conncheck_process() and stun_usage_ice_conncheck_create_reply() which allows you to see what status the function call returned.

Members

STUN_USAGE_ICE_RETURN_SUCCESS

The function succeeded

 

STUN_USAGE_ICE_RETURN_ERROR

There was an unspecified error

 

STUN_USAGE_ICE_RETURN_INVALID

The message is invalid for processing

 

STUN_USAGE_ICE_RETURN_ROLE_CONFLICT

A role conflict was detected

 

STUN_USAGE_ICE_RETURN_INVALID_REQUEST

The message is an not a request

 

STUN_USAGE_ICE_RETURN_INVALID_METHOD

The method of the request is invalid

 

STUN_USAGE_ICE_RETURN_MEMORY_ERROR

The buffer size is too small to hold the STUN reply

 

STUN_USAGE_ICE_RETURN_INVALID_ADDRESS

The mapped address argument has an invalid address family

 

STUN_USAGE_ICE_RETURN_NO_MAPPED_ADDRESS

The response is valid but no MAPPED-ADDRESS or XOR-MAPPED-ADDRESS attribute was found

 
libnice-0.1.14/docs/reference/libnice/html/libnice-StunMessage.html0000664000076400007640000035514413070512356022141 00000000000000 StunMessage: libnice Reference Manual

StunMessage

StunMessage — STUN messages parsing and formatting functions

Stability Level

Stable, unless otherwise indicated

Includes

#include <stun/stunmessage.h>

Description

The STUN Messages API allows you to create STUN messages easily as well as to parse existing messages.

Functions

stun_message_init ()

bool
stun_message_init (StunMessage *msg,
                   StunClass c,
                   StunMethod m,
                   const StunTransactionId id);

Initializes a STUN message buffer, with no attributes.

Parameters

msg

The StunMessage to initialize

 

c

STUN message class (host byte order)

 

m

STUN message method (host byte order)

 

id

16-bytes transaction ID

 

Returns

TRUE if the initialization was successful


stun_message_length ()

uint16_t
stun_message_length (const StunMessage *msg);

Get the length of the message (including the header)

Parameters

msg

The StunMessage

 

Returns

The length of the message


stun_message_find ()

const void *
stun_message_find (const StunMessage *msg,
                   StunAttribute type,
                   uint16_t *palen);

Finds an attribute in a STUN message and fetches its content

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

palen

A pointer to store the length of the attribute

 

Returns

A pointer to the start of the attribute payload if found, otherwise NULL.


stun_message_find_flag ()

StunMessageReturn
stun_message_find_flag (const StunMessage *msg,
                        StunAttribute type);

Looks for a flag attribute within a valid STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not zero.


stun_message_find32 ()

StunMessageReturn
stun_message_find32 (const StunMessage *msg,
                     StunAttribute type,
                     uint32_t *pval);

Extracts a 32-bits attribute from a STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

pval

A pointer where to store the value (host byte order)

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not 4 bytes.


stun_message_find64 ()

StunMessageReturn
stun_message_find64 (const StunMessage *msg,
                     StunAttribute type,
                     uint64_t *pval);

Extracts a 64-bits attribute from a STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

pval

A pointer where to store the value (host byte order)

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not 8 bytes.


stun_message_find_string ()

StunMessageReturn
stun_message_find_string (const StunMessage *msg,
                          StunAttribute type,
                          char *buf,
                          size_t buflen);

Extracts an UTF-8 string from a valid STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

buf

A pointer where to store the data

 

buflen

The length of the buffer

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the attribute is improperly encoded STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE is return if the buffer size is too small to hold the string

The string will be nul-terminated.


stun_message_find_addr ()

StunMessageReturn
stun_message_find_addr (const StunMessage *msg,
                        StunAttribute type,
                        struct sockaddr_storage *addr,
                        socklen_t *addrlen);

Extracts a network address attribute from a STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

addr

The sockaddr to be filled

 

addrlen

The size of the addr variable. Must be set to the size of the addr socket address and will be set to the size of the extracted socket address.

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is wrong or if the addrlen is too small STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.


stun_message_find_xor_addr ()

StunMessageReturn
stun_message_find_xor_addr (const StunMessage *msg,
                            StunAttribute type,
                            struct sockaddr_storage *addr,
                            socklen_t *addrlen);

Extracts an obfuscated network address attribute from a STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

addr

The sockaddr to be filled

 

addrlen

The size of the addr variable. Must be set to the size of the addr socket address and will be set to the size of the extracted socket address.

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is wrong or if the addrlen is too small STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.


stun_message_find_xor_addr_full ()

StunMessageReturn
stun_message_find_xor_addr_full (const StunMessage *msg,
                                 StunAttribute type,
                                 struct sockaddr_storage *addr,
                                 socklen_t *addrlen,
                                 uint32_t magic_cookie);

Extracts an obfuscated network address attribute from a STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to find

 

addr

The sockaddr to be filled

 

addrlen

The size of the addr variable. Must be set to the size of the addr socket address and will be set to the size of the extracted socket address.

 

magic_cookie

The magic cookie to use to XOR the address.

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is wrong or if the addrlen is too small STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.


stun_message_find_error ()

StunMessageReturn
stun_message_find_error (const StunMessage *msg,
                         int *code);

Extract the error response code from a STUN message

Parameters

msg

The StunMessage

 

code

A pointer where to store the value

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the value is invalid


stun_message_append ()

void *
stun_message_append (StunMessage *msg,
                     StunAttribute type,
                     size_t length);

Reserves room for appending an attribute to an unfinished STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

length

The length of the attribute

 

Returns

A pointer to an unitialized buffer of length bytes to where the attribute payload must be written, or NULL if there is not enough room in the STUN message buffer.


stun_message_append_bytes ()

StunMessageReturn
stun_message_append_bytes (StunMessage *msg,
                           StunAttribute type,
                           const void *data,
                           size_t len);

Appends a binary value to a STUN message

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

data

The data to append

 

len

The length of the attribute

 

Returns

A StunMessageReturn value.


stun_message_append_flag ()

StunMessageReturn
stun_message_append_flag (StunMessage *msg,
                          StunAttribute type);

Appends an empty flag attribute to a STUN message

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

Returns

A StunMessageReturn value.


stun_message_append32 ()

StunMessageReturn
stun_message_append32 (StunMessage *msg,
                       StunAttribute type,
                       uint32_t value);

Appends a 32-bits value attribute to a STUN message

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

value

The value to append (host byte order)

 

Returns

A StunMessageReturn value.


stun_message_append64 ()

StunMessageReturn
stun_message_append64 (StunMessage *msg,
                       StunAttribute type,
                       uint64_t value);

Appends a 64-bits value attribute to a STUN message

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

value

The value to append (host byte order)

 

Returns

A StunMessageReturn value.


stun_message_append_string ()

StunMessageReturn
stun_message_append_string (StunMessage *msg,
                            StunAttribute type,
                            const char *str);

Adds an attribute from a nul-terminated string to a STUN message

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

str

The string to append

 

Returns

A StunMessageReturn value.


stun_message_append_addr ()

StunMessageReturn
stun_message_append_addr (StunMessage *msg,
                          StunAttribute type,
                          const struct sockaddr *addr,
                          socklen_t addrlen);

Append a network address attribute to a STUN message

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

addr

The sockaddr to be append

 

addrlen

The size of the addr variable.

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the addrlen is too small STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.


stun_message_append_xor_addr ()

StunMessageReturn
stun_message_append_xor_addr (StunMessage *msg,
                              StunAttribute type,
                              const struct sockaddr_storage *addr,
                              socklen_t addrlen);

Append an obfuscated network address attribute to a STUN message

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

addr

The sockaddr to be append

 

addrlen

The size of the addr variable.

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the addrlen is too small STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.


stun_message_append_xor_addr_full ()

StunMessageReturn
stun_message_append_xor_addr_full (StunMessage *msg,
                                   StunAttribute type,
                                   const struct sockaddr_storage *addr,
                                   socklen_t addrlen,
                                   uint32_t magic_cookie);

Append an obfuscated network address attribute from a STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to append

 

addr

The sockaddr to be append

 

addrlen

The size of the addr variable.

 

magic_cookie

The magic cookie to use to XOR the address.

 

Returns

A StunMessageReturn value. STUN_MESSAGE_RETURN_INVALID is returned if the addrlen is too small STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.


stun_message_append_error ()

StunMessageReturn
stun_message_append_error (StunMessage *msg,
                           StunError code);

Appends the ERROR-CODE attribute to the STUN message and fills it according to code

Parameters

msg

The StunMessage

 

code

The error code value

 

Returns

A StunMessageReturn value.


stun_message_validate_buffer_length ()

int
stun_message_validate_buffer_length (const uint8_t *msg,
                                     size_t length,
                                     bool has_padding);

This function will take a data buffer and will try to validate whether it is a STUN message or if it's not or if it's an incomplete STUN message and will provide us with the length of the STUN message.

Parameters

msg

The buffer to validate

 

length

The length of the buffer

 

has_padding

Set TRUE if attributes should be padded to multiple of 4 bytes

 

Returns

The length of the valid STUN message in the buffer.

See also: STUN_MESSAGE_BUFFER_INCOMPLETE

See also: STUN_MESSAGE_BUFFER_INVALID


stun_message_validate_buffer_length_fast ()

ssize_t
stun_message_validate_buffer_length_fast
                               (StunInputVector *buffers,
                                int n_buffers,
                                size_t total_length,
                                bool has_padding);

Quickly validate whether the message in the given buffers is potentially a valid STUN message, an incomplete STUN message, or if it’s definitely not one at all.

This is designed as a first-pass validation only, and does not check the message’s attributes for validity. If this function returns success, the buffers can be compacted and a more thorough validation can be performed using stun_message_validate_buffer_length(). If it fails, the buffers definitely do not contain a complete, valid STUN message.

Parameters

buffers

array of contiguous StunInputVectors containing already-received message data.

[array length=n_buffers][in caller-allocated]

n_buffers

number of entries in buffers or if -1 , then buffers is terminated by a StunInputVector with the buffer pointer being NULL.

 

total_length

total number of valid bytes stored consecutively in buffers

 

has_padding

TRUE if attributes should be padded to 4-byte boundaries

 

Returns

The length of the valid STUN message in the buffer, or zero or -1 on failure

See also: STUN_MESSAGE_BUFFER_INCOMPLETE

See also: STUN_MESSAGE_BUFFER_INVALID

Since: 0.1.5


stun_message_id ()

void
stun_message_id (const StunMessage *msg,
                 StunTransactionId id);

Retreive the STUN transaction id from a STUN message

Parameters

msg

The StunMessage

 

id

The StunTransactionId to fill

 

stun_message_get_class ()

StunClass
stun_message_get_class (const StunMessage *msg);

Retreive the STUN class from a STUN message

Parameters

msg

The StunMessage

 

Returns

The StunClass


stun_message_get_method ()

StunMethod
stun_message_get_method (const StunMessage *msg);

Retreive the STUN method from a STUN message

Parameters

msg

The StunMessage

 

Returns

The StunMethod


stun_message_has_attribute ()

bool
stun_message_has_attribute (const StunMessage *msg,
                            StunAttribute type);

Checks if an attribute is present within a STUN message.

Parameters

msg

The StunMessage

 

type

The StunAttribute to look for

 

Returns

TRUE if the attribute is found, FALSE otherwise


stun_message_has_cookie ()

bool
stun_message_has_cookie (const StunMessage *msg);

Checks if the STUN message has a RFC5389 compatible cookie

Parameters

msg

The StunMessage

 

Returns

TRUE if the cookie is present, FALSE otherwise


stun_optional ()

bool
stun_optional (uint16_t t);

Helper function that checks whether a STUN attribute is a mandatory or an optional attribute

Parameters

t

An attribute type

 

Returns

TRUE if the attribute is an optional one


stun_strerror ()

const char *
stun_strerror (StunError code);

Transforms a STUN error-code into a human readable string

Parameters

code

host-byte order error code

 

Returns

A static pointer to a nul-terminated error message string.

Types and Values

struct StunMessage

struct StunMessage {
  StunAgent *agent;
  uint8_t *buffer;
  size_t buffer_len;
  uint8_t *key;
  size_t key_len;
  uint8_t long_term_key[16];
  bool long_term_valid;
};

This structure represents a STUN message

Members

StunAgent *agent;

The agent that created or validated this message

 

uint8_t *buffer;

The buffer containing the STUN message

 

size_t buffer_len;

The length of the buffer (not the size of the message)

 

uint8_t *key;

The short term credentials key to use for authentication validation or that was used to finalize this message

 

size_t key_len;

The length of the associated key

 

uint8_t long_term_key[16];

The long term credential key to use for authentication validation or that was used to finalize this message

 

bool long_term_valid;

Whether or not the long_term_key variable contains valid data

 

enum StunClass

This enum is used to represent the class of a STUN message, as defined in RFC5389

Members

STUN_REQUEST

A STUN Request message

 

STUN_INDICATION

A STUN indication message

 

STUN_RESPONSE

A STUN Response message

 

STUN_ERROR

A STUN Error message

 

enum StunMethod

This enum is used to represent the method of a STUN message, as defined by various RFCs

Members

STUN_BINDING

The Binding method as defined by the RFC5389

 

STUN_SHARED_SECRET

The Shared-Secret method as defined by the RFC3489

 

STUN_ALLOCATE

The Allocate method as defined by the TURN draft 12

 

STUN_SET_ACTIVE_DST

The Set-Active-Destination method as defined by the TURN draft 4

 

STUN_REFRESH

The Refresh method as defined by the TURN draft 12

 

STUN_SEND

The Send method as defined by the TURN draft 00

 

STUN_CONNECT

The Connect method as defined by the TURN draft 4

 

STUN_OLD_SET_ACTIVE_DST

The older Set-Active-Destination method as defined by the TURN draft 0

 

STUN_IND_SEND

The Send method used in indication messages as defined by the TURN draft 12

 

STUN_IND_DATA

The Data method used in indication messages as defined by the TURN draft 12

 

STUN_IND_CONNECT_STATUS

The Connect-Status method used in indication messages as defined by the TURN draft 4

 

STUN_CREATEPERMISSION

The CreatePermission method as defined by the TURN draft 12

 

STUN_CHANNELBIND

The ChannelBind method as defined by the TURN draft 12

 

enum StunAttribute

Known STUN attribute types as defined by various RFCs and drafts

Members

STUN_ATTRIBUTE_MAPPED_ADDRESS

The MAPPED-ADDRESS attribute as defined by RFC5389

 

STUN_ATTRIBUTE_RESPONSE_ADDRESS

The RESPONSE-ADDRESS attribute as defined by RFC3489

 

STUN_ATTRIBUTE_CHANGE_REQUEST

The CHANGE-REQUEST attribute as defined by RFC3489

 

STUN_ATTRIBUTE_SOURCE_ADDRESS

The SOURCE-ADDRESS attribute as defined by RFC3489

 

STUN_ATTRIBUTE_CHANGED_ADDRESS

The CHANGED-ADDRESS attribute as defined by RFC3489

 

STUN_ATTRIBUTE_USERNAME

The USERNAME attribute as defined by RFC5389

 

STUN_ATTRIBUTE_PASSWORD

The PASSWORD attribute as defined by RFC3489

 

STUN_ATTRIBUTE_MESSAGE_INTEGRITY

The MESSAGE-INTEGRITY attribute as defined by RFC5389

 

STUN_ATTRIBUTE_ERROR_CODE

The ERROR-CODE attribute as defined by RFC5389

 

STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES

The UNKNOWN-ATTRIBUTES attribute as defined by RFC5389

 

STUN_ATTRIBUTE_REFLECTED_FROM

The REFLECTED-FROM attribute as defined by RFC3489

 

STUN_ATTRIBUTE_CHANNEL_NUMBER

The CHANNEL-NUMBER attribute as defined by TURN draft 09 and 12

 

STUN_ATTRIBUTE_LIFETIME

The LIFETIME attribute as defined by TURN draft 04, 09 and 12

 

STUN_ATTRIBUTE_MS_ALTERNATE_SERVER

The ALTERNATE-SERVER attribute as defined by [MS-TURN]

 

STUN_ATTRIBUTE_MAGIC_COOKIE

The MAGIC-COOKIE attribute as defined by the rosenberg-midcom TURN draft 08

 

STUN_ATTRIBUTE_BANDWIDTH

The BANDWIDTH attribute as defined by TURN draft 04

 

STUN_ATTRIBUTE_DESTINATION_ADDRESS

The DESTINATION-ADDRESS attribute as defined by the rosenberg-midcom TURN draft 08

 

STUN_ATTRIBUTE_REMOTE_ADDRESS

The REMOTE-ADDRESS attribute as defined by TURN draft 04

 

STUN_ATTRIBUTE_PEER_ADDRESS

The PEER-ADDRESS attribute as defined by TURN draft 09

 

STUN_ATTRIBUTE_XOR_PEER_ADDRESS

The XOR-PEER-ADDRESS attribute as defined by TURN draft 12

 

STUN_ATTRIBUTE_DATA

The DATA attribute as defined by TURN draft 04, 09 and 12

 

STUN_ATTRIBUTE_REALM

The REALM attribute as defined by RFC5389

 

STUN_ATTRIBUTE_NONCE

The NONCE attribute as defined by RFC5389

 

STUN_ATTRIBUTE_RELAY_ADDRESS

The RELAY-ADDRESS attribute as defined by TURN draft 04

 

STUN_ATTRIBUTE_RELAYED_ADDRESS

The RELAYED-ADDRESS attribute as defined by TURN draft 09

 

STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS

The XOR-RELAYED-ADDRESS attribute as defined by TURN draft 12

 

STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE

The REQUESTED-ADDRESS-TYPE attribute as defined by TURN-IPV6 draft 05

 

STUN_ATTRIBUTE_REQUESTED_PORT_PROPS

The REQUESTED-PORT-PROPS attribute as defined by TURN draft 04

 

STUN_ATTRIBUTE_REQUESTED_PROPS

The REQUESTED-PROPS attribute as defined by TURN draft 09

 

STUN_ATTRIBUTE_EVEN_PORT

The EVEN-PORT attribute as defined by TURN draft 12

 

STUN_ATTRIBUTE_REQUESTED_TRANSPORT

The REQUESTED-TRANSPORT attribute as defined by TURN draft 12

 

STUN_ATTRIBUTE_DONT_FRAGMENT

The DONT-FRAGMENT attribute as defined by TURN draft 12

 

STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS

The XOR-MAPPED-ADDRESS attribute as defined by RFC5389

 

STUN_ATTRIBUTE_TIMER_VAL

The TIMER-VAL attribute as defined by TURN draft 04

 

STUN_ATTRIBUTE_REQUESTED_IP

The REQUESTED-IP attribute as defined by TURN draft 04

 

STUN_ATTRIBUTE_RESERVATION_TOKEN

The RESERVATION-TOKEN attribute as defined by TURN draft 09 and 12

 

STUN_ATTRIBUTE_CONNECT_STAT

The CONNECT-STAT attribute as defined by TURN draft 04

 

STUN_ATTRIBUTE_PRIORITY

The PRIORITY attribute as defined by ICE draft 19

 

STUN_ATTRIBUTE_USE_CANDIDATE

The USE-CANDIDATE attribute as defined by ICE draft 19

 

STUN_ATTRIBUTE_OPTIONS

The OPTIONS optional attribute as defined by libjingle

 

STUN_ATTRIBUTE_MS_VERSION

The MS-VERSION optional attribute as defined by [MS-TURN]

 

STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS

The XOR-MAPPED-ADDRESS optional attribute as defined by [MS-TURN]

 

STUN_ATTRIBUTE_SOFTWARE

The SOFTWARE optional attribute as defined by RFC5389

 

STUN_ATTRIBUTE_ALTERNATE_SERVER

The ALTERNATE-SERVER optional attribute as defined by RFC5389

 

STUN_ATTRIBUTE_FINGERPRINT

The FINGERPRINT optional attribute as defined by RFC5389

 

STUN_ATTRIBUTE_ICE_CONTROLLED

The ICE-CONTROLLED optional attribute as defined by ICE draft 19

 

STUN_ATTRIBUTE_ICE_CONTROLLING

The ICE-CONTROLLING optional attribute as defined by ICE draft 19

 

STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER

The MS-SEQUENCE NUMBER optional attribute as defined by [MS-TURN]

 

STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER

The CANDIDATE-IDENTIFIER optional attribute as defined by [MS-ICE2]

 

STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION

The IMPLEMENTATION-VERSION optional attribute as defined by [MS-ICE2]

 

StunTransactionId

typedef uint8_t StunTransactionId[STUN_MESSAGE_TRANS_ID_LEN];

A type that holds a STUN transaction id.


enum StunError

STUN error codes as defined by various RFCs and drafts

Members

STUN_ERROR_TRY_ALTERNATE

The ERROR-CODE value for the "Try Alternate" error as defined in RFC5389

 

STUN_ERROR_BAD_REQUEST

The ERROR-CODE value for the "Bad Request" error as defined in RFC5389

 

STUN_ERROR_UNAUTHORIZED

The ERROR-CODE value for the "Unauthorized" error as defined in RFC5389

 

STUN_ERROR_UNKNOWN_ATTRIBUTE

The ERROR-CODE value for the "Unknown Attribute" error as defined in RFC5389

 

STUN_ERROR_ALLOCATION_MISMATCH

The ERROR-CODE value for the "Allocation Mismatch" error as defined in TURN draft 12. Equivalent to the "No Binding" error defined in TURN draft 04.

 

STUN_ERROR_STALE_NONCE

The ERROR-CODE value for the "Stale Nonce" error as defined in RFC5389

 

STUN_ERROR_ACT_DST_ALREADY

The ERROR-CODE value for the "Active Destination Already Set" error as defined in TURN draft 04.

 

STUN_ERROR_UNSUPPORTED_FAMILY

The ERROR-CODE value for the "Address Family not Supported" error as defined in TURN IPV6 Draft 05.

 

STUN_ERROR_WRONG_CREDENTIALS

The ERROR-CODE value for the "Wrong Credentials" error as defined in TURN Draft 12.

 

STUN_ERROR_UNSUPPORTED_TRANSPORT

he ERROR-CODE value for the "Unsupported Transport Protocol" error as defined in TURN Draft 12.

 

STUN_ERROR_INVALID_IP

The ERROR-CODE value for the "Invalid IP Address" error as defined in TURN draft 04.

 

STUN_ERROR_INVALID_PORT

The ERROR-CODE value for the "Invalid Port" error as defined in TURN draft 04.

 

STUN_ERROR_OP_TCP_ONLY

The ERROR-CODE value for the "Operation for TCP Only" error as defined in TURN draft 04.

 

STUN_ERROR_CONN_ALREADY

The ERROR-CODE value for the "Connection Already Exists" error as defined in TURN draft 04.

 

STUN_ERROR_ALLOCATION_QUOTA_REACHED

The ERROR-CODE value for the "Allocation Quota Reached" error as defined in TURN draft 12.

 

STUN_ERROR_ROLE_CONFLICT

The ERROR-CODE value for the "Role Conflict" error as defined in ICE draft 19.

 

STUN_ERROR_SERVER_ERROR

The ERROR-CODE value for the "Server Error" error as defined in RFC5389

 

STUN_ERROR_SERVER_CAPACITY

The ERROR-CODE value for the "Insufficient Capacity" error as defined in TURN draft 04.

 

STUN_ERROR_INSUFFICIENT_CAPACITY

The ERROR-CODE value for the "Insufficient Capacity" error as defined in TURN draft 12.

 

STUN_ERROR_MAX

The maximum possible ERROR-CODE value as defined by RFC 5389.

 

enum StunMessageReturn

The return value of most stun_message_* functions. This enum will report on whether an operation was successful or not and what error occured if any.

Members

STUN_MESSAGE_RETURN_SUCCESS

The operation was successful

 

STUN_MESSAGE_RETURN_NOT_FOUND

The attribute was not found

 

STUN_MESSAGE_RETURN_INVALID

The argument or data is invalid

 

STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE

There is not enough space in the message to append data to it, or not enough in an argument to fill it with the data requested.

 

STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS

The address in the arguments or in the STUN message is not supported.

 

STUN_MESSAGE_BUFFER_INCOMPLETE

#define STUN_MESSAGE_BUFFER_INCOMPLETE 0

Convenience macro for stun_message_validate_buffer_length() meaning that the data to validate does not hold a complete STUN message


STUN_MESSAGE_BUFFER_INVALID

#define STUN_MESSAGE_BUFFER_INVALID -1

Convenience macro for stun_message_validate_buffer_length() meaning that the data to validate is not a valid STUN message


StunInputVector

typedef struct {
  const uint8_t *buffer;
  size_t size;
} StunInputVector;

Container for a single buffer which also stores its length. This is designed for vectored I/O: typically an array of StunInputVectors is passed to functions, providing multiple buffers which store logically contiguous received data.

This is guaranteed to be layed out identically in memory to GInputVector.

Members

const uint8_t *buffer;

a buffer containing already-received binary data

 

size_t size;

length of buffer , in bytes

 

Since: 0.1.5

See Also

StunAgent

libnice-0.1.14/docs/reference/libnice/html/pt01.html0000664000076400007640000000521113070512356017047 00000000000000 Part I. ICE Library: libnice Reference Manual

Part I. ICE Library

Table of Contents

NiceAgent — ICE agent API implementation
NiceAddress — IP address convenience library
NiceCandidate — ICE candidate representation
Libnice helper functions
Debug messages — Debug messages utility functions
Network interfaces discovery — Utility functions to discover local network interfaces
libnice-0.1.14/docs/reference/libnice/html/ix08.html0000664000076400007640000001571213070512356017062 00000000000000 Index of new symbols in 0.0.11: libnice Reference Manual libnice-0.1.14/docs/reference/libnice/html/libnice-NiceAddress.html0000664000076400007640000011151713070512356022061 00000000000000 NiceAddress: libnice Reference Manual

NiceAddress

NiceAddress — IP address convenience library

Stability Level

Stable, unless otherwise indicated

Types and Values

Description

The NiceAddress structure will allow you to easily set/get and modify an IPv4 or IPv6 address in order to communicate with the NiceAgent.

Functions

nice_address_init ()

void
nice_address_init (NiceAddress *addr);

Initialize a NiceAddress into an undefined address

Parameters

addr

The NiceAddress to init

 

nice_address_new ()

NiceAddress *
nice_address_new (void);

Create a new NiceAddress with undefined address You must free it with nice_address_free()

Returns

The new NiceAddress


nice_address_free ()

void
nice_address_free (NiceAddress *addr);

Frees a NiceAddress created with nice_address_new() or nice_address_dup()

Parameters

addr

The NiceAddress to free

 

nice_address_dup ()

NiceAddress *
nice_address_dup (const NiceAddress *addr);

Creates a new NiceAddress with the same address as addr

Parameters

addr

The NiceAddress to dup

 

Returns

The new NiceAddress


nice_address_set_ipv4 ()

void
nice_address_set_ipv4 (NiceAddress *addr,
                       guint32 addr_ipv4);

Set addr to an IPv4 address using the data from addr_ipv4

This function will reset the port to 0, so make sure you call it before nice_address_set_port()

Parameters

addr

The NiceAddress to modify

 

addr_ipv4

The IPv4 address

 

nice_address_set_ipv6 ()

void
nice_address_set_ipv6 (NiceAddress *addr,
                       const guchar *addr_ipv6);

Set addr to an IPv6 address using the data from addr_ipv6

This function will reset the port to 0, so make sure you call it before nice_address_set_port()

Parameters

addr

The NiceAddress to modify

 

addr_ipv6

The IPv6 address

 

nice_address_set_port ()

void
nice_address_set_port (NiceAddress *addr,
                       guint port);

Set the port of addr to port

Parameters

addr

The NiceAddress to modify

 

port

The port to set

 

nice_address_get_port ()

guint
nice_address_get_port (const NiceAddress *addr);

Retreive the port of addr

Parameters

addr

The NiceAddress to query

 

Returns

The port of addr


nice_address_set_from_string ()

gboolean
nice_address_set_from_string (NiceAddress *addr,
                              const gchar *str);

Sets an IPv4 or IPv6 address from the string str

Parameters

addr

The NiceAddress to modify

 

str

The string to set

 

Returns

TRUE if success, FALSE on error


nice_address_set_from_sockaddr ()

void
nice_address_set_from_sockaddr (NiceAddress *addr,
                                const struct sockaddr *sin);

Sets an IPv4 or IPv6 address from the sockaddr structure sin

Parameters

addr

The NiceAddress to modify

 

sin

The sockaddr to set

 

nice_address_copy_to_sockaddr ()

void
nice_address_copy_to_sockaddr (const NiceAddress *addr,
                               struct sockaddr *sin);

Fills the sockaddr structure sin with the address contained in addr

Parameters

addr

The NiceAddress to query

 

sin

The sockaddr to fill

 

nice_address_equal ()

gboolean
nice_address_equal (const NiceAddress *a,
                    const NiceAddress *b);

Compares two NiceAddress structures to see if they contain the same address and the same port.

Parameters

a

First NiceAddress to compare

 

b

Second NiceAddress to compare

 

Returns

TRUE if a and b are the same address, FALSE if they are different


nice_address_equal_no_port ()

gboolean
nice_address_equal_no_port (const NiceAddress *a,
                            const NiceAddress *b);

Compares two NiceAddress structures to see if they contain the same address, ignoring the port.

Parameters

a

First NiceAddress to compare

 

b

Second NiceAddress to compare

 

Returns

TRUE if a and b are the same address, FALSE if they are different

Since: 0.1.8


nice_address_to_string ()

void
nice_address_to_string (const NiceAddress *addr,
                        gchar *dst);

Transforms the address addr into a human readable string

Parameters

addr

The NiceAddress to query

 

dst

The string to fill

 

nice_address_is_private ()

gboolean
nice_address_is_private (const NiceAddress *addr);

Verifies if the address in addr is a private address or not

Parameters

addr

The NiceAddress to query

 

Returns

TRUE if addr is a private address, FALSE otherwise


nice_address_is_valid ()

gboolean
nice_address_is_valid (const NiceAddress *addr);

Validate whether the NiceAddress addr is a valid IPv4 or IPv6 address

Parameters

addr

The NiceAddress to query

 

Returns

TRUE if addr is valid, FALSE otherwise


nice_address_ip_version ()

int
nice_address_ip_version (const NiceAddress *addr);

Returns the IP version of the address

Parameters

addr

The NiceAddress to query

 

Returns

4 for IPv4, 6 for IPv6 and 0 for undefined address

Types and Values

NiceAddress

typedef struct {
  union
  {
    struct sockaddr     addr;
    struct sockaddr_in  ip4;
    struct sockaddr_in6 ip6;
  } s;
} NiceAddress;

The NiceAddress structure that represents an IPv4 or IPv6 address.


NICE_ADDRESS_STRING_LEN

#define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN

The maximum string length representation of an address. When using nice_address_to_string() make sure the string has a size of at least NICE_ADDRESS_STRING_LEN

libnice-0.1.14/docs/reference/libnice/html/left-insensitive.png0000644000076400007640000000061313070512356021372 00000000000000PNG  IHDRabKGD pHYs B(xtIMEƫqIDAT8͒NQ@pds`*4@W@ A!Ԇ@6^ 5hxIH R`sQp̙339B|sKEQTK@۝΁i^~Wʆ`0TJ6TcYn6A ƀ~߱>}ǭs; lYkwr 5U= /" "uU=ɲlArDzp5I4^E+P3Ɯq_p ̥iUYp=#IENDB`libnice-0.1.14/docs/reference/libnice/html/libnice-Timer.html0000664000076400007640000005621213070512356020755 00000000000000 Timer: libnice Reference Manual

Timer

Timer — STUN timer Usage

Stability Level

Stable, unless otherwise indicated

Includes

#include <stun/usages/timer.h>

Description

The STUN timer usage is a set of helpful utility functions that allows you to easily track when a STUN message should be retransmitted or considered as timed out.

Example 3. Simple example on how to use the timer usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
StunTimer timer;
unsigned remainder;
StunUsageTimerReturn ret;

// Build the message, etc..
...

// Send the message and start the timer
send(socket, request, sizeof(request));
stun_timer_start(&timer, STUN_TIMER_DEFAULT_TIMEOUT,
                 STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS);

// Loop until we get the response
for (;;) {
  remainder = stun_timer_remainder(&timer);

  // Poll the socket until data is received or the timer expires
  if (poll (&pollfd, 1, delay) <= 0) {
    // Time out and no response was received
    ret = stun_timer_refresh (&timer);
    if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) {
      // Transaction timed out
      break;
    } else if (ret == STUN_USAGE_TIMER_RETURN_RETRANSMIT) {
      // A retransmission is necessary
      send(socket, request, sizeof(request));
      continue;
    } else if (ret == STUN_USAGE_TIMER_RETURN_SUCCESS) {
      // The refresh succeeded and nothing has to be done, continue polling
      continue;
    }
  } else {
    // We received a response, read it
    recv(socket, response, sizeof(response));
    break;
  }
}

// Check if the transaction timed out or not
if (ret == STUN_USAGE_TIMER_RETURN_TIMEOUT) {
  // do whatever needs to be done in that case
} else {
  // Parse the response
}

Functions

stun_timer_start ()

void
stun_timer_start (StunTimer *timer,
                  unsigned int initial_timeout,
                  unsigned int max_retransmissions);

Starts a STUN transaction retransmission timer. This should be called as soon as you send the message for the first time on a UDP socket. The timeout before the next retransmission is set to initial_timeout , then each time a packet is retransmited, that timeout will be doubled, until the max_retransmissions retransmissions limit is reached.

To determine the total timeout value, one can use the following equation :

 total_timeout =  initial_timeout * (2^(max_retransmissions + 1) - 1);
 

See also: STUN_TIMER_DEFAULT_TIMEOUT

See also: STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS

Parameters

timer

The StunTimer to start

 

initial_timeout

The initial timeout to use before the first retransmission

 

max_retransmissions

The maximum number of transmissions before the StunTimer times out

 

stun_timer_start_reliable ()

void
stun_timer_start_reliable (StunTimer *timer,
                           unsigned int initial_timeout);

Starts a STUN transaction retransmission timer for a reliable transport. This should be called as soon as you send the message for the first time on a TCP socket

Parameters

timer

The StunTimer to start

 

initial_timeout

The initial timeout to use before the first retransmission

 

stun_timer_refresh ()

StunUsageTimerReturn
stun_timer_refresh (StunTimer *timer);

Updates a STUN transaction retransmission timer.

Parameters

timer

The StunTimer to refresh

 

Returns

A StunUsageTimerReturn telling you what to do next


stun_timer_remainder ()

unsigned
stun_timer_remainder (const StunTimer *timer);

Query the timer on the time left before the next refresh should be done

Parameters

timer

The StunTimer to query

 

Returns

The time remaining for the timer to expire in milliseconds

Types and Values

StunTimer

typedef struct stun_timer_s StunTimer;

An opaque structure representing a STUN transaction retransmission timer


enum StunUsageTimerReturn

Return value of stun_usage_timer_refresh() which provides you with status information on the timer.

Members

STUN_USAGE_TIMER_RETURN_SUCCESS

The timer was refreshed successfully and there is nothing to be done

 

STUN_USAGE_TIMER_RETURN_RETRANSMIT

The timer expired and the message should be retransmitted now.

 

STUN_USAGE_TIMER_RETURN_TIMEOUT

The timer expired as well as all the retransmissions, the transaction timed out

 

STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS

#define STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS 7

The default maximum retransmissions allowed before a timer decides to timeout


STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT

#define STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT 7900

The default intial timeout to use for a reliable timer


STUN_TIMER_DEFAULT_TIMEOUT

#define STUN_TIMER_DEFAULT_TIMEOUT 200

The default intial timeout to use for the timer RFC recommendds 500, but it's ridiculous, 50ms is known to work in most cases as it is also what is used by SIP style VoIP when sending A-Law and mu-Law audio, so 200ms should be hyper safe.

libnice-0.1.14/docs/reference/libnice/html/right.png0000644000076400007640000000040513070512356017216 00000000000000PNG  IHDRabKGD pHYs B(xtIME!GIDAT8үa?MIdEr,-hAIl ry}sX6 !9#D r$-Br$G"$;WZ&!cq \`軀O=QoufIENDB`libnice-0.1.14/docs/reference/libnice/html/ix05.html0000664000076400007640000000426313070512356017056 00000000000000 Index of new symbols in 0.0.7: libnice Reference Manual

Index of new symbols in 0.0.7

A

NiceAgent:upnp, object property in NiceAgent
NiceAgent:upnp-timeout, object property in NiceAgent
libnice-0.1.14/docs/reference/libnice/html/states.png0000664000076400007640000013713413070512356017420 00000000000000PNG  IHDREsזbKGD IDATxy@TU0:+٢ ccbEXK.< .[j*  0ye^FqC;>9{~{=c B61:!bH\ .󑞞4ܽ{r* 1\'___sy8<]j&hRĕ+WL|t?LMM-J#55hhh-BCCѷo_XZZP%+LǏ_~^|E_ЀtdeeJ5,--! amm V*9sϟG]]z1c^MP%/H$2dx `XܹsD333666  Q#H H PPPtTUULLLлwoUʕ+ػw/1h :GՄ*ñcǰ~`̘1y-8p ӧBCCagg&}d2\x(**P(>\'NСCx1m46雐@T*?Ç;v,ʰw^\zݻwرc榕LHJJ#"##ѽ{w_Tx !ŋǘ1c0l0x<ܺu 6mP(رc/r{;7Í7~z&M4'1Tx !#fXXX ::~:okkk̟?O\k:tሌDZcǐhՋDQ%<}_~ŋB,[ ]vŌ3t1JD7oĊ+#44x$//K.ŀ0f?Ā0zhBx'N@bb"`ii\xk׮ǵi&cɒ%4zI!~>}[l̘1[lѫ .̙{7f͚}>\.:4%<ƍ؈磨|rq]I$̛7GFxx8Olݺ6mһ?6ѥfBH>3x{{cܸq… ic -B۷ocؾ};_,BebҤI|2֭[m۶ʊhZqF( FFFVXU %hڷo1i$\z[noE>B|g͚֢KQ;unܸ#33k׮W_}e/6md2{ #F@ll,ױHE矣 ضmB|GHMMʼn'0h t:逨B 5k@&aΜ9mŊHLL͛71uT={iii\" M" &&Ç+9s`ҤIѣױtRCC&L۷aعs'͹F:\E;~8\\\+x>/_?O~/y*Tx 1`ػw/fϞw"99'O:C߾}sNvvvx"ױHA|r|GKb͚5'8ƍEEE7o֯_Bu,P%@ݾ}УG|9r>ZK.Ųe`bbiӦa֭\G"^B ʕ+`D">}oב:'''t 1`ܼyeee\": /!(99}􁕕/_%KpÊBBB/:qTx 1@~-&LחHɓTTTXDQ%x饗`ffx̞=Hހp9( ̙37o:aTx 10۶môiPRR###rI/5 @PPQ[[u$b@~άY7 Ǐ1'b޽\G": /!d7nQQQooo# p?!!!?Dt^B Hzz:?7:yqa'2339NDt^B ğ^z>oq"cmmHRسgבK8t"""PUUpI/ >ǎrrrCt^B H$=#FpGo 8Otyyy'" /! ]rݻ7lj@ RJBq#CpJ% {9ݻ7n&KHII4qG#)) &&&hhh:1Tx 12 BΝS|Iܹ֭@QQlj.KcA ݻsHx<t]B=777@CC9Nd!TB=c]"++ {.qKKOOG@@v, iiiD":!Tx sEEEpssC~~>ݹc0\tpҾ`ii,X[[~ }ݻ!J ڵk۷/Ξ=L"++ * 7nIJeJ{ӐH$X~=uHB<:u*/Ç{?1a8p2 ?3v@=z4&Oo„ | V/kkkյ|=!zm1Μ9Lm5~z6e;wfyyyLRXvڥ>c1<޾o>6}t6b֯_?&˙\.g;wdT*<7nh۷okd}v>Z}G7 1L?1M#߶2zhC눊1h gΜ 8x ?bȑ? B @y<`߾}رcZ/((H#cPPP>= PHvIb `eef pt{ Ebb"***4gcJR+pe;vLm!J4Iixc3K.UϬ@xx8 _}lmmP?~o67 77ǏǩS~Ν;P(o>}:n݊gϢ\G2uuuX|9V^3f`˖-\G" ]j&DϙVVVx=u?皞'Fmm-q FmmiKKsuuEaa!t"~m:t|Tx sMoǡkW)bq>?M:>*蹦veeeiii:!Tx s(..XXX<#Erkx<J%{y&ljJRMMMK4P%XXX8s qލ7 (..lj.K۷/RRRl轤$fff\!: /! 44gϞC&qHݾ}p^yC`kk~+^F̙3޽;-\B4P%@888Æ O?u[nJHKKCvvv $ /!Tn侮gX[[C"Ph'ǏotC  puuEEEܹBzGK`o~.V~!>Æ ?q:#`eeSSSڵ 755`ee<4 HB5zQ\ =1 Yq 4~ܳo>5 1_kmm kkk0PQQw...4Zш=Q(/#]=;Q]?@wwwZJ T*W^Arr2Dx<888(//GZZJKKR95^B:8 ?\au | D"1{llڴСC׿o?uM ߽{٨o븄Ct1因`2 t6&\TTn݊XXX ''G:z?_[nF";;;A&RkԄ :ӧoŜ9s`ff[n0hllĞ={k.ܹs^^^m^tQX,FNNT*  ۼ?~hKh/`%pD lۤI&!..fffxVZW^y{guF+}rC*ޞ.Cw ghr!:JѢE8]Cc˒6+駟b尰a?Yۆ"??ׯ=}jҥ T*q3:.5cUH.߄rY:EѴk 5j&Lֶ튻[x1֬YT={`޽xptt#jjjp]|>LR3!:A&Q}d2{صk駟bΝt l޼6663f bcc[o^:X,Fii)h"K̈́5?H0]sSNŪUwyZ#qrrr0f\x1*`ii ___8::"77:HAbGλ(0 g Rӧ1x`kA,cXt)D"h"c=9|}}憂dffX.5kDRYgb۶m=z4FY>}Q]]xxx@(xϮk ^B)cQ <_@oH褔ݻ6m!?"99nnnxw<%%%8t._DFFK.}zJچRDnn.<<zB&D"={ΝC]]0byL,ȑ#8q qтiIoooqGP%QJe(o3q:T8pӧƌ+++ ^|x>>G^BZv(nמh rd[JOOGRR]H Ó-B"HtJ C^藼d̄KR*VQ bjkk355UUU`ATC"1sss G`` VSTɁ)ܸ*4wb*)r<ok`rD"t*9cpGLZJHEWd2r!#55 \:*t5,6s(>Tx@g(kzX {\G!-«|>!PTTuK څW&p'N@||<Ν {{{&̞=ӦM{1dȐ6~ ǃ-222  ;U0BѢE,WrEJbRd|>5440ח0\b11c;y$>|8KIIhʕ+ҥKQ򘳳ƾϟx4id2fllb_rs4Ċۛ[?0 &H_'P(|ybX ud\GidLVQ-(],^TokeAT'TWW###Bhh(ѩS'(J@pp0nݺWb>sxp5)//Gtt4ҥKL?}7o>ǫR^"ߔsڴiB=K.&N===]#cӱ5?۷oիaaa\z~~&]|}Dcll ooo#001iKLb֦M4>KbԨQ •+W77n7##ӦM{vZ+GAHHr9N: &<3e-&$E]]JKKѵkW<3TxQ29vLd:UTTb1^z%#,,v:KFFEM#.5йsgeFbÆ ٳg[3p1߿aaa8qN_ J1bN"\G/i?Xv-JKKsvaذa6lN<#** }КκN"ҒDBBPp7>!ٳ0a°a]"!!;f͚Hu$&W6"cЬfҶJ%VX>ݻw=Uccc|ETTfϞ_~X4% HR(JN7шRL8>,yzzDZcǰn:*\]]Q\\i*Mܽ{sڵkѯ_?<1ccc|ܹsT*DKͤYYYA,s /yfW\ŋ_ё82b3ӦMT*:?t[[[TUUq?^L._-[`Ν:3ݻ7ΝiӦ8tTTTp?^jذa6oެ7o Ftt4̙JHjllԛ-;x<ITxIcѢEضmb ѣuBH;qrrByy9'}S%OMP?ĦM[XXs,,,P__ITxS[lfΜ ;;;ʕ+}6Q!̌ɔTxS9y$uXj-[F3 C\MKT*w}yqEk,,,/(IWޟJW'rJ|_|555HKK:&P(ڧa%L^x(XhV\u BHܹ3jjj'^D֮]hcpsٳ'Ο?uAmԩ'^XYYYY̏3eر\ z.5Yfqsfff ˗bjkk;2cZ}A ^HPT:"{M>;w:AKRo,K5j1t5 g+ZLB(B"h?*Ν;}rC1?1^-BPLS%UTT.]"yבu Gx< /yӧO_:xZ ihhK^P;zu ԳgO\rzFD6K\Itшh)^ҢJ8::rCg 77zM$s\ 2L+}Q%-JKKC`` 1tM:k_033:1&&&Tx RSSu !hs**E:Nҥ 󹎡蕀DnUWWT*l߾>>>?|0Μ94h;x<|wUİNٳ5>dcی1ƚ T*7n|ii)svv~`#F~1\r9۹sc3>={g϶j_x>>s mOСClǎ1gYvv6JhCw^\xQqllsss!((Hc޽[sMT1Jz*1y97n… j*Gf|VVVkվO>XhODGG#** K,AZZD"!pI|066hcʔ)6l~$$$`…/<ܹ?п=fvv6^u\zUƢE'55o&̙nݺUŋk?ǁLl޼Bqq1/vvv_cNIIQ,_?94i ˨(,]Tc{x<9٘3g>3۷g}] 4ݾ_ZCiKZ9H$1Ʈ]|}}ٝ;wc}lϞ=l„ lժU}6D #_YY۴i:t(STk.&Yxx8駟خ]iOyz6w\M-R|>khh`/+))arɓl,%%6\.]|>;z(ayyyٙ͘1Cc{د޽{dzhivr9cisyuB`1ƜH$bof~Ϲs9 bEEEM#c,1,,,?sb '..R222U2%-b?#33hll#ƌ͛7c߾}PTeEϞ='֯_u* * {… iI$§ޏ,Xo!.._8{,jkkq)ppp7|܇f|Zuuu _x7n$''fΜI&aĉ@dd$^~eL06W,,,Dhh(rƾ۷cԩoϚ5 Ѱ44hcǪyW7{P //7o쌭[">>۷oǘ1cySYY> .YM(^^^t`ĉ5i:YoߎիW`\z~~~|2>'^G<ڡ k3gƍ󹎢n݊W_}U=R!m'%%lu6m822R]̗.]QF!((W\ ܞͶܧ:rpuL0AQTΆo{wuFE(++ QtVii)`̚5롟+++իK/!88={|6rf_O뭷ނB /uQ%-Gzz:G(..V_#mK$߿ꫯڭmpM M"-CFF1tӹe{@RY &AZ[@Q% dA]] |>`oo~Tw޽;1Vk,%#kd2Q[[ J333t ^^^leeE")) :ޒdH 7TxPcc#jjjP]] R WcׯΟ?~;w`޼y\ t@TxBH$BMM T*LLLйs. ŋG"Ԕ&VBZ oUWWHT @\.P(zI2d?~׿ڵؾ};1c&FWbTTT@&X=/cTxOAAi)vTSSN:qvCW0P[[JrXZZŅ˼MޢQQQ\k'krcAVV ĽYfa\\EED /w4JH$BUUJ%lll驳/mmmacc tڕ8ٰaN/B/}G#^-aǃ/䤳Eɼyb cp&++ :ޣKxY]][[[|m^}U;v ]l֮]u @;*ŰF.]`llug6yd7P(:9r:AK]jn# HOOGii)777(-\111\GњB=z&L:H$|:!\D"ӑ KKKS-?$((!!!HHH:JS*OG :hkB655 /toXL:\G!*OȀP(D`` \\\:dgvZ!''(b۶mA>}bpc\G ]Q} JRܹsB`` )|嗈Fii)qTbb"jjj0ydX]D!J !((h"xkkkczS|>?\G1H4{=*AZZJKKZ\\\yf̛7w:3ٱc]+Wr`Ņ+*wyw܁D"`bbu[nŲep穩T*,YJ˗/:A+**+1iW]xc())Ajj*x<JZ ;ve˖ARq鉔cĉ )ScC`1RAAAHO/bʔ):ĉ?>s /1 5SHRb... :^2d^|Euꑫ,[ ?S@YY`d2TG{'{w-B!,--aaaXաJ` رc>aT^^NOc|Er HХK聴dTޅI~jjj Q[[ \sssXYYsptt޾_1}tR __LաNNNpss:i#6&5}rh=K E, 022B@@3& A?<1iwb"33...>>  ]!RtjiQBڋNVkllDZZ 00q4CYC~/!DgG"45P/!2趂!`b7`܈1<(׀y {#[1K+ЩT*ENNaeeu!c#sșDKrssu BBgFχ?]7FxzzrЉ›zӬF۸V}_4f\=NOOGxx8s|{k$&&8u{#^*PpZxJ%`ii .dۏUVi!=+W>жh۟6ÇQ]] 777899'N@~~>.>sUgφ3?<)akk]qݾ}) .'H,XR1LT2>JJJ\.gb͘1hyv%c=zİ<쬱5ٲ޽{dz6Zڧ8r9c=q` 3'''&۷Fۏ:Osp9 bEEEMǦ,h~^,,,D"QL(ӧ?!ET mtK(--E`` %e%p\#F###(J@zTUU!44hsԩJ% 88nիW1~x}{9{+,d۶m011СC5hihzoy'|HR!;;!6c4?ӂD"s|cSs4?/~~~(,,T}aa!f&G~~~? m9r:u r Mu4bT*]JɁLCZM$//%keX^z  k>FFF8rٻa@}e}Դ4UK>YKJ"ffin *Kٷ$[7ddEf< 8=u]]i}a>s2dTĐizU)))QHHK؛;]Kjm{˖-jm>>c1VxSSSakk GGZ10Fcp'D"PAi{}S%jfmq'Q!E^xsrr rA YO~1jeees18j-yyy(//>WI@}YQͪx!-7oR[-++C~~>BC4C\`懼G߾}1zhlڴ *޽;!ljΝ;9Byts+Ny!Э[7!## J9!#dtAq1\PPKKK١eeeH$JzxxJ FhVIHLLbH5BA {onYWqL&ӧ888_~ڵ+}DĠ...ׯ^{5Äh֏N ccc8;;F(BD^{c|xw Dׯc޽1dȐVZgϞʼn'  1f׏N?[YY zh5QGxw?h cǎh/t8|0N>@Dc'K obb"|}}鏁hj&ut;Vc1l0ظG mԯ(x3*Mf˃-`,hq[q2>;JHH  `E Ht'NĹsxG"D-|+!ХKD3BޑкkYYYh߾}k!ٙx]='/.Gr9>0ưuV, 0w\***xG"YXxR)d2Lo[Q\V;RƜ9s0p@L4wy0i$CH=fffCYѨcBDğ 8SLĉ1dqԪK.Xv-BCC;!MhJn܈rh^R~)$rޑԪ3gĂ лwoqZEe|(,,'jfgg.{F!}>C)9;Z0"$$xiUNNNXn}CH-48511{/2˯#:c6e}l2kxyGшva±_ш o~~~tN631c r2>y`l'O;FuFڵkyG!A \899i2 !Zz6HexGjLĭ[yG!DI[]]MS?{nG816nL; ! o~~> {B9Lډ1N>X|.Y]OOOzSSS8p((+㑅μ&x~ox"Κ8?ء rjkS Bt7o*hE/nn+o)8G:t|M5o+  ye!D mi&yͬ3d}Ut2&mv{qqq0`꡶mhNQxctS!g ƶ߂k! bQtrVxݵؚF=zwww Dž 6O+H`jj3 ! ۀ1B*D?cK^x_y/+;s 1yW;1p[QQ333Y1xm,~ &yEKUy9UIr|8kW]ڶmL13'DX;ü;J)IoP| 2?XZZrLQVVFێpTxHBK4^`$0%YLyn3@.ӧ^}B J$iӆgBHڽgި7BEDt?nܸApKw4;D"yIżcfBvԩ:EEEcFn"+**駟"<<;wĠAPVV˗ȑ#صk-[2#G vvvJƏ={@  &&QQQ RC"<<>|8!→\QXXO>{Ν;ѡCo?:GbŌf̘yϟ"##,44(EGGӧ3{7XT*eR޽[4\j}7n\VBBc)^[`xٳ[ f$Xrr&ux A{ :T̙3Ŵh>FB>}pBC(Vs\V.]e߿_ŋx^B Lnn `)sLW_}K.ĉN 9*TuɁ-ڵkxز; !O /!& gΜQ^QQzK+cѐ066pBrpp@޽ѱcz˪[j_~7gϞ{.:wۃM3~K!dǎXt)߿XXX`X~=HիWƩS0zh8;;͛S|`ݨFtt4bbbvZe 4ϟ;ܹs(..tDDD믿FFFc7nmHz&%%ϏwBH̘1۶mCg#ur׷uN5qCۏDdddD?Dt1tcx WTx ADc褌 弣EԩS'*-$|bbdggw4b q"Bt/xI7oѮ];O="??尶 ,--9% /!:w ?P@ 5<.%%%Cff&B!aoo##:IH^B\LL D" [[[QgTWWĤћlll`ccqHIIL&affDP%DOسg6mҥ O1ntzլyB!(--ŃPUUsss899¢5=EMbzR}&O\|c:sI 2ڰ7쌼x!<3g3Ν;}ZfffH$3Ba-$Nn߾~ )))pppk_~Y? 3qDkDYf᫯R:m %%%Ɂ\.5|4$x L??#ѣG[M?<[hN=|&&&/*UWW#''>5\]]alLuBZQyy9~:u 0`,^XtzJ~-BCCf066F۶mѶm[ 55FFFpww ^BԬOӧ!0dlذn133?.]޽{2tY~~>JKKѱcGQj% ٳe.W__~z_tÇI=a:%'NgggL<c3gয়~ڵkyGiu{AQQxGѸrܻwO 0i>MR%zGEll,0f ciTtt4pBQZŋգG.^{ow$G?_wn݊<,Zw Jsssxxx3/!-PXXGݱpB _om۶К5k`ccCEts|||݊h^r9p1B=ӦMK+ 02e VZbEEE7oF^{w;;;Ύj:LtRff&݋K.a?~<=RDEEE;w. ѣGlW\7|+Vhⴠ^x!ѡCK UUU8~8bcc)So 1ưaܻw_|Zn-k׮Eaa!K؄rӓV /!$$$ ::6l|Mz^QMb `„ Z s}v̚5 /8:K.#%%666t*!** }YӍR8vBBB;7i&t KMQQQiTxz*v \`{'Dh+**Bvv6:vH_h@kqqqԩS薣j߿Epp0|||Z}=qeӦMZYee%RRRsssqK ݻwk.bܸq1b2ػw/ЩS'wj9Bbۈ K ISd2$%%]v}^r9~:t utDJJ p%0`kkN:)Uy$HPTTTD"$&&"771tDnKG1bi}*D`G`` Ǝkp雚k+))Ayy9r9S =~fVVVAΝGGGI1ܽ{vvvy /)))@NN&N_~w${xmcHKK=nD}5ӧO 1$HOOǣG;^KF"`޽ŠAvZꜝTeV@|8!RwEx<"Mdd$N>cbH!OOO$&&֖/\;VVVػw/D8{,Ǘ0s>& M4h`*PGUR'2224H3~g ** AAA^`fbF \.gǏgǏgP IDATdrw$Gҧ+~^d b1bŊzJGjCrʼR cmbIR %j}2%%%)7TlgTa4uA <{쁑 #== @||qDsPZPΝ;M%L&cɊmN:Լz\^u 믿Xpp0۽{7鬪1XϞ=.wa1XQQ{7X,fصkԩSYUή\rss͆f1GGGbNNjښݾ}kS; 57A՗ Uۤhur@i]j/C{ROר::Ǩܹsرc&MDw!YngL8-sND"O>?~<֭[T>}x0rH 0C֭[qDFFCJJ ƍ_|QmذaL+WB.+-… ژ6mBCC1gx{{ŋɓ'+MŊvlllYǍW/@,￯!--M7o*mYf)ᅬ>GEvn5((H)G\K.UZwyG U\\\ѣ&ʕ+ .(~O8~8 99Yi׸yf7HJJ_шP###k:uBΝѱcGiӆZu233Cee%: /g'֭[ GҠ[n!..n݂|}}#FGyor9ݻHӧOc˖-H$СЧO[ *TVVb`a޽h DEEA$gϞ DXXX{+22271daǎpssѵkWuѐ6m@*Fаܸq_5>#ՋwBꉏGxx8ڶm`tܹ՗{͛5jFIGD'oaL&W_}DpFhXxeDC&!&&1bKKKd$!YYY8q"/.* H$Ν;ƭ?P DEE~:,yQ^^;֣#^ EDD֮]KcV""==+W3H o_| H^1舷UWWcpCEh`ҤIի6mڤUE6 ,]&M”)S;!O o+Ą EѣD>}Ǻu;N?Axx8;޽wzɨ-–-[/C?w 8baa7B.ctZS YZZw FWcop-w$Blڴ XtN2e ^yA*Cje???|':K,3>CQ"00Ǐnj3P]];)j~*jp}L<ӧOǛo0hDlٲ^^^ E^|E{ DgP}JW^żyat֍wBٷo$ }]QZ /#F`ҥ$Tx޽{7ƍzsz!ڶm{BtsUUZ o ^XnuNRaa![,[w6m.\;wbQQQ;֢L1|pvvƬYx!D%>cZʠFod궐3* 2 ~!ɓ'CH"##1l0x{{QϰrJQ Qm*̘1cƌax!AEEEѣyGGJtʙ#ccczīTxBCC'*,Y>w >s|JTx!!!Xt)z;!JLL5:u; W>|8?; !PmDyy9fΜ+WLJwBhƍ={6Zaر^N葢QmD"3h"*D'ܻwprrE+B <N V «T*ᅬsμ$6mG0a;A0*ud2̚5 ڵ+84D"Aqq1yG*&&&FJJ ( oèٳ1i$ݛwBĉxxJؿ?)jZ/__/(4ɓ'1tP1Rǎ!&+5ȑ#Ő!CxG!Y*++annnP]C6WϞ=C h\rըvN>MaY'8p Μ9;ch/Xf [Qi3g`ch=z͛czW5.Rg7|SSSqim۶ch#/ΫYfffTxU0;o<̝;>N ##;;w bjjJ1C[nxxG!rrr;NH$àjYx322믿"$$wBH$?: iw cpW.coxG!ݽ{c脎;"99w BWxO< @DEE!((ދ,XsΎi&L8 agg***駟"<<;wĠAeeeX|99]vaٲe8~8\]]G9ɓ*ٳg :qzػw/v܉ liifGڱD"VWv TZ]x DmKϟ"##aPͦOx ֿ&JT*ewf1ryUKHH`1kT[51߲f3cM>Eż#4L&cɚXoM#عs'ǏwށH$B`` }p֞ҥKƍqFDEEaĉJ/ҥKy DmJJJ`ee8̙3111PL#G0j( .NjUkDDD ??_t颔K.*Ƒ#G΄[GkAAA6lJKK1sLm7bccU6R3@JJ fΜDOA9r SDTUU\.&<(zU&)~ꫯp%8qBaȑhpy =o]=;Sl akk L\.W0`=ݻbDtt4&L; !jeii٢J](VTT1QF!..N1x뭷 allc…^z;\kCy322ڴiC^ pႢׂ>}kߎ?h |G۷b͛71n8??L4I#+Ҙ 6`޼y022Fii ڱc.]4hV^opppH$€?cpvvt8uT.\޽ՈFLL ֮][oyϟO弟| ""(**ʕ+[~kӦ y*WΤ$ΣvEEE?>o; !jyfk׮h=f͚-[bPR);Jr9RSS5xY?\~=BCCy U8;;#''w 3陘hM@ oQQ3BHԩb1:A$Gtpׅwxy Pm:HHJJBvv6uDg$JBZܹVVVpssԢ X,ѣakk q1(//GQQ aaaX[[͘m=tF;!jaܺu amm \N Ex|%,--j qNNcxDFFF`]믿b׮]cƭ[PUU*xxxFΝqmxf^[+؆XXXB{II rrrPQQccc888Ύ H3ՌRԒ^^LxzzDݸqHkkk+D"/"##֭[ۈ?C?AsX[[^ j888Qх.iXM'Tx=~@pp04KUUbcc(--3<#G*ۭڵk[oanvbcc?UBptt\.Gaa! `ooGGGW^޻wSNcD刍ɓ'QRRW_}˗/MךpttT.`ggGYSu\.W122Caa!RRRSLkcjj"1ެ,xzzAHqQ;w>|86lФAAAFXX꼳gϢ־@ =!QPPdBh(}C5+ӻ{1%8uN> DÇcj>ػwolڴI-m#Go222RJAff&6&&&J:+ׯ_y 1={c #F5kZß_|UE>P(T I&&&tAS'w1FVWGdd$^믿{g0*lذfCqwL&SŅM2@zUxSRRСC1d8qN8WWWL4I1XXXcǎr {9.[磨HF] pww; `eewww#ڀUz*}*((]pM1Bm[b̙3g"""ek׮j"%%FFFh߾}n#M [;1 رcd2Ls/'NM ܹ3(Odee???#==Bڵӻ, kUV@Hkr mooo,\NNN#3uT7lR7hŊغu+baa???TVV"==&&&h׮ebbDB^C /ݤ@Z˵kװcb͚5Jk@ `{F71fff#CMLL JB%i]r.Ξ=5k/Љ=zǎEn߾ׯcѼ<5 t x!HOM6Jch9!:ݿW6n9Чbԩٳ'xiueeeXlXfcc!!!۷ch){=Oyy96o HŋtXf BCCsN3g,Y4>qtt=222  T3ѣS4yZBBB]vtѭ˗cڴizW~~]tU ۷GJJ rrrxGj2:?zSx%~O4skwς?Ĝ9s yQUVw}:-Z~uLMMѹsg"++w)Hwe,[ ?y۷oǃ0w\(TիWСCQadd:M6HJJL&IA 4Ґ۶mΝ; rrU0m4aϞ=#ty;={ʕ+uUH5gfY522oSHm۶ᆪm:uꄈBL0.\ ӧ q!uvݻZq ^YAJJ D/-[NF?۷oǥK0qDrruƊ+`ll ܿyyyܳPգljgիW; 1̝;VgφD"={0ydt lХK^666|8:t@k->w_F||<i߿@Cedd(# IDATM{/=?ᔊ4EMig^  ©Sx DiRv z9BVs]uvvÇy^&Э[71 Xe٬^z%_crss=*Aر#PUU;A;j(>|w ?CL;vݻw' |mQ1!zYx`ر8tDrss;!:x(zMo o`` f ?4P!Otưmիde`Q\\;!:iii菑?RM]vA4C{.4POOOmcccd2K𚙙.]j,Xʉ%C[jk-1h ۸d9z(\aJquEDD`ժU6mBBBs|g.IZhh;5Ծ:޳ 6`Ϟ=8x`yj>|gϞFCZkjHs?#RSS׋D"t޽Iyvd9r$O9 B8p111BPPP5w?)_b飒6e1YbFцr9=qzS:tEDD0۳g_/$$Dvvv޽{L.ŋkK*ќL Ks4ֆךcyyy5͢ҧ+~^d 7_SƾN/ޟmݽ{Yy,V\\ƍ*_}d2KNNĢ}e׳ӧO+MKMMecSLalРAlΝl,""EFF &0DRݩScǎ~1Xee%;w.[jٹsbSN1L׳۷o+-_|Xo2zk+ꮋ+cScm{vvvUo;'&&2Ƶk*櫝f}k/5j oZZ;{, d>Tf-ݷjQo˫޺]СC>`sit?VTTĦOΆg, @_MϓڟE"SB߿}k׮YM/2 ~j**j&H;CTjd2& Yee%|}}كT*e'Nd9r$˗ŋP(d1v1`v=f̘Jk[ /&LҔ描oT*e UWW3sssc%$$0EuYW+mڥKv}m\wzP‚1+--e.]Rfׯgl*@׵LuEv*--UZǦn'X۪2._̜mji|[}QSxW^&MVZ4_ݟձZo5e,ߜu.5ˬb&&&g [`d _.ߏ>j,gu׆\h?33}*͚43𶂣Gݻw+M9::*޼*Ak7dbX1JJ ˎ=͛yHuv{Mvԩ{*W5O흲eݝ]r2///Eu篫۷]5}ݎ emzgE"ڵR`V]]RSSYbb"cׯ3P&UXw;\'m'XIYM}2Լ/5Θ>[#*}:b?c2ֳgOŗP6km֔u.u׷,''`-bǏo}UYTMƓڮ>-((`>TоYoVEϼd뛫j9r$PPPYnܸ8s `̙2e V\ ?֭S9UAAN> ___\p, 0cǎU/;wֻc֬Y9r$ q)-Сi͛4OBB֭[+Wݻ[w}hvfUaSZtڴi Ŝ9s퍋/&O4],+PO?UϥK0oѣGӕ!O$ӪbÆ -J?ߗ.]1cƠK.|2ݟ8&T<-e5׏?ooo\~&M@ Pرc?8t@ @UUad{xm]:fڬ@^^ڵk6A.#55Ux`ڵѣGnoP<.zg6EABhs)t{Ov3KRK4e2k*ZzBnGni&"03 /ss$Qa~05/e۾?4h222 - X~7spT]|DAAz!JKKM0ͨCTTT];82Ջ͟?x衇 J}Q^[%]/˝X4`Z:f tk5 H.7"[oIB9e˰qFnjD"Z2t$8rP&^s2u=yҗ,d@:";;%z)L&S^.xVZKݗ+HOO'xOӹnGp aaaxg(pB'JגGh\RcߗIDuAcc#BBBHkt'|^zj|>&"G s%bt[aYfnnnC\>ヒ 6@TaB6m͛*AT2% #xh#:KR! tM$ VZ7xD[b\y={x|=' GPQ܌@aj4KLL {9rOOOܹ6mѣGIӫ 3b;! IV"a{1c@$C ۷olj'p) %2t(T'566"((tjya4hP(Ɂ'Υɢ3JJJB D", [X%DlH$HHH?O!99)))AbbbŒF#ylڴC᫯!H[.]¾}Ԅdc/ƍÈ#05:*!KokaϞ=tY )--Ųe˰|r 8t8c޽´iӺ}G ??駟_~믿حmPwi5P[7i⽃)SǏ' `'NDNN֬Y۷ R?]=ڞD" իW{=-JJODo{ꫯpYҡPM6! YYYr z\.ǬYj*3ơm4;v+ߛz hnO dž PTTD:g}[nŗ_~y桩tH=B._֭[=عs'mۆSN#44ԡmJvx;H"`۶mXb]F:ooo,[ sŒ%KqFX,auZ7x[l!^ [lG}Dov{˲Z߹A{Tyyya۶mXd =Paǎ>>C-@sb۶mCXdm}D{]9r$1gΜ^•{XhrssEaΜ9͋'|Lat< .`0) \=IA(bؾ};ID@ @FF222ڊbϞ=O?aÆ9&… HMMuC@233_:_) z=n2tP꫘1cӮlzM]va(..ꫯs7L4au{ ?#0dyVWNۍ^,Yf–-[I:$ldggCR믿ɄCGlllP(-*P( "O{X%I-´iۛtH1~x,#//pssߏtDEEuK{EEE{Z6j(g!S2;4R.99o6fΜm۶.T"0tP :`6q)|'vbbb.-Gzzz7G#GiRSC/#{aX~=*Q #F#ٳظq#`XT}`ذad2(=~ _ݻwj"//> WfA(b֭ܶ\T*j^*T?#222:Skk+v {0 Æ J±cwLѣkYuo4i233YE0 D"CڢƢEl2 0t8 y饗gߑ̫W"..Wh4=ԿWrLR"""k.l۶?(G t,ˋJU0 ./xb1C$6mRěoEu\zt]bߏJiqfa'uqW*B9Qf3fc=̧4rHK~Ww}p 4vdrؾb.rn(2~a\sN:KIIsH%?Cb* I@~sNlٲ KD"H$Ӯ]0N!!!pߎf}9OOOlٲFgϦSTxgnQߙ3gB: cY)nqjx;ܹs1}t\pt8T/G:Վ]vuʕ+L ڴ FƩ;KNNݻgaƍN"IP(Ę1cCrtaW×swr:^^^k羚Ϗwww 99SNE}}=鐨^"33{q)5k`ܹ=^///.Z/Q* ~~~kJ_yj̘1Xn-Zt8T/ 1{ll޼t(uQ 2Cὺ:^ilX HHцfQnJhnnvXTDž 77ΝÛo D:$=è@aa!PڥT*^zt(0 qܮp䶝`C&ZEB!,Yq!++ ?HD9իWcŊCieY$566"((te6yxİ2GEEʑP4x`ݻ+^y޽hR f͚rҖ.]ɓ'#""t(Nšs]Rt[&^///D"Z͊$ .\3g^_˒0{lޜf 2G&Sj&9Pŝl6~ 5EDD#:Aa߾}\ݠi0sLbX &zQmll$`ﶉW  ..tXp!Ol@k , /rT* 7Ρm;3ԦNRՐdoWv  ֭Ccc#/_NPV`9SL^ʱcǰk. 88HJJ]>7|}}Ir[f& j5t:FO>N"`ҥX`,Y 6UTd2|ǐJSDDDN{fi4']zK$P׮  >O>o=˔4V-[ʕ+b$%%EEEHHH =|BDPT+--ŪUᐹ;wjjj?~ T zhZnH$BZZFlee%d2o bZQUUjz}%J` y#׵ \ߨЀxӢn#GW_Ejj*p^l6sx񁧧g\}uRSS???,ʕ+߿?G/p}ةe'yf`ٲe!EeY#&&WHhZT*r9H]u\z!!!.477cڵlX|9mu'V%%%HLL$@F(ޮhDuu5}ⵓ0LsN6l@1{lqh4III.ZSRRxsniiNCxx88χ״pEEEJQw/99[nŀ0yd>RW\_'&;wǏQ@ҡ8^T*%mY,h4jm6xWwxcB!"##bX5Ʉ={'͛4!QshRj%rNg ** bDFFvۖn}nGբAAAӧOO7G0N]vŋ3gRRRHDbDDDt+..FBB;2 &nee%|}}x@c]CCJ%G5KZ 6sEID(aP\\8L&jkkyb bhllb!x r|@Tb̙ͨ3! W^EbbbWYY^nbniiBsNQBA}}=JKKՍ|r|(((ĉqaaQ.F" ** h?~cʔ)ذaw E$L6aǎ8q":hG,؟aƍ8v w^deeb8R(ڋz# \Nlr |Ox#aPWWVZg!)) 3f];{\v ^^^m~X\.Ǿ}0j(GN pJ$V4I$Wu0hllDKK |||›r_Tו`ǎhmmŬY0x`!QXYY{P3<$&&I7&^abބ 駟B"@׷GrWo߾D z8BjPP$''(..N.11k׮Ś5k?"33f# r( {Rp1šC^6^W_}]~L4 z|eYXV^&ݚd2"IWP@T:[á۱ZhjjZL&CHH7Sw0 k9r9s&^fN [ż+ ^H]SSa ;|'* MMM7鐨tirJ:$0(++CRRݬ_rɼ$5˲,^ LἉ nmm;yύ3ZC=I&+t:nP(  Gp^ T>t{#ш&hZ"88);{,>3l6deeѺ]iiiZ!""7e0u:jjjWVڵk$hJ7h4hjjjE@@nfٳ/^Dzz:{9  ?NAYY{b0PUUD6445&^;eRP(,|}}H{NeY`Y_I9Hee%|||x[~ *++:GnP^^___8MZ[[T*a4@8J72 8r~HRL: :}IQQ~t:үrѽq͎%t:(J H$@&\?/^Đ!CIcQŲ,ChZ_~Dh4s,ڵk`ѼZݍ\;d2ZB~~~CN_~cᩧwT7Z(--EBB/*]t BqqqDcwH/ J`aVD%^z+l6܌1cgS TF+{t:D 466B:!eQSSɄW8Ɍ&ގX,hiiFbT*sNd2ѣGa#k?O4ӧOs瓻!>>AAA2̭VQ[[vM] J@d2:$t::-z'AS(tD:u bQQQeVUUUpssC~48MweYhZh4 0 T ___WsZz?b̘1x{u uuu  0Z]*,Q]] ^xxx@*"((qqq페믰X, uhQUXE}}=4 xyXVsCFR;윊d?O=zuuuHMMJ:4ʁjmQ3L8~8T*! HFb@բ eeej{ӟ_~~~~0`@OGURTCHHO;MV,b1|}}ʟJ6 ?>f 4O>$HF0K.h4x"v V1c ##Sô … QSS~<֏477CR!..Ƕ zrxyy!,,v>h%ffYdd ø|21f_ 3api|אӧF#GfNeYTUU k.\111=0ؾ};._n}R(hnnVr& tǭLXN10z| ?'Nqqqxꩧ0l0zf3QVV˗/cɒ%9bŊXfM>˲D"-J6 0 ׯ3x˲0 \2ZX T T ///OHii);C("-- #,bҥHMMų>K,V9s`>Zӡ ݺUd2V4vMj`m6XD"ᆫܱl6>}?#!Gyx$f,bx駑A:L&KxWol6)QWW^n[ܤP__eN;&^Wc2#tR 6 .\ɓ'QVVш`Ĉ:t()"쭷<'xt(шl{n9#)) (//GpppmiiACC<==F&^: N^ Y xyy tbZ8s qU@1l0 :vlݺt(tEٳ| T*!!!HNN a2B䄤^&^, URAΪ(((RH$=܃)))|XŔ)SuVZhԀaNxYBBKo{MTϰ/1)ɽ'ufCaa!N>d2 )))D;O>eZo`رTt:nr`` E/x,d2h4r{B%s/*Tz?NBII ;!C`РAtG;f3駟Î?JL6Sfnnn %C/? d2q3˲m;]ey%%%8{, R`XT 0zĮfΝc=F:N®]3 BquRNO L&#+rNVKmX , 777so\2h䆪 LO(++ | 0:;, 7xk`0 '':o{-h( Ʉף fspz=oߎcHIIkSA/EQTWb۶m|2 q߿aY+8ViӦ쁈)(n,|WhiiA`` $DEEZ Jbʕ+`7n=5KQ՝J%~wڵkj0 ??? !!HLLէ\MEQ@'rHGAQEQ.$GIENDB`libnice-0.1.14/docs/reference/libnice/html/api-index-full.html0000664000076400007640000020565413070512356021116 00000000000000 API Index: libnice Reference Manual

API Index

A

NiceAddress, struct in NiceAddress
nice_address_copy_to_sockaddr, function in NiceAddress
nice_address_dup, function in NiceAddress
nice_address_equal, function in NiceAddress
nice_address_equal_no_port, function in NiceAddress
nice_address_free, function in NiceAddress
nice_address_get_port, function in NiceAddress
nice_address_init, function in NiceAddress
nice_address_ip_version, function in NiceAddress
nice_address_is_private, function in NiceAddress
nice_address_is_valid, function in NiceAddress
nice_address_new, function in NiceAddress
nice_address_set_from_sockaddr, function in NiceAddress
nice_address_set_from_string, function in NiceAddress
nice_address_set_ipv4, function in NiceAddress
nice_address_set_ipv6, function in NiceAddress
nice_address_set_port, function in NiceAddress
NICE_ADDRESS_STRING_LEN, macro in NiceAddress
nice_address_to_string, function in NiceAddress
NiceAgent, struct in NiceAgent
NiceAgent::candidate-gathering-done, object signal in NiceAgent
NiceAgent::component-state-changed, object signal in NiceAgent
NiceAgent::initial-binding-request-received, object signal in NiceAgent
NiceAgent::new-candidate, object signal in NiceAgent
NiceAgent::new-candidate-full, object signal in NiceAgent
NiceAgent::new-remote-candidate, object signal in NiceAgent
NiceAgent::new-remote-candidate-full, object signal in NiceAgent
NiceAgent::new-selected-pair, object signal in NiceAgent
NiceAgent::new-selected-pair-full, object signal in NiceAgent
NiceAgent::reliable-transport-writable, object signal in NiceAgent
NiceAgent::streams-removed, object signal in NiceAgent
NiceAgent:bytestream-tcp, object property in NiceAgent
NiceAgent:compatibility, object property in NiceAgent
NiceAgent:controlling-mode, object property in NiceAgent
NiceAgent:force-relay, object property in NiceAgent
NiceAgent:full-mode, object property in NiceAgent
NiceAgent:ice-tcp, object property in NiceAgent
NiceAgent:ice-udp, object property in NiceAgent
NiceAgent:keepalive-conncheck, object property in NiceAgent
NiceAgent:main-context, object property in NiceAgent
NiceAgent:max-connectivity-checks, object property in NiceAgent
NiceAgent:proxy-ip, object property in NiceAgent
NiceAgent:proxy-password, object property in NiceAgent
NiceAgent:proxy-port, object property in NiceAgent
NiceAgent:proxy-type, object property in NiceAgent
NiceAgent:proxy-username, object property in NiceAgent
NiceAgent:reliable, object property in NiceAgent
NiceAgent:stun-pacing-timer, object property in NiceAgent
NiceAgent:stun-server, object property in NiceAgent
NiceAgent:stun-server-port, object property in NiceAgent
NiceAgent:upnp, object property in NiceAgent
NiceAgent:upnp-timeout, object property in NiceAgent
NiceAgentRecvFunc, user_function in NiceAgent
nice_agent_add_local_address, function in NiceAgent
nice_agent_add_stream, function in NiceAgent
nice_agent_attach_recv, function in NiceAgent
nice_agent_forget_relays, function in NiceAgent
nice_agent_gather_candidates, function in NiceAgent
nice_agent_generate_local_candidate_sdp, function in NiceAgent
nice_agent_generate_local_sdp, function in NiceAgent
nice_agent_generate_local_stream_sdp, function in NiceAgent
nice_agent_get_component_state, function in NiceAgent
nice_agent_get_default_local_candidate, function in NiceAgent
nice_agent_get_io_stream, function in NiceAgent
nice_agent_get_local_candidates, function in NiceAgent
nice_agent_get_local_credentials, function in NiceAgent
nice_agent_get_remote_candidates, function in NiceAgent
nice_agent_get_selected_pair, function in NiceAgent
nice_agent_get_selected_socket, function in NiceAgent
nice_agent_get_stream_name, function in NiceAgent
NICE_AGENT_MAX_REMOTE_CANDIDATES, macro in NiceAgent
nice_agent_new, function in NiceAgent
nice_agent_new_reliable, function in NiceAgent
nice_agent_parse_remote_candidate_sdp, function in NiceAgent
nice_agent_parse_remote_sdp, function in NiceAgent
nice_agent_parse_remote_stream_sdp, function in NiceAgent
nice_agent_recv, function in NiceAgent
nice_agent_recv_messages, function in NiceAgent
nice_agent_recv_messages_nonblocking, function in NiceAgent
nice_agent_recv_nonblocking, function in NiceAgent
nice_agent_remove_stream, function in NiceAgent
nice_agent_restart, function in NiceAgent
nice_agent_restart_stream, function in NiceAgent
nice_agent_send, function in NiceAgent
nice_agent_send_messages_nonblocking, function in NiceAgent
nice_agent_set_local_credentials, function in NiceAgent
nice_agent_set_port_range, function in NiceAgent
nice_agent_set_relay_info, function in NiceAgent
nice_agent_set_remote_candidates, function in NiceAgent
nice_agent_set_remote_credentials, function in NiceAgent
nice_agent_set_selected_pair, function in NiceAgent
nice_agent_set_selected_remote_candidate, function in NiceAgent
nice_agent_set_software, function in NiceAgent
nice_agent_set_stream_name, function in NiceAgent
nice_agent_set_stream_tos, function in NiceAgent

C

NiceCandidate, struct in NiceCandidate
NiceCandidateTransport, enum in NiceCandidate
NiceCandidateType, enum in NiceCandidate
nice_candidate_copy, function in NiceCandidate
nice_candidate_free, function in NiceCandidate
NICE_CANDIDATE_MAX_FOUNDATION, macro in NiceCandidate
nice_candidate_new, function in NiceCandidate
NiceCompatibility, enum in NiceAgent
NiceComponentState, enum in NiceAgent
NiceComponentType, enum in NiceAgent
nice_component_state_to_string, function in NiceAgent

D

nice_debug_disable, function in Debug messages
nice_debug_enable, function in Debug messages

I

NiceInputMessage, struct in NiceAgent
nice_interfaces_get_ip_for_interface, function in Network interfaces discovery
nice_interfaces_get_local_interfaces, function in Network interfaces discovery
nice_interfaces_get_local_ips, function in Network interfaces discovery

O

NiceOutputMessage, struct in NiceAgent

P

NiceProxyType, enum in NiceAgent
PseudoTcpCallbacks, struct in Pseudo TCP Socket
PseudoTcpDebugLevel, enum in Pseudo TCP Socket
PseudoTcpShutdown, enum in Pseudo TCP Socket
PseudoTcpSocket, struct in Pseudo TCP Socket
PseudoTcpSocket:ack-delay, object property in Pseudo TCP Socket
PseudoTcpSocket:callbacks, object property in Pseudo TCP Socket
PseudoTcpSocket:conversation, object property in Pseudo TCP Socket
PseudoTcpSocket:no-delay, object property in Pseudo TCP Socket
PseudoTcpSocket:rcv-buf, object property in Pseudo TCP Socket
PseudoTcpSocket:snd-buf, object property in Pseudo TCP Socket
PseudoTcpSocket:state, object property in Pseudo TCP Socket
PseudoTcpSocket:support-fin-ack, object property in Pseudo TCP Socket
PseudoTcpState, enum in Pseudo TCP Socket
PseudoTcpWriteResult, enum in Pseudo TCP Socket
pseudo_tcp_set_debug_level, function in Pseudo TCP Socket
pseudo_tcp_socket_can_send, function in Pseudo TCP Socket
pseudo_tcp_socket_close, function in Pseudo TCP Socket
pseudo_tcp_socket_connect, function in Pseudo TCP Socket
pseudo_tcp_socket_get_available_bytes, function in Pseudo TCP Socket
pseudo_tcp_socket_get_available_send_space, function in Pseudo TCP Socket
pseudo_tcp_socket_get_error, function in Pseudo TCP Socket
pseudo_tcp_socket_get_next_clock, function in Pseudo TCP Socket
pseudo_tcp_socket_is_closed, function in Pseudo TCP Socket
pseudo_tcp_socket_is_closed_remotely, function in Pseudo TCP Socket
pseudo_tcp_socket_new, function in Pseudo TCP Socket
pseudo_tcp_socket_notify_clock, function in Pseudo TCP Socket
pseudo_tcp_socket_notify_message, function in Pseudo TCP Socket
pseudo_tcp_socket_notify_mtu, function in Pseudo TCP Socket
pseudo_tcp_socket_notify_packet, function in Pseudo TCP Socket
pseudo_tcp_socket_recv, function in Pseudo TCP Socket
pseudo_tcp_socket_send, function in Pseudo TCP Socket
pseudo_tcp_socket_set_time, function in Pseudo TCP Socket
pseudo_tcp_socket_shutdown, function in Pseudo TCP Socket

R

NiceRelayType, enum in NiceCandidate

S

StunAgent, typedef in StunAgent
StunAgentUsageFlags, enum in StunAgent
StunAttribute, enum in StunMessage
StunClass, enum in StunMessage
StunCompatibility, enum in StunAgent
StunDebugHandler, user_function in StunAgent
StunDefaultValidaterData, struct in StunAgent
StunError, enum in StunMessage
StunInputVector, struct in StunMessage
StunMessage, struct in StunMessage
StunMessageIntegrityValidate, user_function in StunAgent
StunMessageReturn, enum in StunMessage
StunMethod, enum in StunMessage
StunTimer, typedef in Timer
StunTransactionId, typedef in StunMessage
StunUsageBindReturn, enum in Bind
StunUsageIceCompatibility, enum in ICE
StunUsageIceReturn, enum in ICE
StunUsageTimerReturn, enum in Timer
StunUsageTurnCompatibility, enum in TURN
StunUsageTurnRequestPorts, enum in TURN
StunUsageTurnReturn, enum in TURN
StunValidationStatus, enum in StunAgent
stun_agent_build_unknown_attributes_error, function in StunAgent
stun_agent_default_validater, function in StunAgent
stun_agent_finish_message, function in StunAgent
stun_agent_forget_transaction, function in StunAgent
stun_agent_init, function in StunAgent
stun_agent_init_error, function in StunAgent
stun_agent_init_indication, function in StunAgent
stun_agent_init_request, function in StunAgent
stun_agent_init_response, function in StunAgent
STUN_AGENT_MAX_SAVED_IDS, macro in STUN Constants
STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES, macro in STUN Constants
stun_agent_set_software, function in StunAgent
stun_agent_validate, function in StunAgent
STUN_ATTRIBUTE_HEADER_LENGTH, macro in STUN Constants
STUN_ATTRIBUTE_LENGTH_LEN, macro in STUN Constants
STUN_ATTRIBUTE_LENGTH_POS, macro in STUN Constants
STUN_ATTRIBUTE_TYPE_LEN, macro in STUN Constants
STUN_ATTRIBUTE_TYPE_POS, macro in STUN Constants
STUN_ATTRIBUTE_VALUE_POS, macro in STUN Constants
stun_debug_disable, function in StunAgent
stun_debug_enable, function in StunAgent
STUN_ID_LEN, macro in STUN Constants
STUN_MAGIC_COOKIE, macro in STUN Constants
STUN_MAX_MESSAGE_SIZE, macro in STUN Constants
STUN_MAX_MESSAGE_SIZE_IPV4, macro in STUN Constants
STUN_MAX_MESSAGE_SIZE_IPV6, macro in STUN Constants
stun_message_append, function in StunMessage
stun_message_append32, function in StunMessage
stun_message_append64, function in StunMessage
stun_message_append_addr, function in StunMessage
stun_message_append_bytes, function in StunMessage
stun_message_append_error, function in StunMessage
stun_message_append_flag, function in StunMessage
stun_message_append_string, function in StunMessage
stun_message_append_xor_addr, function in StunMessage
stun_message_append_xor_addr_full, function in StunMessage
STUN_MESSAGE_ATTRIBUTES_POS, macro in STUN Constants
STUN_MESSAGE_BUFFER_INCOMPLETE, macro in StunMessage
STUN_MESSAGE_BUFFER_INVALID, macro in StunMessage
stun_message_find, function in StunMessage
stun_message_find32, function in StunMessage
stun_message_find64, function in StunMessage
stun_message_find_addr, function in StunMessage
stun_message_find_error, function in StunMessage
stun_message_find_flag, function in StunMessage
stun_message_find_string, function in StunMessage
stun_message_find_xor_addr, function in StunMessage
stun_message_find_xor_addr_full, function in StunMessage
stun_message_get_class, function in StunMessage
stun_message_get_method, function in StunMessage
stun_message_has_attribute, function in StunMessage
stun_message_has_cookie, function in StunMessage
STUN_MESSAGE_HEADER_LENGTH, macro in STUN Constants
stun_message_id, function in StunMessage
stun_message_init, function in StunMessage
stun_message_length, function in StunMessage
STUN_MESSAGE_LENGTH_LEN, macro in STUN Constants
STUN_MESSAGE_LENGTH_POS, macro in STUN Constants
STUN_MESSAGE_TRANS_ID_LEN, macro in STUN Constants
STUN_MESSAGE_TRANS_ID_POS, macro in STUN Constants
STUN_MESSAGE_TYPE_LEN, macro in STUN Constants
STUN_MESSAGE_TYPE_POS, macro in STUN Constants
stun_message_validate_buffer_length, function in StunMessage
stun_message_validate_buffer_length_fast, function in StunMessage
stun_optional, function in StunMessage
stun_set_debug_handler, function in StunAgent
stun_strerror, function in StunMessage
STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS, macro in Timer
STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT, macro in Timer
STUN_TIMER_DEFAULT_TIMEOUT, macro in Timer
stun_timer_refresh, function in Timer
stun_timer_remainder, function in Timer
stun_timer_start, function in Timer
stun_timer_start_reliable, function in Timer
stun_usage_bind_create, function in Bind
stun_usage_bind_keepalive, function in Bind
stun_usage_bind_process, function in Bind
stun_usage_bind_run, function in Bind
stun_usage_ice_conncheck_create, function in ICE
stun_usage_ice_conncheck_create_reply, function in ICE
stun_usage_ice_conncheck_priority, function in ICE
stun_usage_ice_conncheck_process, function in ICE
stun_usage_ice_conncheck_use_candidate, function in ICE
stun_usage_turn_create, function in TURN
stun_usage_turn_create_permission, function in TURN
stun_usage_turn_create_refresh, function in TURN
stun_usage_turn_process, function in TURN
stun_usage_turn_refresh_process, function in TURN

T

TurnServer, struct in NiceCandidate
TURN_MAGIC_COOKIE, macro in STUN Constants
libnice-0.1.14/docs/reference/libnice/html/pt04.html0000664000076400007640000000564213070512356017062 00000000000000 Part IV. Appendices: libnice Reference Manual libnice-0.1.14/docs/reference/libnice/html/ix04.html0000664000076400007640000000376313070512356017061 00000000000000 Index of new symbols in 0.0.6: libnice Reference Manual

Index of new symbols in 0.0.6

S

stun_agent_forget_transaction, function in StunAgent
libnice-0.1.14/docs/reference/libnice/html/index.html0000664000076400007640000001273113070512356017377 00000000000000 libnice Reference Manual: libnice Reference Manual

The latest version of this documentation can be found on-line at http://nice.freedesktop.org/libnice/.


I. ICE Library
NiceAgent — ICE agent API implementation
NiceAddress — IP address convenience library
NiceCandidate — ICE candidate representation
Libnice helper functions
Debug messages — Debug messages utility functions
Network interfaces discovery — Utility functions to discover local network interfaces
II. STUN Library
StunAgent — STUN agent for building and validating STUN messages
StunMessage — STUN messages parsing and formatting functions
STUN Constants — STUN constants
STUN usages
Bind — STUN Binding Usage
ICE — STUN ICE Usage
TURN — TURN Allocation Usage
Timer — STUN timer Usage
III. Pseudo TCP Socket implementation
Pseudo TCP Socket — Pseudo TCP implementation
IV. Appendices
API Index
Index of deprecated symbols
Index of new symbols in 0.0.4
Index of new symbols in 0.0.6
Index of new symbols in 0.0.7
Index of new symbols in 0.0.9
Index of new symbols in 0.0.10
Index of new symbols in 0.0.11
Index of new symbols in 0.1.4
Index of new symbols in 0.1.5
Index of new symbols in 0.1.6
Index of new symbols in 0.1.8
Index of new symbols in 0.1.14
Annotation Glossary

The libnice library contains the ICE library and the STUN library as well as a Pseudo TCP socket implementation.

libnice-0.1.14/docs/reference/libnice/html/home.png0000644000076400007640000000040013070512356017024 00000000000000PNG  IHDRabKGD pHYs B(xtIME &IDAT8ҽ Aߞf`n v`6`/`Yܡ`f&k$,} 0b+ԸaQW~b O e{y N[L}.piBzmm o.I]7^[;%:VIENDB`libnice-0.1.14/docs/reference/libnice/html/ch02.html0000664000076400007640000000406213070512356017022 00000000000000 Libnice helper functions: libnice Reference Manual

Libnice helper functions

Debug messages — Debug messages utility functions
Network interfaces discovery — Utility functions to discover local network interfaces
libnice-0.1.14/docs/reference/libnice/html/ix07.html0000664000076400007640000000454213070512356017060 00000000000000 Index of new symbols in 0.0.10: libnice Reference Manual

Index of new symbols in 0.0.10

A

nice_agent_set_software, function in NiceAgent

S

stun_agent_set_software, function in StunAgent
libnice-0.1.14/docs/reference/libnice/html/ch05.html0000664000076400007640000000341113070512356017022 00000000000000 : libnice Reference Manual
Pseudo TCP Socket — Pseudo TCP implementation
libnice-0.1.14/docs/reference/libnice/html/NiceCandidate.html0000664000076400007640000006133013070512356020742 00000000000000 NiceCandidate: libnice Reference Manual

NiceCandidate

NiceCandidate — ICE candidate representation

Stability Level

Stable, unless otherwise indicated

Object Hierarchy

    GBoxed
    ╰── NiceCandidate

Description

A representation of an ICE candidate. Make sure you read the ICE drafts[1] to understand correctly the concept of ICE candidates.

[1] http://tools.ietf.org/wg/mmusic/draft-ietf-mmusic-ice/

Functions

nice_candidate_new ()

NiceCandidate *
nice_candidate_new (NiceCandidateType type);

Creates a new candidate. Must be freed with nice_candidate_free()

Parameters

type

The NiceCandidateType of the candidate to create

 

Returns

A new NiceCandidate


nice_candidate_free ()

void
nice_candidate_free (NiceCandidate *candidate);

Frees a NiceCandidate

Parameters

candidate

The candidate to free

 

nice_candidate_copy ()

NiceCandidate *
nice_candidate_copy (const NiceCandidate *candidate);

Makes a copy of a NiceCandidate

Parameters

candidate

The candidate to copy

 

Returns

A new NiceCandidate, a copy of candidate

Types and Values

struct NiceCandidate

struct NiceCandidate {
  NiceCandidateType type;
  NiceCandidateTransport transport;
  NiceAddress addr;
  NiceAddress base_addr;
  guint32 priority;
  guint stream_id;
  guint component_id;
  gchar foundation[NICE_CANDIDATE_MAX_FOUNDATION];
  gchar *username;        /* pointer to a nul-terminated username string */
  gchar *password;        /* pointer to a nul-terminated password string */
  TurnServer *turn;
  gpointer sockptr;
};

A structure to represent an ICE candidate

The priority is an integer as specified in the ICE draft 19. If you are using the MSN or the GOOGLE compatibility mode (which are based on ICE draft 6, which uses a floating point qvalue as priority), then the priority value will represent the qvalue multiplied by 1000.

Members

NiceCandidateType type;

The type of candidate

 

NiceCandidateTransport transport;

The transport being used for the candidate

 

NiceAddress addr;

The NiceAddress of the candidate

 

NiceAddress base_addr;

The NiceAddress of the base address used by the candidate

 

guint32 priority;

The priority of the candidate see note

 

guint stream_id;

The ID of the stream to which belongs the candidate

 

guint component_id;

The ID of the component to which belongs the candidate

 

gchar foundation[NICE_CANDIDATE_MAX_FOUNDATION];

The foundation of the candidate

 

gchar *username;

The candidate-specific username to use (overrides the one set by nice_agent_set_local_credentials() or nice_agent_set_remote_credentials())

 

gchar *password;

The candidate-specific password to use (overrides the one set by nice_agent_set_local_credentials() or nice_agent_set_remote_credentials())

 

TurnServer *turn;

The TurnServer settings if the candidate is of type NICE_CANDIDATE_TYPE_RELAYED

 

gpointer sockptr;

The underlying socket

 

enum NiceCandidateType

An enum represneting the type of a candidate

Members

NICE_CANDIDATE_TYPE_HOST

A host candidate

 

NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE

A server reflexive candidate

 

NICE_CANDIDATE_TYPE_PEER_REFLEXIVE

A peer reflexive candidate

 

NICE_CANDIDATE_TYPE_RELAYED

A relay candidate

 

enum NiceCandidateTransport

An enum representing the type of transport to use

Members

NICE_CANDIDATE_TRANSPORT_UDP

UDP transport

 

NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE

TCP Active transport

 

NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE

TCP Passive transport

 

NICE_CANDIDATE_TRANSPORT_TCP_SO

TCP Simultaneous-Open transport

 

struct TurnServer

struct TurnServer {
  gint ref_count;

  NiceAddress server;
  gchar *username;
  gchar *password;
  NiceRelayType type;
};

A structure to store the TURN relay settings

Members

gint ref_count;

Reference count for the structure.

 

NiceAddress server;

The NiceAddress of the TURN server

 

gchar *username;

The TURN username

 

gchar *password;

The TURN password

 

NiceRelayType type;

The NiceRelayType of the server

 

enum NiceRelayType

An enum representing the type of relay to use

Members

NICE_RELAY_TYPE_TURN_UDP

A TURN relay using UDP

 

NICE_RELAY_TYPE_TURN_TCP

A TURN relay using TCP

 

NICE_RELAY_TYPE_TURN_TLS

A TURN relay using TLS over TCP

 

NICE_CANDIDATE_MAX_FOUNDATION

#define NICE_CANDIDATE_MAX_FOUNDATION                (32+1)

The maximum size a candidate foundation can have.

See Also

NiceAddress

libnice-0.1.14/docs/reference/libnice/html/libnice-Pseudo-TCP-Socket.html0000664000076400007640000022240613070512356023006 00000000000000 Pseudo TCP Socket: libnice Reference Manual

Pseudo TCP Socket

Pseudo TCP Socket — Pseudo TCP implementation

Stability Level

Stable, unless otherwise indicated

Properties

guint ack-delay Read / Write
gpointer callbacks Read / Write
guint conversation Read / Write / Construct Only
gboolean no-delay Read / Write
guint rcv-buf Read / Write
guint snd-buf Read / Write
guint state Read
gboolean support-fin-ack Read / Write / Construct Only

Object Hierarchy

    GObject
    ╰── PseudoTcpSocket

Includes

#include <pseudotcp.h>

Description

The PseudoTcpSocket is an object implementing a Pseudo Tcp Socket for use over UDP. The socket will implement a subset of the TCP stack to allow for a reliable transport over non-reliable sockets (such as UDP).

See the file tests/test-pseudotcp.c in the source package for an example of how to use the object.

Functions

pseudo_tcp_socket_new ()

PseudoTcpSocket *
pseudo_tcp_socket_new (guint32 conversation,
                       PseudoTcpCallbacks *callbacks);

Creates a new PseudoTcpSocket for the specified conversation

The callbacks must be non-NULL, in order to get notified of packets the socket needs to send.

If the callbacks structure was dynamicly allocated, it can be freed after the call pseudo_tcp_socket_new

Parameters

conversation

The conversation id for the socket.

 

callbacks

A pointer to the PseudoTcpCallbacks structure for getting notified of the PseudoTcpSocket events.

 

Returns

The new PseudoTcpSocket object, NULL on error

Since: 0.0.11


pseudo_tcp_socket_connect ()

gboolean
pseudo_tcp_socket_connect (PseudoTcpSocket *self);

Connects the PseudoTcpSocket to the peer with the same conversation id. The connection will only be successful after the PseudoTcpCallbacks:PseudoTcpOpened callback is called

Parameters

self

The PseudoTcpSocket object.

 

Returns

TRUE on success, FALSE on failure (not in TCP_LISTEN state)

See also: pseudo_tcp_socket_get_error()

Since: 0.0.11


pseudo_tcp_socket_recv ()

gint
pseudo_tcp_socket_recv (PseudoTcpSocket *self,
                        char *buffer,
                        size_t len);

Receive data from the socket.

Only call this on the PseudoTcpCallbacks:PseudoTcpReadable callback.

This function should be called in a loop. If this function does not return -1 with EWOULDBLOCK as the error, the PseudoTcpCallbacks:PseudoTcpReadable callback will not be called again.

Parameters

self

The PseudoTcpSocket object.

 

buffer

The buffer to fill with received data

 

len

The length of buffer

 

Returns

The number of bytes received or -1 in case of error

See also: pseudo_tcp_socket_get_error()

Since: 0.0.11


pseudo_tcp_socket_send ()

gint
pseudo_tcp_socket_send (PseudoTcpSocket *self,
                        const char *buffer,
                        guint32 len);

Send data on the socket.

If this function return -1 with EWOULDBLOCK as the error, or if the return value is lower than len, then the PseudoTcpCallbacks:PseudoTcpWritable callback will be called when the socket will become writable.

Parameters

self

The PseudoTcpSocket object.

 

buffer

The buffer with data to send

 

len

The length of buffer

 

Returns

The number of bytes sent or -1 in case of error

See also: pseudo_tcp_socket_get_error()

Since: 0.0.11


pseudo_tcp_socket_close ()

void
pseudo_tcp_socket_close (PseudoTcpSocket *self,
                         gboolean force);

Close the socket for sending. If force is set to FALSE, the socket will finish sending pending data before closing. If it is set to TRUE, the socket will discard pending data and close the connection immediately (sending a TCP RST segment).

The socket will be closed in both directions – sending and receiving – and any pending received data must be read before calling this function, by calling pseudo_tcp_socket_recv() until it blocks. If any pending data is in the receive buffer when pseudo_tcp_socket_close() is called, a TCP RST segment will be sent to the peer to notify it of the data loss.

The PseudoTcpCallbacks:PseudoTcpClosed callback will not be called once the socket gets closed. It is only used for aborted connection. Instead, the socket gets closed when the pseudo_tcp_socket_get_next_clock() function returns FALSE.

See also: pseudo_tcp_socket_get_next_clock()

Parameters

self

The PseudoTcpSocket object.

 

force

TRUE to close the socket forcefully, FALSE to close it gracefully

 

Since: 0.0.11


pseudo_tcp_socket_shutdown ()

void
pseudo_tcp_socket_shutdown (PseudoTcpSocket *self,
                            PseudoTcpShutdown how);

Shut down sending, receiving, or both on the socket, depending on the value of how . The behaviour of pseudo_tcp_socket_send() and pseudo_tcp_socket_recv() will immediately change after this function returns (depending on the value of how ), though the socket may continue to process network traffic in the background even if sending or receiving data is forbidden.

This is equivalent to the POSIX shutdown() function. Setting how to PSEUDO_TCP_SHUTDOWN_RDWR is equivalent to calling pseudo_tcp_socket_close().

Parameters

self

The PseudoTcpSocket object.

 

how

The directions of the connection to shut down.

 

Since: 0.1.8


pseudo_tcp_socket_is_closed ()

gboolean
pseudo_tcp_socket_is_closed (PseudoTcpSocket *self);

Gets whether the socket is closed, with the shutdown handshake completed, and both peers no longer able to read or write data to the connection.

Parameters

self

The PseudoTcpSocket object.

 

Returns

TRUE if the socket is closed in both directions, FALSE otherwise

Since: 0.1.8


pseudo_tcp_socket_is_closed_remotely ()

gboolean
pseudo_tcp_socket_is_closed_remotely (PseudoTcpSocket *self);

Gets whether the socket has been closed on the remote peer’s side of the connection (i.e. whether pseudo_tcp_socket_close() has been called there). This is guaranteed to return TRUE if pseudo_tcp_socket_is_closed() returns TRUE. It will not return TRUE after pseudo_tcp_socket_close() is called until a FIN segment is received from the remote peer.

Parameters

self

The PseudoTcpSocket object.

 

Returns

TRUE if the remote peer has closed its side of the connection, FALSE otherwise

Since: 0.1.8


pseudo_tcp_socket_get_error ()

int
pseudo_tcp_socket_get_error (PseudoTcpSocket *self);

Return the last encountered error.

The return value can be :

EINVAL (for pseudo_tcp_socket_connect()).

EWOULDBLOCK or ENOTCONN (for pseudo_tcp_socket_recv() and pseudo_tcp_socket_send()).

Parameters

self

The PseudoTcpSocket object.

 

Returns

The error code

See also: pseudo_tcp_socket_connect()

See also: pseudo_tcp_socket_recv()

See also: pseudo_tcp_socket_send()

Since: 0.0.11


pseudo_tcp_socket_get_next_clock ()

gboolean
pseudo_tcp_socket_get_next_clock (PseudoTcpSocket *self,
                                  guint64 *timeout);

Call this to determine the timeout needed before the next time call to pseudo_tcp_socket_notify_clock() should be made.

Parameters

self

The PseudoTcpSocket object.

 

timeout

A pointer to be filled with the new timeout.

 

Returns

TRUE if timeout was filled, FALSE if the socket is closed and ready to be destroyed.

See also: pseudo_tcp_socket_notify_clock()

Since: 0.0.11


pseudo_tcp_socket_notify_clock ()

void
pseudo_tcp_socket_notify_clock (PseudoTcpSocket *self);

Start the processing of receiving data, pending data or syn/acks. Call this based on timeout value returned by pseudo_tcp_socket_get_next_clock(). It's ok to call this too frequently.

See also: pseudo_tcp_socket_get_next_clock()

Parameters

self

The PseudoTcpSocket object.

 

Since: 0.0.11


pseudo_tcp_socket_notify_mtu ()

void
pseudo_tcp_socket_notify_mtu (PseudoTcpSocket *self,
                              guint16 mtu);

Set the MTU of the socket

Parameters

self

The PseudoTcpSocket object.

 

mtu

The new MTU of the socket

 

Since: 0.0.11


pseudo_tcp_socket_notify_packet ()

gboolean
pseudo_tcp_socket_notify_packet (PseudoTcpSocket *self,
                                 const gchar *buffer,
                                 guint32 len);

Notify the PseudoTcpSocket when a new packet arrives

Parameters

self

The PseudoTcpSocket object.

 

buffer

The buffer containing the received data

 

len

The length of buffer

 

Returns

TRUE if the packet was processed successfully, FALSE otherwise

Since: 0.0.11


pseudo_tcp_set_debug_level ()

void
pseudo_tcp_set_debug_level (PseudoTcpDebugLevel level);

Sets the debug level to enable/disable normal/verbose debug messages.

Parameters

level

The level of debug to set

 

Since: 0.0.11


pseudo_tcp_socket_get_available_bytes ()

gint
pseudo_tcp_socket_get_available_bytes (PseudoTcpSocket *self);

Gets the number of bytes of data in the buffer that can be read without receiving more packets from the network.

Parameters

self

The PseudoTcpSocket object.

 

Returns

The number of bytes or -1 if the connection is not established

Since: 0.1.5


pseudo_tcp_socket_can_send ()

gboolean
pseudo_tcp_socket_can_send (PseudoTcpSocket *self);

Returns if there is space in the send buffer to send any data.

Parameters

self

The PseudoTcpSocket object.

 

Returns

TRUE if data can be sent, FALSE otherwise

Since: 0.1.5


pseudo_tcp_socket_get_available_send_space ()

gsize
pseudo_tcp_socket_get_available_send_space
                               (PseudoTcpSocket *self);

Gets the number of bytes of space available in the transmission buffer.

Parameters

self

The PseudoTcpSocket object.

 

Returns

The number of bytes, or 0 if the connection is not established.

Since: 0.1.5


pseudo_tcp_socket_notify_message ()

gboolean
pseudo_tcp_socket_notify_message (PseudoTcpSocket *self,
                                  NiceInputMessage *message);

Notify the PseudoTcpSocket that a new message has arrived, and enqueue the data in its buffers to the PseudoTcpSocket’s receive buffer.

Parameters

self

The PseudoTcpSocket object.

 

message

A NiceInputMessage containing the received data.

 

Returns

TRUE if the packet was processed successfully, FALSE otherwise

Since: 0.1.5


pseudo_tcp_socket_set_time ()

void
pseudo_tcp_socket_set_time (PseudoTcpSocket *self,
                            guint32 current_time);

Sets the current monotonic time to be used by the TCP socket when calculating timeouts and expiry times. If this function is not called, or is called with current_time as zero, g_get_monotonic_time() will be used. Otherwise, the specified current_time will be used until it is updated by calling this function again.

This function is intended for testing only, and should not be used in production code.

Parameters

self

The PseudoTcpSocket object.

 

current_time

Current monotonic time, in milliseconds; or zero to use the system monotonic clock.

 

Since: 0.1.8

Types and Values

PseudoTcpSocket

typedef struct _PseudoTcpSocket PseudoTcpSocket;

The PseudoTcpSocket is the GObject implementing the Pseudo TCP Socket

Since: 0.0.11


enum PseudoTcpState

An enum representing the state of the PseudoTcpSocket. These states correspond to the TCP states in RFC 793.

See also: “state”

Members

TCP_LISTEN

The socket's initial state. The socket isn't connected and is listening for an incoming connection

 

TCP_SYN_SENT

The socket has sent a connection request (SYN) packet and is waiting for an answer

 

TCP_SYN_RECEIVED

The socket has received a connection request (SYN) packet.

 

TCP_ESTABLISHED

The socket is connected

 

TCP_CLOSED

The socket has been closed

 

TCP_FIN_WAIT_1

The socket has been closed locally but not remotely (Since: 0.1.8)

 

TCP_FIN_WAIT_2

The socket has been closed locally but not remotely (Since: 0.1.8)

 

TCP_CLOSING

The socket has been closed locally and remotely (Since: 0.1.8)

 

TCP_TIME_WAIT

The socket has been closed locally and remotely (Since: 0.1.8)

 

TCP_CLOSE_WAIT

The socket has been closed remotely but not locally (Since: 0.1.8)

 

TCP_LAST_ACK

The socket has been closed locally and remotely (Since: 0.1.8)

 

Since: 0.0.11


enum PseudoTcpWriteResult

An enum representing the result value of the write operation requested by the PseudoTcpSocket.

See also: PseudoTcpCallbacks:WritePacket

Members

WR_SUCCESS

The write operation was successful

 

WR_TOO_LARGE

The socket type requires that message be sent atomically and the size of the message to be sent made this impossible.

 

WR_FAIL

There was an error sending the message

 

Since: 0.0.11


PseudoTcpCallbacks

typedef struct {
  gpointer user_data;
  void  (*PseudoTcpOpened) (PseudoTcpSocket *tcp, gpointer data);
  void  (*PseudoTcpReadable) (PseudoTcpSocket *tcp, gpointer data);
  void  (*PseudoTcpWritable) (PseudoTcpSocket *tcp, gpointer data);
  void  (*PseudoTcpClosed) (PseudoTcpSocket *tcp, guint32 error, gpointer data);
  PseudoTcpWriteResult (*WritePacket) (PseudoTcpSocket *tcp,
      const gchar * buffer, guint32 len, gpointer data);
} PseudoTcpCallbacks;

A structure containing callbacks functions that will be called by the PseudoTcpSocket when some events happen.

See also: PseudoTcpWriteResult

Members

gpointer user_data;

A user defined pointer to be passed to the callbacks

 

PseudoTcpOpened ()

The PseudoTcpSocket is now connected

 

PseudoTcpReadable ()

The socket is readable

 

PseudoTcpWritable ()

The socket is writable

 

PseudoTcpClosed ()

The socket was closed (both sides)

 

WritePacket ()

This callback is called when the socket needs to send data.

 

Since: 0.0.11


enum PseudoTcpDebugLevel

Valid values of debug levels to be set.

Members

PSEUDO_TCP_DEBUG_NONE

Disable debug messages

 

PSEUDO_TCP_DEBUG_NORMAL

Enable basic debug messages

 

PSEUDO_TCP_DEBUG_VERBOSE

Enable verbose debug messages

 

Since: 0.0.11


enum PseudoTcpShutdown

Options for which parts of a connection to shut down when calling pseudo_tcp_socket_shutdown(). These correspond to the values passed to POSIX shutdown().

Members

PSEUDO_TCP_SHUTDOWN_RD

Shut down the local reader only

 

PSEUDO_TCP_SHUTDOWN_WR

Shut down the local writer only

 

PSEUDO_TCP_SHUTDOWN_RDWR

Shut down both reading and writing

 

Since: 0.1.8

Property Details

The “ack-delay” property

  “ack-delay”                guint

Delayed ACK timeout (in milliseconds).

Flags: Read / Write

Default value: 100


The “callbacks” property

  “callbacks”                gpointer

Structure with the callbacks to call when PseudoTcp events happen.

Flags: Read / Write


The “conversation” property

  “conversation”             guint

The TCP Conversation ID.

Flags: Read / Write / Construct Only

Default value: 0


The “no-delay” property

  “no-delay”                 gboolean

Disable the Nagle algorithm (like the TCP_NODELAY option).

Flags: Read / Write

Default value: FALSE


The “rcv-buf” property

  “rcv-buf”                  guint

Receive Buffer size.

Flags: Read / Write

Allowed values: >= 1

Default value: 61440


The “snd-buf” property

  “snd-buf”                  guint

Send Buffer size.

Flags: Read / Write

Allowed values: >= 1

Default value: 92160


The “state” property

  “state”                    guint

The current state (enum PseudoTcpState) of the PseudoTcp socket.

Flags: Read

Allowed values: <= 4

Default value: 0


The “support-fin-ack” property

  “support-fin-ack”          gboolean

Whether to support the FIN–ACK extension to the pseudo-TCP protocol for this socket. The extension is only compatible with other libnice pseudo-TCP stacks, and not with Jingle pseudo-TCP stacks. If enabled, support is negotiatied on connection setup, so it is safe for a PseudoTcpSocket with support enabled to be used with one with it disabled, or with a Jingle pseudo-TCP socket which doesn’t support it at all.

Support is enabled by default.

Flags: Read / Write / Construct Only

Default value: TRUE

Since: 0.1.8

libnice-0.1.14/docs/reference/libnice/html/ix13.html0000664000076400007640000000375713070512356017064 00000000000000 Index of new symbols in 0.1.14: libnice Reference Manual

Index of new symbols in 0.1.14

A

NiceAgent:force-relay, object property in NiceAgent
libnice-0.1.14/docs/reference/libnice/html/ch03.html0000664000076400007640000000404213070512356017021 00000000000000 : libnice Reference Manual
StunAgent — STUN agent for building and validating STUN messages
StunMessage — STUN messages parsing and formatting functions
STUN Constants — STUN constants
libnice-0.1.14/docs/reference/libnice/html/ix10.html0000664000076400007640000001456113070512356017054 00000000000000 Index of new symbols in 0.1.5: libnice Reference Manual libnice-0.1.14/docs/reference/libnice/html/right-insensitive.png0000644000076400007640000000056513070512356021563 00000000000000PNG  IHDRabKGD pHYs B(xtIME ^IDAT8͒J` /S_$AqrW(>m"]\(49.Nd39{eM#MSIιEiHz|3{̲l3,KkV'@EEQlwyiq]Kh4:mĦ,;ts\aR5/7'Wps׭I,K1=0j0Wg> PU𻤝0 ]?qCҫιg~kA_IENDB`libnice-0.1.14/docs/reference/libnice/html/libnice-StunAgent.html0000664000076400007640000022431513070512356021606 00000000000000 StunAgent: libnice Reference Manual

StunAgent

StunAgent — STUN agent for building and validating STUN messages

Stability Level

Stable, unless otherwise indicated

Includes

#include <stun/stunagent.h>

Description

The STUN Agent allows you to create and validate STUN messages easily. It's main purpose is to make sure the building and validation methods used are compatible with the RFC you create it with. It also tracks the transaction ids of the requests you send, so you can validate if a STUN response you received should be processed by that agent or not.

Functions

StunMessageIntegrityValidate ()

bool
(*StunMessageIntegrityValidate) (StunAgent *agent,
                                 StunMessage *message,
                                 uint8_t *username,
                                 uint16_t username_len,
                                 uint8_t **password,
                                 size_t *password_len,
                                 void *user_data);

This is the prototype for the validater argument of the stun_agent_validate() function.

See also: stun_agent_validate()

Parameters

agent

The StunAgent

 

message

The StunMessage being validated

 

username

The username found in the message

 

username_len

The length of username

 

password

The password associated with that username. This argument is a pointer to a byte array that must be set by the validater function.

 

password_len

The length of password which must also be set by the validater function.

 

user_data

Data to give the function

 

Returns

TRUE if the authentication was successful, FALSE if the authentication failed


StunDebugHandler ()

void
(*StunDebugHandler) (const char *format,
                     va_list ap);

Callback for a debug message from the STUN code.

Parameters

format

printf()-style debug message format string

 

ap

Parameters to substitute into message placeholders

 

stun_agent_init ()

void
stun_agent_init (StunAgent *agent,
                 const uint16_t *known_attributes,
                 StunCompatibility compatibility,
                 StunAgentUsageFlags usage_flags);

This function must be called to initialize an agent before it is being used.

The known_attributes data must exist in memory as long as the agent is used

If the STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS and STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS usage flags are not set, then the agent will default in using the short term credentials mechanism

The STUN_AGENT_USAGE_USE_FINGERPRINT and STUN_AGENT_USAGE_ADD_SOFTWARE usage flags are only valid if the STUN_COMPATIBILITY_RFC5389 or STUN_COMPATIBILITY_MSICE2 compatibility is used

Parameters

agent

The StunAgent to initialize

 

known_attributes

An array of uint16_t specifying which attributes should be known by the agent. Any STUN message received that contains a mandatory attribute that is not in this array will yield a STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE or a STUN_VALIDATION_UNKNOWN_ATTRIBUTE error when calling stun_agent_validate()

 

compatibility

The StunCompatibility to use for this agent. This will affect how the agent builds and validates the STUN messages

 

usage_flags

A bitflag using StunAgentUsageFlags values to define which STUN usages the agent should use.

 

stun_agent_validate ()

StunValidationStatus
stun_agent_validate (StunAgent *agent,
                     StunMessage *msg,
                     const uint8_t *buffer,
                     size_t buffer_len,
                     StunMessageIntegrityValidate validater,
                     void *validater_data);

This function is used to validate an inbound STUN message and transform its data buffer into a StunMessage. It will take care of various validation algorithms to make sure that the STUN message is valid and correctly authenticated.

See also: stun_agent_default_validater()

Parameters

agent

The StunAgent

 

msg

The StunMessage to build

 

buffer

The data buffer of the STUN message

 

buffer_len

The length of buffer

 

validater

A StunMessageIntegrityValidate function callback that will be called if the agent needs to validate a MESSAGE-INTEGRITY attribute. It will only be called if the agent finds a message that needs authentication and a USERNAME is present in the STUN message, but no password is known. The validater will not be called if the STUN_AGENT_USAGE_IGNORE_CREDENTIALS usage flag is set on the agent, and it will always be called if the STUN_AGENT_USAGE_FORCE_VALIDATER usage flag is set on the agent.

 

validater_data

A user data to give to the validater callback when it gets called.

 

Returns

A StunValidationStatus

if the return value is different from STUN_VALIDATION_NOT_STUN or STUN_VALIDATION_INCOMPLETE_STUN, then the msg argument will contain a valid STUN message that can be used. This means that you can use the msg variable as the request argument to functions like stun_agent_init_error() or stun_agent_build_unknown_attributes_error(). If the return value is STUN_VALIDATION_BAD_REQUEST, STUN_VALIDATION_UNAUTHORIZED or STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST then the key in the StunMessage will not be set, so that error responses will not have a MESSAGE-INTEGRITY attribute.


stun_agent_default_validater ()

bool
stun_agent_default_validater (StunAgent *agent,
                              StunMessage *message,
                              uint8_t *username,
                              uint16_t username_len,
                              uint8_t **password,
                              size_t *password_len,
                              void *user_data);

This is a helper function to be used with stun_agent_validate(). If no complicated processing of the username needs to be done, this function can be used with stun_agent_validate() to quickly and easily match the username of a STUN message with its password. Its user_data argument must be an array of StunDefaultValidaterData which will allow us to map a username to a password

See also: stun_agent_validate()

Parameters

agent

The StunAgent

 

message

The StunMessage being validated

 

username

The username found in the message

 

username_len

The length of username

 

password

The password associated with that username. This argument is a pointer to a byte array that must be set by the validater function.

 

password_len

The length of password which must also be set by the validater function.

 

user_data

This must be an array of StunDefaultValidaterData structures. The last element in the array must have a username set to NULL

 

Returns

TRUE if the authentication was successful, FALSE if the authentication failed


stun_agent_init_request ()

bool
stun_agent_init_request (StunAgent *agent,
                         StunMessage *msg,
                         uint8_t *buffer,
                         size_t buffer_len,
                         StunMethod m);

Creates a new STUN message of class STUN_REQUEST and with the method m

Parameters

agent

The StunAgent

 

msg

The StunMessage to build

 

buffer

The buffer to use in the StunMessage

 

buffer_len

The length of the buffer

 

m

The StunMethod of the request

 

Returns

TRUE if the message was initialized correctly, FALSE otherwise


stun_agent_init_indication ()

bool
stun_agent_init_indication (StunAgent *agent,
                            StunMessage *msg,
                            uint8_t *buffer,
                            size_t buffer_len,
                            StunMethod m);

Creates a new STUN message of class STUN_INDICATION and with the method m

Parameters

agent

The StunAgent

 

msg

The StunMessage to build

 

buffer

The buffer to use in the StunMessage

 

buffer_len

The length of the buffer

 

m

The StunMethod of the indication

 

Returns

TRUE if the message was initialized correctly, FALSE otherwise


stun_agent_init_response ()

bool
stun_agent_init_response (StunAgent *agent,
                          StunMessage *msg,
                          uint8_t *buffer,
                          size_t buffer_len,
                          const StunMessage *request);

Creates a new STUN message of class STUN_RESPONSE and with the same method and transaction ID as the message request . This will also copy the pointer to the key that was used to authenticate the request, so you won't need to specify the key with stun_agent_finish_message()

Parameters

agent

The StunAgent

 

msg

The StunMessage to build

 

buffer

The buffer to use in the StunMessage

 

buffer_len

The length of the buffer

 

request

The StunMessage of class STUN_REQUEST that this response is for

 

Returns

TRUE if the message was initialized correctly, FALSE otherwise


stun_agent_init_error ()

bool
stun_agent_init_error (StunAgent *agent,
                       StunMessage *msg,
                       uint8_t *buffer,
                       size_t buffer_len,
                       const StunMessage *request,
                       StunError err);

Creates a new STUN message of class STUN_ERROR and with the same method and transaction ID as the message request . This will also copy the pointer to the key that was used to authenticate the request (if authenticated), so you won't need to specify the key with stun_agent_finish_message(). It will then add the ERROR-CODE attribute with code err and the associated string.

Parameters

agent

The StunAgent

 

msg

The StunMessage to build

 

buffer

The buffer to use in the StunMessage

 

buffer_len

The length of the buffer

 

request

The StunMessage of class STUN_REQUEST that this error response is for

 

err

The StunError to put in the ERROR-CODE attribute of the error response

 

Returns

TRUE if the message was initialized correctly, FALSE otherwise


stun_agent_build_unknown_attributes_error ()

size_t
stun_agent_build_unknown_attributes_error
                               (StunAgent *agent,
                                StunMessage *msg,
                                uint8_t *buffer,
                                size_t buffer_len,
                                const StunMessage *request);

Creates a new STUN message of class STUN_ERROR and with the same method and transaction ID as the message request . It will then add the ERROR-CODE attribute with code STUN_ERROR_UNKNOWN_ATTRIBUTE and add all the unknown mandatory attributes from the request STUN message in the STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES attribute, it will then finish the message by calling stun_agent_finish_message()

Parameters

agent

The StunAgent

 

msg

The StunMessage to build

 

buffer

The buffer to use in the StunMessage

 

buffer_len

The length of the buffer

 

request

The StunMessage of class STUN_REQUEST that this response is for

 

Returns

The size of the message built


stun_agent_finish_message ()

size_t
stun_agent_finish_message (StunAgent *agent,
                           StunMessage *msg,
                           const uint8_t *key,
                           size_t key_len);

This function will 'finish' a message and make it ready to be sent. It will add the MESSAGE-INTEGRITY and FINGERPRINT attributes if necessary. If the STUN message has a STUN_REQUEST class, it will save the transaction id of the message in the agent for future matching of the response.

See also: stun_agent_forget_transaction()

Parameters

agent

The StunAgent

 

msg

The StunMessage to finish

 

key

The key to use for the MESSAGE-INTEGRITY attribute

 

key_len

The length of the key

 

Returns

The final size of the message built or 0 if an error occured

The return value must always be checked. a value of 0 means the either the buffer's size is too small to contain the finishing attributes (MESSAGE-INTEGRITY, FINGERPRINT), or that there is no more free slots for saving the sent id in the agent's state.

Everytime stun_agent_finish_message() is called for a STUN_REQUEST message, you must make sure to call stun_agent_forget_transaction() in case the response times out and is never received. This is to avoid filling up the StunAgent's sent ids state preventing any further use of the stun_agent_finish_message()


stun_agent_forget_transaction ()

bool
stun_agent_forget_transaction (StunAgent *agent,
                               StunTransactionId id);

This function is used to make the StunAgent forget about a previously created transaction.

This function should be called when a STUN request was previously created with stun_agent_finish_message() and for which no response was ever received (timed out). The StunAgent keeps a list of the sent transactions in order to validate the responses received. If the response is never received this will allow the StunAgent to forget about the timed out transaction and free its slot for future transactions.

Parameters

agent

The StunAgent

 

id

The StunTransactionId of the transaction to forget

 

Returns

TRUE if the transaction was found, FALSE otherwise

Since: 0.0.6


stun_agent_set_software ()

void
stun_agent_set_software (StunAgent *agent,
                         const char *software);

This function will set the value of the SOFTWARE attribute to be added to STUN requests, responses and error responses.

Calling this function will automatically enable the addition of the SOFTWARE attribute for RFC5389 and MSICE2 compatibility modes.

The software argument must be in UTF-8 encoding and only the first 128 characters will be sent.

The value of the software argument must stay valid throughout the life of the StunAgent's life. Do not free its content.

Parameters

agent

The StunAgent

 

software

The value of the SOFTWARE attribute to add.

 

Since: 0.0.10


stun_debug_enable ()

void
stun_debug_enable (void);

Enable debug messages to stderr


stun_debug_disable ()

void
stun_debug_disable (void);

Disable debug messages to stderr


stun_set_debug_handler ()

void
stun_set_debug_handler (StunDebugHandler handler);

Set a callback function to be invoked for each debug message from the STUN code. The callback will only be invoked if STUN debugging is enabled using stun_debug_enable().

The default callback prints the formatted debug message to stderr.

Parameters

handler

Handler for STUN debug messages, or NULL to use the default.

[nullable]

Types and Values

StunAgent

typedef struct stun_agent_t StunAgent;

An opaque structure representing the STUN agent.


enum StunCompatibility

Enum that specifies the STUN compatibility mode of the StunAgent

STUN_COMPATIBILITY_WLM2009 is deprecated and should not be used in newly-written code. It is kept for compatibility reasons and represents the same compatibility as STUN_COMPATIBILITY_MSICE2.

Members

STUN_COMPATIBILITY_RFC3489

Use the STUN specifications compatible with RFC 3489

 

STUN_COMPATIBILITY_RFC5389

Use the STUN specifications compatible with RFC 5389

 

STUN_COMPATIBILITY_MSICE2

Use the STUN specifications compatible with [MS-ICE2] (a mix between RFC3489 and RFC5389)

 

STUN_COMPATIBILITY_OC2007

Use the STUN specifications compatible with Microsoft Office Communicator 2007 (basically RFC3489 with swapped REALM and NONCE attribute hex IDs, attributes are not aligned)

 

STUN_COMPATIBILITY_WLM2009

An alias for STUN_COMPATIBILITY_MSICE2

 

STUN_COMPATIBILITY_LAST

Dummy last compatibility mode

 

enum StunAgentUsageFlags

This enum defines a bitflag usages for a StunAgent and they will define how the agent should behave, independently of the compatibility mode it uses.

See also: stun_agent_init()

See also: stun_agent_validate()

Members

STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS

The agent should be using the short term credentials mechanism for authenticating STUN messages

 

STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS

The agent should be using the long term credentials mechanism for authenticating STUN messages

 

STUN_AGENT_USAGE_USE_FINGERPRINT

The agent should add the FINGERPRINT attribute to the STUN messages it creates.

 

STUN_AGENT_USAGE_ADD_SOFTWARE

The agent should add the SOFTWARE attribute to the STUN messages it creates. Calling nice_agent_set_software() will have the same effect as enabling this Usage. STUN Indications do not have the SOFTWARE attributes added to them though. The SOFTWARE attribute is only added for the RFC5389 and MSICE2 compatibility modes.

 

STUN_AGENT_USAGE_IGNORE_CREDENTIALS

The agent should ignore any credentials in the STUN messages it receives (the MESSAGE-INTEGRITY attribute will never be validated by stun_agent_validate())

 

STUN_AGENT_USAGE_NO_INDICATION_AUTH

The agent should ignore credentials in the STUN messages it receives if the StunClass of the message is STUN_INDICATION (some implementation require STUN_INDICATION messages to be authenticated, while others never add a MESSAGE-INTEGRITY attribute to a STUN_INDICATION message)

 

STUN_AGENT_USAGE_FORCE_VALIDATER

The agent should always try to validate the password of a STUN message, even if it already knows what the password should be (a response to a previously created request). This means that the StunMessageIntegrityValidate callback will always be called when there is a MESSAGE-INTEGRITY attribute.

 

STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES

The agent should not assume STUN attributes are aligned on 32-bit boundaries when parsing messages and also do not add padding when creating messages.

 

enum StunValidationStatus

This enum is used as the return value of stun_agent_validate() and represents the status result of the validation of a STUN message.

Members

STUN_VALIDATION_SUCCESS

The message is validated

 

STUN_VALIDATION_NOT_STUN

This is not a valid STUN message

 

STUN_VALIDATION_INCOMPLETE_STUN

The message seems to be valid but incomplete

 

STUN_VALIDATION_BAD_REQUEST

The message does not have the cookie or the fingerprint while the agent needs it with its usage

 

STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST

The message is valid but unauthorized with no username and message-integrity attributes. A BAD_REQUEST error must be generated

 

STUN_VALIDATION_UNAUTHORIZED

The message is valid but unauthorized as the username/password do not match. An UNAUTHORIZED error must be generated

 

STUN_VALIDATION_UNMATCHED_RESPONSE

The message is valid but this is a response/error that doesn't match a previously sent request

 

STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE

The message is valid but contains one or more unknown comprehension attributes. stun_agent_build_unknown_attributes_error() should be called

 

STUN_VALIDATION_UNKNOWN_ATTRIBUTE

The message is valid but contains one or more unknown comprehension attributes. This is a response, or error, or indication message and no error response should be sent

 

StunDefaultValidaterData

typedef struct {
  uint8_t *username;
  size_t username_len;
  uint8_t *password;
  size_t password_len;
} StunDefaultValidaterData;

This structure is used as an element of the user_data to the stun_agent_default_validater() function for authenticating a STUN message during validationg.

See also: stun_agent_default_validater()

Members

uint8_t *username;

The username

 

size_t username_len;

The length of the username

 

uint8_t *password;

The password

 

size_t password_len;

The length of the password

 

See Also

StunMessage

libnice-0.1.14/docs/reference/libnice/html/ix06.html0000664000076400007640000000373013070512356017055 00000000000000 Index of new symbols in 0.0.9: libnice Reference Manual

Index of new symbols in 0.0.9

A

nice_agent_set_stream_tos, function in NiceAgent
libnice-0.1.14/docs/reference/libnice/html/NiceAgent.html0000664000076400007640000077455413070512356020147 00000000000000 NiceAgent: libnice Reference Manual

NiceAgent

NiceAgent — ICE agent API implementation

Stability Level

Stable, unless otherwise indicated

Functions

void (*NiceAgentRecvFunc) ()
NiceAgent * nice_agent_new ()
NiceAgent * nice_agent_new_reliable ()
gboolean nice_agent_add_local_address ()
void nice_agent_set_port_range ()
guint nice_agent_add_stream ()
void nice_agent_remove_stream ()
gboolean nice_agent_set_relay_info ()
gboolean nice_agent_forget_relays ()
gboolean nice_agent_gather_candidates ()
gboolean nice_agent_set_remote_credentials ()
gboolean nice_agent_get_local_credentials ()
gboolean nice_agent_set_local_credentials ()
int nice_agent_set_remote_candidates ()
GSList * nice_agent_get_remote_candidates ()
GSList * nice_agent_get_local_candidates ()
gboolean nice_agent_get_selected_pair ()
gint nice_agent_send ()
gint nice_agent_send_messages_nonblocking ()
gssize nice_agent_recv ()
gint nice_agent_recv_messages ()
gssize nice_agent_recv_nonblocking ()
gint nice_agent_recv_messages_nonblocking ()
gboolean nice_agent_attach_recv ()
gboolean nice_agent_set_selected_pair ()
gboolean nice_agent_set_selected_remote_candidate ()
void nice_agent_set_stream_tos ()
void nice_agent_set_software ()
gboolean nice_agent_restart ()
gboolean nice_agent_restart_stream ()
gboolean nice_agent_set_stream_name ()
const gchar * nice_agent_get_stream_name ()
NiceCandidate * nice_agent_get_default_local_candidate ()
gchar * nice_agent_generate_local_sdp ()
gchar * nice_agent_generate_local_stream_sdp ()
gchar * nice_agent_generate_local_candidate_sdp ()
int nice_agent_parse_remote_sdp ()
GSList * nice_agent_parse_remote_stream_sdp ()
NiceCandidate * nice_agent_parse_remote_candidate_sdp ()
GIOStream * nice_agent_get_io_stream ()
GSocket * nice_agent_get_selected_socket ()
NiceComponentState nice_agent_get_component_state ()
const gchar * nice_component_state_to_string ()

Properties

gboolean bytestream-tcp Read
guint compatibility Read / Write / Construct Only
gboolean controlling-mode Read / Write
gboolean force-relay Read / Write
gboolean full-mode Read / Write / Construct Only
gboolean ice-tcp Read / Write
gboolean ice-udp Read / Write
gboolean keepalive-conncheck Read / Write
gpointer main-context Read / Write / Construct Only
guint max-connectivity-checks Read / Write
gchar * proxy-ip Read / Write
gchar * proxy-password Read / Write
guint proxy-port Read / Write
guint proxy-type Read / Write
gchar * proxy-username Read / Write
gboolean reliable Read / Write / Construct Only
guint stun-pacing-timer Read / Write / Construct
gchar * stun-server Read / Write
guint stun-server-port Read / Write
gboolean upnp Read / Write / Construct
guint upnp-timeout Read / Write / Construct

Object Hierarchy

    GObject
    ╰── NiceAgent

Includes

#include <agent.h>

Description

The NiceAgent is your main object when using libnice. It is the agent that will take care of everything relating to ICE. It will take care of discovering your local candidates and do connectivity checks to create a stream of data between you and your peer.

A NiceAgent must always be used with a GMainLoop running the GMainContext passed into nice_agent_new() (or nice_agent_new_reliable()). Without the GMainContext being iterated, the agent’s timers will not fire, etc.

Streams and their components are referenced by integer IDs (with respect to a given NiceAgent). These IDs are guaranteed to be positive (i.e. non-zero) for valid streams/components.

To complete the ICE connectivity checks, the user must either register an I/O callback (with nice_agent_attach_recv()) or call nice_agent_recv_messages() in a loop on a dedicated thread. Technically, NiceAgent does not poll the streams on its own, since user data could arrive at any time; to receive STUN packets required for establishing ICE connectivity, it is backpiggying on the facility chosen by the user. NiceAgent will handle all STUN packets internally; they're never actually passed to the I/O callback or returned from nice_agent_recv_messages() and related functions.

Each stream can receive data in one of two ways: using nice_agent_attach_recv() or nice_agent_recv_messages() (and the derived NiceInputStream and NiceIOStream classes accessible using nice_agent_get_io_stream()). nice_agent_attach_recv() is non-blocking: it takes a user-provided callback function and attaches the stream’s socket to the provided GMainContext, invoking the callback in that context for every packet received. nice_agent_recv_messages() instead blocks on receiving a packet, and writes it directly into a user-provided buffer. This reduces the number of callback invokations and (potentially) buffer copies required to receive packets. nice_agent_recv_messages() (or NiceInputStream) is designed to be used in a blocking loop in a separate thread.

Example 1. Simple example on how to use libnice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
guint stream_id;
gchar buffer[] = "hello world!";
gchar *ufrag = NULL, *pwd = NULL;
gchar *remote_ufrag, *remote_pwd;
GSList *lcands = NULL;

// Create a nice agent, passing in the global default GMainContext.
NiceAgent *agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245);
spawn_thread_to_run_main_loop (g_main_loop_new (NULL, FALSE));

// Connect the signals
g_signal_connect (G_OBJECT (agent), "candidate-gathering-done",
                  G_CALLBACK (cb_candidate_gathering_done), NULL);
g_signal_connect (G_OBJECT (agent), "component-state-changed",
                  G_CALLBACK (cb_component_state_changed), NULL);
g_signal_connect (G_OBJECT (agent), "new-selected-pair",
                  G_CALLBACK (cb_new_selected_pair), NULL);

// Create a new stream with one component and start gathering candidates
stream_id = nice_agent_add_stream (agent, 1);
nice_agent_gather_candidates (agent, stream_id);

// Attach I/O callback the component to ensure that:
// 1) agent gets its STUN packets (not delivered to cb_nice_recv)
// 2) you get your own data
nice_agent_attach_recv (agent, stream_id, 1, NULL,
                       cb_nice_recv, NULL);

// ... Wait until the signal candidate-gathering-done is fired ...
lcands = nice_agent_get_local_candidates(agent, stream_id, 1);

nice_agent_get_local_credentials(agent, stream_id, &ufrag, &pwd);

// ... Send local candidates and credentials to the peer

// Set the peer's remote credentials and remote candidates
nice_agent_set_remote_credentials (agent, stream_id, remote_ufrag, remote_pwd);
nice_agent_set_remote_candidates (agent, stream_id, 1, rcands);

// ... Wait until the signal new-selected-pair is fired ...
// Send our message!
nice_agent_send (agent, stream_id, 1, sizeof(buffer), buffer);

// Anything received will be received through the cb_nice_recv callback.
// You must be running a GMainLoop on the global default GMainContext in
// another thread for this to work.

// Destroy the object
g_object_unref(agent);

Refer to the examples in the examples/ subdirectory of the libnice source for more complete examples.

Functions

NiceAgentRecvFunc ()

void
(*NiceAgentRecvFunc) (NiceAgent *agent,
                      guint stream_id,
                      guint component_id,
                      guint len,
                      gchar *buf,
                      gpointer user_data);

Callback function when data is received on a component

Parameters

agent

The NiceAgent Object

 

stream_id

The id of the stream

 

component_id

The id of the component of the stream which received the data

 

len

The length of the data

 

buf

The buffer containing the data received

 

user_data

The user data set in nice_agent_attach_recv()

 

nice_agent_new ()

NiceAgent *
nice_agent_new (GMainContext *ctx,
                NiceCompatibility compat);

Create a new NiceAgent. The returned object must be freed with g_object_unref()

Parameters

ctx

The Glib Mainloop Context to use for timers

 

compat

The compatibility mode of the agent

 

Returns

The new agent GObject


nice_agent_new_reliable ()

NiceAgent *
nice_agent_new_reliable (GMainContext *ctx,
                         NiceCompatibility compat);

Create a new NiceAgent in reliable mode. If the connectivity is established through ICE-UDP, then a PseudoTcpSocket will be transparently used to ensure reliability of the messages. The returned object must be freed with g_object_unref()

See also: “reliable-transport-writable”

Parameters

ctx

The Glib Mainloop Context to use for timers

 

compat

The compatibility mode of the agent

 

Returns

The new agent GObject

Since: 0.0.11


nice_agent_add_local_address ()

gboolean
nice_agent_add_local_address (NiceAgent *agent,
                              NiceAddress *addr);

Add a local address from which to derive local host candidates for candidate gathering.

Since 0.0.5, if this method is not called, libnice will automatically discover the local addresses available

See also: nice_agent_gather_candidates()

Parameters

agent

The NiceAgent Object

 

addr

The address to listen to If the port is 0, then a random port will be chosen by the system

 

Returns

TRUE on success, FALSE on fatal (memory allocation) errors


nice_agent_set_port_range ()

void
nice_agent_set_port_range (NiceAgent *agent,
                           guint stream_id,
                           guint component_id,
                           guint min_port,
                           guint max_port);

Sets a preferred port range for allocating host candidates.

If a local host candidate cannot be created on that port range, then the nice_agent_gather_candidates() call will fail.

This MUST be called before nice_agent_gather_candidates()

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

min_port

The minimum port to use

 

max_port

The maximum port to use

 

nice_agent_add_stream ()

guint
nice_agent_add_stream (NiceAgent *agent,
                       guint n_components);

Adds a data stream to agent containing n_components components. The returned stream ID is guaranteed to be positive on success.

Parameters

agent

The NiceAgent Object

 

n_components

The number of components to add to the stream

 

Returns

The ID of the new stream, 0 on failure


nice_agent_remove_stream ()

void
nice_agent_remove_stream (NiceAgent *agent,
                          guint stream_id);

Remove and free a previously created data stream from agent . If any I/O streams have been created using nice_agent_get_io_stream(), they should be closed completely using g_io_stream_close() before this is called, or they will get broken pipe errors.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream to remove

 

nice_agent_set_relay_info ()

gboolean
nice_agent_set_relay_info (NiceAgent *agent,
                           guint stream_id,
                           guint component_id,
                           const gchar *server_ip,
                           guint server_port,
                           const gchar *username,
                           const gchar *password,
                           NiceRelayType type);

Sets the settings for using a relay server during the candidate discovery. This may be called multiple times to add multiple relay servers to the discovery process; one TCP and one UDP, for example.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

server_ip

The IP address of the TURN server

 

server_port

The port of the TURN server

 

username

The TURN username to use for the allocate

 

password

The TURN password to use for the allocate

 

type

The type of relay to use

 

Returns

TRUE if the TURN settings were accepted. FALSE if the address was invalid.


nice_agent_forget_relays ()

gboolean
nice_agent_forget_relays (NiceAgent *agent,
                          guint stream_id,
                          guint component_id);

Forget all the relay servers previously added using nice_agent_set_relay_info(). Currently connected streams will keep using the relay as long as they have not been restarted and haven't succesfully negotiated a different path.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

Returns

FALSE if the component could not be found, TRUE otherwise

Since: 0.1.6


nice_agent_gather_candidates ()

gboolean
nice_agent_gather_candidates (NiceAgent *agent,
                              guint stream_id);

Allocate and start listening on local candidate ports and start the remote candidate gathering process. Once done, “candidate-gathering-done” is called for the stream. As soon as this function is called, “new-candidate” signals may be emitted, even before this function returns.

nice_agent_get_local_candidates() will only return non-empty results after calling this function.

See also: nice_agent_add_local_address()

See also: nice_agent_set_port_range()

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream to start

 

Returns

FALSE if the stream ID is invalid or if a host candidate couldn't be allocated on the requested interfaces/ports; TRUE otherwise

Local addresses can be previously set with nice_agent_add_local_address()

Since 0.0.5, If no local address was previously added, then the nice agent will automatically detect the local address using nice_interfaces_get_local_ips()


nice_agent_set_remote_credentials ()

gboolean
nice_agent_set_remote_credentials (NiceAgent *agent,
                                   guint stream_id,
                                   const gchar *ufrag,
                                   const gchar *pwd);

Sets the remote credentials for stream stream_id .

Stream credentials do not override per-candidate credentials if set

Due to the native of peer-reflexive candidates, any agent using a per-stream credentials (RFC5245, WLM2009, OC2007R2 and DRAFT19) instead of per-candidate credentials (GOOGLE, MSN, OC2007), must use the nice_agent_set_remote_credentials() API instead of setting the username and password on the candidates.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

ufrag

nul-terminated string containing an ICE username fragment (length must be between 22 and 256 chars)

 

pwd

nul-terminated string containing an ICE password (length must be between 4 and 256 chars)

 

Returns

TRUE on success, FALSE on error.


nice_agent_get_local_credentials ()

gboolean
nice_agent_get_local_credentials (NiceAgent *agent,
                                  guint stream_id,
                                  gchar **ufrag,
                                  gchar **pwd);

Gets the local credentials for stream stream_id . This may be called any time after creating a stream using nice_agent_add_stream().

An error will be returned if this is called for a non-existent stream, or if either of ufrag or pwd are NULL.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

ufrag

return location for a nul-terminated string containing an ICE username fragment; must be freed with g_free().

[out callee-allocates]

pwd

return location for a nul-terminated string containing an ICE password; must be freed with g_free().

[out callee-allocates]

Returns

TRUE on success, FALSE on error.


nice_agent_set_local_credentials ()

gboolean
nice_agent_set_local_credentials (NiceAgent *agent,
                                  guint stream_id,
                                  const gchar *ufrag,
                                  const gchar *pwd);

Sets the local credentials for stream stream_id .

This is only effective before ICE negotiation has started.

Since 0.1.11

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

ufrag

nul-terminated string containing an ICE username fragment (length must be between 22 and 256 chars)

 

pwd

nul-terminated string containing an ICE password (length must be between 4 and 256 chars)

 

Returns

TRUE on success, FALSE on error.


nice_agent_set_remote_candidates ()

int
nice_agent_set_remote_candidates (NiceAgent *agent,
                                  guint stream_id,
                                  guint component_id,
                                  const GSList *candidates);

Sets, adds or updates the remote candidates for a component of a stream.

NICE_AGENT_MAX_REMOTE_CANDIDATES is the absolute maximum limit for remote candidates.

You must first call nice_agent_gather_candidates() and wait for the “candidate-gathering-done” signale before calling nice_agent_set_remote_candidates()

Since 0.1.3, there is no need to wait for the candidate-gathering-done signal. Remote candidates can be set even while gathering local candidates. Newly discovered local candidates will automatically be paired with existing remote candidates.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream the candidates are for

 

component_id

The ID of the component the candidates are for

 

candidates

a GSList of NiceCandidate items describing each candidate to add.

[element-type NiceCandidate][transfer none]

Returns

The number of candidates added, negative on errors (memory allocation error or invalid component)


nice_agent_get_remote_candidates ()

GSList *
nice_agent_get_remote_candidates (NiceAgent *agent,
                                  guint stream_id,
                                  guint component_id);

Get a list of the remote candidates set on a stream's component

The caller owns the returned GSList as well as the candidates contained within it.

The list of remote candidates can change during processing. The client should register for the “new-remote-candidate” signal to get notified of new remote candidates.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

Returns

a GSList of NiceCandidates objects representing the remote candidates set on the agent .

[element-type NiceCandidate][transfer full]


nice_agent_get_local_candidates ()

GSList *
nice_agent_get_local_candidates (NiceAgent *agent,
                                 guint stream_id,
                                 guint component_id);

Retrieve from the agent the list of all local candidates for a stream's component

The caller owns the returned GSList as well as the candidates contained within it. To get full results, the client should wait for the “candidate-gathering-done” signal.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

Returns

a GSList of NiceCandidate objects representing the local candidates of agent .

[element-type NiceCandidate][transfer full]


nice_agent_get_selected_pair ()

gboolean
nice_agent_get_selected_pair (NiceAgent *agent,
                              guint stream_id,
                              guint component_id,
                              NiceCandidate **local,
                              NiceCandidate **remote);

Retreive the selected candidate pair for media transmission for a given stream's component.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

local

The local selected candidate

 

remote

The remote selected candidate

 

Returns

TRUE on success, FALSE if there is no selected candidate pair


nice_agent_send ()

gint
nice_agent_send (NiceAgent *agent,
                 guint stream_id,
                 guint component_id,
                 guint len,
                 const gchar *buf);

Sends a data payload over a stream's component.

Component state MUST be NICE_COMPONENT_STATE_READY, or as a special case, in any state if component was in READY state before and was then restarted

In reliable mode, the -1 error value means either that you are not yet connected or that the send buffer is full (equivalent to EWOULDBLOCK). In both cases, you simply need to wait for the “reliable-transport-writable” signal to be fired before resending the data.

In non-reliable mode, it will virtually never happen with UDP sockets, but it might happen if the active candidate is a TURN-TCP connection that got disconnected.

In both reliable and non-reliable mode, a -1 error code could also mean that the stream_id and/or component_id are invalid.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream to send to

 

component_id

The ID of the component to send to

 

len

The length of the buffer to send

 

buf

The buffer of data to send

 

Returns

The number of bytes sent, or negative error code


nice_agent_send_messages_nonblocking ()

gint
nice_agent_send_messages_nonblocking (NiceAgent *agent,
                                      guint stream_id,
                                      guint component_id,
                                      const NiceOutputMessage *messages,
                                      guint n_messages,
                                      GCancellable *cancellable,
                                      GError **error);

Sends multiple messages on the socket identified by the given stream/component pair. Transmission is non-blocking, so a G_IO_ERROR_WOULD_BLOCK error may be returned if the send buffer is full.

As with nice_agent_send(), the given component must be in NICE_COMPONENT_STATE_READY or, as a special case, in any state if it was previously ready and was then restarted.

On success, the number of messages written to the socket will be returned, which may be less than n_messages if transmission would have blocked part-way through. Zero will be returned if n_messages is zero, or if transmission would have blocked on the first message.

In reliable mode, it is instead recommended to use nice_agent_send(). The return value can be less than n_messages or 0 even if it is still possible to send a partial message. In this case, "nice-agent-writable" will never be triggered, so the application would have to use nice_agent_sent() to fill the buffer or have to retry sending at a later point.

On failure, -1 will be returned and error will be set. If the NiceAgent is reliable and the socket is not yet connected, G_IO_ERROR_BROKEN_PIPE will be returned; if the write buffer is full, G_IO_ERROR_WOULD_BLOCK will be returned. In both cases, wait for the “reliable-transport-writable” signal before trying again. If the given stream_id or component_id are invalid or not yet connected, G_IO_ERROR_BROKEN_PIPE will be returned. G_IO_ERROR_FAILED will be returned for other errors.

Parameters

agent

a NiceAgent

 

stream_id

the ID of the stream to send to

 

component_id

the ID of the component to send to

 

messages

array of messages to send, of at least n_messages entries in length.

[array length=n_messages]

n_messages

number of entries in messages

 

cancellable

a GCancellable to cancel the operation from another thread, or NULL.

[allow-none]

error

return location for a GError, or NULL.

[allow-none]

Returns

the number of messages sent (may be zero), or -1 on error

Since: 0.1.5


nice_agent_recv ()

gssize
nice_agent_recv (NiceAgent *agent,
                 guint stream_id,
                 guint component_id,
                 guint8 *buf,
                 gsize buf_len,
                 GCancellable *cancellable,
                 GError **error);

A single-message version of nice_agent_recv_messages().

Parameters

agent

a NiceAgent

 

stream_id

the ID of the stream to receive on

 

component_id

the ID of the component to receive on

 

buf

caller-allocated buffer to write the received data into, of length at least buf_len .

[array length=buf_len][out caller-allocates]

buf_len

length of buf

 

cancellable

a GCancellable to allow the operation to be cancelled from another thread, or NULL.

[allow-none]

error

return location for a GError, or NULL.

[allow-none]

Returns

the number of bytes written to buf on success (guaranteed to be greater than 0 unless buf_len is 0), 0 if in reliable mode and the remote peer closed the stream, or -1 on error

Since: 0.1.5


nice_agent_recv_messages ()

gint
nice_agent_recv_messages (NiceAgent *agent,
                          guint stream_id,
                          guint component_id,
                          NiceInputMessage *messages,
                          guint n_messages,
                          GCancellable *cancellable,
                          GError **error);

Block on receiving data from the given stream/component combination on agent , returning only once exactly n_messages messages have been received and written into messages , the stream is closed by the other end or by calling nice_agent_remove_stream(), or cancellable is cancelled.

Any STUN packets received will not be added to messages ; instead, they'll be passed for processing to NiceAgent itself. Since NiceAgent does not poll for messages on its own, it's therefore essential to keep calling this function for ICE connection establishment to work.

In the non-error case, in reliable mode, this will block until all buffers in all n_messages have been filled with received data (i.e. messages is treated as a large, flat array of buffers). In non-reliable mode, it will block until n_messages messages have been received, each of which does not have to fill all the buffers in its NiceInputMessage. In the non-reliable case, each NiceInputMessage must have enough buffers to contain an entire message (65536 bytes), or any excess data may be silently dropped.

For each received message, “length” will be set to the number of valid bytes stored in the message’s buffers. The bytes are stored sequentially in the buffers; there are no gaps apart from at the end of the buffer array (in non-reliable mode). If non-NULL on input, “from” will have the address of the sending peer stored in it. The base addresses, sizes, and number of buffers in each message will not be modified in any case.

This must not be used in combination with nice_agent_attach_recv() on the same stream/component pair.

If the stream/component pair doesn’t exist, or if a suitable candidate socket hasn’t yet been selected for it, a G_IO_ERROR_BROKEN_PIPE error will be returned. A G_IO_ERROR_CANCELLED error will be returned if the operation was cancelled. G_IO_ERROR_FAILED will be returned for other errors.

Parameters

agent

a NiceAgent

 

stream_id

the ID of the stream to receive on

 

component_id

the ID of the component to receive on

 

messages

caller-allocated array of NiceInputMessages to write the received messages into, of length at least n_messages .

[array length=n_messages][out caller-allocates]

n_messages

number of entries in messages

 

cancellable

a GCancellable to allow the operation to be cancelled from another thread, or NULL.

[allow-none]

error

return location for a GError, or NULL.

[allow-none]

Returns

the number of valid messages written to messages on success (guaranteed to be greater than 0 unless n_messages is 0), 0 if the remote peer closed the stream, or -1 on error

Since: 0.1.5


nice_agent_recv_nonblocking ()

gssize
nice_agent_recv_nonblocking (NiceAgent *agent,
                             guint stream_id,
                             guint component_id,
                             guint8 *buf,
                             gsize buf_len,
                             GCancellable *cancellable,
                             GError **error);

A single-message version of nice_agent_recv_messages_nonblocking().

Parameters

agent

a NiceAgent

 

stream_id

the ID of the stream to receive on

 

component_id

the ID of the component to receive on

 

buf

caller-allocated buffer to write the received data into, of length at least buf_len .

[array length=buf_len][out caller-allocates]

buf_len

length of buf

 

cancellable

a GCancellable to allow the operation to be cancelled from another thread, or NULL.

[allow-none]

error

return location for a GError, or NULL.

[allow-none]

Returns

the number of bytes received into buf on success (guaranteed to be greater than 0 unless buf_len is 0), 0 if in reliable mode and the remote peer closed the stream, or -1 on error

Since: 0.1.5


nice_agent_recv_messages_nonblocking ()

gint
nice_agent_recv_messages_nonblocking (NiceAgent *agent,
                                      guint stream_id,
                                      guint component_id,
                                      NiceInputMessage *messages,
                                      guint n_messages,
                                      GCancellable *cancellable,
                                      GError **error);

Try to receive data from the given stream/component combination on agent , without blocking. If receiving data would block, -1 is returned and G_IO_ERROR_WOULD_BLOCK is set in error . If any other error occurs, -1 is returned and error is set accordingly. Otherwise, 0 is returned if (and only if) n_messages is 0. In all other cases, the number of valid messages stored in messages is returned, and will be greater than 0.

This function behaves similarly to nice_agent_recv_messages(), except that it will not block on filling (in reliable mode) or receiving (in non-reliable mode) exactly n_messages messages. In reliable mode, it will receive bytes into messages until it would block; in non-reliable mode, it will receive messages until it would block.

Any STUN packets received will not be added to messages ; instead, they'll be passed for processing to NiceAgent itself. Since NiceAgent does not poll for messages on its own, it's therefore essential to keep calling this function for ICE connection establishment to work.

As this function is non-blocking, cancellable is included only for parity with nice_agent_recv_messages(). If cancellable is cancelled before this function is called, a G_IO_ERROR_CANCELLED error will be returned immediately.

This must not be used in combination with nice_agent_attach_recv() on the same stream/component pair.

Parameters

agent

a NiceAgent

 

stream_id

the ID of the stream to receive on

 

component_id

the ID of the component to receive on

 

messages

caller-allocated array of NiceInputMessages to write the received messages into, of length at least n_messages .

[array length=n_messages][out caller-allocates]

n_messages

number of entries in messages

 

cancellable

a GCancellable to allow the operation to be cancelled from another thread, or NULL.

[allow-none]

error

return location for a GError, or NULL.

[allow-none]

Returns

the number of valid messages written to messages on success (guaranteed to be greater than 0 unless n_messages is 0), 0 if in reliable mode and the remote peer closed the stream, or -1 on error

Since: 0.1.5


nice_agent_attach_recv ()

gboolean
nice_agent_attach_recv (NiceAgent *agent,
                        guint stream_id,
                        guint component_id,
                        GMainContext *ctx,
                        NiceAgentRecvFunc func,
                        gpointer data);

Attaches the stream's component's sockets to the Glib Mainloop Context in order to be notified whenever data becomes available for a component, and to enable NiceAgent to receive STUN messages (during the establishment of ICE connectivity).

This must not be used in combination with nice_agent_recv_messages() (or NiceIOStream or NiceInputStream) on the same stream/component pair.

Calling nice_agent_attach_recv() with a NULL func will detach any existing callback and cause reception to be paused for the given stream/component pair. You must iterate the previously specified GMainContext sufficiently to ensure all pending I/O callbacks have been received before calling this function to unset func , otherwise data loss of received packets may occur.

[skip]

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of stream

 

component_id

The ID of the component

 

ctx

The Glib Mainloop Context to use for listening on the component

 

func

The callback function to be called when data is received on the stream's component (will not be called for STUN messages that should be handled by NiceAgent itself)

 

data

user data associated with the callback

 

Returns

TRUE on success, FALSE if the stream or component IDs are invalid.


nice_agent_set_selected_pair ()

gboolean
nice_agent_set_selected_pair (NiceAgent *agent,
                              guint stream_id,
                              guint component_id,
                              const gchar *lfoundation,
                              const gchar *rfoundation);

Sets the selected candidate pair for media transmission for a given stream's component. Calling this function will disable all further ICE processing (connection check, state machine updates, etc). Note that keepalives will continue to be sent.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

lfoundation

The local foundation of the candidate to use

 

rfoundation

The remote foundation of the candidate to use

 

Returns

TRUE on success, FALSE if the candidate pair cannot be found


nice_agent_set_selected_remote_candidate ()

gboolean
nice_agent_set_selected_remote_candidate
                               (NiceAgent *agent,
                                guint stream_id,
                                guint component_id,
                                NiceCandidate *candidate);

Sets the selected remote candidate for media transmission for a given stream's component. This is used to force the selection of a specific remote candidate even when connectivity checks are failing (e.g. non-ICE compatible candidates). Calling this function will disable all further ICE processing (connection check, state machine updates, etc). Note that keepalives will continue to be sent.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

candidate

The NiceCandidate to select

 

Returns

TRUE on success, FALSE on failure


nice_agent_set_stream_tos ()

void
nice_agent_set_stream_tos (NiceAgent *agent,
                           guint stream_id,
                           gint tos);

Sets the IP_TOS and/or IPV6_TCLASS field on the stream's sockets' options

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

tos

The ToS to set

 

Since: 0.0.9


nice_agent_set_software ()

void
nice_agent_set_software (NiceAgent *agent,
                         const gchar *software);

This function will set the value of the SOFTWARE attribute to be added to STUN requests, responses and error responses sent during connectivity checks.

The SOFTWARE attribute will only be added in the NICE_COMPATIBILITY_RFC5245 and NICE_COMPATIBILITY_WLM2009 compatibility modes.

The software argument will be appended with the libnice version before being sent.

The software argument must be in UTF-8 encoding and only the first 128 characters will be sent.

Parameters

agent

The NiceAgent Object

 

software

The value of the SOFTWARE attribute to add.

 

Since: 0.0.10


nice_agent_restart ()

gboolean
nice_agent_restart (NiceAgent *agent);

Restarts the session as defined in ICE draft 19. This function needs to be called both when initiating (ICE spec section 9.1.1.1. "ICE Restarts"), as well as when reacting (spec section 9.2.1.1. "Detecting ICE Restart") to a restart.

Parameters

agent

The NiceAgent Object

 

Returns

TRUE on success FALSE on error


nice_agent_restart_stream ()

gboolean
nice_agent_restart_stream (NiceAgent *agent,
                           guint stream_id);

Restarts a single stream as defined in RFC 5245. This function needs to be called both when initiating (ICE spec section 9.1.1.1. "ICE Restarts"), as well as when reacting (spec section 9.2.1.1. "Detecting ICE Restart") to a restart.

Unlike nice_agent_restart(), this applies to a single stream. It also does not generate a new tie breaker.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

Returns

TRUE on success FALSE on error

Since: 0.1.6


nice_agent_set_stream_name ()

gboolean
nice_agent_set_stream_name (NiceAgent *agent,
                            guint stream_id,
                            const gchar *name);

This function will assign a media type to a stream. The only values that can be used to produce a valid SDP are: "audio", "video", "text", "application", "image" and "message".

This is only useful when parsing and generating an SDP of the candidates.

See also: nice_agent_generate_local_sdp()

See also: nice_agent_parse_remote_sdp()

See also: nice_agent_get_stream_name()

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream to change

 

name

The new name of the stream or NULL

 

Returns

TRUE if the name has been set. FALSE in case of error (invalid stream or duplicate name).

Since: 0.1.4


nice_agent_get_stream_name ()

const gchar *
nice_agent_get_stream_name (NiceAgent *agent,
                            guint stream_id);

This function will return the name assigned to a stream.

See also: nice_agent_set_stream_name()

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream to change

 

Returns

The name of the stream. The name is only valid while the stream exists or until it changes through a call to nice_agent_set_stream_name().

Since: 0.1.4


nice_agent_get_default_local_candidate ()

NiceCandidate *
nice_agent_get_default_local_candidate
                               (NiceAgent *agent,
                                guint stream_id,
                                guint component_id);

This helper function will return the recommended default candidate to be used for non-ICE compatible clients. This will usually be the candidate with the lowest priority, since it will be the longest path but the one with the most chances of success.

This function is only useful in order to manually generate the local SDP

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

Returns

The candidate to be used as the default candidate, or NULL in case of error. Must be freed with nice_candidate_free() once done.


nice_agent_generate_local_sdp ()

gchar *
nice_agent_generate_local_sdp (NiceAgent *agent);

Generate an SDP string containing the local candidates and credentials for all streams and components in the agent.

The SDP will not contain any codec lines and the 'm' line will not list any payload types.

It is highly recommended to set names on the streams prior to calling this function. Unnamed streams will show up as '-' in the 'm' line, but the SDP will not be parseable with nice_agent_parse_remote_sdp() if a stream is unnamed.

The default candidate in the SDP will be selected based on the lowest priority candidate for the first component.

See also: nice_agent_set_stream_name()

See also: nice_agent_parse_remote_sdp()

See also: nice_agent_generate_local_stream_sdp()

See also: nice_agent_generate_local_candidate_sdp()

See also: nice_agent_get_default_local_candidate()

Parameters

agent

The NiceAgent Object

 

Returns

A string representing the local SDP. Must be freed with g_free() once done.

Since: 0.1.4


nice_agent_generate_local_stream_sdp ()

gchar *
nice_agent_generate_local_stream_sdp (NiceAgent *agent,
                                      guint stream_id,
                                      gboolean include_non_ice);

Generate an SDP string containing the local candidates and credentials for a stream.

The SDP will not contain any codec lines and the 'm' line will not list any payload types.

It is highly recommended to set the name of the stream prior to calling this function. Unnamed streams will show up as '-' in the 'm' line.

The default candidate in the SDP will be selected based on the lowest priority candidate.

See also: nice_agent_set_stream_name()

See also: nice_agent_parse_remote_stream_sdp()

See also: nice_agent_generate_local_sdp()

See also: nice_agent_generate_local_candidate_sdp()

See also: nice_agent_get_default_local_candidate()

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

include_non_ice

Whether or not to include non ICE specific lines (m=, c= and a=rtcp: lines)

 

Returns

A string representing the local SDP for the stream. Must be freed with g_free() once done.

Since: 0.1.4


nice_agent_generate_local_candidate_sdp ()

gchar *
nice_agent_generate_local_candidate_sdp
                               (NiceAgent *agent,
                                NiceCandidate *candidate);

Generate an SDP string representing a local candidate.

See also: nice_agent_parse_remote_candidate_sdp()

See also: nice_agent_generate_local_sdp()

See also: nice_agent_generate_local_stream_sdp()

Parameters

agent

The NiceAgent Object

 

candidate

The candidate to generate

 

Returns

A string representing the SDP for the candidate. Must be freed with g_free() once done.

Since: 0.1.4


nice_agent_parse_remote_sdp ()

int
nice_agent_parse_remote_sdp (NiceAgent *agent,
                             const gchar *sdp);

Parse an SDP string and extracts candidates and credentials from it and sets them on the agent.

This function will return an error if a stream has not been assigned a name with nice_agent_set_stream_name() as it becomes troublesome to assign the streams from the agent to the streams in the SDP.

See also: nice_agent_set_stream_name()

See also: nice_agent_generate_local_sdp()

See also: nice_agent_parse_remote_stream_sdp()

See also: nice_agent_parse_remote_candidate_sdp()

Parameters

agent

The NiceAgent Object

 

sdp

The remote SDP to parse

 

Returns

The number of candidates added, negative on errors

Since: 0.1.4


nice_agent_parse_remote_stream_sdp ()

GSList *
nice_agent_parse_remote_stream_sdp (NiceAgent *agent,
                                    guint stream_id,
                                    const gchar *sdp,
                                    gchar **ufrag,
                                    gchar **pwd);

Parse an SDP string representing a single stream and extracts candidates and credentials from it.

See also: nice_agent_generate_local_stream_sdp()

See also: nice_agent_parse_remote_sdp()

See also: nice_agent_parse_remote_candidate_sdp()

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream to parse

 

sdp

The remote SDP to parse

 

ufrag

Pointer to store the ice ufrag if non NULL. Must be freed with g_free() after use

 

pwd

Pointer to store the ice password if non NULL. Must be freed with g_free() after use

 

Returns

A GSList of candidates parsed from the SDP, or NULL in case of errors.

[element-type NiceCandidate][transfer full]

Since: 0.1.4


nice_agent_parse_remote_candidate_sdp ()

NiceCandidate *
nice_agent_parse_remote_candidate_sdp (NiceAgent *agent,
                                       guint stream_id,
                                       const gchar *sdp);

Parse an SDP string and extracts the candidate from it.

See also: nice_agent_generate_local_candidate_sdp()

See also: nice_agent_parse_remote_sdp()

See also: nice_agent_parse_remote_stream_sdp()

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream the candidate belongs to

 

sdp

The remote SDP to parse

 

Returns

The parsed candidate or NULL if there was an error.

Since: 0.1.4


nice_agent_get_io_stream ()

GIOStream *
nice_agent_get_io_stream (NiceAgent *agent,
                          guint stream_id,
                          guint component_id);

Gets a GIOStream wrapper around the given stream and component in agent . The I/O stream will be valid for as long as stream_id is valid. The GInputStream and GOutputStream implement GPollableInputStream and GPollableOutputStream.

This function may only be called on reliable NiceAgents. It is a programming error to try and create an I/O stream wrapper for an unreliable stream.

Parameters

agent

A NiceAgent

 

stream_id

The ID of the stream to wrap

 

component_id

The ID of the component to wrap

 

Returns

A GIOStream.

[transfer full]

Since: 0.1.5


nice_agent_get_selected_socket ()

GSocket *
nice_agent_get_selected_socket (NiceAgent *agent,
                                guint stream_id,
                                guint component_id);

Retreive the local socket associated with the selected candidate pair for media transmission for a given stream's component.

This is useful for adding ICE support to legacy applications that already have a protocol that maintains a connection. If the socket is duplicated before unrefing the agent, the application can take over and continue to use it. New applications are encouraged to use the built in libnice stream handling instead and let libnice handle the connection maintenance.

Users of this method are encouraged to not use a TURN relay or any kind of proxy, as in this case, the socket will not be available to the application because the packets are encapsulated.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

Returns

pointer to the GSocket, or NULL if there is no selected candidate or if the selected candidate is a relayed candidate.

[transfer full][nullable]

Since: 0.1.5


nice_agent_get_component_state ()

NiceComponentState
nice_agent_get_component_state (NiceAgent *agent,
                                guint stream_id,
                                guint component_id);

Retrieves the current state of a component.

Parameters

agent

The NiceAgent Object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

Returns

the NiceComponentState of the component and NICE_COMPONENT_STATE_FAILED if the component was invalid.

Since: 0.1.8


nice_component_state_to_string ()

const gchar *
nice_component_state_to_string (NiceComponentState state);

Returns a string representation of the state, generally to use in debug messages.

Parameters

state

a NiceComponentState

 

Returns

a string representation of state .

[transfer none]

Since: 0.1.6

Types and Values

NiceAgent

typedef struct _NiceAgent NiceAgent;

The NiceAgent is the main GObject of the libnice library and represents the ICE agent.


enum NiceComponentState

An enum representing the state of a component.

See also: “component-state-changed”

Members

NICE_COMPONENT_STATE_DISCONNECTED

No activity scheduled

 

NICE_COMPONENT_STATE_GATHERING

Gathering local candidates

 

NICE_COMPONENT_STATE_CONNECTING

Establishing connectivity

 

NICE_COMPONENT_STATE_CONNECTED

At least one working candidate pair

 

NICE_COMPONENT_STATE_READY

ICE concluded, candidate pair selection is now final

 

NICE_COMPONENT_STATE_FAILED

Connectivity checks have been completed, but connectivity was not established

 

NICE_COMPONENT_STATE_LAST

Dummy state

 

enum NiceComponentType

Convenience enum representing the type of a component for use as the component_id for RTP/RTCP usages.

Example 2. Example of use.

1
nice_agent_send (agent, stream_id, NICE_COMPONENT_TYPE_RTP, len, buf);

Members

NICE_COMPONENT_TYPE_RTP

RTP Component type

 

NICE_COMPONENT_TYPE_RTCP

RTCP Component type

 

enum NiceProxyType

An enum to specify which proxy type to use for relaying. Note that the proxies will only be used with TCP TURN relaying.

See also: “proxy-type”

Members

NICE_PROXY_TYPE_NONE

Do not use a proxy

 

NICE_PROXY_TYPE_SOCKS5

Use a SOCKS5 proxy

 

NICE_PROXY_TYPE_HTTP

Use an HTTP proxy

 

NICE_PROXY_TYPE_LAST

Dummy last proxy type

 

Since: 0.0.4


enum NiceCompatibility

An enum to specify which compatible specifications the NiceAgent should use. Use with nice_agent_new()

NICE_COMPATIBILITY_DRAFT19 is deprecated and should not be used in newly-written code. It is kept for compatibility reasons and represents the same compatibility as NICE_COMPATIBILITY_RFC5245

If NICE_COMPATIBILITY_RFC5245 compatibility mode is used for a non-reliable agent, then ICE-UDP will be used with higher priority and ICE-TCP will also be used when the UDP connectivity fails. If it is used with a reliable agent, then ICE-UDP will be used with the TCP-Over-UDP (PseudoTcpSocket) if ICE-TCP fails and ICE-UDP succeeds.

Members

NICE_COMPATIBILITY_RFC5245

Use compatibility with the RFC5245 ICE-UDP specs and RFC6544 ICE-TCP specs

 

NICE_COMPATIBILITY_DRAFT19

Use compatibility for ICE Draft 19 specs

 

NICE_COMPATIBILITY_GOOGLE

Use compatibility for Google Talk specs

 

NICE_COMPATIBILITY_MSN

Use compatibility for MSN Messenger specs

 

NICE_COMPATIBILITY_WLM2009

Use compatibility with Windows Live Messenger 2009

 

NICE_COMPATIBILITY_OC2007

Use compatibility with Microsoft Office Communicator 2007

 

NICE_COMPATIBILITY_OC2007R2

Use compatibility with Microsoft Office Communicator 2007 R2

 

NICE_COMPATIBILITY_LAST

Dummy last compatibility mode

 

NiceInputMessage

typedef struct {
  GInputVector *buffers;
  gint n_buffers;  /* may be -1 to indicate @buffers is NULL-terminated */
  NiceAddress *from;  /* return location for address of message sender */
  gsize length;  /* sum of the lengths of @buffers */
} NiceInputMessage;

Represents a single message received off the network. For reliable connections, this is essentially just an array of buffers (specifically, from can be ignored). for non-reliable connections, it represents a single packet as received from the OS.

n_buffers may be -1 to indicate that buffers is terminated by a GInputVector with a NULL buffer pointer.

By providing arrays of NiceInputMessages to functions like nice_agent_recv_messages(), multiple messages may be received with a single call, which is more efficient than making multiple calls in a loop. In this manner, nice_agent_recv_messages() is analogous to recvmmsg(); and NiceInputMessage to struct mmsghdr.

Members

GInputVector *buffers;

unowned array of GInputVector buffers to store data in for this message.

[array length=n_buffers]

gint n_buffers;

number of GInputVectors in buffers , or -1 to indicate buffers is NULL-terminated

 

NiceAddress *from;

return location to store the address of the peer who transmitted the message, or NULL.

[allow-none]

gsize length;

total number of valid bytes contiguously stored in buffers

 

Since: 0.1.5


NiceOutputMessage

typedef struct {
  GOutputVector *buffers;
  gint n_buffers;
} NiceOutputMessage;

Represents a single message to transmit on the network. For reliable connections, this is essentially just an array of buffer. for non-reliable connections, it represents a single packet to send to the OS.

n_buffers may be -1 to indicate that buffers is terminated by a GOutputVector with a NULL buffer pointer.

By providing arrays of NiceOutputMessages to functions like nice_agent_send_messages_nonblocking(), multiple messages may be transmitted with a single call, which is more efficient than making multiple calls in a loop. In this manner, nice_agent_send_messages_nonblocking() is analogous to sendmmsg(); and NiceOutputMessage to struct mmsghdr.

Members

GOutputVector *buffers;

unowned array of GOutputVector buffers which contain data to transmit for this message.

[array length=n_buffers]

gint n_buffers;

number of GOutputVectors in buffers , or -1 to indicate buffers is NULL-terminated

 

Since: 0.1.5


NICE_AGENT_MAX_REMOTE_CANDIDATES

#define NICE_AGENT_MAX_REMOTE_CANDIDATES    25

A hard limit for the number of remote candidates. This limit is enforced to protect against malevolent remote clients.

Property Details

The “bytestream-tcp” property

  “bytestream-tcp”           gboolean

This property defines whether receive/send over a TCP or pseudo-TCP, in reliable mode, are considered as packetized or as bytestream. In unreliable mode, every send/recv is considered as packetized, and this property is ignored and cannot be set.

In reliable mode, this property will always return TRUE in the NICE_COMPATIBILITY_GOOGLE compatibility mode.

If the property is TRUE, the stream is considered in bytestream mode and data can be read with any receive size. If the property is FALSE, then the stream is considred packetized and each receive will return one packet of the same size as what was sent from the peer. If in packetized mode, then doing a receive with a size smaller than the packet, will cause the remaining bytes in the packet to be dropped, breaking the reliability of the stream.

This property is currently read-only, and will become read/write once bytestream mode will be supported.

Flags: Read

Default value: FALSE

Since: 0.1.8


The “compatibility” property

  “compatibility”            guint

The Nice agent can work in various compatibility modes depending on what the application/peer needs.

See also: NiceCompatibility

Flags: Read / Write / Construct Only

Allowed values: <= 5

Default value: 0


The “controlling-mode” property

  “controlling-mode”         gboolean

Whether the agent is in controlling mode.

Flags: Read / Write

Default value: FALSE


The “force-relay” property

  “force-relay”              gboolean

Force all traffic to go through a relay for added privacy, this allows hiding the local IP address. When this is enabled, so local candidates are available before relay servers have been set with nice_agent_set_relay_info().

Flags: Read / Write

Default value: FALSE

Since: 0.1.14


The “full-mode” property

  “full-mode”                gboolean

Whether agent runs in ICE full mode.

Flags: Read / Write / Construct Only

Default value: TRUE


The “ice-tcp” property

  “ice-tcp”                  gboolean

Whether the agent should use ICE-TCP when gathering candidates. If the option is disabled, no TCP candidates will be generated. If the agent is in reliable mode, then pseudotcp will need to be used over UDP candidates.

This option should be set before gathering candidates and should not be modified afterwards.

The “ice-tcp” property can be set at the same time as the “ice-udp” property, but both cannot be unset at the same time. If “ice-udp” is set to FALSE, then this property cannot be set to FALSE as well.

ICE-TCP is only supported for NICE_COMPATIBILITY_RFC5245, NICE_COMPATIBILITY_OC2007 and NICE_COMPATIBILITY_OC2007R2 compatibility modes.

Flags: Read / Write

Default value: TRUE

Since: 0.1.8


The “ice-udp” property

  “ice-udp”                  gboolean

Whether the agent should use ICE-UDP when gathering candidates. If the option is disabled, no UDP candidates will be generated. If the agent is in reliable mode, then pseudotcp will not be used since pseudotcp works on top of UDP candidates.

This option should be set before gathering candidates and should not be modified afterwards.

The “ice-udp” property can be set at the same time as the “ice-tcp” property, but both cannot be unset at the same time. If “ice-tcp” is set to FALSE, then this property cannot be set to FALSE as well.

Flags: Read / Write

Default value: TRUE

Since: 0.1.8


The “keepalive-conncheck” property

  “keepalive-conncheck”      gboolean

Use binding requests as keepalives instead of binding indications. This means that the keepalives may time out which will change the component state to NICE_COMPONENT_STATE_FAILED.

Enabing this is a slight violation of RFC 5245 section 10 which recommends using Binding Indications for keepalives.

This is always enabled if the compatibility mode is NICE_COMPATIBILITY_GOOGLE.

Flags: Read / Write

Default value: FALSE

Since: 0.1.8


The “main-context” property

  “main-context”             gpointer

A GLib main context is needed for all timeouts used by libnice. This is a property being set by the nice_agent_new() call.

Flags: Read / Write / Construct Only


The “max-connectivity-checks” property

  “max-connectivity-checks”  guint

Upper limit for the total number of connectivity checks performed.

Flags: Read / Write

Default value: 0


The “proxy-ip” property

  “proxy-ip”                 gchar *

The proxy server IP used to bypass a proxy firewall

Flags: Read / Write

Default value: NULL

Since: 0.0.4


The “proxy-password” property

  “proxy-password”           gchar *

The password used to authenticate with the proxy

Flags: Read / Write

Default value: NULL

Since: 0.0.4


The “proxy-port” property

  “proxy-port”               guint

The proxy server port used to bypass a proxy firewall

Flags: Read / Write

Allowed values: [1,65536]

Default value: 1

Since: 0.0.4


The “proxy-type” property

  “proxy-type”               guint

The type of proxy set in the proxy-ip property

Flags: Read / Write

Allowed values: <= 2

Default value: 0

Since: 0.0.4


The “proxy-username” property

  “proxy-username”           gchar *

The username used to authenticate with the proxy

Flags: Read / Write

Default value: NULL

Since: 0.0.4


The “reliable” property

  “reliable”                 gboolean

Whether the agent is providing a reliable transport of messages (through ICE-TCP or PseudoTCP over ICE-UDP)

Flags: Read / Write / Construct Only

Default value: FALSE

Since: 0.0.11


The “stun-pacing-timer” property

  “stun-pacing-timer”        guint

Timer 'Ta' (msecs) used in the IETF ICE specification for pacing candidate gathering and sending of connectivity checks.

Flags: Read / Write / Construct

Allowed values: >= 1

Default value: 20


The “stun-server” property

  “stun-server”              gchar *

The IP address (not the hostname) of the STUN server to use.

Flags: Read / Write

Default value: NULL


The “stun-server-port” property

  “stun-server-port”         guint

Port of the STUN server used to gather server-reflexive candidates.

Flags: Read / Write

Allowed values: [1,65536]

Default value: 1


The “upnp” property

  “upnp”                     gboolean

Whether the agent should use UPnP to open a port in the router and get the external IP

Flags: Read / Write / Construct

Default value: TRUE

Since: 0.0.7


The “upnp-timeout” property

  “upnp-timeout”             guint

The maximum amount of time (in milliseconds) to wait for UPnP discovery to finish before signaling the “candidate-gathering-done” signal

Flags: Read / Write / Construct

Allowed values: [100,60000]

Default value: 200

Since: 0.0.7

Signal Details

The “candidate-gathering-done” signal

void
user_function (NiceAgent *agent,
               guint      stream_id,
               gpointer   user_data)

This signal is fired whenever a stream has finished gathering its candidates after a call to nice_agent_gather_candidates()

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last


The “component-state-changed” signal

void
user_function (NiceAgent *agent,
               guint      stream_id,
               guint      component_id,
               guint      state,
               gpointer   user_data)

This signal is fired whenever a component’s state changes. There are many valid state transitions.

State transition diagram

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

state

The new NiceComponentState of the component

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last


The “initial-binding-request-received” signal

void
user_function (NiceAgent *agent,
               guint      stream_id,
               gpointer   user_data)

This signal is fired when we received our first binding request from the peer.

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last


The “new-candidate” signal

void
user_function (NiceAgent *agent,
               guint      stream_id,
               guint      component_id,
               gchar     *foundation,
               gpointer   user_data)

This signal is fired when the agent discovers a new local candidate. When this signal is emitted, a matching “new-candidate-full” is also emitted with the candidate.

See also: “candidate-gathering-done”, “new-candidate-full”

NiceAgent::new-candidate has been deprecated since version 0.1.8 and should not be used in newly-written code.

Use “new-candidate-full”

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

foundation

The foundation of the new candidate

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last


The “new-candidate-full” signal

void
user_function (NiceAgent     *agent,
               NiceCandidate *candidate,
               gpointer       user_data)

This signal is fired when the agent discovers a new local candidate. When this signal is emitted, a matching “new-candidate” is also emitted with the candidate's foundation.

See also: “candidate-gathering-done”, “new-candidate”

Parameters

agent

The NiceAgent object

 

candidate

The new NiceCandidate

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last

Since: 0.1.8


The “new-remote-candidate” signal

void
user_function (NiceAgent *agent,
               guint      stream_id,
               guint      component_id,
               gchar     *foundation,
               gpointer   user_data)

This signal is fired when the agent discovers a new remote candidate. This can happen with peer reflexive candidates. When this signal is emitted, a matching “new-remote-candidate-full” is also emitted with the candidate.

See also: “new-remote-candidate-full”

NiceAgent::new-remote-candidate has been deprecated since version 0.1.8 and should not be used in newly-written code.

Use “new-remote-candidate-full”

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

foundation

The foundation of the new candidate

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last


The “new-remote-candidate-full” signal

void
user_function (NiceAgent     *agent,
               NiceCandidate *candidate,
               gpointer       user_data)

This signal is fired when the agent discovers a new remote candidate. This can happen with peer reflexive candidates. When this signal is emitted, a matching “new-remote-candidate” is also emitted with the candidate's foundation.

See also: “new-remote-candidate”

Parameters

agent

The NiceAgent object

 

candidate

The new NiceCandidate

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last

Since: 0.1.8


The “new-selected-pair” signal

void
user_function (NiceAgent *agent,
               guint      stream_id,
               guint      component_id,
               gchar     *lfoundation,
               gchar     *rfoundation,
               gpointer   user_data)

This signal is fired once a candidate pair is selected for data transfer for a stream's component This is emitted along with “new-selected-pair-full” which has the whole candidate, the Foundation of a Candidate is not a unique identifier.

See also: “new-selected-pair-full”

NiceAgent::new-selected-pair has been deprecated since version 0.1.8 and should not be used in newly-written code.

Use “new-selected-pair-full”

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

lfoundation

The local foundation of the selected candidate pair

 

rfoundation

The remote foundation of the selected candidate pair

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last


The “new-selected-pair-full” signal

void
user_function (NiceAgent     *agent,
               guint          stream_id,
               guint          component_id,
               NiceCandidate *lcandidate,
               NiceCandidate *rcandidate,
               gpointer       user_data)

This signal is fired once a candidate pair is selected for data transfer for a stream's component. This is emitted along with “new-selected-pair”.

See also: “new-selected-pair”

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

lcandidate

The local NiceCandidate of the selected candidate pair

 

rcandidate

The remote NiceCandidate of the selected candidate pair

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last

Since: 0.1.8


The “reliable-transport-writable” signal

void
user_function (NiceAgent *agent,
               guint      stream_id,
               guint      component_id,
               gpointer   user_data)

This signal is fired on the reliable NiceAgent when the underlying reliable transport becomes writable. This signal is only emitted when the nice_agent_send() function returns less bytes than requested to send (or -1) and once when the connection is established.

Parameters

agent

The NiceAgent object

 

stream_id

The ID of the stream

 

component_id

The ID of the component

 

user_data

user data set when the signal handler was connected.

 

Flags: Run Last

Since: 0.0.11


The “streams-removed” signal

void
user_function (NiceAgent           *agent,
               _NiceAgentStreamIds *stream_ids,
               gpointer             user_data)

This signal is fired whenever one or more streams are removed from the agent .

Parameters

agent

The NiceAgent object

 

stream_ids

An array of unsigned integer stream IDs, ending with a 0 ID.

[array zero-terminated=1][element-type uint]

user_data

user data set when the signal handler was connected.

 

Flags: Run Last

Since: 0.1.5

libnice-0.1.14/docs/reference/libnice/html/libnice-TURN.html0000664000076400007640000011327113070512356020464 00000000000000 TURN: libnice Reference Manual

TURN

TURN — TURN Allocation Usage

Stability Level

Stable, unless otherwise indicated

Includes

#include <stun/usages/turn.h>

Description

The STUN TURN usage allows for easily creating and parsing STUN Allocate requests and responses used for TURN. The API allows you to create a new allocation or refresh an existing one as well as to parse a response to an allocate or refresh request.

Functions

stun_usage_turn_create ()

size_t
stun_usage_turn_create (StunAgent *agent,
                        StunMessage *msg,
                        uint8_t *buffer,
                        size_t buffer_len,
                        StunMessage *previous_response,
                        StunUsageTurnRequestPorts request_ports,
                        int32_t bandwidth,
                        int32_t lifetime,
                        uint8_t *username,
                        size_t username_len,
                        uint8_t *password,
                        size_t password_len,
                        StunUsageTurnCompatibility compatibility);

Create a new TURN Allocation request

Parameters

agent

The StunAgent to use to build the request

 

msg

The StunMessage to build

 

buffer

The buffer to use for creating the StunMessage

 

buffer_len

The size of the buffer

 

previous_response

If this is the first request you are sending, set this argument to NULL, if it's a subsequent request you are building, then set this argument to the response you have received. This argument is used for building long term credentials (using the REALM and NONCE attributes) as well as for getting the RESERVATION-TOKEN attribute when you previously requested an allocation which reserved two ports

 

request_ports

Specify how you want to request the allocated port(s). This is only used if the compatibility is set to STUN_USAGE_TURN_COMPATIBILITY_DRAFT9

See StunUsageTurnRequestPorts

 

bandwidth

The bandwidth to request from the server for the allocation. If this value is negative, then no BANDWIDTH attribute is added to the request. This is only used if the compatibility is set to STUN_USAGE_TURN_COMPATIBILITY_DRAFT9

 

lifetime

The lifetime of the allocation to request from the server. If this value is negative, then no LIFETIME attribute is added to the request. This is only used if the compatibility is set to STUN_USAGE_TURN_COMPATIBILITY_DRAFT9

 

username

The username to use in the request

 

username_len

The length of username

 

password

The key to use for building the MESSAGE-INTEGRITY

 

password_len

The length of password

 

compatibility

The compatibility mode to use for building the Allocation request

 

Returns

The length of the message to send


stun_usage_turn_create_refresh ()

size_t
stun_usage_turn_create_refresh (StunAgent *agent,
                                StunMessage *msg,
                                uint8_t *buffer,
                                size_t buffer_len,
                                StunMessage *previous_response,
                                int32_t lifetime,
                                uint8_t *username,
                                size_t username_len,
                                uint8_t *password,
                                size_t password_len,
                                StunUsageTurnCompatibility compatibility);

Create a new TURN Refresh request

Parameters

agent

The StunAgent to use to build the request

 

msg

The StunMessage to build

 

buffer

The buffer to use for creating the StunMessage

 

buffer_len

The size of the buffer

 

previous_response

If this is the first request you are sending, set this argument to NULL, if it's a subsequent request you are building, then set this argument to the response you have received. This argument is used for building long term credentials (using the REALM and NONCE attributes)

 

lifetime

The lifetime of the allocation to request from the server. If this value is negative, then no LIFETIME attribute is added to the request. This is only used if the compatibility is set to STUN_USAGE_TURN_COMPATIBILITY_DRAFT9

 

username

The username to use in the request

 

username_len

The length of username

 

password

The key to use for building the MESSAGE-INTEGRITY

 

password_len

The length of password

 

compatibility

The compatibility mode to use for building the Allocation request

 

Returns

The length of the message to send


stun_usage_turn_process ()

StunUsageTurnReturn
stun_usage_turn_process (StunMessage *msg,
                         struct sockaddr_storage *relay_addr,
                         socklen_t *relay_addrlen,
                         struct sockaddr_storage *addr,
                         socklen_t *addrlen,
                         struct sockaddr_storage *alternate_server,
                         socklen_t *alternate_server_len,
                         uint32_t *bandwidth,
                         uint32_t *lifetime,
                         StunUsageTurnCompatibility compatibility);

Process a TURN Allocate response and extract the necessary information from the message

Parameters

msg

The message containing the response

 

relay_addr

A pointer to a sockaddr structure to fill with the relay address that the TURN server allocated for us

 

relay_addrlen

The length of relay_addr

 

addr

A pointer to a sockaddr structure to fill with the mapped address that the STUN response contains. This argument will only be filled if the return value of the function is STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS

 

addrlen

The length of addr

 

alternate_server

A pointer to a sockaddr structure to fill with the address of an alternate server to which we should send our new STUN Allocate request, in case the currently used TURN server is requesting the use of an alternate server. This argument will only be filled if the return value of the function is STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER

 

alternate_server_len

The length of alternate_server

 

bandwidth

A pointer to fill with the bandwidth the TURN server allocated us

 

lifetime

A pointer to fill with the lifetime of the allocation

 

compatibility

The compatibility mode to use for processing the Allocation response

 

Returns

A StunUsageTurnReturn value


stun_usage_turn_refresh_process ()

StunUsageTurnReturn
stun_usage_turn_refresh_process (StunMessage *msg,
                                 uint32_t *lifetime,
                                 StunUsageTurnCompatibility compatibility);

Process a TURN Refresh response and extract the necessary information from the message

Parameters

msg

The message containing the response

 

lifetime

A pointer to fill with the lifetime of the allocation

 

compatibility

The compatibility mode to use for processing the Refresh response

 

Returns

A StunUsageTurnReturn value. A STUN_USAGE_TURN_RETURN_RELAY_SUCCESS means the Refresh was successful, but no relay address is given (kept the same as for the original allocation)


stun_usage_turn_create_permission ()

size_t
stun_usage_turn_create_permission (StunAgent *agent,
                                   StunMessage *msg,
                                   uint8_t *buffer,
                                   size_t buffer_len,
                                   uint8_t *username,
                                   size_t username_len,
                                   uint8_t *password,
                                   size_t password_len,
                                   uint8_t *realm,
                                   size_t realm_len,
                                   uint8_t *nonce,
                                   size_t nonce_len,
                                   struct sockaddr_storage *peer,
                                   StunUsageTurnCompatibility compatibility);

Create a new TURN CreatePermission request

Parameters

agent

The StunAgent to use to build the request

 

msg

The StunMessage to build

 

buffer

The buffer to use for creating the StunMessage

 

buffer_len

The size of the buffer

 

username

The username to use in the request

 

username_len

The length of username

 

password

The key to use for building the MESSAGE-INTEGRITY

 

password_len

The length of password

 

realm

The realm identifier to use in the request

 

realm_len

The length of realm

 

nonce

Unique and securely random nonce to use in the request

 

nonce_len

The length of nonce

 

peer

Server-reflexive host address to request permission for

 

compatibility

The compatibility mode to use for building the CreatePermission request

 

Returns

The length of the message to send

Types and Values

enum StunUsageTurnCompatibility

Specifies which TURN specification compatibility to use

Members

STUN_USAGE_TURN_COMPATIBILITY_DRAFT9

Use the specification compatible with TURN Draft 09

 

STUN_USAGE_TURN_COMPATIBILITY_GOOGLE

Use the specification compatible with Google Talk's relay server

 

STUN_USAGE_TURN_COMPATIBILITY_MSN

Use the specification compatible with MSN TURN servers

 

STUN_USAGE_TURN_COMPATIBILITY_OC2007

Use the specification compatible with Microsoft Office Communicator 2007

 

STUN_USAGE_TURN_COMPATIBILITY_RFC5766

Use the specification compatible with RFC 5766 (the final, canonical TURN standard)

 

enum StunUsageTurnRequestPorts

This enum is used to specify which port configuration you want when creating a new Allocation

Members

STUN_USAGE_TURN_REQUEST_PORT_NORMAL

Request a normal port

 

STUN_USAGE_TURN_REQUEST_PORT_EVEN

Request an even port

 

STUN_USAGE_TURN_REQUEST_PORT_EVEN_AND_RESERVE

Request an even port and reserve the next higher port

 

enum StunUsageTurnReturn

Return value of stun_usage_turn_process() and stun_usage_turn_refresh_process() which allows you to see what status the function call returned.

Members

STUN_USAGE_TURN_RETURN_RELAY_SUCCESS

The response was successful and a relay address is provided

 

STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS

The response was successful and a relay address as well as a mapped address are provided

 

STUN_USAGE_TURN_RETURN_ERROR

The response resulted in an error

 

STUN_USAGE_TURN_RETURN_INVALID

The response is not a valid response

 

STUN_USAGE_TURN_RETURN_ALTERNATE_SERVER

The server requests the message to be sent to an alternate server

 
libnice-0.1.14/docs/reference/libnice/html/ix09.html0000664000076400007640000000735713070512356017071 00000000000000 Index of new symbols in 0.1.4: libnice Reference Manual libnice-0.1.14/docs/reference/libnice/html/pt03.html0000664000076400007640000000362013070512356017053 00000000000000 Part III. Pseudo TCP Socket implementation: libnice Reference Manual

Part III. Pseudo TCP Socket implementation

Table of Contents

Pseudo TCP Socket — Pseudo TCP implementation
libnice-0.1.14/docs/reference/libnice/html/ix03.html0000664000076400007640000000641213070512356017052 00000000000000 Index of new symbols in 0.0.4: libnice Reference Manual

Index of new symbols in 0.0.4

A

NiceAgent:proxy-ip, object property in NiceAgent
NiceAgent:proxy-password, object property in NiceAgent
NiceAgent:proxy-port, object property in NiceAgent
NiceAgent:proxy-type, object property in NiceAgent
NiceAgent:proxy-username, object property in NiceAgent

P

NiceProxyType, enum in NiceAgent
libnice-0.1.14/docs/reference/libnice/html/ch01.html0000664000076400007640000000374213070512356017025 00000000000000 : libnice Reference Manual
NiceAgent — ICE agent API implementation
NiceAddress — IP address convenience library
NiceCandidate — ICE candidate representation
libnice-0.1.14/docs/reference/libnice/html/ch04.html0000664000076400007640000000425213070512356017025 00000000000000 STUN usages: libnice Reference Manual

STUN usages

Bind — STUN Binding Usage
ICE — STUN ICE Usage
TURN — TURN Allocation Usage
Timer — STUN timer Usage
libnice-0.1.14/docs/reference/libnice/html/libnice-Debug-messages.html0000664000076400007640000002046513070512356022531 00000000000000 Debug messages: libnice Reference Manual

Debug messages

Debug messages — Debug messages utility functions

Stability Level

Unstable, unless otherwise indicated

Functions

Description

Libnice can output a lot of information when debug messages are enabled. This can significantly help track down problems and/or understand what it's doing.

You can enable/disable the debug messages by calling nice_debug_enable() or nice_debug_disable() and choosing whether you want only ICE debug messages or also stun debug messages.

By default, the debug messages are disabled, unless the environment variable NICE_DEBUG is set, in which case, it must contain a comma separated list of flags specifying which debug to enable.

The currently available flags are "nice", "stun", "pseudotcp", "pseudotcp-verbose" or "all" to enable all debug messages.

If the 'pseudotcp' flag is enabled, then 'pseudotcp-verbose' gets automatically disabled. This is to allow the use of the 'all' flag without having verbose messages from pseudotcp. You can enable verbose debug messages from the pseudotcp layer by specifying 'pseudotcp-verbose' without the 'pseudotcp' flag.

This API is unstable and is subject to change at any time... More flags are to come and a better API to enable/disable each flag should be added.

Functions

nice_debug_enable ()

void
nice_debug_enable (gboolean with_stun);

Enables libnice debug output to the terminal. Note that the G_MESSAGES_DEBUG and NICE_DEBUG environment variables must be set to the set of logging domains to print, in order for any output to be printed. Set them to all to print all debugging messages, or any of the following domains:

  • libnice-stun

  • libnice-tests

  • libnice-socket

  • libnice

  • libnice-pseudotcp

  • libnice-pseudotcp-verbose

Parameters

with_stun

Also enable STUN debugging messages

 

nice_debug_disable ()

void
nice_debug_disable (gboolean with_stun);

Disables libnice debug output to the terminal

Parameters

with_stun

Also disable stun debugging messages

 

Types and Values

libnice-0.1.14/docs/reference/libnice/html/ix11.html0000664000076400007640000000512413070512356017050 00000000000000 Index of new symbols in 0.1.6: libnice Reference Manual

Index of new symbols in 0.1.6

A

nice_agent_forget_relays, function in NiceAgent
nice_agent_restart_stream, function in NiceAgent

C

nice_component_state_to_string, function in NiceAgent
libnice-0.1.14/docs/reference/libnice/html/up.png0000644000076400007640000000040413070512356016524 00000000000000PNG  IHDRabKGD pHYs B(xtIME IDAT81 @D{xa;$]r =JR1, Sd-}0̟oL:m-QO[ k TzMޠL,:ךu!tK; Pp Ot@l/̵*l}IENDB`libnice-0.1.14/docs/reference/libnice/html/api-index-deprecated.html0000664000076400007640000000474113070512356022246 00000000000000 Index of deprecated symbols: libnice Reference Manual

Index of deprecated symbols

A

NiceAgent::new-candidate, object signal in NiceAgent
NiceAgent::new-remote-candidate, object signal in NiceAgent
NiceAgent::new-selected-pair, object signal in NiceAgent
libnice-0.1.14/docs/reference/libnice/html/libnice-Network-interfaces-discovery.html0000664000076400007640000002232213070512356025447 00000000000000 Network interfaces discovery: libnice Reference Manual

Network interfaces discovery

Network interfaces discovery — Utility functions to discover local network interfaces

Stability Level

Stable, unless otherwise indicated

Includes

#include <interfaces.h>

Description

These utility functions allow the discovery of local network interfaces in a portable manner, they also allow finding the local ip addresses or the address allocated to a network interface.

Functions

nice_interfaces_get_ip_for_interface ()

gchar *
nice_interfaces_get_ip_for_interface (gchar *interface_name);

Retrieves the IP address of an interface by its name. If this fails, NULL is returned.

Parameters

interface_name

name of local interface

 

Returns

a newly-allocated string with the IP address.

[nullable][transfer full]


nice_interfaces_get_local_interfaces ()

GList *
nice_interfaces_get_local_interfaces (void);

Get the list of local interfaces

Returns

a newly-allocated GList of strings. The caller must free it.

[element-type utf8][transfer full]


nice_interfaces_get_local_ips ()

GList *
nice_interfaces_get_local_ips (gboolean include_loopback);

Get a list of local ipv4 interface addresses

Parameters

include_loopback

Include any loopback devices

 

Returns

a newly-allocated GList of strings. The caller must free it.

[element-type utf8][transfer full]

Types and Values

libnice-0.1.14/docs/reference/libnice/html/left.png0000644000076400007640000000040613070512356017034 00000000000000PNG  IHDRabKGD pHYs B(xtIME,`m;IDAT8үa?DAPY\$[p+IIMlf('}Mpy{_ޥ}^q xZ <=Yj) <04\~+Pl#",Qϑp Iǐlsw>[/]_i03IENDB`libnice-0.1.14/docs/reference/libnice/states.png0000664000076400007640000013713412661700132016450 00000000000000PNG  IHDREsזbKGD IDATxy@TU0:+٢ ccbEXK.< .[j*  0ye^FqC;>9{~{=c B61:!bH\ .󑞞4ܽ{r* 1\'___sy8<]j&hRĕ+WL|t?LMM-J#55hhh-BCCѷo_XZZP%+LǏ_~^|E_ЀtdeeJ5,--! amm V*9sϟG]]z1c^MP%/H$2dx `XܹsD333666  Q#H H PPPtTUULLLлwoUʕ+ػw/1h :GՄ*ñcǰ~`̘1y-8p ӧBCCagg&}d2\x(**P(>\'NСCx1m46雐@T*?Ç;v,ʰw^\zݻwرc榕LHJJ#"##ѽ{w_Tx !ŋǘ1c0l0x<ܺu 6mP(رc/r{;7Í7~z&M4'1Tx !#fXXX ::~:okkk̟?O\k:tሌDZcǐhՋDQ%<}_~ŋB,[ ]vŌ3t1JD7oĊ+#44x$//K.ŀ0f?Ā0zhBx'N@bb"`ii\xk׮ǵi&cɒ%4zI!~>}[l̘1[lѫ .̙{7f͚}>\.:4%<ƍ؈磨|rq]I$̛7GFxx8Olݺ6mһ?6ѥfBH>3x{{cܸq… ic -B۷ocؾ};_,BebҤI|2֭[m۶ʊhZqF( FFFVXU %hڷo1i$\z[noE>B|g͚֢KQ;unܸ#33k׮W_}e/6md2{ #F@ll,ױHE矣 ضmB|GHMMʼn'0h t:逨B 5k@&aΜ9mŊHLL͛71uT={iii\" M" &&Ç+9s`ҤIѣױtRCC&L۷aعs'͹F:\E;~8\\\+x>/_?O~/y*Tx 1`ػw/fϞw"99'O:C߾}sNvvvx"ױHA|r|GKb͚5'8ƍEEE7o֯_Bu,P%@ݾ}УG|9r>ZK.Ųe`bbiӦa֭\G"^B ʕ+`D">}oב:'''t 1`ܼyeee\": /!(99}􁕕/_%KpÊBBB/:qTx 1@~-&LחHɓTTTXDQ%x饗`ffx̞=Hހp9( ̙37o:aTx 10۶môiPRR###rI/5 @PPQ[[u$b@~άY7 Ǐ1'b޽\G": /!d7nQQQooo# p?!!!?Dt^B Hzz:?7:yqa'2339NDt^B ğ^z>oq"cmmHRسgבK8t"""PUUpI/ >ǎrrrCt^B H$=#FpGo 8Otyyy'" /! ]rݻ7lj@ RJBq#CpJ% {9ݻ7n&KHII4qG#)) &&&hhh:1Tx 12 BΝS|Iܹ֭@QQlj.KcA ݻsHx<t]B=777@CC9Nd!TB=c]"++ {.qKKOOG@@v, iiiD":!Tx sEEEpssC~~>ݹc0\tpҾ`ii,X[[~ }ݻ!J ڵk۷/Ξ=L"++ * 7nIJeJ{ӐH$X~=uHB<:u*/Ç{?1a8p2 ?3v@=z4&Oo„ | V/kkkյ|=!zm1Μ9Lm5~z6e;wfyyyLRXvڥ>c1<޾o>6}t6b֯_?&˙\.g;wdT*<7nh۷okd}v>Z}G7 1L?1M#߶2zhC눊1h gΜ 8x ?bȑ? B @y<`߾}رcZ/((H#cPPP>= PHvIb `eef pt{ Ebb"***4gcJR+pe;vLm!J4Iixc3K.UϬ@xx8 _}lmmP?~o67 77ǏǩS~Ν;P(o>}:n݊gϢ\G2uuuX|9V^3f`˖-\G" ]j&DϙVVVx=u?皞'Fmm-q FmmiKKsuuEaa!t"~m:t|Tx sMoǡkW)bq>?M:>*蹦veeeiii:!Tx s(..XXX<#Erkx<J%{y&ljJRMMMK4P%XXX8s qލ7 (..lj.K۷/RRRl轤$fff\!: /! 44gϞC&qHݾ}p^yC`kk~+^F̙3޽;-\B4P%@888Æ O?u[nJHKKCvvv $ /!Tn侮gX[[C"Ph'ǏotC  puuEEEܹBzGK`o~.V~!>Æ ?q:#`eeSSSڵ 755`ee<4 HB5zQ\ =1 Yq 4~ܳo>5 1_kmm kkk0PQQw...4Zш=Q(/#]=;Q]?@wwwZJ T*W^Arr2Dx<888(//GZZJKKR95^B:8 ?\au | D"1{llڴСC׿o?uM ߽{٨o븄Ct1因`2 t6&\TTn݊XXX ''G:z?_[nF";;;A&RkԄ :ӧoŜ9s`ff[n0hllĞ={k.ܹs^^^m^tQX,FNNT*  ۼ?~hKh/`%pD lۤI&!..fffxVZW^y{guF+}rC*ޞ.Cw ghr!:JѢE8]Cc˒6+駟b尰a?Yۆ"??ׯ=}jҥ T*q3:.5cUH.߄rY:EѴk 5j&Lֶ튻[x1֬YT={`޽xptt#jjjp]|>LR3!:A&Q}d2{صk駟bΝt l޼6663f bcc[o^:X,Fii)h"K̈́5?H0]sSNŪUwyZ#qrrr0f\x1*`ii ___8::"77:HAbGλ(0 g Rӧ1x`kA,cXt)D"h"c=9|}}憂dffX.5kDRYgb۶m=z4FY>}Q]]xxx@(xϮk ^B)cQ <_@oH褔ݻ6m!?"99nnnxw<%%%8t._DFFK.}zJچRDnn.<<zB&D"={ΝC]]0byL,ȑ#8q qтiIoooqGP%QJe(o3q:T8pӧƌ+++ ^|x>>G^BZv(nמh rd[JOOGRR]H Ó-B"HtJ C^藼d̄KR*VQ bjkk355UUU`ATC"1sss G`` VSTɁ)ܸ*4wb*)r<ok`rD"t*9cpGLZJHEWd2r!#55 \:*t5,6s(>Tx@g(kzX {\G!-«|>!PTTuK څW&p'N@||<Ν {{{&̞=ӦM{1dȐ6~ ǃ-222  ;U0BѢE,WrEJbRd|>5440ח0\b11c;y$>|8KIIhʕ+ҥKQ򘳳ƾϟx4id2fllb_rs4Ċۛ[?0 &H_'P(|ybX ud\GidLVQ-(],^TokeAT'TWW###Bhh(ѩS'(J@pp0nݺWb>sxp5)//Gtt4ҥKL?}7o>ǫR^"ߔsڴiB=K.&N===]#cӱ5?۷oիaaa\z~~&]|}Dcll ooo#001iKLb֦M4>KbԨQ •+W77n7##ӦM{vZ+GAHHr9N: &<3e-&$E]]JKKѵkW<3TxQ29vLd:UTTb1^z%#,,v:KFFEM#.5йsgeFbÆ ٳg[3p1߿aaa8qN_ J1bN"\G/i?Xv-JKKsvaذa6lN<#** }КκN"ҒDBBPp7>!ٳ0a°a]"!!;f͚Hu$&W6"cЬfҶJ%VX>ݻw=Uccc|ETTfϞ_~X4% HR(JN7шRL8>,yzzDZcǰn:*\]]Q\\i*Mܽ{sڵkѯ_?<1ccc|ܹsT*DKͤYYYA,s /yfW\ŋ_ё82b3ӦMT*:?t[[[TUUq?^L._-[`Ν:3ݻ7ΝiӦ8tTTTp?^jذa6oެ7o Ftt4̙JHjllԛ-;x<ITxIcѢEضmb ѣuBH;qrrByy9'}S%OMP?ĦM[XXs,,,P__ITxS[lfΜ ;;;ʕ+}6Q!̌ɔTxS9y$uXj-[F3 C\MKT*w}yqEk,,,/(IWޟJW'rJ|_|555HKK:&P(ڧa%L^x(XhV\u BHܹ3jjj'^D֮]hcpsٳ'Ο?uAmԩ'^XYYYY̏3eر\ z.5Yfqsfff ˗bjkk;2cZ}A ^HPT:"{M>;w:AKRo,K5j1t5 g+ZLB(B"h?*Ν;}rC1?1^-BPLS%UTT.]"yבu Gx< /yӧO_:xZ ihhK^P;zu ԳgO\rzFD6K\Itшh)^ҢJ8::rCg 77zM$s\ 2L+}Q%-JKKC`` 1tM:k_033:1&&&Tx RSSu !hs**E:Nҥ 󹎡蕀DnUWWT*l߾>>>?|0Μ94h;x<|wUİNٳ5>dcی1ƚ T*7n|ii)svv~`#F~1\r9۹sc3>={g϶j_x>>s mOСClǎ1gYvv6JhCw^\xQqllsss!((Hc޽[sMT1Jz*1y97n… j*Gf|VVVkվO>XhODGG#** K,AZZD"!pI|066hcʔ)6l~$$$`…/<ܹ?п=fvv6^u\zUƢE'55o&̙nݺUŋk?ǁLl޼Bqq1/vvv_cNIIQ,_?94i ˨(,]Tc{x<9٘3g>3۷g}] 4ݾ_ZCiKZ9H$1Ʈ]|}}ٝ;wc}lϞ=l„ lժU}6D #_YY۴i:t(STk.&Yxx8駟خ]iOyz6w\M-R|>khh`/+))arɓl,%%6\.]|>;z(ayyyٙ͘1Cc{د޽{dzhivr9cisyuB`1ƜH$bof~Ϲs9 bEEEM#c,1,,,?sb '..R222U2%-b?#33hll#ƌ͛7c߾}PTeEϞ='֯_u* * {… iI$§ޏ,Xo!.._8{,jkkq)ppp7|܇f|Zuuu _x7n$''fΜI&aĉ@dd$^~eL06W,,,Dhh(rƾ۷cԩoϚ5 Ѱ44hcǪyW7{P //7o쌭[">>۷oǘ1cySYY> .YM(^^^t`ĉ5i:YoߎիW`\z~~~|2>'^G<ڡ k3gƍ󹎢n݊W_}U=R!m'%%lu6m822R]̗.]QF!((W\ ܞͶܧ:rpuL0AQTΆo{wuFE(++ QtVii)`̚5롟+++իK/!88={|6rf_O뭷ނB /uQ%-Gzz:G(..V_#mK$߿ꫯڭmpM M"-CFF1tӹe{@RY &AZ[@Q% dA]] |>`oo~Tw޽;1Vk,%#kd2Q[[ J333t ^^^leeE")) :ޒdH 7TxPcc#jjjP]] R WcׯΟ?~;w`޼y\ t@TxBH$BMM T*LLLйs. ŋG"Ԕ&VBZ oUWWHT @\.P(zI2d?~׿ڵؾ};1c&FWbTTT@&X=/cTxOAAi)vTSSN:qvCW0P[[JrXZZŅ˼MޢQQQ\k'krcAVV ĽYfa\\EED /w4JH$BUUJ%lll驳/mmmacc tڕ8ٰaN/B/}G#^-aǃ/䤳Eɼyb cp&++ :ޣKxY]][[[|m^}U;v ]l֮]u @;*ŰF.]`llug6yd7P(:9r:AK]jn# HOOGii)777(-\111\GњB=z&L:H$|:!\D"ӑ KKKS-?$((!!!HHH:JS*OG :hkB655 /toXL:\G!*OȀP(D`` \\\:dgvZ!''(b۶mA>}bpc\G ]Q} JRܹsB`` )|嗈Fii)qTbb"jjj0ydX]D!J !((h"xkkkczS|>?\G1H4{=*AZZJKKZ\\\yf̛7w:3ٱc]+Wr`Ņ+*wyw܁D"`bbu[nŲep穩T*,YJ˗/:A+**+1iW]xc())Ajj*x<JZ ;ve˖ARq鉔cĉ )ScC`1RAAAHO/bʔ):ĉ?>s /1 5SHRb... :^2d^|Euꑫ,[ ?S@YY`d2TG{'{w-B!,--aaaXաJ` رc>aT^^NOc|Er HХK聴dTޅI~jjj Q[[ \sssXYYsptt޾_1}tR __LաNNNpss:i#6&5}rh=K E, 022B@@3& A?<1iwb"33...>>  ]!RtjiQBڋNVkllDZZ 00q4CYC~/!DgG"45P/!2趂!`b7`܈1<(׀y {#[1K+ЩT*ENNaeeu!c#sșDKrssu BBgFχ?]7FxzzrЉ›zӬF۸V}_4f\=NOOGxx8s|{k$&&8u{#^*PpZxJ%`ii .dۏUVi!=+W>жh۟6ÇQ]] 777899'N@~~>.>sUgφ3?<)akk]qݾ}) .'H,XR1LT2>JJJ\.gb͘1hyv%c=zİ<쬱5ٲ޽{dz6Zڧ8r9c=q` 3'''&۷Fۏ:Osp9 bEEEMǦ,h~^,,,D"QL(ӧ?!ET mtK(--E`` %e%p\#F###(J@zTUU!44hsԩJ% 88nիW1~x}{9{+,d۶m011СC5hihzoy'|HR!;;!6c4?ӂD"s|cSs4?/~~~(,,T}aa!f&G~~~? m9r:u r Mu4bT*]JɁLCZM$//%keX^z  k>FFF8rٻa@}e}Դ4UK>YKJ"ffin *Kٷ$[7ddEf< 8=u]]i}a>s2dTĐizU)))QHHK؛;]Kjm{˖-jm>>c1VxSSSakk GGZ10Fcp'D"PAi{}S%jfmq'Q!E^xsrr rA YO~1jeees18j-yyy(//>WI@}YQͪx!-7oR[-++C~~>BC4C\`懼G߾}1zhlڴ *޽;!ljΝ;9Byts+Ny!Э[7!## J9!#dtAq1\PPKKK١eeeH$JzxxJ FhVIHLLbH5BA {onYWqL&ӧ888_~ڵ+}DĠ...ׯ^{5Äh֏N ccc8;;F(BD^{c|xw Dׯc޽1dȐVZgϞʼn'  1f׏N?[YY zh5QGxw?h cǎh/t8|0N>@Dc'K obb"|}}鏁hj&ut;Vc1l0ظG mԯ(x3*Mf˃-`,hq[q2>;JHH  `E Ht'NĹsxG"D-|+!ХKD3BޑкkYYYh߾}k!ٙx]='/.Gr9>0ưuV, 0w\***xG"YXxR)d2Lo[Q\V;RƜ9s0p@L4wy0i$CH=fffCYѨcBDğ 8SLĉ1dqԪK.Xv-BCC;!MhJn܈rh^R~)$rޑԪ3gĂ лwoqZEe|(,,'jfgg.{F!}>C)9;Z0"$$xiUNNNXn}CH-48511{/2˯#:c6e}l2kxyGшva±_ш o~~~tN631c r2>y`l'O;FuFڵkyG!A \899i2 !Zz6HexGjLĭ[yG!DI[]]MS?{nG816nL; ! o~~> {B9Lډ1N>X|.Y]OOOzSSS8p((+㑅μ&x~ox"Κ8?ء rjkS Bt7o*hE/nn+o)8G:t|M5o+  ye!D mi&yͬ3d}Ut2&mv{qqq0`꡶mhNQxctS!g ƶ߂k! bQtrVxݵؚF=zwww Dž 6O+H`jj3 ! ۀ1B*D?cK^x_y/+;s 1yW;1p[QQ333Y1xm,~ &yEKUy9UIr|8kW]ڶmL13'DX;ü;J)IoP| 2?XZZrLQVVFێpTxHBK4^`$0%YLyn3@.ӧ^}B J$iӆgBHڽgި7BEDt?nܸApKw4;D"yIżcfBvԩ:EEEcFn"+**駟"<<;wĠAPVV˗ȑ#صk-[2#G vvvJƏ={@  &&QQQ RC"<<>|8!→\QXXO>{Ν;ѡCo?:GbŌf̘yϟ"##,44(EGGӧ3{7XT*eR޽[4\j}7n\VBBc)^[`xٳ[ f$Xrr&ux A{ :T̙3Ŵh>FB>}pBC(Vs\V.]e߿_ŋx^B Lnn `)sLW_}K.ĉN 9*TuɁ-ڵkxز; !O /!& gΜQ^QQzK+cѐ066pBrpp@޽ѱcz˪[j_~7gϞ{.:wۃM3~K!dǎXt)߿XXX`X~=HիWƩS0zh8;;͛S|`ݨFtt4bbbvZe 4ϟ;ܹs(..tDDD믿FFFc7nmHz&%%ϏwBH̘1۶mCg#ur׷uN5qCۏDdddD?Dt1tcx WTx ADc褌 弣EԩS'*-$|bbdggw4b q"Bt/xI7oѮ];O="??尶 ,--9% /!:w ?P@ 5<.%%%Cff&B!aoo##:IH^B\LL D" [[[QgTWWĤћlll`ccqHIIL&affDP%DOسg6mҥ O1ntzլyB!(--ŃPUUsss899¢5=EMbzR}&O\|c:sI 2ڰ7쌼x!<3g3Ν;}ZfffH$3Ba-$Nn߾~ )))pppk_~Y? 3qDkDYf᫯R:m %%%Ɂ\.5|4$x L??#ѣG[M?<[hN=|&&&/*UWW#''>5\]]alLuBZQyy9~:u 0`,^XtzJ~-BCCf066F۶mѶm[ 55FFFpww ^BԬOӧ!0dlذn133?.]޽{2tY~~>JKKѱcGQj% ٳe.W__~z_tÇI=a:%'NgggL<c3gয়~ڵkyGiu{AQQxGѸrܻwO 0i>MR%zGEll,0f ciTtt4pBQZŋգG.^{ow$G?_wn݊<,Zw Jsssxxx3/!-PXXGݱpB _om۶К5k`ccCEts|||݊h^r9p1B=ӦMK+ 02e VZbEEE7oF^{w;;;Ύj:LtRff&݋K.a?~<=RDEEE;w. ѣGlW\7|+Vhⴠ^x!ѡCK UUU8~8bcc)So 1ưaܻw_|Zn-k׮Eaa!K؄rӓV /!$$$ ::6l|Mz^QMb `„ Z s}v̚5 /8:K.#%%666t*!** }YӍR8vBBB;7i&t KMQQQiTxz*v \`{'Dh+**Bvv6:vH_h@kqqqԩS薣j߿Epp0|||Z}=qeӦMZYee%RRRsssqK ݻwk.bܸq1b2ػw/ЩS'wj9Bbۈ K ISd2$%%]v}^r9~:t utDJJ p%0`kkN:)Uy$HPTTTD"$&&"771tDnKG1bi}*D`G`` Ǝkp雚k+))Ayy9r9S =~fVVVAΝGGGI1ܽ{vvvy /)))@NN&N_~w${xmcHKK=nD}5ӧO 1$HOOǣG;^KF"`޽ŠAvZꜝTeV@|8!RwEx<"Mdd$N>cbH!OOO$&&֖/\;VVVػw/D8{,Ǘ0s>& M4h`*PGUR'2224H3~g ** AAA^`fbF \.gǏgǏgP IDATdrw$Gҧ+~^d b1bŊzJGjCrʼR cmbIR %j}2%%%)7TlgTa4uA <{쁑 #== @||qDsPZPΝ;M%L&cɊmN:Լz\^u 믿Xpp0۽{7鬪1XϞ=.wa1XQQ{7X,fصkԩSYUή\rss͆f1GGGbNNjښݾ}kS; 57A՗ Uۤhur@i]j/C{ROר::Ǩܹsرc&MDw!YngL8-sND"O>?~<֭[T>}x0rH 0C֭[qDFFCJJ ƍ_|QmذaL+WB.+-… ژ6mBCC1gx{{ŋɓ'+MŊvlllYǍW/@,￯!--M7o*mYf)ᅬ>GEvn5((H)G\K.UZwyG U\\\ѣ&ʕ+ .(~O8~8 99Yi׸yf7HJJ_шP###k:uBΝѱcGiӆZu233Cee%: /g'֭[ GҠ[n!..n݂|}}#FGyor9ݻHӧOc˖-H$СЧO[ *TVVb`a޽h DEEA$gϞ DXXX{+22271daǎpssѵkWuѐ6m@*Fаܸq_5>#ՋwBꉏGxx8ڶm`tܹ՗{͛5jFIGD'oaL&W_}DpFhXxeDC&!&&1bKKKd$!YYY8q"/.* H$Ν;ƭ?P DEE~:,yQ^^;֣#^ EDD֮]KcV""==+W3H o_| H^1舷UWWcpCEh`ҤIի6mڤUE6 ,]&M”)S;!O o+Ą EѣD>}Ǻu;N?Axx8;޽wzɨ-–-[/C?w 8baa7B.ctZS YZZw FWcop-w$Blڴ XtN2e ^yA*Cje???|':K,3>CQ"00Ǐnj3P]];)j~*jp}L<ӧOǛo0hDlٲ^^^ E^|E{ DgP}JW^żyat֍wBٷo$ }]QZ /#F`ҥ$Tx޽{7ƍzsz!ڶm{BtsUUZ o ^XnuNRaa![,[w6m.\;wbQQQ;֢L1|pvvƬYx!D%>cZʠFod궐3* 2 ~!ɓ'CH"##1l0x{{QϰrJQ Qm*̘1cƌax!AEEEѣyGGJtʙ#ccczīTxBCC'*,Y>w >s|JTx!!!Xt)z;!JLL5:u; W>|8?; !PmDyy9fΜ+WLJwBhƍ={6Zaر^N葢QmD"3h"*D'ܻwprrE+B <N V «T*ᅬsμ$6mG0a;A0*ud2̚5 ڵ+84D"Aqq1yG*&&&FJJ ( oèٳ1i$ݛwBĉxxJؿ?)jZ/__/(4ɓ'1tP1Rǎ!&+5ȑ#Ő!CxG!Y*++annnP]C6WϞ=C h\rըvN>MaY'8p Μ9;ch/Xf [Qi3g`ch=z͛czW5.Rg7|SSSqim۶ch#/ΫYfffTxU0;o<̝;>N ##;;w bjjJ1C[nxxG!rrr;NH$àjYx322믿"$$wBH$?: iw cpW.coxG!ݽ{c脎;"99w BWxO< @DEE!((ދ,XsΎi&L8 agg***駟"<<;wĠAeeeX|99]vaٲe8~8\]]G9ɓ*ٳg :qzػw/v܉ liifGڱD"VWv TZ]x DmKϟ"##aPͦOx ֿ&JT*ewf1ryUKHH`1kT[51߲f3cM>Eż#4L&cɚXoM#عs'ǏwށH$B`` }p֞ҥKƍqFDEEaĉJ/ҥKy DmJJJ`ee8̙3111PL#G0j( .NjUkDDD ??_t颔K.*Ƒ#G΄[GkAAA6lJKK1sLm7bccU6R3@JJ fΜDOA9r SDTUU\.&<(zU&)~ꫯp%8qBaȑhpy =o]=;Sl akk L\.W0`=ݻbDtt4&L; !jeii٢J](VTT1QF!..N1x뭷 allc…^z;\kCy322ڴiC^ pႢׂ>}kߎ?h |G۷b͛71n8??L4I#+Ҙ 6`޼y022Fii ڱc.]4hV^opppH$€?cpvvt8uT.\޽ՈFLL ֮][oyϟO弟| ""(**ʕ+[~kӦ y*WΤ$ΣvEEE?>o; !jyfk׮h=f͚-[bPR);Jr9RSS5xY?\~=BCCy U8;;#''w 3陘hM@ oQQ3BHԩb1:A$Gtpׅwxy Pm:HHJJBvv6uDg$JBZܹVVVpssԢ X,ѣakk q1(//GQQ aaaX[[͘m=tF;!jaܺu amm \N Ex|%,--j qNNcxDFFF`]믿b׮]cƭ[PUU*xxxFΝqmxf^[+؆XXXB{II rrrPQQccc888Ύ H3ՌRԒ^^LxzzDݸqHkkk+D"/"##֭[ۈ?C?AsX[[^ j888Qх.iXM'Tx=~@pp04KUUbcc(--3<#G*ۭڵk[oanvbcc?UBptt\.Gaa! `ooGGGW^޻wSNcD刍ɓ'QRRW_}˗/MךpttT.`ggGYSu\.W122Caa!RRRSLkcjj"1ެ,xzzAHqQ;w>|86lФAAAFXX꼳gϢ־@ =!QPPdBh(}C5+ӻ{1%8uN> DÇcj>ػwolڴI-m#Go222RJAff&6&&&J:+ׯ_y 1={c #F5kZß_|UE>P(T I&&&tAS'w1FVWGdd$^믿{g0*lذfCqwL&SŅM2@zUxSRRСC1d8qN8WWWL4I1XXXcǎr {9.[磨HF] pww; `eewww#ڀUz*}*((]pM1Bm[b̙3g"""ek׮j"%%FFFh߾}n#M [;1 رcd2Ls/'NM ܹ3(Odee???#==Bڵӻ, kUV@Hkr mooo,\NNN#3uT7lR7hŊغu+baa???TVV"==&&&h׮ebbDB^C /ݤ@Z˵kװcb͚5Jk@ `{F71fff#CMLL JB%i]r.Ξ=5k/Љ=zǎEn߾ׯcѼ<5 t x!HOM6Jch9!:ݿW6n9Чbԩٳ'xiueeeXlXfcc!!!۷ch){=Oyy96o HŋtXf BCCsN3g,Y4>qtt=222  T3ѣS4yZBBB]vtѭ˗cڴizW~~]tU ۷GJJ rrrxGj2:?zSx%~O4skwς?Ĝ9s yQUVw}:-Z~uLMMѹsg"++w)Hwe,[ ?y۷oǃ0w\(TիWСCQadd:M6HJJL&IA 4Ґ۶mΝ; rrU0m4aϞ=#ty;={ʕ+uUH5gfY522oSHm۶ᆪm:uꄈBL0.\ ӧ q!uvݻZq ^YAJJ D/-[NF?۷oǥK0qDrruƊ+`ll ܿyyyܳPգljgիW; 1̝;VgφD"={0ydt lХK^666|8:t@k->w_F||<i߿@Cedd(# IDATM{/=?ᔊ4EMig^  ©Sx DiRv z9BVs]uvvÇy^&Э[71 Xe٬^z%_crss=*Aر#PUU;A;j(>|w ?CL;vݻw' |mQ1!zYx`ر8tDrss;!:x(zMo o`` f ?4P!Otưmիde`Q\\;!:iii菑?RM]vA4C{.4POOOmcccd2K𚙙.]j,Xʉ%C[jk-1h ۸d9z(\aJquEDD`ժU6mBBBs|g.IZhh;5Ծ:޳ 6`Ϟ=8x`yj>|gϞFCZkjHs?#RSS׋D"t޽Iyvd9r$O9 B8p111BPPP5w?)_b飒6e1YbFцr9=qzS:tEDD0۳g_/$$Dvvv޽{L.ŋkK*ќL Ks4ֆךcyyy5͢ҧ+~^d 7_SƾN/ޟmݽ{Yy,V\\ƍ*_}d2KNNĢ}e׳ӧO+MKMMecSLalРAlΝl,""EFF &0DRݩScǎ~1Xee%;w.[jٹsbSN1L׳۷o+-_|Xo2zk+ꮋ+cScm{vvvUo;'&&2Ƶk*櫝f}k/5j oZZ;{, d>Tf-ݷjQo˫޺]СC>`sit?VTTĦOΆg, @_MϓڟE"SB߿}k׮YM/2 ~j**j&H;CTjd2& Yee%|}}كT*e'Nd9r$˗ŋP(d1v1`v=f̘Jk[ /&LҔ描oT*e UWW3sssc%$$0EuYW+mڥKv}m\wzP‚1+--e.]Rfׯgl*@׵LuEv*--UZǦn'X۪2._̜mji|[}QSxW^&MVZ4_ݟձZo5e,ߜu.5ˬb&&&g [`d _.ߏ>j,gu׆\h?33}*͚43𶂣Gݻw+M9::*޼*Ak7dbX1JJ ˎ=͛yHuv{Mvԩ{*W5O흲eݝ]r2///Eu篫۷]5}ݎ emzgE"ڵR`V]]RSSYbb"cׯ3P&UXw;\'m'XIYM}2Լ/5Θ>[#*}:b?c2ֳgOŗP6km֔u.u׷,''`-bǏo}UYTMƓڮ>-((`>TоYoVEϼd뛫j9r$PPPYnܸ8s `̙2e V\ ?֭S9UAAN> ___\p, 0cǎU/;wֻc֬Y9r$ q)-Сi͛4OBB֭[+Wݻ[w}hvfUaSZtڴi Ŝ9s퍋/&O4],+PO?UϥK0oѣGӕ!O$ӪbÆ -J?ߗ.]1cƠK.|2ݟ8&T<-e5׏?ooo\~&M@ Pرc?8t@ @UUad{xm]:fڬ@^^ڵk6A.#55Ux`ڵѣGnoP<.zg6EABhs)t{Ov3KRK4e2k*ZzBnGni&"03 /ss$Qa~05/e۾?4h222 - X~7spT]|DAAz!JKKM0ͨCTTT];82Ջ͟?x衇 J}Q^[%]/˝X4`Z:f tk5 H.7"[oIB9e˰qFnjD"Z2t$8rP&^s2u=yҗ,d@:";;%z)L&S^.xVZKݗ+HOO'xOӹnGp aaaxg(pB'JגGh\RcߗIDuAcc#BBBHkt'|^zj|>&"G s%bt[aYfnnnC\>ヒ 6@TaB6m͛*AT2% #xh#:KR! tM$ VZ7xD[b\y={x|=' GPQ܌@aj4KLL {9rOOOܹ6mѣGIӫ 3b;! IV"a{1c@$C ۷olj'p) %2t(T'566"((tjya4hP(Ɂ'Υɢ3JJJB D", [X%DlH$HHH?O!99)))AbbbŒF#ylڴC᫯!H[.]¾}Ԅdc/ƍÈ#05:*!KokaϞ=tY )--Ųe˰|r 8t8c޽´iӺ}G ??駟_~믿حmPwi5P[7i⽃)SǏ' `'NDNN֬Y۷ R?]=ڞD" իW{=-JJODo{ꫯpYҡPM6! YYYr z\.ǬYj*3ơm4;v+ߛz hnO dž PTTD:g}[nŗ_~y桩tH=B._֭[=عs'mۆSN#44ԡmJvx;H"`۶mXb]F:ooo,[ sŒ%KqFX,auZ7x[l!^ [lG}Dov{˲Z߹A{Tyyya۶mXd =Paǎ>>C-@sb۶mCXdm}D{]9r$1gΜ^•{XhrssEaΜ9͋'|Lat< .`0) \=IA(bؾ};ID@ @FF222ڊbϞ=O?aÆ9&… HMMuC@233_:_) z=n2tP꫘1cӮlzM]va(..ꫯs7L4au{ ?#0dyVWNۍ^,Yf–-[I:$ldggCR믿ɄCGlllP(-*P( "O{X%I-´iۛtH1~x,#//pssߏtDEEuK{EEE{Z6j(g!S2;4R.99o6fΜm۶.T"0tP :`6q)|'vbbb.-Gzzz7G#GiRSC/#{aX~=*Q #F#ٳظq#`XT}`ذad2(=~ _ݻwj"//> WfA(b֭ܶ\T*j^*T?#222:Skk+v {0 Æ J±cwLѣkYuo4i233YE0 D"CڢƢEl2 0t8 y饗gߑ̫W"..Wh4=ԿWrLR"""k.l۶?(G t,ˋJU0 ./xb1C$6mRěoEu\zt]bߏJiqfa'uqW*B9Qf3fc=̧4rHK~Ww}p 4vdrؾb.rn(2~a\sN:KIIsH%?Cb* I@~sNlٲ KD"H$Ӯ]0N!!!pߎf}9OOOlٲFgϦSTxgnQߙ3gB: cY)nqjx;ܹs1}t\pt8T/G:Վ]vuʕ+L ڴ FƩ;KNNݻgaƍN"IP(Ę1cCrtaW×swr:^^^k羚Ϗwww 99SNE}}=鐨^"33{q)5k`ܹ=^///.Z/Q* ~~~kJ_yj̘1Xn-Zt8T/ 1{ll޼t(uQ 2Cὺ:^ilX HHцfQnJhnnvXTDž 77ΝÛo D:$=è@aa!PڥT*^zt(0 qܮp䶝`C&ZEB!,Yq!++ ?HD9իWcŊCieY$566"((te6yxİ2GEEʑP4x`ݻ+^y޽hR f͚rҖ.]ɓ'#""t(Nšs]Rt[&^///D"Z͊$ .\3g^_˒0{lޜf 2G&Sj&9Pŝl6~ 5EDD#:Aa߾}\ݠi0sLbX &zQmll$`ﶉW  ..tXp!Ol@k , /rT* 7Ρm;3ԦNRՐdoWv  ֭Ccc#/_NPV`9SL^ʱcǰk. 88HJJ]>7|}}Ir[f& j5t:FO>N"`ҥX`,Y 6UTd2|ǐJSDDDN{fi4']zK$P׮  >O>o=˔4V-[ʕ+b$%%EEEHHH =|BDPT+--ŪUᐹ;wjjj?~ T zhZnH$BZZFlee%d2o bZQUUjz}%J` y#׵ \ߨЀxӢn#GW_Ejj*p^l6sx񁧧g\}uRSS???,ʕ+߿?G/p}ةe'yf`ٲe!EeY#&&WHhZT*r9H]u\z!!!.477cڵlX|9mu'V%%%HLL$@F(ޮhDuu5}ⵓ0LsN6l@1{lqh4III.ZSRRxsniiNCxx88χ״pEEEJQw/99[nŀ0yd>RW\_'&;wǏQ@ҡ8^T*%mY,h4jm6xWwxcB!"##bX5Ʉ={'͛4!QshRj%rNg ** bDFFvۖn}nGբAAAӧOO7G0N]vŋ3gRRRHDbDDDt+..FBB;2 &nee%|}}x@c]CCJ%G5KZ 6sEID(aP\\8L&jkkyb bhllb!x r|@Tb̙ͨ3! W^EbbbWYY^nbniiBsNQBA}}=JKKՍ|r|(((ĉqaaQ.F" ** h?~cʔ)ذaw E$L6aǎ8q":hG,؟aƍ8v w^deeb8R(ڋz# \Nlr |Ox#aPWWVZg!)) 3f];{\v ^^^m~X\.Ǿ}0j(GN pJ$V4I$Wu0hllDKK |||›r_Tו`ǎhmmŬY0x`!QXYY{P3<$&&I7&^abބ 駟B"@׷GrWo߾D z8BjPP$''(..N.11k׮Ś5k?"33f# r( {Rp1šC^6^W_}]~L4 z|eYXV^&ݚd2"IWP@T:[á۱ZhjjZL&CHH7Sw0 k9r9s&^fN [ż+ ^H]SSa ;|'* MMM7鐨tirJ:$0(++CRRݬ_rɼ$5˲,^ LἉ nmm;yύ3ZC=I&+t:nP(  Gp^ T>t{#ш&hZ"88);{,>3l6deeѺ]iiiZ!""7e0u:jjjWVڵk$hJ7h4hjjjE@@nfٳ/^Dzz:{9  ?NAYY{b0PUUD6445&^;eRP(,|}}H{NeY`Y_I9Hee%|||x[~ *++:GnP^^___8MZ[[T*a4@8J72 8r~HRL: :}IQQ~t:үrѽq͎%t:(J H$@&\?/^Đ!CIcQŲ,ChZ_~Dh4s,ڵk`ѼZݍ\;d2ZB~~~CN_~cᩧwT7Z(--EBB/*]t BqqqDcwH/ J`aVD%^z+l6܌1cgS TF+{t:D 466B:!eQSSɄW8Ɍ&ގX,hiiFbT*sNd2ѣGa#k?O4ӧOs瓻!>>AAA2̭VQ[[vM] J@d2:$t::-z'AS(tD:u bQQQeVUUUpssC~48MweYhZh4 0 T ___WsZz?b̘1x{u uuu  0Z]*,Q]] ^xxx@*"((qqq페믰X, uhQUXE}}=4 xyXVsCFR;윊d?O=zuuuHMMJ:4ʁjmQ3L8~8T*! HFb@բ eeej{ӟ_~~~~0`@OGURTCHHO;MV,b1|}}ʟJ6 ?>f 4O>$HF0K.h4x"v V1c ##Sô … QSS~<֏477CR!..Ƕ zrxyy!,,v>h%ffYdd ø|21f_ 3api|אӧF#GfNeYTUU k.\111=0ؾ};._n}R(hnnVr& tǭLXN10z| ?'Nqqqxꩧ0l0zf3QVV˗/cɒ%9bŊXfM>˲D"-J6 0 ׯ3x˲0 \2ZX T T ///OHii);C("-- #,bҥHMMų>K,V9s`>Zӡ ݺUd2V4vMj`m6XD"ᆫܱl6>}?#!Gyx$f,bx駑A:L&KxWol6)QWW^n[ܤP__eN;&^Wc2#tR 6 .\ɓ'QVVш`Ĉ:t()"쭷<'xt(шl{n9#)) (//GpppmiiACC<==F&^: N^ Y xyy tbZ8s qU@1l0 :vlݺt(tEٳ| T*!!!HNN a2B䄤^&^, URAΪ(((RH$=܃)))|XŔ)SuVZhԀaNxYBBKo{MTϰ/1)ɽ'ufCaa!N>d2 )))D;O>eZo`رTt:nr`` E/x,d2h4r{B%s/*Tz?NBII ;!C`РAtG;f3駟Î?JL6Sfnnn %C/? d2q3˲m;]ey%%%8{, R`XT 0zĮfΝc=F:N®]3 BquRNO L&#+rNVKmX , 777so\2h䆪 LO(++ | 0:;, 7xk`0 '':o{-h( Ʉף fspz=oߎcHIIkSA/EQTWb۶m|2 q߿aY+8ViӦ쁈)(n,|WhiiA`` $DEEZ Jbʕ+`7n=5KQ՝J%~wڵkj0 ??? !!HLLէ\MEQ@'rHGAQEQ.$GIENDB`libnice-0.1.14/docs/reference/libnice/libnice-docs.xml0000664000076400007640000000754013070507205017512 00000000000000 libnice Reference Manual The latest version of this documentation can be found on-line at http://nice.freedesktop.org/libnice/. ICE Library Libnice helper functions STUN Library STUN usages Pseudo TCP Socket implementation The libnice library contains the ICE library and the STUN library as well as a Pseudo TCP socket implementation. Appendices API Index Index of deprecated symbols Index of new symbols in 0.0.4 Index of new symbols in 0.0.6 Index of new symbols in 0.0.7 Index of new symbols in 0.0.9 Index of new symbols in 0.0.10 Index of new symbols in 0.0.11 Index of new symbols in 0.1.4 Index of new symbols in 0.1.5 Index of new symbols in 0.1.6 Index of new symbols in 0.1.8 Index of new symbols in 0.1.14 libnice-0.1.14/docs/reference/libnice/libnice-overrides.txt0000664000076400007640000000000013067560607020576 00000000000000libnice-0.1.14/docs/reference/libnice/libnice-sections.txt0000664000076400007640000001637213070512356020436 00000000000000
agent NiceAgent NiceAgent NiceComponentState NiceComponentType NiceProxyType NiceCompatibility NiceAgentRecvFunc NiceInputMessage NiceOutputMessage NICE_AGENT_MAX_REMOTE_CANDIDATES nice_agent_new nice_agent_new_reliable nice_agent_add_local_address nice_agent_set_port_range nice_agent_add_stream nice_agent_remove_stream nice_agent_set_relay_info nice_agent_forget_relays nice_agent_gather_candidates nice_agent_set_remote_credentials nice_agent_get_local_credentials nice_agent_set_local_credentials nice_agent_set_remote_candidates nice_agent_get_remote_candidates nice_agent_get_local_candidates nice_agent_get_selected_pair nice_agent_send nice_agent_send_messages_nonblocking nice_agent_recv nice_agent_recv_messages nice_agent_recv_nonblocking nice_agent_recv_messages_nonblocking nice_agent_attach_recv nice_agent_set_selected_pair nice_agent_set_selected_remote_candidate nice_agent_set_stream_tos nice_agent_set_software nice_agent_restart nice_agent_restart_stream nice_agent_set_stream_name nice_agent_get_stream_name nice_agent_get_default_local_candidate nice_agent_generate_local_sdp nice_agent_generate_local_stream_sdp nice_agent_generate_local_candidate_sdp nice_agent_parse_remote_sdp nice_agent_parse_remote_stream_sdp nice_agent_parse_remote_candidate_sdp nice_agent_get_io_stream nice_agent_get_selected_socket nice_agent_get_component_state nice_component_state_to_string NICE_AGENT NICE_IS_AGENT NICE_TYPE_AGENT nice_agent_get_type NICE_AGENT_CLASS NICE_IS_AGENT_CLASS NICE_AGENT_GET_CLASS NiceAgentClass
candidate NiceCandidate NiceCandidate NiceCandidateType NiceCandidateTransport TurnServer NiceRelayType NICE_CANDIDATE_MAX_FOUNDATION nice_candidate_new nice_candidate_free nice_candidate_copy NICE_TYPE_CANDIDATE nice_candidate_get_type NICE_CANDIDATE_TYPE_PREF_HOST NICE_CANDIDATE_TYPE_PREF_PEER_REFLEXIVE NICE_CANDIDATE_TYPE_PREF_SERVER_REFLEXIVE NICE_CANDIDATE_TYPE_PREF_RELAYED NICE_CANDIDATE_TYPE_PREF_NAT_ASSISTED NICE_CANDIDATE_TYPE_PREF_UDP_TUNNELED NICE_CANDIDATE_TYPE_PREF_RELAYED_UDP NICE_CANDIDATE_DIRECTION_MS_PREF_ACTIVE NICE_CANDIDATE_DIRECTION_MS_PREF_PASSIVE NICE_CANDIDATE_TRANSPORT_MS_PREF_TCP NICE_CANDIDATE_TRANSPORT_MS_PREF_UDP
address NiceAddress NiceAddress NICE_ADDRESS_STRING_LEN nice_address_init nice_address_new nice_address_free nice_address_dup nice_address_set_ipv4 nice_address_set_ipv6 nice_address_set_port nice_address_get_port nice_address_set_from_string nice_address_set_from_sockaddr nice_address_copy_to_sockaddr nice_address_equal nice_address_equal_no_port nice_address_to_string nice_address_is_private nice_address_is_valid nice_address_ip_version
debug Debug messages nice_debug_enable nice_debug_disable
interfaces Network interfaces discovery nice_interfaces_get_ip_for_interface nice_interfaces_get_local_interfaces nice_interfaces_get_local_ips
stunagent StunAgent StunAgent StunCompatibility StunAgentUsageFlags StunValidationStatus StunMessageIntegrityValidate StunDefaultValidaterData StunDebugHandler stun_agent_init stun_agent_validate stun_agent_default_validater stun_agent_init_request stun_agent_init_indication stun_agent_init_response stun_agent_init_error stun_agent_build_unknown_attributes_error stun_agent_finish_message stun_agent_forget_transaction stun_agent_set_software stun_debug_enable stun_debug_disable stun_set_debug_handler StunAgentSavedIds stun_debug stun_debug_bytes stun_agent_t
stunmessage StunMessage StunMessage StunClass StunMethod StunAttribute StunTransactionId StunError StunMessageReturn STUN_MESSAGE_BUFFER_INCOMPLETE STUN_MESSAGE_BUFFER_INVALID stun_message_init stun_message_length stun_message_find stun_message_find_flag stun_message_find32 stun_message_find64 stun_message_find_string stun_message_find_addr stun_message_find_xor_addr stun_message_find_xor_addr_full stun_message_find_error stun_message_append stun_message_append_bytes stun_message_append_flag stun_message_append32 stun_message_append64 stun_message_append_string stun_message_append_addr stun_message_append_xor_addr stun_message_append_xor_addr_full stun_message_append_error stun_message_validate_buffer_length StunInputVector stun_message_validate_buffer_length_fast stun_message_id stun_message_get_class stun_message_get_method stun_message_has_attribute stun_message_has_cookie stun_optional stun_strerror
stunconstants STUN Constants STUN_AGENT_MAX_SAVED_IDS STUN_AGENT_MAX_UNKNOWN_ATTRIBUTES STUN_ATTRIBUTE_HEADER_LENGTH STUN_ATTRIBUTE_LENGTH_LEN STUN_ATTRIBUTE_LENGTH_POS STUN_ATTRIBUTE_TYPE_LEN STUN_ATTRIBUTE_TYPE_POS STUN_ATTRIBUTE_VALUE_POS STUN_ID_LEN STUN_MAGIC_COOKIE STUN_MAX_MESSAGE_SIZE STUN_MAX_MESSAGE_SIZE_IPV4 STUN_MAX_MESSAGE_SIZE_IPV6 STUN_MESSAGE_ATTRIBUTES_POS STUN_MESSAGE_HEADER_LENGTH STUN_MESSAGE_LENGTH_LEN STUN_MESSAGE_LENGTH_POS STUN_MESSAGE_TRANS_ID_LEN STUN_MESSAGE_TRANS_ID_POS STUN_MESSAGE_TYPE_LEN STUN_MESSAGE_TYPE_POS TURN_MAGIC_COOKIE
turn TURN StunUsageTurnCompatibility StunUsageTurnRequestPorts StunUsageTurnReturn stun_usage_turn_create stun_usage_turn_create_refresh stun_usage_turn_process stun_usage_turn_refresh_process stun_usage_turn_create_permission
ice ICE StunUsageIceCompatibility StunUsageIceReturn stun_usage_ice_conncheck_create stun_usage_ice_conncheck_process stun_usage_ice_conncheck_create_reply stun_usage_ice_conncheck_priority stun_usage_ice_conncheck_use_candidate
timer Timer StunTimer StunUsageTimerReturn STUN_TIMER_DEFAULT_MAX_RETRANSMISSIONS STUN_TIMER_DEFAULT_RELIABLE_TIMEOUT STUN_TIMER_DEFAULT_TIMEOUT stun_timer_start stun_timer_start_reliable stun_timer_refresh stun_timer_remainder stun_timer_s
bind Bind StunUsageBindReturn stun_usage_bind_create stun_usage_bind_process stun_usage_bind_keepalive stun_usage_bind_run
pseudotcp Pseudo TCP Socket PseudoTcpSocket PseudoTcpState PseudoTcpWriteResult PseudoTcpCallbacks PseudoTcpDebugLevel PseudoTcpShutdown pseudo_tcp_socket_new pseudo_tcp_socket_connect pseudo_tcp_socket_recv pseudo_tcp_socket_send pseudo_tcp_socket_close pseudo_tcp_socket_shutdown pseudo_tcp_socket_is_closed pseudo_tcp_socket_is_closed_remotely pseudo_tcp_socket_get_error pseudo_tcp_socket_get_next_clock pseudo_tcp_socket_notify_clock pseudo_tcp_socket_notify_mtu pseudo_tcp_socket_notify_packet pseudo_tcp_set_debug_level pseudo_tcp_socket_get_available_bytes pseudo_tcp_socket_can_send pseudo_tcp_socket_get_available_send_space pseudo_tcp_socket_notify_message pseudo_tcp_socket_set_time pseudo_tcp_socket_get_type PseudoTcpSocketClass PSEUDOTCP_SOCKET_GET_CLASS PSEUDO_TCP_SOCKET PSEUDO_TCP_SOCKET_CLASS PSEUDO_TCP_SOCKET_TYPE IS_PSEUDO_TCP_SOCKET IS_PSEUDO_TCP_SOCKET_CLASS PseudoTcpSocketPrivate
libnice-0.1.14/docs/design.txt0000664000076400007640000002143512661700132013102 00000000000000Nice: Design documentation ========================== Socket ownership ---------------- For UDP candidates, one socket is created for each component and bound to INADDR_ANY. The same local socket is used for the host candidate, STUN candidate as well as the TURN candidate. The socket handles are stored to the Component structure. The library will use the source address of incoming packets in order to identify from which remote candidates, if any (peer-derived candidates), packets were sent. XXX: Describe the subtle issues with ICMP error handling when one socket is used to send to multiple destinations. Real-time considerations ------------------------ One potential use for libnice code is providing network connectivity for media transport in voice and video telephony applications. This means that the libnice code is potentially run in real-time context (for instance under POSIX SCHED_FIFO/SHCED_RR scheduling policy) and ideally has deterministic execution time. To be real-time friendly, operations with non-deterministic execution time (dynamic memory allocation, file and other resource access) should be done at startup/initialization phase. During an active session (connectivity has been established and non-STUN traffic is being sent), code should be as deterministic as possible. Memory management ----------------- To work on platforms where available memory may be constrained, libnice should gracefully handle out of memory situations. If memory allocation fails, the library should return an error via the originating public library API function. Use of glib creates some challenges to meet the above: - A lot of glib's internal code assumes memory allocations will always work. Use of these glib facilities should be limited. While the glib default policy (see g_malloc() documentation) of terminating the process is ok for applications, this is not acceptable for library components. - Glib has weak support for preallocating structures needed at runtime (for instance use of timers creates a lot of memory allocation activity). To work around the above limitations, the following guidelines need to be followed: - Always check return values of glib functions. - Use safe variants: g_malloc_try(), etc - Current issues (last update 2007-05-04) - g_slist_append() will crash if alloc fails Timers ------ Management of timers is handled by the 'agent' module. Other modules may use timer APIs to get timestamps, but they do not run timers. Glib's timer interface has some problems that have affected the design: - an expired timer will destroy the source (a potentially costly operation) - it is not possible to cancel, or adjust the timer expiration timer without destroying the associated source and creating a new one, which again causes malloc/frees and is potentially a costly operation - on Linux, glib uses gettimeofday() which is subject to clock skew, and no monotonic timer API is available Due to the above, 'agent' code runs fixed interval periodic timers (started with g_timeout_add()) during candidate gathering, connectivity check, and session keepalive phases. Timer frequency is set separately for each phase of processing. A more elegant design would use dynamic timeouts, but this would be too expensive with glib timer infrastructure. Control flow for NICE agent API (NiceAgentClass) ------------------------------------------------ The main library interface for applications using libnice is the NiceAgent GObject interface defined in 'nice/agent.h'. The rough order of control follow is as follows: - creation of NiceAgent object instance - setting agent properties such as STUN and TURN server addresses - connecting the GObject signals with g_signal_connect() to application callback functions - adding local interface addresses to use with nice_agent_add_local_address() And continues when making an initial offer: - creating the streams with nice_agent_add_stream() - attach the mainloop context to connect the NiceAgent sockets to the application's event loop (using nice_agent_attach_recv()) - start candidate gathering by calling nice_agent_gather_candidates() - the application should wait for the "candidate-gathering-done" signal before going forward (so that ICE can gather the needed set of local connectiviy candidates) - get the information needed for sending offer using nice_agent_get_local_candidates() and nice_agent_get_local_credentials() - client should now send the session offer - once it receives an answer, it can pass the information to NiceAgent using nice_agent_set_remote_candidates() and nice_agent_set_remote_credentials() Alternatively, when answering to an initial offer: - the first five steps are the same as above (making initial offer) - pass the remote session information to NiceAgent using nice_agent_set_remote_candidates() and nice_agent_set_remote_credentials() - client can send the answer to session offer Special considerations for a SIP client: - Upon sending the initial offer/answer, client should pick one local candidate as the default one, and encode it to the SDP "m" and "c" lines, in addition to the ICE "a=candidate" lines. - Client should connect to "new-selected-pair" signals. If this signal is received, a new candidate pair has been set as a selected pair (highest priority nominated pair). See ICE specification for a definition of "nominated pairs". - Once all components of a stream have reached the "NICE_COMPONENT_STATE_READY" state (as reported by "component-state-changed" signals), the client should check whether its original default candidate matches the latest selected pair. If not, it needs to send an updated offer it is in controlling mode. Before sending the offer, client should check the "controlling-mode" property to check that it still is in controlling mode (might change during ICE processing due to ICE role conflicts). - The "remote-attributes" SDP attribute can be created from the information provided by "component-state-changed" (which components are ready), "new-selected-pair" (which candidates are selected) and "new-remote-candidate" (peer-reflexive candidates discovered during processing) signals. - Supporting forked calls is not yet supported by the API (multiple sets of remote candidates for one local set of candidates). Restarting ICE: - ICE processing can be restarted by calling nice_agent_restart() - Restart will clean the set of remote candidates, so client must afterwards call nice_agent_set_remote_candidates() after receiving a new offer/answer for the restarted ICE session. - Restart will reinitialize the local credentials (see nice_agent_get_local_credentials()). - Note that to modify the set of local candidates, a new stream has to be created. For the remote party, this looks like a ICE restart as well. Handling fallback to non-ICE operation: - If we are the offering party, and the remote party indicates it doesn't support ICE, we can use nice_agent_set_selected_pair() to force selection of a candidate pair (for remote party, the information on SDP 'm=' and 'c=' lines needs to be used to generate one remote candidate for each component of the streams). This function will halt all ICE processing (excluding keepalives), while still allowing to send and receive media (assuming NATs won't interfere). Notes about sending media: - Client may send media once all components of a stream have reached state of NICE_COMPONENT_STATE_CONNECTED or NICE_COMPONENT_STATE_READY, (as reported by "component-state-changed" signals), and a selected pair is set for all components (as reported by "new-selected-pair" signals). STUN API -------- The underlying STUN library takes care of formatting and parsing STUN messages (lower layer), Applications should only need to use the higher layer API which then uses the lower layer API. The following STUN usages are currently implemented by the transaction layer: - Binding discovery (RFC5389 with RFC3489 backward compatibility) - Binding keep-alive - ICE connectivity checks - TURN - STUN retransmission timers STUN message API ---------------- STUN message API provide thin wrappers to parse and format STUN messages. To achieve maximum cross-architectures portability and retain real-time friendliness, these functions are fully "computational" [1]. They also make no assumption about endianess or memory alignment (reading single bytes or using memcpy()). Message buffers are provided by the caller (so these can be preallocated). Because STUN uses a relatively computer-friendly binary format, STUN messages are stored in wire format within the buffers. There is no intermediary translation, so the APIs can operate directly with data received from or sent to the network. [1] With one exception: The random number generated might access the system entropy pool (/dev/urandom) if available. libnice-0.1.14/TODO0000664000076400007640000000113312520743534010630 00000000000000- High priority: Refactor/cleanup conncheck.c and discovery.c Add a nice_agent_create_source() Implement SIP-style forking nice_socket_recv returns -1 means we must close the nice_socket and stop all connchecks/candidates and reelect if was eleected... Bytestream mode (non packetized) for standard ICE-TCP Standard (RFC 6062) TURN-TCP Server reflexive candidates for ICE-TCP (aka STUN TCP) Clear unused local sockets (freeing file descriptions in the process) on READY TCP simultaneous-open (S-O) - Low priority: Add HTTP Digest support check for the cookie and act accordingly for incoming messages. libnice-0.1.14/NEWS0000664000076400007640000002341313070510326010634 00000000000000libnice 0.1.14 (2017-04-03) =========================== Improved RFC compliance Split verbose logs into a separate option Numerous bug fixes Use GnuTLS for hash functions Implement NewReno in PseudoTCP Requires GLib 2.44 GnuTLS 2.12 libnice 0.1.13 (2015-04-28) =========================== Fix build on non-Windows platforms that don't have getifaddrs() Fix build regression on Windows libnice 0.1.12 (2015-04-22) =========================== Fix regression in SDP parser Make examples work on Windows Bug fixes on nicesrc libnice 0.1.11 (2015-04-20) =========================== API: nice_agent_set_local_credentials() for WebRTC Nicesink: support GstBufferList Better warnings on programming errors Build fixes for Solaris and Windows Bug and documentation fixes libnice 0.1.10 (2015-01-28) =========================== Fix bug on component change on the sink libnice 0.1.9 (2015-01-28) ========================== Make it possible to statically build the GStreamer plugins Bug fixes, in particular fix compatibility with coTurn servers Documentation fixes libnice 0.1.8 (2014-10-09) ========================== Added FIN-ACK behavior in the PseudoTCP ICE-TCP, both standard mode and Microsoft compatible Microsoft compatible TURN-TCP API: nice_address_equal_no_port() to compare NiceAddresses ignoring the port API: nice_agent_get_component_state() to get the current component state API: agent:keepalive-conncheck to make the agent use conncheck as keepalives and fail the connection if there is no answer API: agent:ice-tcp, agent:udp-tcp to control ICE-UDP vs ICE-TCP behaviours API: agent:bytestream-tcp to know if the send/receives in reliable mode create full packets or not API: New signals agent::new-selected-pair-full, agent::new-candidate-full, agent::new-remote-candidate-full which include the NiceCandidates directly API: Deprecated agent::new-selected-pair and agent::new-candidate and agent::new-remote-candidate signals Now all signals are emitted at the function return time libnice 0.1.7 (2014-05-05) ========================== Fix undesired API change that broke Farstream unit testsx libnice 0.1.6 (2014-04-28) ========================== API: nice_agent_restart_stream() to do a ICE restart on a single strema API: nice_component_state_to_string() to get a printable name for a component state API: nice_agent_forget_relays() to forget the relays set for a specific component, along with nice_agent_restart_stream(), it allows changing the current relay without dropping the connection. It is now possible to add relays after the initial candidate gathering. Many bug fixes libnice 0.1.5 (2014-03-06) ========================== API: nice_agent_recv() and nice_agent_recv_nonblocking() as an alternative to the nice_agent_attach_recv() API: nice_agent_recv_messages() and nice_agent_recv_messages_nonblocking() to receive multiple messages at the same time API: nice_agent_get_io_stream() to get a GIOStream in reliable mode API: nice_agent_get_selected_socket() to extract the selected GSocket Import Google's newer PseudoTCP code including window scaling Improve PseudoTCP performance Improve performance Build fixes libnice 0.1.4 (2013-02-22) ========================== Fix issue with dribble mode Fix issue with TURN permissions Fix missing win32 directory from release archive Fix support for OC2007 Added new nice_address_ip_vesion API Added new nice_agent_get_selected_pair API Added new SDP parsing and generation API Added simple examples (simple, threaded and sdp usages examples) libnice 0.1.3 (2012-09-13) ========================== Dribble mode: You can set remote candidates while gathering the local ones Add support for GStreamer 1.0, will compile plugins for both 1.0 and 0.10 by default Cache GSocketAddress in UdpBsdSocket, creating it is very slow libnice 0.1.2 (2012-04-03) ========================== Fix a bug where a controlled agent may never go to READY if it received early conncheck Restart connchecks on a failed candidate pair when receiving a triggered check Fix a bug where gathering-done signal could be sent before UPnP mapping finishes Fix a race condition where setting remote-candidates on a gathered stream failed if another stream was gathering Many fixes to complete and stabilize TURN support Fix a bug in proxy support where TURN packets were misread Refactor libnice to use GSocket which works around a glib limitation of g_io_channel on windows Fix a bug with receiving error messages during conncheck Fix a possible infinite loop bug Fix memory leaks and multi-threaded race conditions Better compatibility for BSD and Mingw Added support files for Visual Studio compilation Various fixes to UPnP support Fixes to the build system libnice 0.1.1 (2011-09-07) ========================== Fixed BSD and Solaris compatibility Fixed PPC64 symbol test Removed a few possible leak/bugs Fixed compatibility with google's recent protocol change libnice 0.1.0 (2011-01-20) ========================== Added nice_candidate_copy to the public API Make stun_timer timeouts configurable (Break API and ABI) Add compatibility support for MSOC 2007 and MSOC 2007 R2 Add MS-TURN support for MSOC Added and completed TURN RFC 5766 support Add a nice_agent_set_port_range API to force a component to use a specific port Fix various bugs and memory leaks Improve documentation libnice 0.0.13 (2010-07-20) ========================== Add support for IPv6 Fix crc32 function conflict with libz.so Various bug fixing and code cleaning Validate the remote candidate address before adding it libnice 0.0.12 (2010-05-19) ========================== Update compatibility to RFC5245 Fix a memory corruption bug Fix a possible buffer overflow with socks5 proxies libnice 0.0.11 (2010-03-18) =========================== Handle EAGAIN for UDP sockets Fix coverity warnings Fix a bug with TURN and Channel Bindings Add a reliable transport mode using libjingle's PseudoTcp implementation Various fixes libnice 0.0.10 (2009-11-04) =========================== Fix some memory leaks with the gstreamer elements Fix username/foundation for google TURN candidates Fix the sending of hundreds of connectivity checks at once the stream is connected Fix BSD support Fix reprocessing of already processed early incoming checks when in dribble-mode Fix a rare crash with failing relay candidates allocations Add a stun_agent_set_software API Add a nice_agent_set_software API libnice 0.0.9 (2009-07-31) =========================== Fix some more issues with peer-reflexive candidates in google mode (for early incoming checks) Fix SHA1 algorithm when strict aliasing is used Fix google mode connectivity with discovered remote peer reflexive candidates Fix google/msn mode by not limiting the conncheck list Fix the interfaces discovery by using getifaddrs Fix compilation on Mac OS X Add ToS support to the sockets libnice 0.0.8 (2009-06-19) =========================== Remove deprecated g_strcasecmp call Use addr instead of base_addr on assigning remote peer-reflexive candidates (fixes crash) Use a global mutex and g_source_is_destroyed to avoid race conditions (fixes crashes) Unlock the mutex before calling the recv callback libnice 0.0.7 (2009-06-11) =========================== Added UPnP Support Fix a race condition when destroying the nice agent Stun headers are now installed Unset timer's source if they return FALSE Fix interoperability with gtalk2voip.com Avoid a race condition where a candidate has the wrong user/pass Add support for delayed setting of the remote candidates in google mode Better connectivity support and race condition fixes Keepalive connchecks do not change the state if they fail but data was still received Fix foundation generation for remote peer reflexive candidates Drop packets when using TCP and the bandwidth is too slow for the data output libnice 0.0.6 (2009-03-31) =========================== Fix connectivity checks for detecting when we loose the connection Fix a race condition with gtalk that made the call silent after 30 seconds Robustness checks with regards to relay information Fix a race condition crash with retransmission ticks Added a new STUN API : stun_agent_forget_transaction Fix a possible crash if tcp-turn is shutdown early in the process Fix a crash when a stream is removed Fix MSN support by disable keepalive connchecks libnice 0.0.5 (2009-03-04) =========================== Name change from nice to libnice Added support for HTTP proxies Added a nice_interfaces API to query the local interfaces/ips Fixed libnice when used in dribble mode Fix a data corruption issue with the SHA1 algorithm Endianness gets checked at runtime so libnice should compile and work everywhere Add compatiblity for WLM2009 ICE Export libstun API and add documentation for libstun Add connectivity checks during the connection to detect when the peer gets disconnected Bug fixes and code cleaning nice 0.0.4 (2008-12-17) ======================== Fix compilation for 64bits systems Revert the use of netbuffer in the gstreamer elements Added support for pseudossl-tcp TURN relay for Google Added support for SOCKS5 proxy servers for TCP relaying Bug fixes and code cleaning nice 0.0.3 (2008-11-25) ======================== Stable google talk support Added TCP TURN relay support for google. Removed openssl dependency. nice 0.0.2 (2008-11-12) ======================== Better support for google talk compatibility mode as well as UDP TURN relay compatibility for Google. Removed -Werror compile flag for releases nice 0.0.1 (2008-11-05) ======================== Initial release of libnice. It has compatibility support for the latest ICE draft 19, as well as google talk and MSN compatibility. It also has support for TURN relays using TURN draft 9 if you're in ICE draft 19 compatibility, or specific Google/MSN relay support if you're in Google/MSN compatibility mode. The library is multiplatform and should compile fine on Linux, Mac and Windows systems. libnice-0.1.14/AUTHORS0000644000076400007640000000027311241364464011212 00000000000000Dafydd Harries Rémi Denis-Courmont Kai Vehmanen Youness Alaoui libnice-0.1.14/COPYING.MPL0000644000076400007640000006207111241364464011630 00000000000000 MOZILLA PUBLIC LICENSE Version 1.1 --------------- 1. Definitions. 1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. 1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. 1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. 1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. 1.5. "Executable" means Covered Code in any form other than Source Code. 1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. 1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 1.8. "License" means this document. 1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. B. Any new file that contains any part of the Original Code or previous Modifications. 1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. 1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. 1.12. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. Source Code License. 2.1. The Initial Developer Grant. The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. 2.2. Contributor Grant. Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Application of License. The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. 3.2. Availability of Source Code. Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. 3.3. Description of Modifications. You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. 3.4. Intellectual Property Matters (a) Third Party Claims. If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. (b) Contributor APIs. If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. (c) Representations. Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. 3.5. Required Notices. You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.6. Distribution of Executable Versions. You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.7. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. 4. Inability to Comply Due to Statute or Regulation. If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Application of this License. This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. 6. Versions of the License. 6.1. New Versions. Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. 6.2. Effect of New Versions. Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. 6.3. Derivative Works. If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) 7. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 8. TERMINATION. 8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: (a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. (b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. 8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. 8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 10. U.S. GOVERNMENT END USERS. The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 11. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. 12. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. 13. MULTIPLE-LICENSED CODE. Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the NPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. EXHIBIT A -Mozilla Public License. ``The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is the Nice GLib ICE library. The Initial Developers of the Original Code are Collabora Ltd and Nokia Corporation. All Rights Reserved. Contributor(s): ______________________________________. Alternatively, the contents of this file may be used under the terms of the _____ license (the "[___] License"), in which case the provisions of [______] License are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the [___] License. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the [___] License." [NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] libnice-0.1.14/random/0000775000076400007640000000000013070512356011477 500000000000000libnice-0.1.14/random/random.h0000664000076400007640000000444711522161146013056 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006-2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _RANDOM_H #define _RANDOM_H #include G_BEGIN_DECLS typedef struct _NiceRNG NiceRNG; struct _NiceRNG { void (*seed) (NiceRNG *src, guint32 seed); void (*generate_bytes) (NiceRNG *src, guint len, gchar *buf); guint (*generate_int) (NiceRNG *src, guint low, guint high); void (*free) (NiceRNG *src); gpointer priv; }; NiceRNG * nice_rng_new (void); void nice_rng_set_new_func (NiceRNG * (*func) (void)); void nice_rng_seed (NiceRNG *rng, guint32 seed); void nice_rng_generate_bytes (NiceRNG *rng, guint len, gchar *buf); void nice_rng_generate_bytes_print (NiceRNG *rng, guint len, gchar *buf); guint nice_rng_generate_int (NiceRNG *rng, guint low, guint high); void nice_rng_free (NiceRNG *rng); G_END_DECLS #endif // _RANDOM_H libnice-0.1.14/random/random.c0000664000076400007640000000657011522161146013050 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2008 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006-2008 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "random.h" #include "random-glib.h" static NiceRNG * (*nice_rng_new_func) (void) = NULL; /* * Creates a new random number generator instance. */ NiceRNG * nice_rng_new (void) { if (nice_rng_new_func == NULL) return nice_rng_glib_new (); else return nice_rng_new_func (); } /* * Sets a new generator function. */ void nice_rng_set_new_func (NiceRNG * (*func) (void)) { nice_rng_new_func = func; } /* * Frees the random number generator instance. * * @param rng context */ void nice_rng_free (NiceRNG *rng) { rng->free (rng); } /* * Generates random octets. * * @param rng context * @param len number of octets to product * @param buf buffer to store the results */ void nice_rng_generate_bytes (NiceRNG *rng, guint len, gchar *buf) { rng->generate_bytes (rng, len, buf); } /* * Generates a random unsigned integer. * * @param rng context * @param low closed lower bound * @param high open upper bound */ guint nice_rng_generate_int (NiceRNG *rng, guint low, guint high) { return rng->generate_int (rng, low, high); } /* * Generates a stream of octets containing only characters * with ASCII codecs of 0x41-5A (A-Z), 0x61-7A (a-z), * 0x30-39 (0-9), 0x2b (+) and 0x2f (/). This matches * the definition of 'ice-char' in ICE Ispecification, * section 15.1 (ID-16). * * @param rng context * @param len number of octets to product * @param buf buffer to store the results */ void nice_rng_generate_bytes_print (NiceRNG *rng, guint len, gchar *buf) { guint i; const gchar *chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "+/"; for (i = 0; i < len; i++) buf[i] = chars[nice_rng_generate_int (rng, 0, strlen (chars))]; } libnice-0.1.14/random/test.c0000664000076400007640000000456011522161146012544 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006-2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "random-glib.h" int main (void) { NiceRNG *rng; const int rngsize = 256; gchar buf[rngsize]; buf[rngsize - 1] = '\0'; nice_rng_set_new_func (nice_rng_glib_new_predictable); rng = nice_rng_new (); nice_rng_generate_bytes_print (rng, rngsize - 1, buf); /* g_debug ("%s", buf); */ g_assert (0 == strcmp (buf, "sv1AD7DnJTVykXGYYM6BmnXuYRlZNIJUzQzF+PvASjYxzdTTOngBJ5/gfK0Xj+Ly3ciAAk1Fmo0RPEpq6f4BBnp5jm3LuSbAOj1M5qULEGEv/0DMk0oOPUj6XPN1VwxFpjAfFeAxykiwdDiqNwnVJ/AKyr6/X7C5i+je7DSujURybOp6BkKWroLCzQg2AmTuqz48oNeY9CDeirNwoITfIaC40Ds9OgEDtL8WN5tL4QYdVuZQ85219Thogk775GV")); nice_rng_generate_bytes (rng, 4, buf); buf[4] = 0; g_assert (0 == strcmp (buf, "\x1f\x0d\x47\xb8")); nice_rng_free (rng); return 0; } libnice-0.1.14/random/Makefile.in0000664000076400007640000010365413070512350013467 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ check_PROGRAMS = test$(EXEEXT) subdir = random ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libnice_random_la_LIBADD = am_libnice_random_la_OBJECTS = random.lo random-glib.lo libnice_random_la_OBJECTS = $(am_libnice_random_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = test_SOURCES = test.c test_OBJECTS = test.$(OBJEXT) am__DEPENDENCIES_1 = test_DEPENDENCIES = libnice-random.la $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libnice_random_la_SOURCES) test.c DIST_SOURCES = $(libnice_random_la_SOURCES) test.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda AM_CFLAGS = $(LIBNICE_CFLAGS) $(GLIB_CFLAGS) noinst_LTLIBRARIES = libnice-random.la libnice_random_la_SOURCES = \ random.h \ random.c \ random-glib.h \ random-glib.c test_LDADD = libnice-random.la $(GLIB_LIBS) TESTS = $(check_PROGRAMS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu random/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu random/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libnice-random.la: $(libnice_random_la_OBJECTS) $(libnice_random_la_DEPENDENCIES) $(EXTRA_libnice_random_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libnice_random_la_OBJECTS) $(libnice_random_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) @rm -f test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-glib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test.log: test$(EXEEXT) @p='test$(EXEEXT)'; \ b='test'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am recheck tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/random/Makefile.am0000664000076400007640000000075612363772107013471 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include $(top_srcdir)/common.mk AM_CFLAGS = $(LIBNICE_CFLAGS) $(GLIB_CFLAGS) noinst_LTLIBRARIES = libnice-random.la libnice_random_la_SOURCES = \ random.h \ random.c \ random-glib.h \ random-glib.c check_PROGRAMS = test test_LDADD = libnice-random.la $(GLIB_LIBS) TESTS = $(check_PROGRAMS) libnice-0.1.14/random/random-glib.h0000664000076400007640000000341611522161146013764 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2007 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006-2007 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifndef _RANDOM_GLIB_H #define _RANDOM_GLIB_H #include #include "random.h" G_BEGIN_DECLS NiceRNG * nice_rng_glib_new (void); NiceRNG * nice_rng_glib_new_predictable (void); G_END_DECLS #endif /* _RANDOM_GLIB_H */ libnice-0.1.14/random/random-glib.c0000664000076400007640000000506411522161146013760 00000000000000/* * This file is part of the Nice GLib ICE library. * * (C) 2006-2008 Collabora Ltd. * Contact: Dafydd Harries * (C) 2006-2008 Nokia Corporation. All rights reserved. * Contact: Kai Vehmanen * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Nice GLib ICE library. * * The Initial Developers of the Original Code are Collabora Ltd and Nokia * Corporation. All Rights Reserved. * * Contributors: * Dafydd Harries, Collabora Ltd. * Youness Alaoui, Collabora Ltd. * Kai Vehmanen, Nokia * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "random-glib.h" static void rng_seed ( G_GNUC_UNUSED NiceRNG *rng, guint32 seed) { (void)rng; g_random_set_seed (seed); } static void rng_generate_bytes ( G_GNUC_UNUSED NiceRNG *rng, guint len, gchar *buf) { guint i; (void)rng; for (i = 0; i < len; i++) buf[i] = g_random_int_range (0, 256); } static guint rng_generate_int ( G_GNUC_UNUSED NiceRNG *rng, guint low, guint high) { (void)rng; return g_random_int_range (low, high); } static void rng_free (NiceRNG *rng) { g_slice_free (NiceRNG, rng); } NiceRNG * nice_rng_glib_new (void) { NiceRNG *ret; ret = g_slice_new0 (NiceRNG); ret->seed = rng_seed; ret->generate_bytes = rng_generate_bytes; ret->generate_int = rng_generate_int; ret->free = rng_free; return ret; } NiceRNG * nice_rng_glib_new_predictable (void) { NiceRNG *rng; rng = nice_rng_glib_new (); rng->seed (rng, 0); return rng; } libnice-0.1.14/README0000664000076400007640000000303313070511610011006 00000000000000 Nice: GLib ICE library ====================== Copyright --------- (C) 2006-2017 Collabora Ltd. (C) 2006-2011 Nokia Corporation License ------- See the file COPYING. Requirements ------------ glib >= 2.44 pkg-config gnutls >= 2.12.0 gupnp-igd >= 0.1.2 (optional) gstreamer-0.10 >= 0.10.0 (optional) gstreamer-1.0 (optional) Build instructions ------------------ To build on Linux and Mac, you only need to type the usual commands : ./configure && make && sudo make install Please refer to the INSTALL file for more details. If you are building from git, you must first run the ./autogen.sh script to generate the configure file for you. To build on Windows, please refer to the README.win32 file for build instructions using Microsoft Visual Studio. Structure --------- agent/ - ICE agent docs/ - Design and API documentation gst/ - Gstreamer elements nice/ - libnice library random/ - random number generation socket/ - Socket abstraction layer stun/ - STUN implementation tests/ - Unit tests Relevant standards ------------------ These standards are relevant to nice's current implementation. ICE RFC 5245 http://tools.ietf.org/html/rfc5245 STUN http://tools.ietf.org/html/rfc3489 http://tools.ietf.org/html/rfc5389 TURN http://tools.ietf.org/html/rfc5766 RTP http://tools.ietf.org/html/rfc3550 XMPP Jingle ICE transport http://www.xmpp.org/extensions/xep-0176.html In future, nice may additionally support the following standards. NAT-PMP http://files.dns-sd.org/draft-cheshire-nat-pmp.txt libnice-0.1.14/configure.ac0000664000076400007640000002342213070512341012422 00000000000000 AC_PREREQ(2.62) dnl Always compile with -Wall; if --enable-compile-warnings=error is passed, dnl also use -Werror. git and pre-releases default to -Werror dnl use a three digit version number for releases, and four for cvs/prerelease AC_INIT([libnice],[0.1.14]) LIBNICE_RELEASE="yes" AC_CANONICAL_TARGET AC_CONFIG_SRCDIR([agent/agent.c]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([1.12 -Wall -Wno-portability subdir-objects]) AC_CONFIG_FILES([ Makefile agent/Makefile stun/Makefile stun/tests/Makefile stun/tools/Makefile socket/Makefile nice/Makefile nice/nice.pc random/Makefile gst/Makefile docs/Makefile docs/reference/Makefile docs/reference/libnice/Makefile tests/Makefile examples/Makefile ]) # Set the libtool C/A/R version info # If the source code was changed, but there were no interface changes: # Increment REVISION. # If there was a compatible interface change: # Increment CURRENT and AGE. Set REVISION to 0 # If there was an incompatible interface change: # Increment CURRENT. Set AGE and REVISION to 0 LIBNICE_CURRENT=17 LIBNICE_REVISION=0 LIBNICE_AGE=7 LIBNICE_LIBVERSION=${LIBNICE_CURRENT}:${LIBNICE_REVISION}:${LIBNICE_AGE} LIBNICE_LT_LDFLAGS="-version-info ${LIBNICE_LIBVERSION} -no-undefined" AC_SUBST(LIBNICE_LT_LDFLAGS) dnl use pretty build output AM_SILENT_RULES([yes]) # Checks for programs. AC_USE_SYSTEM_EXTENSIONS AC_PROG_CC AM_PROG_AR LT_PREREQ([2.2.6]) LT_INIT([dlopen win32-dll disable-static]) # Check Operating System AC_MSG_CHECKING([operating system]) case "$host" in *-*-*mingw*|*-*-*cygwin*) platform=win32 AC_MSG_RESULT($platform) ;; *) platform=linux/other AC_MSG_RESULT($platform) ;; esac AM_CONDITIONAL([WINDOWS], [test "$platform" = "win32"]) # Checks for compiler features AC_C_RESTRICT AC_C_VARARRAYS AC_HEADER_ASSERT AC_HEADER_STDBOOL AH_VERBATIM([_FORTIFY_SOURCE], [/* Define to `2' to get GNU/libc warnings. */ /* Only define if -O1 or more is enabled */ #if defined __OPTIMIZE__ && __OPTIMIZE__ > 0 # define _FORTIFY_SOURCE 2 #endif]) AC_DEFINE([NICEAPI_EXPORT], [ ], [Public library function implementation]) AC_CHECK_HEADERS([arpa/inet.h net/in.h netdb.h]) AC_CHECK_HEADERS([ifaddrs.h], \ [AC_DEFINE(HAVE_GETIFADDRS, [1], \ [Whether getifaddrs() is available on the system])]) AC_CHECK_TYPES([size_t, ssize_t]) # Also put matching version in LIBNICE_CFLAGS GLIB_REQ=2.44 LIBNICE_CFLAGS="-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_44 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_44" dnl Support different levels of compiler error reporting. dnl This configure flag is designed to mimic one from gnome-common, dnl Defaults to "error" except for releases where it defaults to "yes" AC_ARG_ENABLE(compile-warnings, AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@], [Enable different levels of compiler warnings]),, [AS_IF([test "$LIBNICE_RELEASE" = "yes"], [enable_compile_warnings="yes"], [enable_compile_warnings="error"])]) AC_DEFUN([NICE_ADD_FLAG], AS_COMPILER_FLAG([-Werror $1], LIBNICE_CFLAGS="$LIBNICE_CFLAGS $1", []) ) NICE_ADD_FLAG([-fno-strict-aliasing]) AS_IF([test "$enable_compile_warnings" != "no"],[ NICE_ADD_FLAG([-Wall]) ]) AS_IF([test "x$enable_compile_warnings" != "xno" -a \ "x$enable_compile_warnings" != "xminimum"],[ NICE_ADD_FLAG([-Wextra]) NICE_ADD_FLAG([-Wundef]) NICE_ADD_FLAG([-Wnested-externs]) NICE_ADD_FLAG([-Wwrite-strings]) NICE_ADD_FLAG([-Wpointer-arith]) NICE_ADD_FLAG([-Wmissing-declarations]) NICE_ADD_FLAG([-Wmissing-prototypes]) NICE_ADD_FLAG([-Wstrict-prototypes]) NICE_ADD_FLAG([-Wredundant-decls]) NICE_ADD_FLAG([-Wno-unused-parameter]) NICE_ADD_FLAG([-Wno-missing-field-initializers]) NICE_ADD_FLAG([-Wdeclaration-after-statement]) NICE_ADD_FLAG([-Wformat=2]) NICE_ADD_FLAG([-Wold-style-definition]) NICE_ADD_FLAG([-Wcast-align]) NICE_ADD_FLAG([-Wformat-nonliteral]) NICE_ADD_FLAG([-Wformat-security]) ]) AS_IF([test "$enable_compile_warnings" = "yes" -o \ "$enable_compile_warnings" = "maximum" -o \ "$enable_compile_warnings" = "error"],[ NICE_ADD_FLAG([-Wsign-compare]) NICE_ADD_FLAG([-Wstrict-aliasing]) NICE_ADD_FLAG([-Wshadow]) NICE_ADD_FLAG([-Winline]) NICE_ADD_FLAG([-Wpacked]) NICE_ADD_FLAG([-Wmissing-format-attribute]) NICE_ADD_FLAG([-Winit-self]) NICE_ADD_FLAG([-Wredundant-decls]) NICE_ADD_FLAG([-Wmissing-include-dirs]) NICE_ADD_FLAG([-Wunused-but-set-variable]) NICE_ADD_FLAG([-Warray-bounds]) ]) AS_IF([test "$enable_compile_warnings" = "maximum" -o \ "$enable_compile_warnings" = "error"],[ NICE_ADD_FLAG([-Wswitch-enum]) NICE_ADD_FLAG([-Wswitch-default]) NICE_ADD_FLAG([-Waggregate-return]) ]) AS_IF([test "x$enable_compile_warnings" = "xerror"],[ NICE_ADD_FLAG([-Werror]) NICE_ADD_FLAG([-Wno-suggest-attribute=format]) ]) # # Fixes for Solaris # AC_SEARCH_LIBS([inet_pton],[nsl]) AC_SEARCH_LIBS([socket],[socket inet]) case $host in *-*-solaris* ) AC_DEFINE(_XOPEN_SOURCE, 600, Needed to get declarations for msg_control and msg_controllen on Solaris) AC_DEFINE(__EXTENSIONS__, 1, Needed to get declarations for msg_control and msg_controllen on Solaris) ;; esac AC_SUBST(LIBNICE_CFLAGS) AC_MSG_NOTICE([set LIBNICE_CFLAGS to $LIBNICE_CFLAGS]) # Checks for libraries. AC_CHECK_LIB(rt, clock_gettime, [LIBRT="-lrt"], [LIBRT=""]) AC_CHECK_FUNCS([poll]) AC_SUBST(LIBRT) # Dependencies GNUTLS_PACKAGES_PRIVATE="gnutls >= 2.12.0" PKG_CHECK_MODULES(GNUTLS, [$GNUTLS_PACKAGES_PRIVATE]) NICE_PACKAGES_PUBLIC="glib-2.0 >= $GLIB_REQ gio-2.0 >= $GLIB_REQ gobject-2.0 >= $GLIB_REQ" NICE_PACKAGES_PRIVATE="gthread-2.0" PKG_CHECK_MODULES(GLIB, [$NICE_PACKAGES_PUBLIC $NICE_PACKAGES_PRIVATE]) NICE_PACKAGES_PRIVATE="$NICE_PACKAGES_PRIVATE $GNUTLS_PACKAGES_PRIVATE" AC_SUBST([NICE_PACKAGES_PUBLIC]) AC_SUBST([NICE_PACKAGES_PRIVATE]) AC_ARG_WITH(gstreamer, AS_HELP_STRING([--with-gstreamer],[build GStreamer plugin]), [with_gstreamer=${withval}], [with_gstreamer=auto]) AC_ARG_WITH(gstreamer-0.10, AS_HELP_STRING([--with-gstreamer-0.10],[build GStreamer 0.10 plugin]), [with_gstreamer010=${withval}], [with_gstreamer010=auto]) AS_IF([test "$with_gstreamer" != no], [ PKG_CHECK_MODULES(GST, [ gstreamer-1.0 >= 0.11.91 gstreamer-base-1.0 >= 0.11.91 ], [ with_gstreamer=yes GST_MAJORMINOR=1.0 gstplugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" ], [ AS_IF([test "$with_gstreamer" = yes], [ AC_MSG_ERROR([GStreamer 1.0 support was requested but GStreamer 1.0 libraries are not available]) ]) with_gstreamer=no ]) PKG_CHECK_MODULES(GST_CHECK, [ gstreamer-check-1.0 >= 0.11.91 ], [ have_gst_check=yes ], [ have_gst_check=no ]) ]) AS_IF([test "$with_gstreamer010" != no], [ PKG_CHECK_MODULES(GST010, [ gstreamer-0.10 >= 0.10.10 gstreamer-base-0.10 >= 0.10.10 ], [ with_gstreamer010=yes GST_MAJORMINOR=0.10 gstplugin010dir="\$(libdir)/gstreamer-$GST_MAJORMINOR" ], [ AS_IF([test "$with_gstreamer010" = yes], [ AC_MSG_ERROR([GStreamer 0.10 support was requested but GStreamer 0.10 libraries are not available]) ]) with_gstreamer010=no ]) ]) AC_SUBST(gstplugindir) AC_SUBST(gstplugin010dir) AM_CONDITIONAL(WITH_GSTREAMER, test "$with_gstreamer" = yes) AM_CONDITIONAL(HAVE_GST_CHECK, test "$have_gst_check" = yes) AM_CONDITIONAL(WITH_GSTREAMER010, test "$with_gstreamer010" = yes) GUPNP_IGD_REQUIRED=0.2.4 AC_ARG_ENABLE([gupnp], AS_HELP_STRING([--disable-gupnp],[Disable GUPnP IGD support]), [case "${enableval}" in yes) WANT_GUPNP=yes ;; no) WANT_GUPNP=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-gupnp) ;; esac], WANT_GUPNP=test) GUPNP_PACKAGES_PUBLIC="" GUPNP_PACKAGES_PRIVATE="gupnp-igd-1.0 >= $GUPNP_IGD_REQUIRED" GUPNP_PACKAGES="$GUPNP_PACKAGES_PUBLIC $GUPNP_PACKAGES_PRIVATE" HAVE_GUPNP=no if test "x$WANT_GUPNP" != "xno"; then PKG_CHECK_MODULES(GUPNP, [$GUPNP_PACKAGES], [ HAVE_GUPNP=yes ], [ HAVE_GUPNP=no ]) fi if test "x$WANT_GUPNP" = "xyes" && test "x$HAVE_GUPNP" = "xno"; then AC_MSG_ERROR([Requested GUPnP IGD, but it is not available]) fi if test "x$HAVE_GUPNP" = "xyes"; then AC_DEFINE(HAVE_GUPNP,,[Have the GUPnP IGD library]) UPNP_ENABLED="true" else GUPNP_PACKAGES_PUBLIC="" GUPNP_PACKAGES_PRIVATE="" GUPNP_PACKAGES="" fi AC_SUBST([GUPNP_PACKAGES_PUBLIC]) AC_SUBST([GUPNP_PACKAGES_PRIVATE]) AC_SUBST([GUPNP_PACKAGES]) AC_SUBST(HAVE_GUPNP) AC_SUBST([UPNP_ENABLED]) dnl Test coverage AC_ARG_ENABLE([coverage], [AS_HELP_STRING([--enable-coverage], [build for test coverage (default disabled)])],, [enable_coverage="no"]) AS_IF([test "${enable_coverage}" != "no"], [ CFLAGS="${CFLAGS} -g -O0 -fprofile-arcs -ftest-coverage" LDFLAGS="-lgcov" CCACHE_DISABLE=1 ]) AC_SUBST(CCACHE_DISABLE) dnl build static plugins or not AC_MSG_CHECKING([whether to build static plugins or not]) AC_ARG_ENABLE( static-plugins, AC_HELP_STRING( [--enable-static-plugins], [build static plugins @<:@default=no@:>@]), [AS_CASE( [$enableval], [no], [], [yes], [], [AC_MSG_ERROR([bad value "$enableval" for --enable-static-plugins])])], [enable_static_plugins=no]) AC_MSG_RESULT([$enable_static_plugins]) if test "x$enable_static_plugins" = xyes; then AC_DEFINE(GST_PLUGIN_BUILD_STATIC, 1, [Define if static plugins should be built]) fi AM_CONDITIONAL(GST_PLUGIN_BUILD_STATIC, test "x$enable_static_plugins" = "xyes") case $host_os in solaris*) LDFLAGS="$LDFLAGS -lsocket -lnsl" ;; *) ;; esac # check for gtk-doc m4_ifdef([GTK_DOC_CHECK], [ GTK_DOC_CHECK([1.10],[--flavour no-tmpl]) ],[ AM_CONDITIONAL([ENABLE_GTK_DOC], false) ]) # GObject introspection GOBJECT_INTROSPECTION_CHECK([1.30.0]) AC_CONFIG_MACRO_DIR(m4) AC_OUTPUT libnice-0.1.14/m4/0000775000076400007640000000000013070512355010536 500000000000000libnice-0.1.14/m4/ltversion.m40000644000076400007640000000127313067560503012752 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) libnice-0.1.14/m4/ltoptions.m40000644000076400007640000003426213067560503012764 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) libnice-0.1.14/m4/gtk-doc.m40000644000076400007640000000631213067560475012264 00000000000000dnl -*- mode: autoconf -*- # serial 2 dnl Usage: dnl GTK_DOC_CHECK([minimum-gtk-doc-version]) AC_DEFUN([GTK_DOC_CHECK], [ AC_REQUIRE([PKG_PROG_PKG_CONFIG]) AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first ifelse([$1],[],[gtk_doc_requires="gtk-doc"],[gtk_doc_requires="gtk-doc >= $1"]) AC_MSG_CHECKING([for gtk-doc]) PKG_CHECK_EXISTS([$gtk_doc_requires],[have_gtk_doc=yes],[have_gtk_doc=no]) AC_MSG_RESULT($have_gtk_doc) if test "$have_gtk_doc" = "no"; then AC_MSG_WARN([ You will not be able to create source packages with 'make dist' because $gtk_doc_requires is not found.]) fi dnl check for tools we added during development dnl Use AC_CHECK_PROG to avoid the check target using an absolute path that dnl may not be writable by the user. Currently, automake requires that the dnl test name must end in '.test'. dnl https://bugzilla.gnome.org/show_bug.cgi?id=701638 AC_CHECK_PROG([GTKDOC_CHECK],[gtkdoc-check],[gtkdoc-check.test]) AC_PATH_PROG([GTKDOC_CHECK_PATH],[gtkdoc-check]) AC_PATH_PROGS([GTKDOC_REBASE],[gtkdoc-rebase],[true]) AC_PATH_PROG([GTKDOC_MKPDF],[gtkdoc-mkpdf]) dnl for overriding the documentation installation directory AC_ARG_WITH([html-dir], AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, [with_html_dir='${datadir}/gtk-doc/html']) HTML_DIR="$with_html_dir" AC_SUBST([HTML_DIR]) dnl enable/disable documentation building AC_ARG_ENABLE([gtk-doc], AS_HELP_STRING([--enable-gtk-doc], [use gtk-doc to build documentation [[default=no]]]),, [enable_gtk_doc=no]) AC_MSG_CHECKING([whether to build gtk-doc documentation]) AC_MSG_RESULT($enable_gtk_doc) if test "x$enable_gtk_doc" = "xyes" && test "$have_gtk_doc" = "no"; then AC_MSG_ERROR([ You must have $gtk_doc_requires installed to build documentation for $PACKAGE_NAME. Please install gtk-doc or disable building the documentation by adding '--disable-gtk-doc' to '[$]0'.]) fi dnl don't check for glib if we build glib if test "x$PACKAGE_NAME" != "xglib"; then dnl don't fail if someone does not have glib PKG_CHECK_MODULES(GTKDOC_DEPS, glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0,,[:]) fi dnl enable/disable output formats AC_ARG_ENABLE([gtk-doc-html], AS_HELP_STRING([--enable-gtk-doc-html], [build documentation in html format [[default=yes]]]),, [enable_gtk_doc_html=yes]) AC_ARG_ENABLE([gtk-doc-pdf], AS_HELP_STRING([--enable-gtk-doc-pdf], [build documentation in pdf format [[default=no]]]),, [enable_gtk_doc_pdf=no]) if test -z "$GTKDOC_MKPDF"; then enable_gtk_doc_pdf=no fi if test -z "$AM_DEFAULT_VERBOSITY"; then AM_DEFAULT_VERBOSITY=1 fi AC_SUBST([AM_DEFAULT_VERBOSITY]) AM_CONDITIONAL([HAVE_GTK_DOC], [test x$have_gtk_doc = xyes]) AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes]) AM_CONDITIONAL([GTK_DOC_BUILD_HTML], [test x$enable_gtk_doc_html = xyes]) AM_CONDITIONAL([GTK_DOC_BUILD_PDF], [test x$enable_gtk_doc_pdf = xyes]) AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"]) AM_CONDITIONAL([GTK_DOC_USE_REBASE], [test -n "$GTKDOC_REBASE"]) ]) libnice-0.1.14/m4/lt~obsolete.m40000644000076400007640000001377413067560503013310 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) libnice-0.1.14/m4/pkg.m40000644000076400007640000002401113067560431011501 00000000000000dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR libnice-0.1.14/m4/introspection.m40000664000076400007640000000673612520743534013640 00000000000000dnl -*- mode: autoconf -*- dnl Copyright 2009 Johan Dahlin dnl dnl This file is free software; the author(s) gives unlimited dnl permission to copy and/or distribute it, with or without dnl modifications, as long as this notice is preserved. dnl # serial 1 m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL], [ AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first AC_BEFORE([LT_INIT],[$0])dnl setup libtool first dnl enable/disable introspection m4_if([$2], [require], [dnl enable_introspection=yes ],[dnl AC_ARG_ENABLE(introspection, AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]], [Enable introspection for this build]),, [enable_introspection=auto]) ])dnl AC_MSG_CHECKING([for gobject-introspection]) dnl presence/version checking AS_CASE([$enable_introspection], [no], [dnl found_introspection="no (disabled, use --enable-introspection to enable)" ],dnl [yes],[dnl PKG_CHECK_EXISTS([gobject-introspection-1.0],, AC_MSG_ERROR([gobject-introspection-1.0 is not installed])) PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME])) ],dnl [auto],[dnl PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no) dnl Canonicalize enable_introspection enable_introspection=$found_introspection ],dnl [dnl AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@]) ])dnl AC_MSG_RESULT([$found_introspection]) INTROSPECTION_SCANNER= INTROSPECTION_COMPILER= INTROSPECTION_GENERATE= INTROSPECTION_GIRDIR= INTROSPECTION_TYPELIBDIR= if test "x$found_introspection" = "xyes"; then INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection fi AC_SUBST(INTROSPECTION_SCANNER) AC_SUBST(INTROSPECTION_COMPILER) AC_SUBST(INTROSPECTION_GENERATE) AC_SUBST(INTROSPECTION_GIRDIR) AC_SUBST(INTROSPECTION_TYPELIBDIR) AC_SUBST(INTROSPECTION_CFLAGS) AC_SUBST(INTROSPECTION_LIBS) AC_SUBST(INTROSPECTION_MAKEFILE) AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes") ]) dnl Usage: dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version]) AC_DEFUN([GOBJECT_INTROSPECTION_CHECK], [ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1]) ]) dnl Usage: dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version]) AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE], [ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require]) ]) libnice-0.1.14/m4/as-compiler-flag.m40000664000076400007640000000255412363772107014057 00000000000000dnl as-compiler-flag.m4 0.1.0 dnl autostars m4 macro for detection of compiler flags dnl David Schleef dnl Tim-Philipp Müller dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) dnl Tries to compile with the given CFLAGS. dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, dnl and ACTION-IF-NOT-ACCEPTED otherwise. AC_DEFUN([AS_COMPILER_FLAG], [ AC_MSG_CHECKING([to see if compiler understands $1]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then $2 true else $3 true fi AC_MSG_RESULT([$flag_ok]) ]) dnl AS_CXX_COMPILER_FLAG(CPPFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) dnl Tries to compile with the given CPPFLAGS. dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, dnl and ACTION-IF-NOT-ACCEPTED otherwise. AC_DEFUN([AS_CXX_COMPILER_FLAG], [ AC_REQUIRE([AC_PROG_CXX]) AC_MSG_CHECKING([to see if c++ compiler understands $1]) save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $1" AC_LANG_PUSH(C++) AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) CPPFLAGS="$save_CPPFLAGS" if test "X$flag_ok" = Xyes ; then $2 true else $3 true fi AC_LANG_POP(C++) AC_MSG_RESULT([$flag_ok]) ]) libnice-0.1.14/m4/libtool.m40000644000076400007640000112530613067560503012376 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _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" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS libnice-0.1.14/m4/ltsugar.m40000644000076400007640000001044013067560503012402 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) libnice-0.1.14/win32/0000775000076400007640000000000012363772107011167 500000000000000libnice-0.1.14/win32/vs9/0000775000076400007640000000000013070511675011705 500000000000000libnice-0.1.14/win32/vs9/test-thread.vcproj0000664000076400007640000001076312262633251015302 00000000000000 libnice-0.1.14/win32/vs9/test-dribble.vcproj0000664000076400007640000001070612262633251015433 00000000000000 libnice-0.1.14/win32/vs9/config.h0000664000076400007640000001014212262633251013236 00000000000000/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ /* #undef HAVE_ARPA_INET_H */ /* Define to 1 if C supports variable-length arrays. */ #define HAVE_C_VARARRAYS 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_DLFCN_H */ /* \ Whether getifaddrs() is available on the system */ /* #undef HAVE_GETIFADDRS */ /* Have the GUPnP IGD library */ /* #undef HAVE_GUPNP */ /* Define to 1 if you have the header file. */ /* #undef HAVE_IFADDRS_H */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_NET_IN_H */ /* Define to 1 if you have the `poll' function. */ /* #undef HAVE_POLL */ /* Define to 1 if stdbool.h conforms to C99. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if the system has the type `_Bool'. */ #define HAVE__BOOL 1 /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if assertions should be disabled. */ /* #undef NDEBUG */ /* Public library function implementation */ #define NICEAPI_EXPORT /* Name of package */ #define PACKAGE "libnice" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "libnice" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "libnice 0.1.1.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libnice" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "0.1.1.1" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # define _ALL_SOURCE 1 #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # define _POSIX_PTHREAD_SEMANTICS 1 #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # define _TANDEM_SOURCE 1 #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # define __EXTENSIONS__ 1 #endif /* Version number of package */ #define VERSION "0.1.1.1" /* Define to `2' to get GNU/libc warnings. */ #define _FORTIFY_SOURCE 2 /* Define to 1 if on MINIX. */ /* #undef _MINIX */ /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ /* #undef _POSIX_1_SOURCE */ /* Define to 1 if you need to in order for `stat' and other things to work. */ /* #undef _POSIX_SOURCE */ /* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported directly. */ /*#define restrict __restrict*/ /* Work around a bug in Sun C++: it does not support _Restrict or __restrict__, even though the corresponding Sun C compiler ends up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. Perhaps some future version of Sun C++ will work with restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ #if defined __SUNPRO_CC && !defined __RESTRICT # define _Restrict # define __restrict__ #endif libnice-0.1.14/win32/vs9/test-address.vcproj0000664000076400007640000001070612262633251015455 00000000000000 libnice-0.1.14/win32/vs9/test-add-remove-stream.vcproj0000664000076400007640000001074212262633251017344 00000000000000 libnice-0.1.14/win32/vs9/test-fallback.vcproj0000664000076400007640000001077112262633251015571 00000000000000 libnice-0.1.14/win32/vs9/test-fullmode.vcproj0000664000076400007640000001102512262633251015632 00000000000000 libnice-0.1.14/win32/vs9/libnice.vcproj0000664000076400007640000002545212520743534014467 00000000000000 libnice-0.1.14/win32/vs9/test-parse.vcproj0000664000076400007640000001040712262633251015140 00000000000000 libnice-0.1.14/win32/vs9/libnice.sln0000664000076400007640000002231712262633251013752 00000000000000 Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnice", "libnice.vcproj", "{550C7FB8-DBFE-4364-B26A-DAF7158CD878}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{3B5FCB79-8AAA-4388-926B-3AD3F8BBB5D8}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-dribble", "test-dribble.vcproj", "{4E64F83D-4AE9-468A-867A-CB42A8B89150}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-fullmode", "test-fullmode.vcproj", "{60EC66A2-FE1F-413E-8FEE-204386D62617}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glib", "glib.vcproj", "{DD34FAC7-C1A2-4F29-8C96-3F053B47D714}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-pseudotcp", "test-pseudotcp.vcproj", "{619723EB-D355-46DC-AF8F-0A04F44AC581}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{D3264B88-D38F-41E4-A2CB-C53644913D75}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{46508783-E794-4688-B045-DE02A626B078}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-parse", "test-parse.vcproj", "{6E766AF4-4FFD-40AE-B425-54E4874E3AE4}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-bind", "test-bind.vcproj", "{07645BAF-F78D-413C-B257-E348B2CEA18A}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-restart", "test-restart.vcproj", "{A503EF24-EB17-44FA-ABB1-42DCF361F4EA}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-fallback", "test-fallback.vcproj", "{751C43C2-5987-4C4E-AD74-2737814890F0}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-address", "test-address.vcproj", "{3E9D5FA3-F7C5-474E-8797-DFA3E6B2E436}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-add-remove-stream", "test-add-remove-stream.vcproj", "{065B91A4-2024-486F-A338-53C31FFC9580}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-thread", "test-thread.vcproj", "{BA3039AD-5FD0-4A8F-A500-22FFBDB2088E}" ProjectSection(ProjectDependencies) = postProject {550C7FB8-DBFE-4364-B26A-DAF7158CD878} = {550C7FB8-DBFE-4364-B26A-DAF7158CD878} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {550C7FB8-DBFE-4364-B26A-DAF7158CD878}.Debug|Win32.ActiveCfg = Debug|Win32 {550C7FB8-DBFE-4364-B26A-DAF7158CD878}.Debug|Win32.Build.0 = Debug|Win32 {550C7FB8-DBFE-4364-B26A-DAF7158CD878}.Release|Win32.ActiveCfg = Release|Win32 {550C7FB8-DBFE-4364-B26A-DAF7158CD878}.Release|Win32.Build.0 = Release|Win32 {3B5FCB79-8AAA-4388-926B-3AD3F8BBB5D8}.Debug|Win32.ActiveCfg = Debug|Win32 {3B5FCB79-8AAA-4388-926B-3AD3F8BBB5D8}.Debug|Win32.Build.0 = Debug|Win32 {3B5FCB79-8AAA-4388-926B-3AD3F8BBB5D8}.Release|Win32.ActiveCfg = Release|Win32 {3B5FCB79-8AAA-4388-926B-3AD3F8BBB5D8}.Release|Win32.Build.0 = Release|Win32 {4E64F83D-4AE9-468A-867A-CB42A8B89150}.Debug|Win32.ActiveCfg = Debug|Win32 {4E64F83D-4AE9-468A-867A-CB42A8B89150}.Debug|Win32.Build.0 = Debug|Win32 {4E64F83D-4AE9-468A-867A-CB42A8B89150}.Release|Win32.ActiveCfg = Release|Win32 {4E64F83D-4AE9-468A-867A-CB42A8B89150}.Release|Win32.Build.0 = Release|Win32 {60EC66A2-FE1F-413E-8FEE-204386D62617}.Debug|Win32.ActiveCfg = Debug|Win32 {60EC66A2-FE1F-413E-8FEE-204386D62617}.Debug|Win32.Build.0 = Debug|Win32 {60EC66A2-FE1F-413E-8FEE-204386D62617}.Release|Win32.ActiveCfg = Release|Win32 {60EC66A2-FE1F-413E-8FEE-204386D62617}.Release|Win32.Build.0 = Release|Win32 {DD34FAC7-C1A2-4F29-8C96-3F053B47D714}.Debug|Win32.ActiveCfg = Debug|Win32 {DD34FAC7-C1A2-4F29-8C96-3F053B47D714}.Debug|Win32.Build.0 = Debug|Win32 {DD34FAC7-C1A2-4F29-8C96-3F053B47D714}.Release|Win32.ActiveCfg = Release|Win32 {DD34FAC7-C1A2-4F29-8C96-3F053B47D714}.Release|Win32.Build.0 = Release|Win32 {619723EB-D355-46DC-AF8F-0A04F44AC581}.Debug|Win32.ActiveCfg = Debug|Win32 {619723EB-D355-46DC-AF8F-0A04F44AC581}.Debug|Win32.Build.0 = Debug|Win32 {619723EB-D355-46DC-AF8F-0A04F44AC581}.Release|Win32.ActiveCfg = Release|Win32 {619723EB-D355-46DC-AF8F-0A04F44AC581}.Release|Win32.Build.0 = Release|Win32 {6E766AF4-4FFD-40AE-B425-54E4874E3AE4}.Debug|Win32.ActiveCfg = Debug|Win32 {6E766AF4-4FFD-40AE-B425-54E4874E3AE4}.Debug|Win32.Build.0 = Debug|Win32 {6E766AF4-4FFD-40AE-B425-54E4874E3AE4}.Release|Win32.ActiveCfg = Release|Win32 {6E766AF4-4FFD-40AE-B425-54E4874E3AE4}.Release|Win32.Build.0 = Release|Win32 {07645BAF-F78D-413C-B257-E348B2CEA18A}.Debug|Win32.ActiveCfg = Debug|Win32 {07645BAF-F78D-413C-B257-E348B2CEA18A}.Debug|Win32.Build.0 = Debug|Win32 {07645BAF-F78D-413C-B257-E348B2CEA18A}.Release|Win32.ActiveCfg = Release|Win32 {07645BAF-F78D-413C-B257-E348B2CEA18A}.Release|Win32.Build.0 = Release|Win32 {A503EF24-EB17-44FA-ABB1-42DCF361F4EA}.Debug|Win32.ActiveCfg = Debug|Win32 {A503EF24-EB17-44FA-ABB1-42DCF361F4EA}.Debug|Win32.Build.0 = Debug|Win32 {A503EF24-EB17-44FA-ABB1-42DCF361F4EA}.Release|Win32.ActiveCfg = Release|Win32 {A503EF24-EB17-44FA-ABB1-42DCF361F4EA}.Release|Win32.Build.0 = Release|Win32 {751C43C2-5987-4C4E-AD74-2737814890F0}.Debug|Win32.ActiveCfg = Debug|Win32 {751C43C2-5987-4C4E-AD74-2737814890F0}.Debug|Win32.Build.0 = Debug|Win32 {751C43C2-5987-4C4E-AD74-2737814890F0}.Release|Win32.ActiveCfg = Release|Win32 {751C43C2-5987-4C4E-AD74-2737814890F0}.Release|Win32.Build.0 = Release|Win32 {3E9D5FA3-F7C5-474E-8797-DFA3E6B2E436}.Debug|Win32.ActiveCfg = Debug|Win32 {3E9D5FA3-F7C5-474E-8797-DFA3E6B2E436}.Debug|Win32.Build.0 = Debug|Win32 {3E9D5FA3-F7C5-474E-8797-DFA3E6B2E436}.Release|Win32.ActiveCfg = Release|Win32 {3E9D5FA3-F7C5-474E-8797-DFA3E6B2E436}.Release|Win32.Build.0 = Release|Win32 {065B91A4-2024-486F-A338-53C31FFC9580}.Debug|Win32.ActiveCfg = Debug|Win32 {065B91A4-2024-486F-A338-53C31FFC9580}.Debug|Win32.Build.0 = Debug|Win32 {065B91A4-2024-486F-A338-53C31FFC9580}.Release|Win32.ActiveCfg = Release|Win32 {065B91A4-2024-486F-A338-53C31FFC9580}.Release|Win32.Build.0 = Release|Win32 {BA3039AD-5FD0-4A8F-A500-22FFBDB2088E}.Debug|Win32.ActiveCfg = Debug|Win32 {BA3039AD-5FD0-4A8F-A500-22FFBDB2088E}.Debug|Win32.Build.0 = Debug|Win32 {BA3039AD-5FD0-4A8F-A500-22FFBDB2088E}.Release|Win32.ActiveCfg = Release|Win32 {BA3039AD-5FD0-4A8F-A500-22FFBDB2088E}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {4E64F83D-4AE9-468A-867A-CB42A8B89150} = {46508783-E794-4688-B045-DE02A626B078} {60EC66A2-FE1F-413E-8FEE-204386D62617} = {46508783-E794-4688-B045-DE02A626B078} {619723EB-D355-46DC-AF8F-0A04F44AC581} = {46508783-E794-4688-B045-DE02A626B078} {3B5FCB79-8AAA-4388-926B-3AD3F8BBB5D8} = {46508783-E794-4688-B045-DE02A626B078} {6E766AF4-4FFD-40AE-B425-54E4874E3AE4} = {46508783-E794-4688-B045-DE02A626B078} {07645BAF-F78D-413C-B257-E348B2CEA18A} = {46508783-E794-4688-B045-DE02A626B078} {A503EF24-EB17-44FA-ABB1-42DCF361F4EA} = {46508783-E794-4688-B045-DE02A626B078} {751C43C2-5987-4C4E-AD74-2737814890F0} = {46508783-E794-4688-B045-DE02A626B078} {3E9D5FA3-F7C5-474E-8797-DFA3E6B2E436} = {46508783-E794-4688-B045-DE02A626B078} {065B91A4-2024-486F-A338-53C31FFC9580} = {46508783-E794-4688-B045-DE02A626B078} {BA3039AD-5FD0-4A8F-A500-22FFBDB2088E} = {46508783-E794-4688-B045-DE02A626B078} {DD34FAC7-C1A2-4F29-8C96-3F053B47D714} = {D3264B88-D38F-41E4-A2CB-C53644913D75} EndGlobalSection EndGlobal libnice-0.1.14/win32/vs9/test-bind.vcproj0000664000076400007640000001040412262633251014737 00000000000000 libnice-0.1.14/win32/vs9/test-restart.vcproj0000664000076400007640000001076612262633251015522 00000000000000 libnice-0.1.14/win32/vs9/test.vcproj0000664000076400007640000001077312262633251014036 00000000000000 libnice-0.1.14/win32/vs9/test-pseudotcp.vcproj0000664000076400007640000001103012262633251016025 00000000000000 libnice-0.1.14/win32/vs9/glib.vcproj0000664000076400007640000001121712520743534013771 00000000000000 libnice-0.1.14/win32/vs9/libnice.def0000664000076400007640000000740013070511675013713 00000000000000LIBRARY libnice EXPORTS nice_address_copy_to_sockaddr nice_address_dup nice_address_equal nice_address_equal_no_port nice_address_free nice_address_get_port nice_address_init nice_address_ip_version nice_address_is_private nice_address_is_valid nice_address_new nice_address_set_from_sockaddr nice_address_set_from_string nice_address_set_ipv4 nice_address_set_ipv6 nice_address_set_port nice_address_to_string nice_agent_add_local_address nice_agent_add_stream nice_agent_recv nice_agent_recv_messages nice_agent_recv_nonblocking nice_agent_recv_messages_nonblocking nice_agent_attach_recv nice_agent_forget_relays nice_agent_gather_candidates nice_agent_generate_local_candidate_sdp nice_agent_generate_local_sdp nice_agent_generate_local_stream_sdp nice_agent_get_component_state nice_agent_get_default_local_candidate nice_agent_get_io_stream nice_agent_get_local_candidates nice_agent_get_local_credentials nice_agent_get_remote_candidates nice_agent_get_selected_pair nice_agent_get_selected_socket nice_agent_get_stream_name nice_agent_get_type nice_agent_new nice_agent_new_reliable nice_agent_parse_remote_candidate_sdp nice_agent_parse_remote_sdp nice_agent_parse_remote_stream_sdp nice_agent_remove_stream nice_agent_restart nice_agent_restart_stream nice_agent_send nice_agent_send_messages_nonblocking nice_agent_set_port_range nice_agent_set_relay_info nice_agent_set_remote_candidates nice_agent_set_remote_credentials nice_agent_set_local_credentials nice_agent_set_selected_pair nice_agent_set_selected_remote_candidate nice_agent_set_software nice_agent_set_stream_name nice_agent_set_stream_tos nice_candidate_copy nice_candidate_free nice_candidate_new nice_component_state_to_string nice_debug_disable nice_debug_enable nice_interfaces_get_ip_for_interface nice_interfaces_get_local_interfaces nice_interfaces_get_local_ips nice_io_stream_new nice_input_stream_new nice_output_stream_new pseudo_tcp_set_debug_level pseudo_tcp_socket_close pseudo_tcp_socket_connect pseudo_tcp_socket_get_error pseudo_tcp_socket_get_next_clock pseudo_tcp_socket_get_type pseudo_tcp_socket_is_closed pseudo_tcp_socket_is_closed_remotely pseudo_tcp_socket_new pseudo_tcp_socket_notify_clock pseudo_tcp_socket_notify_mtu pseudo_tcp_socket_notify_packet pseudo_tcp_socket_recv pseudo_tcp_socket_send pseudo_tcp_socket_shutdown stun_agent_build_unknown_attributes_error stun_agent_default_validater stun_agent_finish_message stun_agent_forget_transaction stun_agent_init stun_agent_init_error stun_agent_init_indication stun_agent_init_request stun_agent_init_response stun_agent_set_software stun_agent_validate stun_debug_disable stun_debug_enable stun_message_append stun_message_append32 stun_message_append64 stun_message_append_addr stun_message_append_bytes stun_message_append_error stun_message_append_flag stun_message_append_string stun_message_append_xor_addr stun_message_append_xor_addr_full stun_message_find stun_message_find32 stun_message_find64 stun_message_find_addr stun_message_find_error stun_message_find_flag stun_message_find_string stun_message_find_xor_addr stun_message_find_xor_addr_full stun_message_get_class stun_message_get_method stun_message_has_attribute stun_message_has_cookie stun_message_id stun_message_init stun_message_length stun_message_validate_buffer_length stun_optional stun_strerror stun_timer_refresh stun_timer_remainder stun_timer_start stun_timer_start_reliable stun_usage_bind_create stun_usage_bind_keepalive stun_usage_bind_process stun_usage_bind_run stun_usage_ice_conncheck_create stun_usage_ice_conncheck_create_reply stun_usage_ice_conncheck_priority stun_usage_ice_conncheck_process stun_usage_ice_conncheck_use_candidate stun_usage_turn_create stun_usage_turn_create_refresh stun_usage_turn_process stun_usage_turn_refresh_process stun_debug stun_debug_bytes stun_hash_creds libnice-0.1.14/ar-lib0000755000076400007640000001330213067560510011231 00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2012-03-01.08; # UTC # Copyright (C) 2010-2014 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: libnice-0.1.14/examples/0000775000076400007640000000000013070512356012035 500000000000000libnice-0.1.14/examples/Makefile.in0000664000076400007640000005613613070512350014027 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = simple-example$(EXEEXT) threaded-example$(EXEEXT) \ sdp-example$(EXEEXT) subdir = examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-compiler-flag.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/introspection.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_sdp_example_OBJECTS = sdp-example.$(OBJEXT) sdp_example_OBJECTS = $(am_sdp_example_OBJECTS) am__DEPENDENCIES_1 = sdp_example_DEPENDENCIES = $(top_builddir)/agent/libagent.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_simple_example_OBJECTS = simple-example.$(OBJEXT) simple_example_OBJECTS = $(am_simple_example_OBJECTS) simple_example_DEPENDENCIES = $(top_builddir)/agent/libagent.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_threaded_example_OBJECTS = threaded-example.$(OBJEXT) threaded_example_OBJECTS = $(am_threaded_example_OBJECTS) threaded_example_DEPENDENCIES = $(top_builddir)/agent/libagent.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(sdp_example_SOURCES) $(simple_example_SOURCES) \ $(threaded_example_SOURCES) DIST_SOURCES = $(sdp_example_SOURCES) $(simple_example_SOURCES) \ $(threaded_example_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/common.mk \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgincludedir = $(includedir)/nice ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCACHE_DISABLE = @CCACHE_DISABLE@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GST010_CFLAGS = @GST010_CFLAGS@ GST010_LIBS = @GST010_LIBS@ GST_CFLAGS = @GST_CFLAGS@ GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@ GST_CHECK_LIBS = @GST_CHECK_LIBS@ GST_LIBS = @GST_LIBS@ GTKDOC_CHECK = @GTKDOC_CHECK@ GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ GUPNP_CFLAGS = @GUPNP_CFLAGS@ GUPNP_LIBS = @GUPNP_LIBS@ GUPNP_PACKAGES = @GUPNP_PACKAGES@ GUPNP_PACKAGES_PRIVATE = @GUPNP_PACKAGES_PRIVATE@ GUPNP_PACKAGES_PUBLIC = @GUPNP_PACKAGES_PUBLIC@ HAVE_GUPNP = @HAVE_GUPNP@ HTML_DIR = @HTML_DIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBNICE_CFLAGS = @LIBNICE_CFLAGS@ LIBNICE_LT_LDFLAGS = @LIBNICE_LT_LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBRT = @LIBRT@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NICE_PACKAGES_PRIVATE = @NICE_PACKAGES_PRIVATE@ NICE_PACKAGES_PUBLIC = @NICE_PACKAGES_PUBLIC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ UPNP_ENABLED = @UPNP_ENABLED@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ gstplugin010dir = @gstplugin010dir@ gstplugindir = @gstplugindir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *.gcno *.gcda AM_CFLAGS = \ -I $(top_srcdir) \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUPNP_CFLAGS) simple_example_SOURCES = simple-example.c simple_example_LDADD = $(top_builddir)/agent/libagent.la \ $(GLIB_LIBS) $(GUPNP_LIBS) threaded_example_SOURCES = threaded-example.c threaded_example_LDADD = $(top_builddir)/agent/libagent.la \ $(GLIB_LIBS) $(GUPNP_LIBS) sdp_example_SOURCES = sdp-example.c sdp_example_LDADD = $(top_builddir)/agent/libagent.la \ $(GLIB_LIBS) $(GUPNP_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_srcdir)/common.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list sdp-example$(EXEEXT): $(sdp_example_OBJECTS) $(sdp_example_DEPENDENCIES) $(EXTRA_sdp_example_DEPENDENCIES) @rm -f sdp-example$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sdp_example_OBJECTS) $(sdp_example_LDADD) $(LIBS) simple-example$(EXEEXT): $(simple_example_OBJECTS) $(simple_example_DEPENDENCIES) $(EXTRA_simple_example_DEPENDENCIES) @rm -f simple-example$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simple_example_OBJECTS) $(simple_example_LDADD) $(LIBS) threaded-example$(EXEEXT): $(threaded_example_OBJECTS) $(threaded_example_DEPENDENCIES) $(EXTRA_threaded_example_DEPENDENCIES) @rm -f threaded-example$(EXEEXT) $(AM_V_CCLD)$(LINK) $(threaded_example_OBJECTS) $(threaded_example_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdp-example.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple-example.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threaded-example.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile check-valgrind: $(MAKE) TESTS_ENVIRONMENT="sh $$(cd "$(top_srcdir)" && pwd)/scripts/valgrind.sh" check .PHONY: check-valgrind # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libnice-0.1.14/examples/Makefile.am0000664000076400007640000000155612363772107014026 00000000000000# # Makefile.am for the Nice Glib ICE library # # (C) 2006, 2007 Collabora Ltd. # (C) 2006, 2007 Nokia Corporation. All rights reserved. # # Licensed under MPL 1.1/LGPL 2.1. See file COPYING. include $(top_srcdir)/common.mk AM_CFLAGS = \ -I $(top_srcdir) \ -I $(top_srcdir)/agent \ -I $(top_srcdir)/random \ -I $(top_srcdir)/socket \ -I $(top_srcdir)/stun \ $(LIBNICE_CFLAGS) \ $(GLIB_CFLAGS) \ $(GUPNP_CFLAGS) bin_PROGRAMS = simple-example threaded-example sdp-example simple_example_SOURCES = simple-example.c simple_example_LDADD = $(top_builddir)/agent/libagent.la \ $(GLIB_LIBS) $(GUPNP_LIBS) threaded_example_SOURCES = threaded-example.c threaded_example_LDADD = $(top_builddir)/agent/libagent.la \ $(GLIB_LIBS) $(GUPNP_LIBS) sdp_example_SOURCES = sdp-example.c sdp_example_LDADD = $(top_builddir)/agent/libagent.la \ $(GLIB_LIBS) $(GUPNP_LIBS) libnice-0.1.14/examples/threaded-example.c0000664000076400007640000003236112661700132015333 00000000000000/* * Copyright 2013 University of Chicago * Contact: Bryce Allen * Copyright 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Example using libnice to negotiate a UDP connection between two clients, * possibly on the same network or behind different NATs and/or stateful * firewalls. * * Build: * gcc -o threaded-example threaded-example.c `pkg-config --cflags --libs nice` * * Run two clients, one controlling and one controlled: * threaded-example 0 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') * threaded-example 1 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') */ #include #include #include #include #include #include static GMainLoop *gloop; static gchar *stun_addr = NULL; static guint stun_port; static gboolean controlling; static gboolean exit_thread, candidate_gathering_done, negotiation_done; static GMutex gather_mutex, negotiate_mutex; static GCond gather_cond, negotiate_cond; static const gchar *candidate_type_name[] = {"host", "srflx", "prflx", "relay"}; static const gchar *state_name[] = {"disconnected", "gathering", "connecting", "connected", "ready", "failed"}; static int print_local_data(NiceAgent *agent, guint stream_id, guint component_id); static int parse_remote_data(NiceAgent *agent, guint stream_id, guint component_id, char *line); static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data); static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar *rfoundation, gpointer data); static void cb_component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data); static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data); static void * example_thread(void *data); int main(int argc, char *argv[]) { GThread *gexamplethread; // Parse arguments if (argc > 4 || argc < 2 || argv[1][1] != '\0') { fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); return EXIT_FAILURE; } controlling = argv[1][0] - '0'; if (controlling != 0 && controlling != 1) { fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); return EXIT_FAILURE; } if (argc > 2) { stun_addr = argv[2]; if (argc > 3) stun_port = atoi(argv[3]); else stun_port = 3478; g_debug("Using stun server '[%s]:%u'\n", stun_addr, stun_port); } g_networking_init(); gloop = g_main_loop_new(NULL, FALSE); // Run the mainloop and the example thread exit_thread = FALSE; gexamplethread = g_thread_new("example thread", &example_thread, NULL); g_main_loop_run (gloop); exit_thread = TRUE; g_thread_join (gexamplethread); g_main_loop_unref(gloop); return EXIT_SUCCESS; } static void * example_thread(void *data) { NiceAgent *agent; NiceCandidate *local, *remote; GIOChannel* io_stdin; guint stream_id; gchar *line = NULL; int rval; #ifdef G_OS_WIN32 io_stdin = g_io_channel_win32_new_fd(_fileno(stdin)); #else io_stdin = g_io_channel_unix_new(fileno(stdin)); #endif g_io_channel_set_flags (io_stdin, G_IO_FLAG_NONBLOCK, NULL); // Create the nice agent agent = nice_agent_new(g_main_loop_get_context (gloop), NICE_COMPATIBILITY_RFC5245); if (agent == NULL) g_error("Failed to create agent"); // Set the STUN settings and controlling mode if (stun_addr) { g_object_set(agent, "stun-server", stun_addr, NULL); g_object_set(agent, "stun-server-port", stun_port, NULL); } g_object_set(agent, "controlling-mode", controlling, NULL); // Connect to the signals g_signal_connect(agent, "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), NULL); g_signal_connect(agent, "new-selected-pair", G_CALLBACK(cb_new_selected_pair), NULL); g_signal_connect(agent, "component-state-changed", G_CALLBACK(cb_component_state_changed), NULL); // Create a new stream with one component stream_id = nice_agent_add_stream(agent, 1); if (stream_id == 0) g_error("Failed to add stream"); // Attach to the component to receive the data // Without this call, candidates cannot be gathered nice_agent_attach_recv(agent, stream_id, 1, g_main_loop_get_context (gloop), cb_nice_recv, NULL); // Start gathering local candidates if (!nice_agent_gather_candidates(agent, stream_id)) g_error("Failed to start candidate gathering"); g_debug("waiting for candidate-gathering-done signal..."); g_mutex_lock(&gather_mutex); while (!exit_thread && !candidate_gathering_done) g_cond_wait(&gather_cond, &gather_mutex); g_mutex_unlock(&gather_mutex); if (exit_thread) goto end; // Candidate gathering is done. Send our local candidates on stdout printf("Copy this line to remote client:\n"); printf("\n "); print_local_data(agent, stream_id, 1); printf("\n"); // Listen on stdin for the remote candidate list printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { // Parse remote candidate list and set it on the agent rval = parse_remote_data(agent, stream_id, 1, line); if (rval == EXIT_SUCCESS) { g_free (line); break; } else { fprintf(stderr, "ERROR: failed to parse remote data\n"); printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); } g_free (line); } else if (s == G_IO_STATUS_AGAIN) { g_usleep (100000); } } g_debug("waiting for state READY or FAILED signal..."); g_mutex_lock(&negotiate_mutex); while (!exit_thread && !negotiation_done) g_cond_wait(&negotiate_cond, &negotiate_mutex); g_mutex_unlock(&negotiate_mutex); if (exit_thread) goto end; // Get current selected candidate pair and print IP address used if (nice_agent_get_selected_pair (agent, stream_id, 1, &local, &remote)) { gchar ipaddr[INET6_ADDRSTRLEN]; nice_address_to_string(&local->addr, ipaddr); printf("\nNegotiation complete: ([%s]:%d,", ipaddr, nice_address_get_port(&local->addr)); nice_address_to_string(&remote->addr, ipaddr); printf(" [%s]:%d)\n", ipaddr, nice_address_get_port(&remote->addr)); } // Listen to stdin and send data written to it printf("\nSend lines to remote (Ctrl-D to quit):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { nice_agent_send(agent, stream_id, 1, strlen(line), line); g_free (line); printf("> "); fflush (stdout); } else if (s == G_IO_STATUS_AGAIN) { g_usleep (100000); } else { // Ctrl-D was pressed. nice_agent_send(agent, stream_id, 1, 1, "\0"); break; } } end: g_io_channel_unref (io_stdin); g_object_unref(agent); g_main_loop_quit (gloop); return NULL; } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug("SIGNAL candidate gathering done\n"); g_mutex_lock(&gather_mutex); candidate_gathering_done = TRUE; g_cond_signal(&gather_cond); g_mutex_unlock(&gather_mutex); } static void cb_component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { g_debug("SIGNAL: state changed %d %d %s[%d]\n", stream_id, component_id, state_name[state], state); if (state == NICE_COMPONENT_STATE_READY) { g_mutex_lock(&negotiate_mutex); negotiation_done = TRUE; g_cond_signal(&negotiate_cond); g_mutex_unlock(&negotiate_mutex); } else if (state == NICE_COMPONENT_STATE_FAILED) { g_main_loop_quit (gloop); } } static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar *rfoundation, gpointer data) { g_debug("SIGNAL: selected pair %s %s", lfoundation, rfoundation); } static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data) { if (len == 1 && buf[0] == '\0') g_main_loop_quit (gloop); printf("%.*s", len, buf); fflush(stdout); } static NiceCandidate * parse_candidate(char *scand, guint stream_id) { NiceCandidate *cand = NULL; NiceCandidateType ntype; gchar **tokens = NULL; guint i; tokens = g_strsplit (scand, ",", 5); for (i = 0; tokens[i]; i++); if (i != 5) goto end; for (i = 0; i < G_N_ELEMENTS (candidate_type_name); i++) { if (strcmp(tokens[4], candidate_type_name[i]) == 0) { ntype = i; break; } } if (i == G_N_ELEMENTS (candidate_type_name)) goto end; cand = nice_candidate_new(ntype); cand->component_id = 1; cand->stream_id = stream_id; cand->transport = NICE_CANDIDATE_TRANSPORT_UDP; strncpy(cand->foundation, tokens[0], NICE_CANDIDATE_MAX_FOUNDATION); cand->foundation[NICE_CANDIDATE_MAX_FOUNDATION - 1] = 0; cand->priority = atoi (tokens[1]); if (!nice_address_set_from_string(&cand->addr, tokens[2])) { g_message("failed to parse addr: %s", tokens[2]); nice_candidate_free(cand); cand = NULL; goto end; } nice_address_set_port(&cand->addr, atoi (tokens[3])); end: g_strfreev(tokens); return cand; } static int print_local_data (NiceAgent *agent, guint stream_id, guint component_id) { int result = EXIT_FAILURE; gchar *local_ufrag = NULL; gchar *local_password = NULL; gchar ipaddr[INET6_ADDRSTRLEN]; GSList *cands = NULL, *item; if (!nice_agent_get_local_credentials(agent, stream_id, &local_ufrag, &local_password)) goto end; cands = nice_agent_get_local_candidates(agent, stream_id, component_id); if (cands == NULL) goto end; printf("%s %s", local_ufrag, local_password); for (item = cands; item; item = item->next) { NiceCandidate *c = (NiceCandidate *)item->data; nice_address_to_string(&c->addr, ipaddr); // (foundation),(prio),(addr),(port),(type) printf(" %s,%u,%s,%u,%s", c->foundation, c->priority, ipaddr, nice_address_get_port(&c->addr), candidate_type_name[c->type]); } printf("\n"); result = EXIT_SUCCESS; end: if (local_ufrag) g_free(local_ufrag); if (local_password) g_free(local_password); if (cands) g_slist_free_full(cands, (GDestroyNotify)&nice_candidate_free); return result; } static int parse_remote_data(NiceAgent *agent, guint stream_id, guint component_id, char *line) { GSList *remote_candidates = NULL; gchar **line_argv = NULL; const gchar *ufrag = NULL; const gchar *passwd = NULL; int result = EXIT_FAILURE; int i; line_argv = g_strsplit_set (line, " \t\n", 0); for (i = 0; line_argv && line_argv[i]; i++) { if (strlen (line_argv[i]) == 0) continue; // first two args are remote ufrag and password if (!ufrag) { ufrag = line_argv[i]; } else if (!passwd) { passwd = line_argv[i]; } else { // Remaining args are serialized canidates (at least one is required) NiceCandidate *c = parse_candidate(line_argv[i], stream_id); if (c == NULL) { g_message("failed to parse candidate: %s", line_argv[i]); goto end; } remote_candidates = g_slist_prepend(remote_candidates, c); } } if (ufrag == NULL || passwd == NULL || remote_candidates == NULL) { g_message("line must have at least ufrag, password, and one candidate"); goto end; } if (!nice_agent_set_remote_credentials(agent, stream_id, ufrag, passwd)) { g_message("failed to set remote credentials"); goto end; } // Note: this will trigger the start of negotiation. if (nice_agent_set_remote_candidates(agent, stream_id, component_id, remote_candidates) < 1) { g_message("failed to set remote candidates"); goto end; } result = EXIT_SUCCESS; end: if (line_argv != NULL) g_strfreev(line_argv); if (remote_candidates != NULL) g_slist_free_full(remote_candidates, (GDestroyNotify)&nice_candidate_free); return result; } libnice-0.1.14/examples/simple-example.c0000664000076400007640000003124112717676416015063 00000000000000/* * Copyright 2013 University of Chicago * Contact: Bryce Allen * Copyright 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Example using libnice to negotiate a UDP connection between two clients, * possibly on the same network or behind different NATs and/or stateful * firewalls. * * Build: * gcc -o simple-example simple-example.c `pkg-config --cflags --libs nice` * * Run two clients, one controlling and one controlled: * simple-example 0 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') * simple-example 1 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') */ #include #include #include #include #include #include static GMainLoop *gloop; static GIOChannel* io_stdin; static guint stream_id; static const gchar *candidate_type_name[] = {"host", "srflx", "prflx", "relay"}; static const gchar *state_name[] = {"disconnected", "gathering", "connecting", "connected", "ready", "failed"}; static int print_local_data(NiceAgent *agent, guint stream_id, guint component_id); static int parse_remote_data(NiceAgent *agent, guint stream_id, guint component_id, char *line); static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data); static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, gchar *lfoundation, gchar *rfoundation, gpointer data); static void cb_component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data); static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data); static gboolean stdin_remote_info_cb (GIOChannel *source, GIOCondition cond, gpointer data); static gboolean stdin_send_data_cb (GIOChannel *source, GIOCondition cond, gpointer data); int main(int argc, char *argv[]) { NiceAgent *agent; gchar *stun_addr = NULL; guint stun_port = 0; gboolean controlling; // Parse arguments if (argc > 4 || argc < 2 || argv[1][1] != '\0') { fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); return EXIT_FAILURE; } controlling = argv[1][0] - '0'; if (controlling != 0 && controlling != 1) { fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); return EXIT_FAILURE; } if (argc > 2) { stun_addr = argv[2]; if (argc > 3) stun_port = atoi(argv[3]); else stun_port = 3478; g_debug("Using stun server '[%s]:%u'\n", stun_addr, stun_port); } g_networking_init(); gloop = g_main_loop_new(NULL, FALSE); #ifdef G_OS_WIN32 io_stdin = g_io_channel_win32_new_fd(_fileno(stdin)); #else io_stdin = g_io_channel_unix_new(fileno(stdin)); #endif // Create the nice agent agent = nice_agent_new(g_main_loop_get_context (gloop), NICE_COMPATIBILITY_RFC5245); if (agent == NULL) g_error("Failed to create agent"); // Set the STUN settings and controlling mode if (stun_addr) { g_object_set(agent, "stun-server", stun_addr, NULL); g_object_set(agent, "stun-server-port", stun_port, NULL); } g_object_set(agent, "controlling-mode", controlling, NULL); // Connect to the signals g_signal_connect(agent, "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), NULL); g_signal_connect(agent, "new-selected-pair", G_CALLBACK(cb_new_selected_pair), NULL); g_signal_connect(agent, "component-state-changed", G_CALLBACK(cb_component_state_changed), NULL); // Create a new stream with one component stream_id = nice_agent_add_stream(agent, 1); if (stream_id == 0) g_error("Failed to add stream"); // Attach to the component to receive the data // Without this call, candidates cannot be gathered nice_agent_attach_recv(agent, stream_id, 1, g_main_loop_get_context (gloop), cb_nice_recv, NULL); // Start gathering local candidates if (!nice_agent_gather_candidates(agent, stream_id)) g_error("Failed to start candidate gathering"); g_debug("waiting for candidate-gathering-done signal..."); // Run the mainloop. Everything else will happen asynchronously // when the candidates are done gathering. g_main_loop_run (gloop); g_main_loop_unref(gloop); g_object_unref(agent); g_io_channel_unref (io_stdin); return EXIT_SUCCESS; } static void cb_candidate_gathering_done(NiceAgent *agent, guint _stream_id, gpointer data) { g_debug("SIGNAL candidate gathering done\n"); // Candidate gathering is done. Send our local candidates on stdout printf("Copy this line to remote client:\n"); printf("\n "); print_local_data(agent, _stream_id, 1); printf("\n"); // Listen on stdin for the remote candidate list printf("Enter remote data (single line, no wrapping):\n"); g_io_add_watch(io_stdin, G_IO_IN, stdin_remote_info_cb, agent); printf("> "); fflush (stdout); } static gboolean stdin_remote_info_cb (GIOChannel *source, GIOCondition cond, gpointer data) { NiceAgent *agent = data; gchar *line = NULL; int rval; gboolean ret = TRUE; if (g_io_channel_read_line (source, &line, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { // Parse remote candidate list and set it on the agent rval = parse_remote_data(agent, stream_id, 1, line); if (rval == EXIT_SUCCESS) { // Return FALSE so we stop listening to stdin since we parsed the // candidates correctly ret = FALSE; g_debug("waiting for state READY or FAILED signal..."); } else { fprintf(stderr, "ERROR: failed to parse remote data\n"); printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); } g_free (line); } return ret; } static void cb_component_state_changed(NiceAgent *agent, guint _stream_id, guint component_id, guint state, gpointer data) { g_debug("SIGNAL: state changed %d %d %s[%d]\n", _stream_id, component_id, state_name[state], state); if (state == NICE_COMPONENT_STATE_CONNECTED) { NiceCandidate *local, *remote; // Get current selected candidate pair and print IP address used if (nice_agent_get_selected_pair (agent, _stream_id, component_id, &local, &remote)) { gchar ipaddr[INET6_ADDRSTRLEN]; nice_address_to_string(&local->addr, ipaddr); printf("\nNegotiation complete: ([%s]:%d,", ipaddr, nice_address_get_port(&local->addr)); nice_address_to_string(&remote->addr, ipaddr); printf(" [%s]:%d)\n", ipaddr, nice_address_get_port(&remote->addr)); } // Listen to stdin and send data written to it printf("\nSend lines to remote (Ctrl-D to quit):\n"); g_io_add_watch(io_stdin, G_IO_IN, stdin_send_data_cb, agent); printf("> "); fflush (stdout); } else if (state == NICE_COMPONENT_STATE_FAILED) { g_main_loop_quit (gloop); } } static gboolean stdin_send_data_cb (GIOChannel *source, GIOCondition cond, gpointer data) { NiceAgent *agent = data; gchar *line = NULL; if (g_io_channel_read_line (source, &line, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { nice_agent_send(agent, stream_id, 1, strlen(line), line); g_free (line); printf("> "); fflush (stdout); } else { nice_agent_send(agent, stream_id, 1, 1, "\0"); // Ctrl-D was pressed. g_main_loop_quit (gloop); } return TRUE; } static void cb_new_selected_pair(NiceAgent *agent, guint _stream_id, guint component_id, gchar *lfoundation, gchar *rfoundation, gpointer data) { g_debug("SIGNAL: selected pair %s %s", lfoundation, rfoundation); } static void cb_nice_recv(NiceAgent *agent, guint _stream_id, guint component_id, guint len, gchar *buf, gpointer data) { if (len == 1 && buf[0] == '\0') g_main_loop_quit (gloop); printf("%.*s", len, buf); fflush(stdout); } static NiceCandidate * parse_candidate(char *scand, guint _stream_id) { NiceCandidate *cand = NULL; NiceCandidateType ntype; gchar **tokens = NULL; guint i; tokens = g_strsplit (scand, ",", 5); for (i = 0; tokens[i]; i++); if (i != 5) goto end; for (i = 0; i < G_N_ELEMENTS (candidate_type_name); i++) { if (strcmp(tokens[4], candidate_type_name[i]) == 0) { ntype = i; break; } } if (i == G_N_ELEMENTS (candidate_type_name)) goto end; cand = nice_candidate_new(ntype); cand->component_id = 1; cand->stream_id = _stream_id; cand->transport = NICE_CANDIDATE_TRANSPORT_UDP; strncpy(cand->foundation, tokens[0], NICE_CANDIDATE_MAX_FOUNDATION); cand->foundation[NICE_CANDIDATE_MAX_FOUNDATION - 1] = 0; cand->priority = atoi (tokens[1]); if (!nice_address_set_from_string(&cand->addr, tokens[2])) { g_message("failed to parse addr: %s", tokens[2]); nice_candidate_free(cand); cand = NULL; goto end; } nice_address_set_port(&cand->addr, atoi (tokens[3])); end: g_strfreev(tokens); return cand; } static int print_local_data (NiceAgent *agent, guint _stream_id, guint component_id) { int result = EXIT_FAILURE; gchar *local_ufrag = NULL; gchar *local_password = NULL; gchar ipaddr[INET6_ADDRSTRLEN]; GSList *cands = NULL, *item; if (!nice_agent_get_local_credentials(agent, _stream_id, &local_ufrag, &local_password)) goto end; cands = nice_agent_get_local_candidates(agent, _stream_id, component_id); if (cands == NULL) goto end; printf("%s %s", local_ufrag, local_password); for (item = cands; item; item = item->next) { NiceCandidate *c = (NiceCandidate *)item->data; nice_address_to_string(&c->addr, ipaddr); // (foundation),(prio),(addr),(port),(type) printf(" %s,%u,%s,%u,%s", c->foundation, c->priority, ipaddr, nice_address_get_port(&c->addr), candidate_type_name[c->type]); } printf("\n"); result = EXIT_SUCCESS; end: if (local_ufrag) g_free(local_ufrag); if (local_password) g_free(local_password); if (cands) g_slist_free_full(cands, (GDestroyNotify)&nice_candidate_free); return result; } static int parse_remote_data(NiceAgent *agent, guint _stream_id, guint component_id, char *line) { GSList *remote_candidates = NULL; gchar **line_argv = NULL; const gchar *ufrag = NULL; const gchar *passwd = NULL; int result = EXIT_FAILURE; int i; line_argv = g_strsplit_set (line, " \t\n", 0); for (i = 0; line_argv && line_argv[i]; i++) { if (strlen (line_argv[i]) == 0) continue; // first two args are remote ufrag and password if (!ufrag) { ufrag = line_argv[i]; } else if (!passwd) { passwd = line_argv[i]; } else { // Remaining args are serialized canidates (at least one is required) NiceCandidate *c = parse_candidate(line_argv[i], _stream_id); if (c == NULL) { g_message("failed to parse candidate: %s", line_argv[i]); goto end; } remote_candidates = g_slist_prepend(remote_candidates, c); } } if (ufrag == NULL || passwd == NULL || remote_candidates == NULL) { g_message("line must have at least ufrag, password, and one candidate"); goto end; } if (!nice_agent_set_remote_credentials(agent, _stream_id, ufrag, passwd)) { g_message("failed to set remote credentials"); goto end; } // Note: this will trigger the start of negotiation. if (nice_agent_set_remote_candidates(agent, _stream_id, component_id, remote_candidates) < 1) { g_message("failed to set remote candidates"); goto end; } result = EXIT_SUCCESS; end: if (line_argv != NULL) g_strfreev(line_argv); if (remote_candidates != NULL) g_slist_free_full(remote_candidates, (GDestroyNotify)&nice_candidate_free); return result; } libnice-0.1.14/examples/sdp-example.c0000664000076400007640000002102012661700132014327 00000000000000/* * Copyright 2013 University of Chicago * Contact: Bryce Allen * Copyright 2013 Collabora Ltd. * Contact: Youness Alaoui * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * Alternatively, the contents of this file may be used under the terms of the * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which * case the provisions of LGPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * LGPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replace * them with the notice and other provisions required by the LGPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the LGPL. */ /* * Example using libnice to negotiate a UDP connection between two clients, * possibly on the same network or behind different NATs and/or stateful * firewalls. * * Build: * gcc -o sdp-example sdp-example.c `pkg-config --cflags --libs nice` * * Run two clients, one controlling and one controlled: * sdp-example 0 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') * sdp-example 1 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') */ #include #include #include #include #include #include static GMainLoop *gloop; static gchar *stun_addr = NULL; static guint stun_port; static gboolean controlling; static gboolean exit_thread, candidate_gathering_done, negotiation_done; static GMutex gather_mutex, negotiate_mutex; static GCond gather_cond, negotiate_cond; static const gchar *state_name[] = {"disconnected", "gathering", "connecting", "connected", "ready", "failed"}; static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data); static void cb_component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data); static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data); static void * example_thread(void *data); int main(int argc, char *argv[]) { GThread *gexamplethread; // Parse arguments if (argc > 4 || argc < 2 || argv[1][1] != '\0') { fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); return EXIT_FAILURE; } controlling = argv[1][0] - '0'; if (controlling != 0 && controlling != 1) { fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); return EXIT_FAILURE; } if (argc > 2) { stun_addr = argv[2]; if (argc > 3) stun_port = atoi(argv[3]); else stun_port = 3478; g_debug("Using stun server '[%s]:%u'\n", stun_addr, stun_port); } g_networking_init(); gloop = g_main_loop_new(NULL, FALSE); // Run the mainloop and the example thread exit_thread = FALSE; gexamplethread = g_thread_new("example thread", &example_thread, NULL); g_main_loop_run (gloop); exit_thread = TRUE; g_thread_join (gexamplethread); g_main_loop_unref(gloop); return EXIT_SUCCESS; } static void * example_thread(void *data) { NiceAgent *agent; GIOChannel* io_stdin; guint stream_id; gchar *line = NULL; gchar *sdp, *sdp64; #ifdef G_OS_WIN32 io_stdin = g_io_channel_win32_new_fd(_fileno(stdin)); #else io_stdin = g_io_channel_unix_new(fileno(stdin)); #endif g_io_channel_set_flags(io_stdin, G_IO_FLAG_NONBLOCK, NULL); // Create the nice agent agent = nice_agent_new(g_main_loop_get_context (gloop), NICE_COMPATIBILITY_RFC5245); if (agent == NULL) g_error("Failed to create agent"); // Set the STUN settings and controlling mode if (stun_addr) { g_object_set(agent, "stun-server", stun_addr, NULL); g_object_set(agent, "stun-server-port", stun_port, NULL); } g_object_set(agent, "controlling-mode", controlling, NULL); // Connect to the signals g_signal_connect(agent, "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), NULL); g_signal_connect(agent, "component-state-changed", G_CALLBACK(cb_component_state_changed), NULL); // Create a new stream with one component stream_id = nice_agent_add_stream(agent, 1); if (stream_id == 0) g_error("Failed to add stream"); nice_agent_set_stream_name (agent, stream_id, "text"); // Attach to the component to receive the data // Without this call, candidates cannot be gathered nice_agent_attach_recv(agent, stream_id, 1, g_main_loop_get_context (gloop), cb_nice_recv, NULL); // Start gathering local candidates if (!nice_agent_gather_candidates(agent, stream_id)) g_error("Failed to start candidate gathering"); g_debug("waiting for candidate-gathering-done signal..."); g_mutex_lock(&gather_mutex); while (!exit_thread && !candidate_gathering_done) g_cond_wait(&gather_cond, &gather_mutex); g_mutex_unlock(&gather_mutex); if (exit_thread) goto end; // Candidate gathering is done. Send our local candidates on stdout sdp = nice_agent_generate_local_sdp (agent); printf("Generated SDP from agent :\n%s\n\n", sdp); printf("Copy the following line to remote client:\n"); sdp64 = g_base64_encode ((const guchar *)sdp, strlen (sdp)); printf("\n %s\n", sdp64); g_free (sdp); g_free (sdp64); // Listen on stdin for the remote candidate list printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { gsize sdp_len; sdp = (gchar *) g_base64_decode (line, &sdp_len); // Parse remote candidate list and set it on the agent if (sdp && nice_agent_parse_remote_sdp (agent, sdp) > 0) { g_free (sdp); g_free (line); break; } else { fprintf(stderr, "ERROR: failed to parse remote data\n"); printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); } g_free (sdp); g_free (line); } else if (s == G_IO_STATUS_AGAIN) { g_usleep (100000); } } g_debug("waiting for state READY or FAILED signal..."); g_mutex_lock(&negotiate_mutex); while (!exit_thread && !negotiation_done) g_cond_wait(&negotiate_cond, &negotiate_mutex); g_mutex_unlock(&negotiate_mutex); if (exit_thread) goto end; // Listen to stdin and send data written to it printf("\nSend lines to remote (Ctrl-D to quit):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { nice_agent_send(agent, stream_id, 1, strlen(line), line); g_free (line); printf("> "); fflush (stdout); } else if (s == G_IO_STATUS_AGAIN) { g_usleep (100000); } else { // Ctrl-D was pressed. nice_agent_send(agent, stream_id, 1, 1, "\0"); break; } } end: g_object_unref(agent); g_io_channel_unref (io_stdin); g_main_loop_quit (gloop); return NULL; } static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data) { g_debug("SIGNAL candidate gathering done\n"); g_mutex_lock(&gather_mutex); candidate_gathering_done = TRUE; g_cond_signal(&gather_cond); g_mutex_unlock(&gather_mutex); } static void cb_component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data) { g_debug("SIGNAL: state changed %d %d %s[%d]\n", stream_id, component_id, state_name[state], state); if (state == NICE_COMPONENT_STATE_READY) { g_mutex_lock(&negotiate_mutex); negotiation_done = TRUE; g_cond_signal(&negotiate_cond); g_mutex_unlock(&negotiate_mutex); } else if (state == NICE_COMPONENT_STATE_FAILED) { g_main_loop_quit (gloop); } } static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data) { if (len == 1 && buf[0] == '\0') g_main_loop_quit (gloop); printf("%.*s", len, buf); fflush(stdout); }