[Pkg-voip-commits] [belle-sip] 02/08: New upstream version 1.6.3
Dr. Tobias Quathamer
toddy at debian.org
Mon Nov 6 13:10:01 UTC 2017
This is an automated email from the git hooks/post-receive script.
toddy pushed a commit to branch master
in repository belle-sip.
commit 01693e932a5c4ffb5af6917d4a112aa95c5a0809
Author: Dr. Tobias Quathamer <toddy at debian.org>
Date: Mon Nov 6 13:36:18 2017 +0100
New upstream version 1.6.3
---
CMakeLists.txt | 50 +-
NEWS | 6 +
README.md | 9 +
belle-sip.spec.in | 2 +-
build/CMakeLists.txt | 50 ++
.../rpm/belle-sip.spec.cmake | 43 +-
cmake/BelleSIPConfig.cmake.in | 45 +-
cmake/FindAntlr3.cmake | 2 +-
cmake/FindZlib.cmake | 4 +-
configure.ac | 4 +-
include/belle-sip/auth-helper.h | 7 +
include/belle-sip/belle-sip.h | 2 +-
include/belle-sip/defs.h | 21 +-
include/belle-sip/headers.h | 51 ++
include/belle-sip/list.h | 1 +
include/belle-sip/object.h | 10 +
include/belle-sip/resolver.h | 4 +-
include/belle-sip/sip-uri.h | 10 +
include/belle-sip/types.h | 4 +-
include/belle-sip/utils.h | 4 +
src/CMakeLists.txt | 14 +-
src/auth_helper.c | 23 +-
src/belle_sip_headers_impl.c | 141 ++++++
src/belle_sip_internal.h | 52 ++-
src/belle_sip_resolver.c | 87 ++--
src/belle_sip_uri_impl.c | 3 +
src/belle_sip_utils.c | 193 +++-----
src/bodyhandler.c | 5 +-
src/channel.c | 83 +++-
src/channel.h | 9 +-
src/dialog.c | 88 ++--
src/dns.c | 78 +++-
src/dns.h | 5 +-
src/grammars/belle_sip_message.g | 190 +++++++-
src/http-provider.c | 6 +-
src/ict.c | 15 +-
src/nist.c | 6 +-
src/parserutils.h | 18 +-
src/port.c | 8 +-
src/port.h | 16 +-
src/provider.c | 47 +-
src/refresher.c | 14 +-
src/transaction.c | 40 +-
src/transports/stream_channel.c | 18 +-
src/transports/stream_channel.h | 4 +-
src/transports/stream_listeningpoint.c | 10 +-
src/transports/tls_channel.c | 2 +-
src/transports/udp_listeningpoint.c | 13 +-
tester/CMakeLists.txt | 11 +-
tester/Makefile.am | 3 +
...ip_uri_tester.c => belle_sip_base_uri_tester.c} | 10 +-
tester/belle_sip_fast_uri_tester.c | 62 +++
tester/belle_sip_headers_tester.c | 97 +++-
tester/belle_sip_register_tester.c | 149 ++++--
tester/belle_sip_resolver_tester.c | 4 +-
tester/belle_sip_tester.c | 19 +-
tester/belle_sip_tester.h | 2 +
tester/belle_sip_tester_windows.cpp | 5 +-
tester/belle_sip_uri_tester.c | 511 +--------------------
tester/get.c | 6 +-
tester/parse.c | 10 +-
61 files changed, 1402 insertions(+), 1004 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9136406..df6d6ba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-############################################################################
+
# CMakeLists.txt
# Copyright (C) 2014 Belledonne Communications, Grenoble France
#
@@ -21,7 +21,7 @@
############################################################################
cmake_minimum_required(VERSION 3.0)
-project(belle-sip VERSION 1.6.1 LANGUAGES C CXX)
+project(belle-sip VERSION 1.6.3 LANGUAGES C CXX)
set(PACKAGE "${PROJECT_NAME}")
@@ -42,22 +42,6 @@ option(ENABLE_TUNNEL "Enable tunnel support" OFF)
option(ENABLE_TESTS "Enable compilation of tests" ON)
-macro(apply_compile_flags SOURCE_FILES)
- if(${SOURCE_FILES})
- set(options "")
- foreach(a ${ARGV})
- if(STRICT_OPTIONS_${a})
- string(REPLACE ";" " " options_${a} "${STRICT_OPTIONS_${a}}")
- set(options "${options} ${options_${a}}")
- endif()
- endforeach()
- if(options)
- set_source_files_properties(${${SOURCE_FILES}} PROPERTIES COMPILE_FLAGS "${options}")
- endif()
- endif()
-endmacro()
-
-
include(CheckLibraryExists)
include(CheckSymbolExists)
include(CheckCSourceCompiles)
@@ -194,7 +178,7 @@ else()
endif()
if(ENABLE_STRICT)
list(APPEND STRICT_OPTIONS_CPP "-Werror" "-Wextra" "-Wno-unused-parameter" "-Wno-error=unknown-pragmas" "-Wuninitialized" "-fno-strict-aliasing")
- list(APPEND STRICT_OPTIONS_C "-Wdeclaration-after-statement" "-Wstrict-prototypes -Wno-missing-field-initializers")
+ list(APPEND STRICT_OPTIONS_C "-Wdeclaration-after-statement" "-Wstrict-prototypes -Wno-missing-field-initializers" "-Wno-error=unused-result")
endif()
# this warning is generated by antlr so ignore it for now
list(APPEND STRICT_OPTIONS_C "-Wno-strict-prototypes" "-Wno-error=sign-compare")
@@ -213,12 +197,17 @@ if(APPLE)
endif()
endif()
string(REPLACE ";" " " LINK_FLAGS_STR "${LINK_FLAGS}")
-if(WIN32)
- add_definitions(
- -DBELLESIP_EXPORTS
- -DBELLESIP_INTERNAL_EXPORTS
- )
+
+set(BELLESIP_CPPFLAGS ${BCTOOLBOX_CPPFLAGS})
+if(ENABLE_STATIC)
+ list(APPEND BELLESIP_CPPFLAGS "-DBELLESIP_STATIC")
+endif()
+if(BELLESIP_CPPFLAGS)
+ list(REMOVE_DUPLICATES BELLESIP_CPPFLAGS)
+ add_definitions(${BELLESIP_CPPFLAGS})
endif()
+add_definitions("-DBELLESIP_EXPORTS")
+
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" OR CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
add_definitions(
-DHAVE_COMPILER_TLS
@@ -270,15 +259,4 @@ install(FILES
DESTINATION ${CONFIG_PACKAGE_LOCATION}
)
-
-# CPack settings
-set(CPACK_PACKAGE_NAME "belle-sip")
-set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
-set(CPACK_SOURCE_GENERATOR "TGZ")
-set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
-set(CPACK_SOURCE_IGNORE_FILES
- "^${CMAKE_BINARY_DIR}"
- "/\\\\..+"
-)
-
-include(CPack)
+add_subdirectory(build)
diff --git a/NEWS b/NEWS
index 4adf907..5a26d8a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+belle_sip-1.6.2 -- July 21th, 2017
+ * Build fix for Windows
+
+belle_sip-1.6.2 -- July 20th, 2017
+ * Bug fixes
+
belle_sip-1.6.1 -- March 2nd, 2017
* Fix bug around nsswitch.conf parsing on GNU/Linux
diff --git a/README.md b/README.md
index f574fc1..7cd412f 100644
--- a/README.md
+++ b/README.md
@@ -65,3 +65,12 @@ Note for packagers
Our CMake scripts may automatically add some paths into research paths of generated binaries.
To ensure that the installed binaries are striped of any rpath, use `-DCMAKE_SKIP_INSTALL_RPATH=ON`
while you invoke cmake.
+
+Rpm packaging
+belle-sip can be generated with cmake3 using the following command:
+mkdir WORK
+cd WORK
+cmake3 ../
+make package_source
+rpmbuild -ta --clean --rmsource --rmspec belle-sip-<version>-<release>.tar.gz
+
diff --git a/belle-sip.spec.in b/belle-sip.spec.in
index 4deb4ad..26cd400 100755
--- a/belle-sip.spec.in
+++ b/belle-sip.spec.in
@@ -63,7 +63,7 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
-%doc AUTHORS ChangeLog COPYING NEWS README
+%doc AUTHORS ChangeLog COPYING NEWS README.md
%{_libdir}/*.so.*
%files devel
diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt
new file mode 100644
index 0000000..9db4d15
--- /dev/null
+++ b/build/CMakeLists.txt
@@ -0,0 +1,50 @@
+############################################################################
+# CMakeLists.txt
+# Copyright (C) 2017 Belledonne Communications, Grenoble France
+#
+############################################################################
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+############################################################################
+
+if (NOT CPACK_PACKAGE_NAME)
+ set(CPACK_PACKAGE_NAME "belle-sip")
+ENDIF()
+
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../COPYING")
+
+set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
+set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
+set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
+
+set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${PROJECT_VERSION})
+
+set(CPACK_SOURCE_GENERATOR "TGZ")
+set(CPACK_SOURCE_IGNORE_FILES
+"${CMAKE_BINARY_DIR}"
+"^${PROJECT_SOURCE_DIR}/.git*"
+)
+bc_project_build_version(${PROJECT_VERSION} PROJECT_VERSION_BUILD)
+
+set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${PROJECT_VERSION_BUILD}")
+
+message("-- Package file name is ${CPACK_PACKAGE_FILE_NAME}" )
+
+set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rpm/belle-sip.spec.cmake ${CMAKE_CURRENT_SOURCE_DIR}/../belle-sip.spec)
+
+include(CPack)
+
diff --git a/belle-sip.spec.in b/build/rpm/belle-sip.spec.cmake
similarity index 65%
copy from belle-sip.spec.in
copy to build/rpm/belle-sip.spec.cmake
index 4deb4ad..fcc2b8e 100755
--- a/belle-sip.spec.in
+++ b/build/rpm/belle-sip.spec.cmake
@@ -15,17 +15,20 @@
%define _datadir %{_datarootdir}
%define _docdir %{_datadir}/doc
+%define build_number @PROJECT_VERSION_BUILD@
+
+
Name: %{pkg_name}
-Version: @VERSION@
-Release: %(version=`git describe --tags --abbrev=40 | sed -rn 's/^.*-([0-9]+)-g[a-z0-9]{40}$/\1/p'` && if test -z "$version" ; then echo 0 ; else echo $version ; fi)%{?dist}
-Summary: Linphone sip stack
+Version: @PROJECT_VERSION@
+Release: %build_number%{?dist}
+Summary: Linphone's sip stack
Group: Applications/Communications
License: GPL
URL: http://www.belle-sip.org
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Source0: %{name}-%{version}.tar.gz
+Source0: %{name}-%{version}-%{build_number}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
%description
Belle-sip is an object oriented SIP stack, written in C, used by Linphone.
@@ -40,18 +43,26 @@ Requires: %{name} = %{version}-%{release}
%description devel
Libraries and headers required to develop software with belle-sip
+%if 0%{?rhel} && 0%{?rhel} <= 7
+%global cmake_name cmake3
+%define ctest_name ctest3
+%else
+%global cmake_name cmake
+%define ctest_name ctest
+%endif
+
%prep
-%setup -q
+%setup -n %{name}-%{version}-%build_number
%build
-%configure \
- --disable-tests --enable-static --docdir=%{_docdir}
-%__make %{?_smp_mflags}
-
+%{expand:%%%cmake_name} . -DCMAKE_INSTALL_LIBDIR:PATH=%{_libdir} -DCMAKE_PREFIX_PATH:PATH=%{_prefix}
+make %{?_smp_mflags}
%install
-rm -rf $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
+make install DESTDIR=%{buildroot}
+
+%check
+#%{ctest_name} -V %{?_smp_mflags}
%clean
rm -rf $RPM_BUILD_ROOT
@@ -63,16 +74,20 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
-%doc AUTHORS ChangeLog COPYING NEWS README
+%doc AUTHORS ChangeLog COPYING NEWS README.md
%{_libdir}/*.so.*
%files devel
%defattr(-,root,root)
%{_includedir}/belle-sip
%{_libdir}/libbellesip.a
-%{_libdir}/libbellesip.la
%{_libdir}/libbellesip.so
%{_libdir}/pkgconfig/belle-sip.pc
+%{_datadir}/BelleSIP/cmake/BelleSIPConfig.cmake
+%{_datadir}/BelleSIP/cmake/BelleSIPConfigVersion.cmake
+%{_datadir}/BelleSIP/cmake/BelleSIPTargets-noconfig.cmake
+%{_datadir}/BelleSIP/cmake/BelleSIPTargets.cmake
+%{_bindir}/*
%changelog
* Mon Aug 19 2013 jehan.monnier <jehan.monnier at linphone.org>
diff --git a/cmake/BelleSIPConfig.cmake.in b/cmake/BelleSIPConfig.cmake.in
index a0932a8..cc0386e 100644
--- a/cmake/BelleSIPConfig.cmake.in
+++ b/cmake/BelleSIPConfig.cmake.in
@@ -26,41 +26,38 @@
# BELLESIP_FOUND - system has belle-sip
# BELLESIP_INCLUDE_DIRS - the belle-sip include directory
# BELLESIP_LIBRARIES - The libraries needed to use belle-sip
+# BELLESIP_CPPFLAGS - The compilation flags needed to use belle-sip
# BELLESIP_LDFLAGS - The linking flags needed to use belle-sip
if(NOT LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
include("${CMAKE_CURRENT_LIST_DIR}/BelleSIPTargets.cmake")
endif()
-if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
- include("${EP_bctoolbox_CONFIG_DIR}/BcToolboxConfig.cmake")
+if(@ENABLE_SHARED@)
+ set(BELLESIP_TARGETNAME bellesip)
+ set(BELLESIP_LIBRARIES ${BELLESIP_TARGETNAME})
else()
- find_package(BcToolbox 0.0.3 REQUIRED COMPONENTS core)
-endif()
-if(@ENABLE_TUNNEL@)
- if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
- include("${EP_tunnel_CONFIG_DIR}/TunnelConfig.cmake")
- else()
- find_package(Tunnel)
+ set(BELLESIP_TARGETNAME bellesip-static)
+ if(TARGET ${BELLESIP_TARGETNAME})
+ if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
+ set(BELLESIP_LIBRARIES ${BELLESIP_TARGETNAME})
+ else()
+ get_target_property(BELLESIP_LIBRARIES ${BELLESIP_TARGETNAME} LOCATION)
+ endif()
+ get_target_property(BELLESIP_LINK_LIBRARIES ${BELLESIP_TARGETNAME} INTERFACE_LINK_LIBRARIES)
+ if(BELLESIP_LINK_LIBRARIES)
+ list(APPEND BELLESIP_LIBRARIES ${BELLESIP_LINK_LIBRARIES})
+ endif()
endif()
endif()
-
-get_filename_component(BELLESIP_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_target_property(BELLESIP_INCLUDE_DIRS ${BELLESIP_TARGETNAME} INTERFACE_INCLUDE_DIRECTORIES)
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
- set(BELLESIP_INCLUDE_DIRS "${EP_bellesip_INCLUDE_DIR}")
+ list(INSERT BELLESIP_INCLUDE_DIRS 0 "${EP_bellesip_INCLUDE_DIR}")
else()
- set(BELLESIP_INCLUDE_DIRS "${BELLESIP_CMAKE_DIR}/../../../include")
+ list(INSERT BELLESIP_INCLUDE_DIRS 0 "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
endif()
-if(@ENABLE_SHARED@)
- set(BELLESIP_LIBRARIES bellesip)
-else()
- set(BELLESIP_LIBRARIES bellesip-static)
-endif()
-list(APPEND BELLESIP_INCLUDE_DIRS ${BCTOOLBOX_CORE_INCLUDE_DIRS})
-list(APPEND BELLESIP_LIBRARIES ${BCTOOLBOX_CORE_LIBRARIES})
+list(REMOVE_DUPLICATES BELLESIP_INCLUDE_DIRS)
+
+set(BELLESIP_CPPFLAGS @BELLESIP_CPPFLAGS@)
set(BELLESIP_LDFLAGS "@LINK_FLAGS_STR@")
-if(TUNNEL_FOUND)
- list(APPEND BELLESIP_INCLUDE_DIRS ${TUNNEL_INCLUDE_DIRS})
- list(APPEND BELLESIP_LIBRARIES ${TUNNEL_LIBRARIES})
-endif()
set(BELLESIP_FOUND 1)
diff --git a/cmake/FindAntlr3.cmake b/cmake/FindAntlr3.cmake
index e2d01a5..ed2baa5 100644
--- a/cmake/FindAntlr3.cmake
+++ b/cmake/FindAntlr3.cmake
@@ -70,7 +70,7 @@ if(NOT ANTLR3_COMMAND)
)
if(ANTLR3_JAR_PATH)
- set(ANTLR3_COMMAND ${Java_JAVA_EXECUTABLE} -Xmx256m -jar ${ANTLR3_JAR_PATH})
+ set(ANTLR3_COMMAND ${Java_JAVA_EXECUTABLE} -Xmx384m -jar ${ANTLR3_JAR_PATH})
endif()
endif()
diff --git a/cmake/FindZlib.cmake b/cmake/FindZlib.cmake
index 8f7e234..3cb42a4 100644
--- a/cmake/FindZlib.cmake
+++ b/cmake/FindZlib.cmake
@@ -26,8 +26,8 @@
# ZLIB_INCLUDE_DIRS - the zlib include directory
# ZLIB_LIBRARIES - The libraries needed to use zlib
-if(APPLE AND NOT IOS)
- set(ZLIB_HINTS "/usr")
+if(APPLE AND NOT IOS AND NOT CMAKE_FIND_ROOT_PATH)
+ set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT}) #On MACOSX zlib is from xcode SDK
endif()
if(ZLIB_HINTS)
set(ZLIB_LIBRARIES_HINTS "${ZLIB_HINTS}/lib")
diff --git a/configure.ac b/configure.ac
index a055532..fd547b7 100755
--- a/configure.ac
+++ b/configure.ac
@@ -128,7 +128,7 @@ case "$target_os" in
esac
if test "$strict" = "true"; then
- STRICT_OPTIONS="$STRICT_OPTIONS -Werror -Wextra -Wno-unused-parameter -Wno-error=unknown-pragmas -Wuninitialized -Wno-error=strict-prototypes -Wno-missing-field-initializers"
+ STRICT_OPTIONS="$STRICT_OPTIONS -Werror -Wextra -Wno-unused-parameter -Wno-error=unknown-pragmas -Wuninitialized -Wno-error=strict-prototypes -Wno-missing-field-initializers -Wno-error=deprecated-declarations"
fi
dnl because of antlr3 we must accept a few warnings...
@@ -217,7 +217,7 @@ antlr_java_prefixes="$antlr_prefix/share/java /usr/local/share/java /usr/share/j
if test $JAVA = "no" ; then
AC_MSG_ERROR([Could not find java prog. Please install java ])
else
- ANTLR="$JAVA -Xmx256m -jar $antlr_jar"
+ ANTLR="$JAVA -Xmx512m -jar $antlr_jar"
fi
fi
AC_SUBST(ANTLR_CFLAGS)
diff --git a/include/belle-sip/auth-helper.h b/include/belle-sip/auth-helper.h
index 26d98e7..3610aab 100644
--- a/include/belle-sip/auth-helper.h
+++ b/include/belle-sip/auth-helper.h
@@ -33,6 +33,13 @@ BELLE_SIP_BEGIN_DECLS
BELLESIP_EXPORT belle_sip_header_authorization_t* belle_sip_auth_helper_create_authorization(const belle_sip_header_www_authenticate_t* authentication);
/**
+ * Create an www_authenticate header from an authorization header, all common parameters are copyed.
+ * copy params: scheme, realm, nonce, algorithm, opaque
+ * @param authorization source to be used as input
+ * @return belle_sip_header_www_authenticate_t*
+ */
+BELLESIP_EXPORT belle_sip_header_www_authenticate_t* belle_sip_auth_helper_create_www_authenticate(const belle_sip_header_authorization_t* authorization);
+/**
* Create an http authorization header from an www_authenticate header, all common parameters are copyed.
* copy params: scheme, realm, nonce, algorithm, opaque
* @param authentication source to be used as input
diff --git a/include/belle-sip/belle-sip.h b/include/belle-sip/belle-sip.h
index 5bbe128..55dbecc 100644
--- a/include/belle-sip/belle-sip.h
+++ b/include/belle-sip/belle-sip.h
@@ -43,7 +43,7 @@
#include "belle-sip/belle-sdp.h"
#include "belle-sip/bodyhandler.h"
-#ifdef ANDROID
+#ifdef __ANDROID__
#include "belle-sip/wakelock.h"
#endif
diff --git a/include/belle-sip/defs.h b/include/belle-sip/defs.h
index 8c953fe..65fe5b0 100644
--- a/include/belle-sip/defs.h
+++ b/include/belle-sip/defs.h
@@ -42,17 +42,18 @@ typedef unsigned __int64 uint64_t;
#define BELLESIP_INLINE inline
#endif
-#ifdef _WIN32
-#ifdef BELLESIP_EXPORTS
-#define BELLESIP_EXPORT __declspec(dllexport)
-#define BELLESIP_VAR_EXPORT __declspec(dllexport)
-#else
-#define BELLESIP_EXPORT
-#define BELLESIP_VAR_EXPORT extern __declspec(dllimport)
-#endif
+#ifdef _MSC_VER
+ #ifdef BELLESIP_STATIC
+ #define BELLESIP_EXPORT
+ #else
+ #ifdef BELLESIP_EXPORTS
+ #define BELLESIP_EXPORT __declspec(dllexport)
+ #else
+ #define BELLESIP_EXPORT __declspec(dllimport)
+ #endif
+ #endif
#else
-#define BELLESIP_VAR_EXPORT extern
-#define BELLESIP_EXPORT extern
+ #define BELLESIP_EXPORT
#endif
#define BELLESIP_UNUSED(a) (void)a;
diff --git a/include/belle-sip/headers.h b/include/belle-sip/headers.h
index 69815f4..997fad1 100644
--- a/include/belle-sip/headers.h
+++ b/include/belle-sip/headers.h
@@ -59,6 +59,12 @@ BELLESIP_EXPORT belle_sip_header_address_t* belle_sip_header_address_create2(con
BELLESIP_EXPORT belle_sip_header_address_t* belle_sip_header_address_parse (const char* address) ;
+/*
+ same as belle_sip_header_address_parse but with less syntax checking
+ */
+BELLESIP_EXPORT belle_sip_header_address_t* belle_sip_header_address_fast_parse (const char* address) ;
+
+
/**
* returns a sip uri. A header address cannot have both a sip uri and an absolute uri.
*/
@@ -753,6 +759,51 @@ BELLESIP_EXPORT void belle_sip_header_accept_set_subtype(belle_sip_header_accept
#define BELLE_SIP_HEADER_ACCEPT(t) BELLE_SIP_CAST(t,belle_sip_header_accept_t)
#define BELLE_SIP_ACCEPT "Accept"
+/******************************
+ * Reason header object inherent from parameters
+ *
+ ******************************/
+typedef struct _belle_sip_header_reason belle_sip_header_reason_t;
+BELLESIP_EXPORT belle_sip_header_reason_t* belle_sip_header_reason_new(void);
+BELLESIP_EXPORT belle_sip_header_reason_t* belle_sip_header_reason_parse (const char* reason) ;
+BELLESIP_EXPORT const char* belle_sip_header_reason_get_protocol(const belle_sip_header_reason_t* reason);
+BELLESIP_EXPORT void belle_sip_header_reason_set_protocol(belle_sip_header_reason_t* reason,const char* protocol);
+BELLESIP_EXPORT int belle_sip_header_reason_get_cause(const belle_sip_header_reason_t* reason);
+BELLESIP_EXPORT void belle_sip_header_reason_set_cause(belle_sip_header_reason_t* reason,int cause);
+BELLESIP_EXPORT void belle_sip_header_reason_set_text(belle_sip_header_reason_t* reason,const char* text);
+BELLESIP_EXPORT const char* belle_sip_header_reason_get_text(const belle_sip_header_reason_t* reason);
+
+#define BELLE_SIP_HEADER_REASON(t) BELLE_SIP_CAST(t,belle_sip_header_reason_t)
+#define BELLE_SIP_REASON "Reason"
+
+
+/******************************
+ * Authentication-Info header inherit from header
+ *
+ ******************************/
+typedef struct _belle_sip_header_authentication_info belle_sip_header_authentication_info_t;
+
+BELLESIP_EXPORT belle_sip_header_authentication_info_t* belle_sip_header_authentication_info_new(void);
+BELLESIP_EXPORT belle_sip_header_authentication_info_t* belle_sip_header_authentication_info_parse(const char* authentication_info );
+BELLESIP_EXPORT const char* belle_sip_header_authentication_info_get_next_nonce(const belle_sip_header_authentication_info_t* authentication_info );
+BELLESIP_EXPORT void belle_sip_header_authentication_info_set_next_nonce(belle_sip_header_authentication_info_t* authentication_info, const char* next_nonce);
+
+/*limited to a sinle value*/
+BELLESIP_EXPORT const char* belle_sip_header_authentication_info_get_qop(const belle_sip_header_authentication_info_t* authentication_info);
+BELLESIP_EXPORT void belle_sip_header_authentication_info_set_qop(belle_sip_header_authentication_info_t* authentication_info, const char* qop);
+
+BELLESIP_EXPORT const char* belle_sip_header_authentication_info_get_rsp_auth(const belle_sip_header_authentication_info_t* rsp_auth);
+BELLESIP_EXPORT void belle_sip_header_authentication_info_set_rsp_auth(belle_sip_header_authentication_info_t* authentication_info, const char* rsp_auth);
+
+BELLESIP_EXPORT const char* belle_sip_header_authentication_info_get_cnonce(const belle_sip_header_authentication_info_t* authentication_info);
+BELLESIP_EXPORT void belle_sip_header_authentication_info_set_cnonce(belle_sip_header_authentication_info_t* authentication_info, const char* cNonce);
+
+BELLESIP_EXPORT void belle_sip_header_authentication_info_set_nonce_count(belle_sip_header_authentication_info_t* authentication_info, int nonceCount);
+BELLESIP_EXPORT int belle_sip_header_authentication_info_get_nonce_count(const belle_sip_header_authentication_info_t* authentication_info);
+
+
+#define BELLE_SIP_HEADER_AUTHENTICATION_INFO(t) BELLE_SIP_CAST(t,belle_sip_header_authentication_info_t)
+#define BELLE_SIP_AUTHENTICATION_INFO "Authentication-Info"
BELLE_SIP_END_DECLS
diff --git a/include/belle-sip/list.h b/include/belle-sip/list.h
index 08af5e9..7d6c7b1 100644
--- a/include/belle-sip/list.h
+++ b/include/belle-sip/list.h
@@ -50,5 +50,6 @@ typedef struct _bctbx_list belle_sip_list_t;
#define belle_sip_list_insert bctbx_list_insert
#define belle_sip_list_copy bctbx_list_copy
#define belle_sip_list_copy_with_data bctbx_list_copy_with_data
+#define belle_sip_list_copy_reverse_with_data bctbx_list_copy_reverse_with_data
#endif /* BELLE_SIP_LIST_H_ */
diff --git a/include/belle-sip/object.h b/include/belle-sip/object.h
index 54aa6bf..6c965f7 100644
--- a/include/belle-sip/object.h
+++ b/include/belle-sip/object.h
@@ -55,6 +55,16 @@ typedef unsigned int belle_sip_type_id_t;
struct object_type##_vptr_struct{\
BELLE_SIP_OBJECT_VPTR_TYPE(parent_type) base;
+#define BELLE_SIP_DECLARE_VPTR_NO_EXPORT(object_type) \
+ typedef belle_sip_object_vptr_t BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\
+ BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void);
+
+#define BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN_NO_EXPORT(object_type, parent_type) \
+ typedef struct object_type##_vptr_struct BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\
+ BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void); \
+ struct object_type##_vptr_struct{\
+ BELLE_SIP_OBJECT_VPTR_TYPE(parent_type) base;
+
#define BELLE_SIP_DECLARE_CUSTOM_VPTR_END };
#define BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(object_type) \
diff --git a/include/belle-sip/resolver.h b/include/belle-sip/resolver.h
index 9b31517..c82f7ec 100644
--- a/include/belle-sip/resolver.h
+++ b/include/belle-sip/resolver.h
@@ -31,14 +31,14 @@ typedef struct belle_sip_resolver_context belle_sip_resolver_context_t;
* Callback prototype for asynchronous DNS SRV resolution.
* The srv_list contains struct dns_srv elements that must be taken and (possibly later) freed by the callee, using belle_sip_free().
*/
-typedef void (*belle_sip_resolver_srv_callback_t)(void *data, const char *name, belle_sip_list_t *srv_list);
+typedef void (*belle_sip_resolver_srv_callback_t)(void *data, const char *name, belle_sip_list_t *srv_list, uint32_t ttl);
/**
* Callback prototype for asynchronous DNS A and AAAA resolution.
* The ai_list contains addrinfo elements that must be taken and (possibly later) freed by the callee, using freeaddrinfo().
* These elements are linked by their ai_next field.
**/
-typedef void (*belle_sip_resolver_callback_t)(void *data, const char *name, struct addrinfo *ai_list);
+typedef void (*belle_sip_resolver_callback_t)(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl);
BELLE_SIP_BEGIN_DECLS
diff --git a/include/belle-sip/sip-uri.h b/include/belle-sip/sip-uri.h
index 80dc587..810a583 100644
--- a/include/belle-sip/sip-uri.h
+++ b/include/belle-sip/sip-uri.h
@@ -35,6 +35,16 @@ BELLESIP_EXPORT belle_sip_uri_t* belle_sip_uri_new(void);
*
*/
BELLESIP_EXPORT belle_sip_uri_t* belle_sip_uri_parse (const char* uri) ;
+
+/**
+ *
+ */
+BELLESIP_EXPORT belle_sip_uri_t* belle_sip_fast_uri_parse (const char* uri) ;
+
+/**
+ * same as belle_sip_uri_parse but with much less checks
+ */
+BELLESIP_EXPORT belle_sip_uri_t* belle_sip_fast_uri_parse (const char* uri) ;
/**
*
*/
diff --git a/include/belle-sip/types.h b/include/belle-sip/types.h
index b3a172e..bb1225c 100644
--- a/include/belle-sip/types.h
+++ b/include/belle-sip/types.h
@@ -143,7 +143,9 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sip_header_event_t),
BELLE_SIP_TYPE_ID(belle_sip_header_supported_t),
BELLE_SIP_TYPE_ID(belle_sip_header_content_disposition_t),
- BELLE_SIP_TYPE_ID(belle_sip_header_accept_t)
+ BELLE_SIP_TYPE_ID(belle_sip_header_accept_t),
+ BELLE_SIP_TYPE_ID(belle_sip_header_reason_t),
+ BELLE_SIP_TYPE_ID(belle_sip_header_authentication_info_t)
BELLE_SIP_DECLARE_TYPES_END
diff --git a/include/belle-sip/utils.h b/include/belle-sip/utils.h
index 825e865..ee4f954 100644
--- a/include/belle-sip/utils.h
+++ b/include/belle-sip/utils.h
@@ -36,6 +36,7 @@
#include "bctoolbox/logging.h"
+#include "bctoolbox/vconnect.h"
BELLE_SIP_BEGIN_DECLS
@@ -136,6 +137,9 @@ BELLESIP_EXPORT uint64_t belle_sip_time_ms(void);
BELLESIP_EXPORT unsigned int belle_sip_random(void);
+/** Connect API */
+BELLESIP_EXPORT void belle_sip_set_socket_api(bctbx_vsocket_api_t* my_api);
+
#if defined(_WIN32)
#include <winsock2.h>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 192f858..315d427 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -165,11 +165,11 @@ if(APPLE)
)
endif()
-apply_compile_flags(BELLE_SIP_SOURCE_FILES_C "CPP" "C")
-apply_compile_flags(BELLE_SIP_SOURCE_FILES_OBJC "CPP" "OBJC")
+bc_apply_compile_flags(BELLE_SIP_SOURCE_FILES_C STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
+bc_apply_compile_flags(BELLE_SIP_SOURCE_FILES_OBJC STRICT_OPTIONS_CPP STRICT_OPTIONS_OBJC)
if(BELLE_SIP_SOURCE_FILES_CXX)
set_source_files_properties(${BELLE_SIP_SOURCE_FILES_CXX} PROPERTIES LANGUAGE CXX)
- apply_compile_flags(BELLE_SIP_SOURCE_FILES_CXX "CPP" "CXX")
+ bc_apply_compile_flags(BELLE_SIP_SOURCE_FILES_CXX STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX)
endif()
if(MSVC)
get_source_file_property(DNS_C_COMPILE_FLAGS dns.c COMPILE_FLAGS)
@@ -186,6 +186,9 @@ if(MSVC)
set(SIP_MESSAGE_PARSER_COMPILE_FLAGS "${SIP_MESSAGE_PARSER_COMPILE_FLAGS} /wd4267") # Disable "possible loss of data" warnings
set_source_files_properties(grammars/belle_sip_messageParser.c PROPERTIES COMPILE_FLAGS "${SIP_MESSAGE_PARSER_COMPILE_FLAGS}")
else()
+ get_source_file_property(DNS_C_COMPILE_FLAGS dns.c COMPILE_FLAGS)
+ set(DNS_C_COMPILE_FLAGS "${DNS_C_COMPILE_FLAGS} -Wno-error")
+ set_source_files_properties(dns.c PROPERTIES COMPILE_FLAGS "${DNS_C_COMPILE_FLAGS}")
get_source_file_property(SIP_MESSAGE_PARSER_COMPILE_FLAGS grammars/belle_sip_messageParser.c COMPILE_FLAGS)
set(SIP_MESSAGE_PARSER_COMPILE_FLAGS "${SIP_MESSAGE_PARSER_COMPILE_FLAGS} -Wno-sign-compare")
set_source_files_properties(grammars/belle_sip_messageParser.c PROPERTIES COMPILE_FLAGS "${SIP_MESSAGE_PARSER_COMPILE_FLAGS}")
@@ -196,7 +199,7 @@ if(ENABLE_STATIC)
add_library(bellesip-static STATIC ${BELLE_SIP_HEADER_FILES} ${BELLE_SIP_SOURCE_FILES_C} ${BELLE_SIP_SOURCE_FILES_CXX} ${BELLE_SIP_SOURCE_FILES_OBJC})
set_target_properties(bellesip-static PROPERTIES OUTPUT_NAME bellesip)
target_include_directories(bellesip-static PUBLIC ${INCLUDES})
- target_link_libraries(bellesip-static ${LIBS})
+ target_link_libraries(bellesip-static INTERFACE ${LIBS})
if(NOT "${LINK_FLAGS_STR}" STREQUAL "")
set_target_properties(bellesip-static PROPERTIES LINK_FLAGS "${LINK_FLAGS_STR}")
endif()
@@ -231,6 +234,3 @@ if(ENABLE_SHARED)
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
endif()
-
-
-
diff --git a/src/auth_helper.c b/src/auth_helper.c
index 3bbd49c..18417ef 100644
--- a/src/auth_helper.c
+++ b/src/auth_helper.c
@@ -39,11 +39,27 @@ static void belle_sip_auth_helper_clone_authorization(belle_sip_header_authoriza
CLONE_STRING_GENERIC(belle_sip_header_www_authenticate,belle_sip_header_authorization,algorithm,authorization,authentication)
CLONE_STRING_GENERIC(belle_sip_header_www_authenticate,belle_sip_header_authorization,opaque,authorization,authentication)
}
+
+static void belle_sip_auth_helper_clone_www_authenticate(belle_sip_header_www_authenticate_t* authentication, const belle_sip_header_authorization_t* authorization) {
+ CLONE_STRING_GENERIC(belle_sip_header_authorization,belle_sip_header_www_authenticate,scheme, authentication, authorization)
+ CLONE_STRING_GENERIC(belle_sip_header_authorization,belle_sip_header_www_authenticate,realm, authentication, authorization)
+ CLONE_STRING_GENERIC(belle_sip_header_authorization,belle_sip_header_www_authenticate,nonce, authentication, authorization)
+ CLONE_STRING_GENERIC(belle_sip_header_authorization,belle_sip_header_www_authenticate,algorithm,authentication ,authorization)
+ CLONE_STRING_GENERIC(belle_sip_header_authorization,belle_sip_header_www_authenticate,opaque,authentication, authorization)
+}
+
belle_sip_header_authorization_t* belle_sip_auth_helper_create_authorization(const belle_sip_header_www_authenticate_t* authentication) {
belle_sip_header_authorization_t* authorization = belle_sip_header_authorization_new();
belle_sip_auth_helper_clone_authorization(authorization,authentication);
return authorization;
}
+
+belle_sip_header_www_authenticate_t* belle_sip_auth_helper_create_www_authenticate(const belle_sip_header_authorization_t* authorization) {
+ belle_sip_header_www_authenticate_t* www_authenticate = belle_sip_header_www_authenticate_new();
+ belle_sip_auth_helper_clone_www_authenticate(www_authenticate, authorization);
+ return www_authenticate;
+}
+
belle_http_header_authorization_t* belle_http_auth_helper_create_authorization(const belle_sip_header_www_authenticate_t* authentication) {
belle_http_header_authorization_t* authorization = belle_http_header_authorization_new();
belle_sip_auth_helper_clone_authorization(BELLE_SIP_HEADER_AUTHORIZATION(authorization),authentication);
@@ -69,7 +85,7 @@ int belle_sip_auth_helper_compute_ha1(const char* userid,const char* realm,const
return -1;
}
if (!realm) {
- belle_sip_error("belle_sip_fill_authorization_header, password not found ");
+ belle_sip_error("belle_sip_fill_authorization_header, realm not found ");
return -1;
}
@@ -238,8 +254,3 @@ int belle_sip_auth_helper_fill_proxy_authorization(belle_sip_header_proxy_author
}
-
-
-
-
-
diff --git a/src/belle_sip_headers_impl.c b/src/belle_sip_headers_impl.c
index e36bf64..270dec1 100644
--- a/src/belle_sip_headers_impl.c
+++ b/src/belle_sip_headers_impl.c
@@ -83,6 +83,8 @@ static struct header_name_func_pair header_table[] = {
,{PROTO_SIP, "k", (header_parse_func)belle_sip_header_supported_parse}
,{PROTO_SIP, BELLE_SIP_CONTENT_DISPOSITION, (header_parse_func)belle_sip_header_content_disposition_parse}
,{PROTO_SIP, BELLE_SIP_ACCEPT, (header_parse_func)belle_sip_header_accept_parse}
+ ,{PROTO_SIP, BELLE_SIP_REASON, (header_parse_func)belle_sip_header_reason_parse}
+ ,{PROTO_SIP, BELLE_SIP_AUTHENTICATION_INFO, (header_parse_func)belle_sip_header_authentication_info_parse}
};
static belle_sip_header_t* belle_header_create(const char* name,const char* value,int protocol) {
@@ -310,6 +312,13 @@ belle_sip_header_address_t* belle_sip_header_address_create2(const char* display
return address;
}
+/*fast header address implemenation*/
+typedef belle_sip_header_address_t belle_sip_fast_header_address_t;
+#define belle_sip_fast_header_address_parse belle_sip_header_address_fast_parse
+BELLE_SIP_PARSE(fast_header_address)
+
+
+
/******************************
* Extension header inherits from header
*
@@ -2021,4 +2030,136 @@ belle_sip_header_accept_t* belle_sip_header_accept_create (const char* type,cons
GET_SET_STRING(belle_sip_header_accept,type);
GET_SET_STRING(belle_sip_header_accept,subtype);
+/******************************
+ * Reason header object inherent from parameters
+ *
+ ******************************/
+struct _belle_sip_header_reason {
+ belle_sip_parameters_t params_list;
+ const char* protocol;
+ const char* unquoted_text;
+};
+
+static void belle_sip_header_reason_destroy(belle_sip_header_reason_t* reason) {
+ DESTROY_STRING(reason,protocol);
+ DESTROY_STRING(reason,unquoted_text);
+}
+
+static void belle_sip_header_reason_clone(belle_sip_header_reason_t* reason, const belle_sip_header_reason_t* orig){
+ CLONE_STRING(belle_sip_header_reason,protocol,reason,orig)
+}
+
+belle_sip_error_code belle_sip_header_reason_marshal(belle_sip_header_reason_t* reason, char* buff, size_t buff_size, size_t *offset) {
+ belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(reason), buff, buff_size, offset);
+ if (error!=BELLE_SIP_OK) return error;
+ error=belle_sip_snprintf(buff,buff_size,offset,"%s ",reason->protocol);
+ if (error!=BELLE_SIP_OK) return error;
+ error=belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(reason), buff, buff_size, offset);
+ if (error!=BELLE_SIP_OK) return error;
+ if (reason->unquoted_text)
+ error=belle_sip_snprintf(buff,buff_size,offset,"; text=\"%s\"",reason->unquoted_text);
+ return error;
+}
+
+GET_SET_STRING(belle_sip_header_reason,unquoted_text);
+
+void belle_sip_header_reason_set_text(belle_sip_header_reason_t* reason,const char* text) {
+ belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(reason),"text"); /*just in case*/
+ belle_sip_header_reason_set_unquoted_text((belle_sip_header_reason_t*)reason, text);
+}
+BELLESIP_EXPORT const char* belle_sip_header_reason_get_text(const belle_sip_header_reason_t* reason) {
+ if (!reason->unquoted_text) {
+ /*try from params*/
+ const char * quoted = belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(reason), "text");
+ if (quoted) {
+ char* unquoted = _belle_sip_str_dup_and_unquote_string(quoted);
+ belle_sip_header_reason_set_unquoted_text((belle_sip_header_reason_t*)reason, unquoted); /*change internal param, ,even if reason is const*/
+ belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(reason),"text");
+ belle_sip_free(unquoted);
+ }
+
+ }
+ return reason->unquoted_text;
+}
+
+GET_SET_STRING(belle_sip_header_reason,protocol);
+
+GET_SET_INT_PARAM(belle_sip_header_reason,cause,int);
+BELLE_SIP_PARSE(header_reason)
+BELLE_SIP_NEW_HEADER(header_reason,parameters,BELLE_SIP_REASON)
+
+/******************************
+ * AuthenticationInfo header hinerite from header
+ *
+ ******************************/
+
+struct _belle_sip_header_authentication_info {
+ belle_sip_header_t header;
+ const char* rsp_auth;
+ const char* cnonce;
+ int nonce_count;
+ const char* qop;
+ const char* next_nonce;
+};
+static void belle_sip_header_authentication_info_destroy(belle_sip_header_authentication_info_t* authentication_info) {
+ DESTROY_STRING(authentication_info,rsp_auth);
+ DESTROY_STRING(authentication_info,cnonce);
+ DESTROY_STRING(authentication_info,qop);
+ DESTROY_STRING(authentication_info,next_nonce);
+
+}
+
+static void belle_sip_header_authentication_info_clone( belle_sip_header_authentication_info_t* authentication_info
+ , const belle_sip_header_authentication_info_t* orig){
+ CLONE_STRING(belle_sip_header_authentication_info,rsp_auth,authentication_info,orig)
+ CLONE_STRING(belle_sip_header_authentication_info,cnonce,authentication_info,orig)
+ CLONE_STRING(belle_sip_header_authentication_info,qop,authentication_info,orig)
+ CLONE_STRING(belle_sip_header_authentication_info,next_nonce,authentication_info,orig)
+}
+
+belle_sip_error_code belle_sip_header_authentication_info_marshal(belle_sip_header_authentication_info_t* authentication_info, char* buff, size_t buff_size, size_t *offset) {
+ char* border="";
+ belle_sip_error_code error=belle_sip_header_marshal(BELLE_SIP_HEADER(authentication_info), buff, buff_size, offset);
+ if (error!=BELLE_SIP_OK) return error;
+
+ if (authentication_info->rsp_auth) {
+ error=belle_sip_snprintf(buff,buff_size,offset,"%srspauth=\"%s\"", border,authentication_info->rsp_auth);
+ border=", ";
+ }
+ if (error!=BELLE_SIP_OK) return error;
+ if (authentication_info->cnonce) {
+ error=belle_sip_snprintf(buff,buff_size,offset,"%scnonce=\"%s\"", border, authentication_info->cnonce);
+ border=", ";
+ }
+ if (error!=BELLE_SIP_OK) return error;
+
+ if (authentication_info->nonce_count >= 0) {
+ error=belle_sip_snprintf(buff,buff_size,offset,"%snc=%08x", border, authentication_info->nonce_count);
+ border=", ";
+ }
+ if (error!=BELLE_SIP_OK) return error;
+
+ if (authentication_info->qop) {
+ error=belle_sip_snprintf(buff,buff_size,offset,"%sqop=%s", border, authentication_info->qop);
+ border=", ";
+ }
+ if (error!=BELLE_SIP_OK) return error;
+
+ if (authentication_info->next_nonce) {
+ error=belle_sip_snprintf(buff,buff_size,offset,"%snextnonce=\"%s\"", border, authentication_info->next_nonce);
+ }
+ return error;
+
+
+}
+void belle_sip_header_authentication_info_init(belle_sip_header_authentication_info_t* header_authentication) {
+ header_authentication->nonce_count=-1;
+}
+BELLE_SIP_NEW_HEADER_INIT(header_authentication_info,header,BELLE_SIP_AUTHENTICATION_INFO,header_authentication_info)
+BELLE_SIP_PARSE(header_authentication_info)
+GET_SET_STRING(belle_sip_header_authentication_info,rsp_auth);
+GET_SET_STRING(belle_sip_header_authentication_info,qop);
+GET_SET_STRING(belle_sip_header_authentication_info,next_nonce);
+GET_SET_STRING(belle_sip_header_authentication_info,cnonce);
+GET_SET_INT(belle_sip_header_authentication_info,nonce_count,int);
diff --git a/src/belle_sip_internal.h b/src/belle_sip_internal.h
index d9acf9b..772a8a9 100644
--- a/src/belle_sip_internal.h
+++ b/src/belle_sip_internal.h
@@ -30,6 +30,7 @@
#include "port.h"
#include <bctoolbox/port.h>
+#include <bctoolbox/vconnect.h>
#ifdef HAVE_CONFIG_H
@@ -81,6 +82,16 @@
__method=BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->method;\
if (__method) BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->
+#define __BELLE_SIP_INVOKE_LISTENER_REVERSE_BEGIN(list,interface_name,method) \
+ if (list!=NULL) {\
+ belle_sip_list_t *__copy=belle_sip_list_copy_reverse_with_data((list), (void* (*)(void*))belle_sip_object_ref);\
+ const belle_sip_list_t *__elem=__copy;\
+ do{\
+ void *__method;\
+ interface_name *__obj=(interface_name*)__elem->data;\
+ __method=BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->method;\
+ if (__method) BELLE_SIP_INTERFACE_GET_METHODS(__obj,interface_name)->
+
#define __BELLE_SIP_INVOKE_LISTENER_END \
__elem=__elem->next;\
}while(__elem!=NULL);\
@@ -97,12 +108,16 @@
method(__obj,arg);\
__BELLE_SIP_INVOKE_LISTENER_END
-
#define BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(list,interface_name,method,arg1,arg2) \
__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name,method)\
method(__obj,arg1,arg2);\
__BELLE_SIP_INVOKE_LISTENER_END
+#define BELLE_SIP_INVOKE_LISTENERS_REVERSE_ARG1_ARG2(list,interface_name,method,arg1,arg2) \
+ __BELLE_SIP_INVOKE_LISTENER_REVERSE_BEGIN(list,interface_name,method)\
+ method(__obj,arg1,arg2);\
+ __BELLE_SIP_INVOKE_LISTENER_END
+
#define BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2_ARG3(list,interface_name,method,arg1,arg2,arg3) \
__BELLE_SIP_INVOKE_LISTENER_BEGIN(list,interface_name)\
method(__obj,arg1,arg2,arg3);\
@@ -211,6 +226,9 @@ BELLE_SIP_DECLARE_VPTR(belle_sip_header_event_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_supported_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_content_disposition_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_accept_t);
+BELLE_SIP_DECLARE_VPTR(belle_sip_header_reason_t);
+BELLE_SIP_DECLARE_VPTR(belle_sip_header_authentication_info_t);
+
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_resolver_context_t,belle_sip_source_t)
void (*cancel)(belle_sip_resolver_context_t *);
@@ -535,11 +553,11 @@ struct belle_sip_stack{
unsigned char dns_search_enabled;
};
-BELLESIP_INTERNAL_EXPORT belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port);
-BELLESIP_INTERNAL_EXPORT belle_sip_hop_t* belle_sip_hop_new_from_uri(const belle_sip_uri_t *uri);
-BELLESIP_INTERNAL_EXPORT belle_sip_hop_t* belle_sip_hop_new_from_generic_uri(const belle_generic_uri_t *uri);
+BELLESIP_EXPORT belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port);
+BELLESIP_EXPORT belle_sip_hop_t* belle_sip_hop_new_from_uri(const belle_sip_uri_t *uri);
+BELLESIP_EXPORT belle_sip_hop_t* belle_sip_hop_new_from_generic_uri(const belle_generic_uri_t *uri);
-BELLESIP_INTERNAL_EXPORT belle_sip_hop_t * belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req);
+BELLESIP_EXPORT belle_sip_hop_t * belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req);
/*
belle_sip_provider_t
@@ -561,12 +579,12 @@ struct belle_sip_provider{
unsigned short unconditional_answer;
};
-BELLESIP_INTERNAL_EXPORT belle_sip_provider_t *belle_sip_provider_new(belle_sip_stack_t *s, belle_sip_listening_point_t *lp);
+BELLESIP_EXPORT belle_sip_provider_t *belle_sip_provider_new(belle_sip_stack_t *s, belle_sip_listening_point_t *lp);
void belle_sip_provider_add_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t);
belle_sip_client_transaction_t *belle_sip_provider_find_matching_client_transaction(belle_sip_provider_t *prov, belle_sip_response_t *resp);
void belle_sip_provider_remove_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t);
void belle_sip_provider_add_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t);
-BELLESIP_INTERNAL_EXPORT belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transaction(belle_sip_provider_t *prov,belle_sip_request_t *req);
+BELLESIP_EXPORT belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transaction(belle_sip_provider_t *prov,belle_sip_request_t *req);
void belle_sip_provider_remove_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t);
void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, belle_sip_transaction_t *t);
void *belle_sip_transaction_get_application_data_internal(const belle_sip_transaction_t *t);
@@ -579,7 +597,7 @@ void belle_sip_provider_remove_internal_sip_listener(belle_sip_provider_t *p, be
belle_sip_client_transaction_t * belle_sip_provider_find_matching_client_transaction_from_req(belle_sip_provider_t *prov, belle_sip_request_t *req);
belle_sip_dialog_t *belle_sip_provider_find_dialog_from_message(belle_sip_provider_t *prov, belle_sip_message_t *msg, int as_uas);
/*for testing purpose only:*/
-BELLESIP_INTERNAL_EXPORT void belle_sip_provider_dispatch_message(belle_sip_provider_t *prov, belle_sip_message_t *msg);
+BELLESIP_EXPORT void belle_sip_provider_dispatch_message(belle_sip_provider_t *prov, belle_sip_message_t *msg);
typedef struct listener_ctx{
belle_sip_listener_t *listener;
@@ -974,16 +992,16 @@ belle_sip_refresher_t* belle_sip_refresher_new(belle_sip_client_transaction_t* t
* returns a char, even if entry is escaped*/
size_t belle_sip_get_char (const char*a,char*out);
/*return an escaped string*/
-BELLESIP_INTERNAL_EXPORT char* belle_sip_uri_to_escaped_username(const char* buff) ;
-BELLESIP_INTERNAL_EXPORT char* belle_sip_uri_to_escaped_userpasswd(const char* buff) ;
-BELLESIP_INTERNAL_EXPORT char* belle_sip_uri_to_escaped_parameter(const char* buff) ;
-BELLESIP_INTERNAL_EXPORT char* belle_sip_uri_to_escaped_header(const char* buff) ;
+BELLESIP_EXPORT char* belle_sip_uri_to_escaped_username(const char* buff) ;
+BELLESIP_EXPORT char* belle_sip_uri_to_escaped_userpasswd(const char* buff) ;
+BELLESIP_EXPORT char* belle_sip_uri_to_escaped_parameter(const char* buff) ;
+BELLESIP_EXPORT char* belle_sip_uri_to_escaped_header(const char* buff) ;
/*(uri RFC 2396)*/
-BELLESIP_INTERNAL_EXPORT char* belle_generic_uri_to_escaped_query(const char* buff);
-BELLESIP_INTERNAL_EXPORT char* belle_generic_uri_to_escaped_path(const char* buff);
+BELLESIP_EXPORT char* belle_generic_uri_to_escaped_query(const char* buff);
+BELLESIP_EXPORT char* belle_generic_uri_to_escaped_path(const char* buff);
#define BELLE_SIP_SOCKET_TIMEOUT 30000
@@ -1019,7 +1037,7 @@ belle_sip_header_extension_t* belle_sip_header_extension_new(void);
belle_sip_header_extension_t* belle_sip_header_extension_parse (const char* extension) ;
belle_sip_header_extension_t* belle_sip_header_extension_create (const char* name,const char* value);
-BELLESIP_INTERNAL_EXPORT const char* belle_sip_header_extension_get_value(const belle_sip_header_extension_t* extension);
+BELLESIP_EXPORT const char* belle_sip_header_extension_get_value(const belle_sip_header_extension_t* extension);
void belle_sip_header_extension_set_value(belle_sip_header_extension_t* extension,const char* value);
#define BELLE_SIP_HEADER_EXTENSION(t) BELLE_SIP_CAST(t,belle_sip_header_extension_t)
@@ -1070,4 +1088,8 @@ void belle_sip_multipart_body_handler_progress_cb(belle_sip_body_handler_t *obj,
*/
belle_sip_list_t *belle_sip_parse_directory(const char *path, const char *file_type);
+typedef struct authorization_context authorization_context_t;
+BELLESIP_EXPORT void belle_sip_authorization_destroy(authorization_context_t* object);
+
+
#endif
diff --git a/src/belle_sip_resolver.c b/src/belle_sip_resolver.c
index dfbdb29..a68a63d 100644
--- a/src/belle_sip_resolver.c
+++ b/src/belle_sip_resolver.c
@@ -18,8 +18,10 @@
#include "belle_sip_internal.h"
#include "dns.h"
+#include <bctoolbox/defs.h>
#include <stdlib.h>
+#include <stdint.h>
#ifdef __APPLE__
#include "TargetConditionals.h"
#endif
@@ -51,7 +53,7 @@ struct belle_sip_dns_srv{
belle_sip_combined_resolver_context_t *root_resolver;/* used internally to combine SRV and A queries*/
belle_sip_resolver_context_t *a_resolver; /* used internally to combine SRV and A queries*/
struct addrinfo *a_results; /* used internally to combine SRV and A queries*/
-
+
};
static void belle_sip_dns_srv_destroy(belle_sip_dns_srv_t *obj){
@@ -102,6 +104,7 @@ BELLE_SIP_INSTANCIATE_VPTR(belle_sip_dns_srv_t, belle_sip_object_t,belle_sip_dns
struct belle_sip_resolver_context{
belle_sip_source_t source;
belle_sip_stack_t *stack;
+ uint32_t min_ttl;
uint8_t notified;
uint8_t cancelled;
uint8_t pad[2];
@@ -167,6 +170,7 @@ struct belle_sip_dual_resolver_context{
void belle_sip_resolver_context_init(belle_sip_resolver_context_t *obj, belle_sip_stack_t *stack){
obj->stack=stack;
+ obj->min_ttl = UINT32_MAX;
belle_sip_init_sockets(); /* Need to be called for DNS resolution to work on Windows platform. */
}
@@ -195,10 +199,10 @@ static struct dns_resolv_conf *resconf(belle_sip_simple_resolver_context_t *ctx)
belle_sip_error("%s dns_resconf_open error: %s", __FUNCTION__, dns_strerror(error));
return NULL;
}
-
+
path = belle_sip_stack_get_dns_resolv_conf_file(ctx->base.stack);
servers = ctx->base.stack->dns_servers;
-
+
if (servers){
belle_sip_message("%s using application supplied dns server list.", __FUNCTION__);
error = dns_resconf_nameservers_from_list(ctx->resconf, servers);
@@ -218,7 +222,7 @@ static struct dns_resolv_conf *resconf(belle_sip_simple_resolver_context_t *ctx)
if (error) {
belle_sip_error("%s dns_resconf_loadwin error", __FUNCTION__);
}
-#elif defined(ANDROID)
+#elif defined(__ANDROID__)
error = dns_resconf_loadandroid(ctx->resconf);
if (error) {
belle_sip_error("%s dns_resconf_loadandroid error", __FUNCTION__);
@@ -250,13 +254,13 @@ static struct dns_resolv_conf *resconf(belle_sip_simple_resolver_context_t *ctx)
return NULL;
}
}
-
+
if (error==0){
char ip[64];
char serv[10];
int using_ipv6=FALSE;
size_t i;
-
+
belle_sip_message("Resolver is using DNS server(s):");
for(i=0;i<sizeof(ctx->resconf->nameserver)/sizeof(ctx->resconf->nameserver[0]);++i){
struct sockaddr *ns_addr=(struct sockaddr*)&ctx->resconf->nameserver[i];
@@ -339,7 +343,7 @@ static belle_sip_dns_srv_t *srv_elect_one(belle_sip_list_t *srv_list){
belle_sip_list_t *elem;
belle_sip_dns_srv_t *srv;
int rand_number;
-
+
for(elem=srv_list;elem!=NULL;elem=elem->next){
srv=(belle_sip_dns_srv_t*)elem->data;
sum+=srv->weight;
@@ -417,11 +421,11 @@ static void simple_resolver_context_notify(belle_sip_resolver_context_t *obj) {
#if USE_GETADDRINFO_FALLBACK
if (ctx->getaddrinfo_ai_list != NULL) ai_list = &ctx->getaddrinfo_ai_list;
#endif
- ctx->cb(ctx->cb_data, ctx->name, *ai_list);
+ ctx->cb(ctx->cb_data, ctx->name, *ai_list, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
*ai_list = NULL;
} else if (ctx->type == DNS_T_SRV) {
ctx->srv_list = srv_select_by_weight(ctx->srv_list);
- ctx->srv_cb(ctx->srv_cb_data, ctx->name, ctx->srv_list);
+ ctx->srv_cb(ctx->srv_cb_data, ctx->name, ctx->srv_list, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
}
}
@@ -431,7 +435,7 @@ static void dual_resolver_context_notify(belle_sip_resolver_context_t *obj) {
results = ai_list_append(results, ctx->a_results);
ctx->a_results = NULL;
ctx->aaaa_results = NULL;
- ctx->cb(ctx->cb_data, ctx->name, results);
+ ctx->cb(ctx->cb_data, ctx->name, results, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
}
static void combined_resolver_context_cleanup(belle_sip_combined_resolver_context_t *ctx) {
@@ -449,7 +453,7 @@ static void combined_resolver_context_cleanup(belle_sip_combined_resolver_contex
static void combined_resolver_context_notify(belle_sip_resolver_context_t *obj) {
belle_sip_combined_resolver_context_t *ctx = BELLE_SIP_COMBINED_RESOLVER_CONTEXT(obj);
- ctx->cb(ctx->cb_data, ctx->name, ctx->final_results);
+ ctx->cb(ctx->cb_data, ctx->name, ctx->final_results, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
ctx->final_results = NULL;
combined_resolver_context_cleanup(ctx);
}
@@ -458,7 +462,7 @@ static void append_dns_result(belle_sip_simple_resolver_context_t *ctx, struct a
char host[NI_MAXHOST + 1];
int gai_err;
int family=ctx->family;
-
+
if ((gai_err=bctbx_getnameinfo(addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST)) != 0){
belle_sip_error("append_dns_result(): getnameinfo() failed: %s",gai_strerror(gai_err));
return;
@@ -482,7 +486,7 @@ static int resolver_process_data(belle_sip_simple_resolver_context_t *ctx, unsig
belle_sip_warning("Simulating DNS timeout");
simulated_timeout=1;
}
-
+
if (simulated_timeout || ((revents & BELLE_SIP_EVENT_TIMEOUT) && ((int)(belle_sip_time_ms()-ctx->start_time)>=timeout))) {
belle_sip_error("%s timed-out", __FUNCTION__);
belle_sip_resolver_context_notify(BELLE_SIP_RESOLVER_CONTEXT(ctx));
@@ -514,6 +518,7 @@ static int resolver_process_data(belle_sip_simple_resolver_context_t *ctx, unsig
sin6.sin6_family = AF_INET6;
sin6.sin6_port = ctx->port;
append_dns_result(ctx,&ctx->ai_list,(struct sockaddr*)&sin6,sizeof(sin6));
+ if (rr.ttl < BELLE_SIP_RESOLVER_CONTEXT(ctx)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(ctx)->min_ttl = rr.ttl;
} else if ((ctx->type == DNS_T_A) && (rr.class == DNS_C_IN) && (rr.type == DNS_T_A)) {
struct dns_a *a = &any.a;
struct sockaddr_in sin;
@@ -522,6 +527,7 @@ static int resolver_process_data(belle_sip_simple_resolver_context_t *ctx, unsig
sin.sin_family = AF_INET;
sin.sin_port = ctx->port;
append_dns_result(ctx,&ctx->ai_list,(struct sockaddr*)&sin,sizeof(sin));
+ if (rr.ttl < BELLE_SIP_RESOLVER_CONTEXT(ctx)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(ctx)->min_ttl = rr.ttl;
} else if ((ctx->type == DNS_T_SRV) && (rr.class == DNS_C_IN) && (rr.type == DNS_T_SRV)) {
char host[NI_MAXHOST + 1];
struct dns_srv *srv = &any.srv;
@@ -529,6 +535,7 @@ static int resolver_process_data(belle_sip_simple_resolver_context_t *ctx, unsig
snprintf(host, sizeof(host), "[target:%s port:%d prio:%d weight:%d]", srv->target, srv->port, srv->priority, srv->weight);
ctx->srv_list = belle_sip_list_insert_sorted(ctx->srv_list, belle_sip_object_ref(b_srv), srv_compare_prio);
belle_sip_message("SRV %s resolved to %s", ctx->name, host);
+ if (rr.ttl < BELLE_SIP_RESOLVER_CONTEXT(ctx)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(ctx)->min_ttl = rr.ttl;
}
}
}
@@ -536,6 +543,9 @@ static int resolver_process_data(belle_sip_simple_resolver_context_t *ctx, unsig
#ifdef USE_GETADDRINFO_FALLBACK
ctx->getaddrinfo_cancelled = TRUE;
#endif
+ if (dns_res_was_asymetric(ctx->R)){
+ belle_sip_warning("DNS answer was not received from the DNS server IP address the request was sent to. This seems to be a known issue with NAT64 networks created by Apple computers.");
+ }
belle_sip_resolver_context_notify(BELLE_SIP_RESOLVER_CONTEXT(ctx));
return BELLE_SIP_STOP;
}
@@ -662,7 +672,7 @@ static int _resolver_send_query(belle_sip_simple_resolver_context_t *ctx) {
static int resolver_process_data_delayed(belle_sip_simple_resolver_context_t *ctx, unsigned int revents) {
int err=_resolver_send_query(ctx);
if (err==0) return BELLE_SIP_CONTINUE;
-
+
return BELLE_SIP_STOP;
}
@@ -684,6 +694,11 @@ static int _resolver_start_query(belle_sip_simple_resolver_context_t *ctx) {
return -1;
memset(&opts, 0, sizeof opts);
+
+ /* When there are IPv6 nameservers, allow responses to arrive from an IP address that is not the IP address to which the request was sent originally.
+ * Mac' NAT64 network tend to do this sometimes.*/
+ opts.udp_uses_connect = ctx->resconf->iface.ss_family != AF_INET6;
+ if (!opts.udp_uses_connect) belle_sip_message("Resolver is not using connect().");
if (!(ctx->R = dns_res_open(ctx->resconf, ctx->hosts, dns_hints_mortal(dns_hints_local(ctx->resconf, &error)), cache(ctx), &opts, &error))) {
belle_sip_error("%s dns_res_open error [%s]: %s", __FUNCTION__, ctx->name, dns_strerror(error));
@@ -908,17 +923,18 @@ static char * srv_prefix_from_service_and_transport(const char *service, const c
return belle_sip_strdup_printf("_%s._udp.", service);
}
-static void process_a_fallback_result(void *data, const char *name, struct addrinfo *ai_list){
+static void process_a_fallback_result(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
belle_sip_combined_resolver_context_t *ctx=(belle_sip_combined_resolver_context_t *)data;
ctx->final_results=ai_list;
belle_sip_resolver_context_notify(BELLE_SIP_RESOLVER_CONTEXT(ctx));
}
-static void combined_resolver_context_check_finished(belle_sip_combined_resolver_context_t *obj){
+static void combined_resolver_context_check_finished(belle_sip_combined_resolver_context_t *obj, uint32_t ttl){
belle_sip_list_t *elem;
struct addrinfo *final=NULL;
unsigned char finished=TRUE;
-
+
+ if (ttl < BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl = ttl;
for(elem=obj->srv_results;elem!=NULL;elem=elem->next){
belle_sip_dns_srv_t *srv=(belle_sip_dns_srv_t*)elem->data;
if (!srv->a_done) {
@@ -940,12 +956,13 @@ static void combined_resolver_context_check_finished(belle_sip_combined_resolver
}
}
-static void process_a_from_srv(void *data, const char *name, struct addrinfo *ai_list){
+static void process_a_from_srv(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
belle_sip_dns_srv_t *srv=(belle_sip_dns_srv_t*)data;
srv->a_results=ai_list;
srv->a_done=TRUE;
belle_sip_message("A query finished for srv result [%s]",srv->target);
- combined_resolver_context_check_finished(srv->root_resolver);
+ if (ttl < BELLE_SIP_RESOLVER_CONTEXT(srv->root_resolver)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(srv->root_resolver)->min_ttl = ttl;
+ combined_resolver_context_check_finished(srv->root_resolver, ttl);
}
static void srv_resolve_a(belle_sip_combined_resolver_context_t *obj, belle_sip_dns_srv_t *srv){
@@ -961,10 +978,11 @@ static void srv_resolve_a(belle_sip_combined_resolver_context_t *obj, belle_sip_
belle_sip_object_unref(srv);
}
-static void process_srv_results(void *data, const char *name, belle_sip_list_t *srv_results){
+static void process_srv_results(void *data, const char *name, belle_sip_list_t *srv_results, uint32_t ttl){
belle_sip_combined_resolver_context_t *ctx=(belle_sip_combined_resolver_context_t *)data;
/*take a ref here, because the A resolution might succeed synchronously and terminate the context before exiting this function*/
belle_sip_object_ref(ctx);
+ if (ttl < BELLE_SIP_RESOLVER_CONTEXT(data)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(data)->min_ttl = ttl;
if (srv_results){
belle_sip_list_t *elem;
/* take a ref of each srv_results because the last A resolution may terminate synchronously
@@ -1014,7 +1032,7 @@ belle_sip_resolver_context_t * belle_sip_stack_resolve(belle_sip_stack_t *stack,
return BELLE_SIP_RESOLVER_CONTEXT(ctx);
} else {
/* There is no resolve to be done */
- cb(data, name, res);
+ cb(data, name, res, UINT32_MAX);
return NULL;
}
}
@@ -1052,14 +1070,14 @@ static void dual_resolver_context_check_finished(belle_sip_dual_resolver_context
}
}
-static void on_ipv4_results(void *data, const char *name, struct addrinfo *ai_list) {
+static void on_ipv4_results(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl) {
belle_sip_dual_resolver_context_t *ctx = BELLE_SIP_DUAL_RESOLVER_CONTEXT(data);
ctx->a_results = ai_list;
ctx->a_notified = TRUE;
dual_resolver_context_check_finished(ctx);
}
-static void on_ipv6_results(void *data, const char *name, struct addrinfo *ai_list) {
+static void on_ipv6_results(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl) {
belle_sip_dual_resolver_context_t *ctx = BELLE_SIP_DUAL_RESOLVER_CONTEXT(data);
ctx->aaaa_results = ai_list;
ctx->aaaa_notified = TRUE;
@@ -1095,6 +1113,7 @@ belle_sip_resolver_context_t * belle_sip_stack_resolve_a(belle_sip_stack_t *stac
switch(family){
case AF_UNSPEC:
family=AF_INET6;
+ BCTBX_NO_BREAK; /*intentionally no break*/
case AF_INET6:
return belle_sip_stack_resolve_dual(stack,name,port,cb,data);
break;
@@ -1106,7 +1125,7 @@ belle_sip_resolver_context_t * belle_sip_stack_resolve_a(belle_sip_stack_t *stac
}
} else {
/* There is no resolve to be done */
- cb(data, name, res);
+ cb(data, name, res, UINT32_MAX);
}
return NULL;
}
@@ -1148,33 +1167,33 @@ It works on all platform except for windows using ipv6 sockets. TODO: find a wor
*/
int belle_sip_get_src_addr_for(const struct sockaddr *dest, socklen_t destlen, struct sockaddr *src, socklen_t *srclen, int local_port){
int af_type=dest->sa_family;
- int sock=(int)socket(af_type,SOCK_DGRAM,IPPROTO_UDP);
+ int sock=(int)bctbx_socket(af_type,SOCK_DGRAM,IPPROTO_UDP);
int ret = 0;
-
+
if (sock==(belle_sip_socket_t)-1){
if (af_type == AF_INET){
belle_sip_fatal("Could not create socket: %s",belle_sip_get_socket_error_string());
}
goto fail;
}
-
+
if (af_type==AF_INET6 && (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6*)dest)->sin6_addr))){
/*this is actually required only for windows, who is unable to provide an ipv4 mapped local address if the remote is ipv4 mapped,
and unable to provide a correct local address if the remote address is true ipv6 address when in dual stack mode*/
belle_sip_socket_enable_dual_stack(sock);
}
-
- if (connect(sock,dest,destlen)==-1){
+ if (bctbx_connect(sock,dest,destlen)==-1){
+ //if (connect(sock,dest,destlen)==-1){
ret = -get_socket_error();
- belle_sip_error("belle_sip_get_src_addr_for: connect() failed: %s",belle_sip_get_socket_error_string_from_code(-ret));
+ belle_sip_error("belle_sip_get_src_addr_for: bctbx_connect() failed: %s",belle_sip_get_socket_error_string_from_code(-ret));
goto fail;
}
- if (getsockname(sock,src,srclen)==-1){
+ if (bctbx_getsockname(sock,src,srclen)==-1){
ret = -get_socket_error();
- belle_sip_error("belle_sip_get_src_addr_for: getsockname() failed: %s",belle_sip_get_socket_error_string_from_code(-ret));
+ belle_sip_error("belle_sip_get_src_addr_for: bctbx_getsockname() failed: %s",belle_sip_get_socket_error_string_from_code(-ret));
goto fail;
}
-
+
if (af_type==AF_INET6){
struct sockaddr_in6 *sin6=(struct sockaddr_in6*)src;
sin6->sin6_port=htons(local_port);
@@ -1182,7 +1201,7 @@ int belle_sip_get_src_addr_for(const struct sockaddr *dest, socklen_t destlen, s
struct sockaddr_in *sin=(struct sockaddr_in*)src;
sin->sin_port=htons(local_port);
}
-
+
belle_sip_close_socket(sock);
return ret;
fail:
diff --git a/src/belle_sip_uri_impl.c b/src/belle_sip_uri_impl.c
index 6f8d370..23615f3 100644
--- a/src/belle_sip_uri_impl.c
+++ b/src/belle_sip_uri_impl.c
@@ -501,3 +501,6 @@ int belle_sip_uri_check_components_from_context(const belle_sip_uri_t* uri,const
}
+/*fast uri implemenation*/
+typedef belle_sip_uri_t belle_sip_fast_uri_t;
+BELLE_SIP_PARSE(fast_uri);
diff --git a/src/belle_sip_utils.c b/src/belle_sip_utils.c
index 40670ff..629421c 100644
--- a/src/belle_sip_utils.c
+++ b/src/belle_sip_utils.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <sys/stat.h>
#include "belle_sip_internal.h"
+#include "bctoolbox/parser.h"
#include "clock_gettime.h" /*for apple*/
@@ -89,7 +90,7 @@ static int find_best_clock_id (void) {
#if 0
struct timespec ts;
static int clock_id=-1;
-#ifndef ANDROID
+#ifndef __ANDROID__
#define DEFAULT_CLOCK_MODE CLOCK_MONOTONIC
#else
#define DEFAULT_CLOCK_MODE CLOCK_REALTIME /*monotonic clock stop during sleep mode*/
@@ -258,6 +259,12 @@ unsigned int belle_sip_random(void){
#endif
}
+
+void belle_sip_set_socket_api(bctbx_vsocket_api_t* my_api){
+
+ bctbx_vsocket_api_set_default(my_api);
+}
+
static const char *symbols="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789-~";
/**
@@ -365,52 +372,14 @@ void belle_sip_util_copy_headers(belle_sip_message_t *orig, belle_sip_message_t
}
}
-static int is_escaped_char(const char *a){
- return a[0] == '%' && a[1] != '\0' && a[2] != '\0';
-}
-
-size_t belle_sip_get_char (const char*a, char*out) {
- if (is_escaped_char(a)) {
- unsigned int tmp;
- sscanf(a+1,"%02x",&tmp);
- *out=(char)tmp;
- return 3;
- } else {
- *out=*a;
- return 1;
- }
-}
char* belle_sip_to_unescaped_string(const char* buff) {
- char *output_buff=belle_sip_malloc(strlen(buff)+1);
- size_t i;
- size_t out_buff_index=0;
-
- for(i=0; buff[i]!='\0'; out_buff_index++) {
- i+=belle_sip_get_char(buff+i,output_buff+out_buff_index);
- }
- output_buff[out_buff_index]='\0';
- return output_buff;
+ return bctbx_unescaped_string(buff);
}
-#define BELLE_SIP_NO_ESCAPES_SIZE 257
-static void noescapes_add_list(char noescapes[BELLE_SIP_NO_ESCAPES_SIZE], const char *allowed) {
- while (*allowed) {
- noescapes[(unsigned int) *allowed] = 1;
- ++allowed;
- }
+size_t belle_sip_get_char(const char* a, char *b) {
+ return bctbx_get_char(a,b);
}
-
-static void noescapes_add_range(char noescapes[BELLE_SIP_NO_ESCAPES_SIZE], char first, char last) {
- memset(noescapes + (unsigned int)first, 1, last-first+1);
-}
-
-static void noescapes_add_alfanums(char noescapes[BELLE_SIP_NO_ESCAPES_SIZE]) {
- noescapes_add_range(noescapes, '0', '9');
- noescapes_add_range(noescapes, 'A', 'Z');
- noescapes_add_range(noescapes, 'a', 'z');
-}
-
/*
static void print_noescapes_map(char noescapes[BELLE_SIP_NO_ESCAPES_SIZE], const char *name) {
unsigned int i;
@@ -423,9 +392,9 @@ static void print_noescapes_map(char noescapes[BELLE_SIP_NO_ESCAPES_SIZE], const
}
*/
-static const char *get_sip_uri_username_noescapes(void) {
- static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
- if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] == 0) {
+static const bctbx_noescape_rules_t* get_sip_uri_username_noescapes(void) {
+ static bctbx_noescape_rules_t noescapes = {0};
+ if (noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] == 0) {
// concurrent initialization should not be an issue
/*user = 1*( unreserved / escaped / user-unreserved )
unreserved = alphanum / mark
@@ -433,39 +402,39 @@ static const char *get_sip_uri_username_noescapes(void) {
/ "(" / ")"
user-unreserved = "&" / "=" / "+" / "$" / "," / ";" / "?" / "/"
*/
- noescapes_add_alfanums(noescapes);
+ bctbx_noescape_rules_add_alfanums(noescapes);
/*mark*/
- noescapes_add_list(noescapes, "-_.!~*'()");
+ bctbx_noescape_rules_add_list(noescapes, "-_.!~*'()");
/*user-unreserved*/
- noescapes_add_list(noescapes, "&=+$,;?/");
+ bctbx_noescape_rules_add_list(noescapes, "&=+$,;?/");
- noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] = 1; // initialized
+ noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] = 1; // initialized
// print_noescapes_map(noescapes, "uri_username");
}
- return noescapes;
+ return (const bctbx_noescape_rules_t*)&noescapes;/*gcc asks for a cast, clang not*/
}
/*
*
* password = *( unreserved / escaped /
"&" / "=" / "+" / "$" / "," )
* */
-static const char *get_sip_uri_userpasswd_noescapes(void) {
- static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
- if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] == 0) {
+static const bctbx_noescape_rules_t* get_sip_uri_userpasswd_noescapes(void) {
+ static bctbx_noescape_rules_t noescapes = {0};
+ if (noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] == 0) {
// unreserved
- noescapes_add_alfanums(noescapes);
- noescapes_add_list(noescapes, "-_.!~*'()");
- noescapes_add_list(noescapes, "&=+$,");
+ bctbx_noescape_rules_add_alfanums(noescapes);
+ bctbx_noescape_rules_add_list(noescapes, "-_.!~*'()");
+ bctbx_noescape_rules_add_list(noescapes, "&=+$,");
- noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] = 1; // initialized
+ noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] = 1; // initialized
}
- return noescapes;
+ return (const bctbx_noescape_rules_t*)&noescapes;/*gcc asks for a cast, clang not*/
}
-static const char *get_sip_uri_parameter_noescapes(void) {
- static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
- if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] == 0) {
+static const bctbx_noescape_rules_t* get_sip_uri_parameter_noescapes(void) {
+ static bctbx_noescape_rules_t noescapes= {0};
+ if (noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] == 0) {
/*
other-param = pname [ "=" pvalue ]
pname = 1*paramchar
@@ -481,23 +450,23 @@ static const char *get_sip_uri_parameter_noescapes(void) {
*/
//param-unreserved =
- noescapes_add_list(noescapes,"[]/:&+$");
+ bctbx_noescape_rules_add_list(noescapes,"[]/:&+$");
// token
- noescapes_add_alfanums(noescapes);
- noescapes_add_list(noescapes, "-.!%*_+`'~");
+ bctbx_noescape_rules_add_alfanums(noescapes);
+ bctbx_noescape_rules_add_list(noescapes, "-.!%*_+`'~");
// unreserved
- noescapes_add_list(noescapes, "-_.!~*'()");
+ bctbx_noescape_rules_add_list(noescapes, "-_.!~*'()");
- noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] = 1; // initialized
+ noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] = 1; // initialized
// print_noescapes_map(noescapes, "uri_parameter");
}
- return noescapes;
+ return (const bctbx_noescape_rules_t*)&noescapes;/*gcc asks for a cast, clang not*/
}
-static const char *get_sip_uri_header_noescapes(void) {
- static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
- if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] == 0) {
+static const bctbx_noescape_rules_t* get_sip_uri_header_noescapes(void) {
+ static bctbx_noescape_rules_t noescapes= {0};
+ if (noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] == 0) {
/*
unreserved = alphanum / mark
mark = "-" / "_" / "." / "!" / "~" / "*" / "'"
@@ -514,61 +483,37 @@ static const char *get_sip_uri_header_noescapes(void) {
// unreserved
//alphanum
- noescapes_add_alfanums(noescapes);
+ bctbx_noescape_rules_add_alfanums(noescapes);
//mark
- noescapes_add_list(noescapes, "-_.!~*'()");
+ bctbx_noescape_rules_add_list(noescapes, "-_.!~*'()");
- noescapes_add_list(noescapes, "[]/?:+$");
+ bctbx_noescape_rules_add_list(noescapes, "[]/?:+$");
//hnv-unreserved
- noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] = 1; // initialized
+ noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] = 1; // initialized
// print_noescapes_map(noescapes, "uri_parameter");
}
- return noescapes;
+ return (const bctbx_noescape_rules_t*)&noescapes;/*gcc asks for a cast, clang not*/
}
-static char* belle_sip_escape(const char* buff, const char *noescapes) {
- size_t outbuf_size=strlen(buff);
- size_t orig_size=outbuf_size;
- char *output_buff=(char*)belle_sip_malloc(outbuf_size + 1);
- int i;
- size_t out_buff_index=0;
-
- for(i=0; buff[i] != '\0'; i++) {
- int c = ((unsigned char*)buff)[i];
- if (outbuf_size < out_buff_index + 3){
- // we will possibly add 3 chars
- outbuf_size += MAX(orig_size/2,3);
- output_buff = belle_sip_realloc(output_buff, outbuf_size + 1);
- }
- if (noescapes[c] == 1) {
- output_buff[out_buff_index++]=c;
- } else {
- // this will write 3 characters
- out_buff_index+=snprintf(output_buff+out_buff_index, outbuf_size +1 - out_buff_index, "%%%02x", c);
- }
- }
- output_buff[out_buff_index]='\0';
- return output_buff;
-}
char* belle_sip_uri_to_escaped_username(const char* buff) {
- return belle_sip_escape(buff, get_sip_uri_username_noescapes());
+ return bctbx_escape(buff, *get_sip_uri_username_noescapes());
}
char* belle_sip_uri_to_escaped_userpasswd(const char* buff) {
- return belle_sip_escape(buff, get_sip_uri_userpasswd_noescapes());
+ return bctbx_escape(buff, *get_sip_uri_userpasswd_noescapes());
}
char* belle_sip_uri_to_escaped_parameter(const char* buff) {
- return belle_sip_escape(buff, get_sip_uri_parameter_noescapes());
+ return bctbx_escape(buff, *get_sip_uri_parameter_noescapes());
}
char* belle_sip_uri_to_escaped_header(const char* buff) {
- return belle_sip_escape(buff, get_sip_uri_header_noescapes());
+ return bctbx_escape(buff, *get_sip_uri_header_noescapes());
}
/*uri (I.E RFC 2396)*/
-static const char *get_generic_uri_query_noescapes(void) {
- static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
- if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] == 0) {
+static const bctbx_noescape_rules_t *get_generic_uri_query_noescapes(void) {
+ static bctbx_noescape_rules_t noescapes= {0};
+ if (noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] == 0) {
/*
uric = reserved | unreserved | escaped
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
@@ -584,18 +529,18 @@ static const char *get_generic_uri_query_noescapes(void) {
*/
/*unreserved*/
- noescapes_add_alfanums(noescapes);
+ bctbx_noescape_rules_add_alfanums(noescapes);
/*mark*/
- noescapes_add_list(noescapes, "-_.!~*'()");
- noescapes_add_list(noescapes, "=&"); // otherwise how to pass parameters?
- noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] = 1; // initialized
+ bctbx_noescape_rules_add_list(noescapes, "-_.!~*'()");
+ bctbx_noescape_rules_add_list(noescapes, "=&"); // otherwise how to pass parameters?
+ noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] = 1; // initialized
}
- return noescapes;
+ return (const bctbx_noescape_rules_t*)&noescapes;/*gcc asks for a cast, clang not*/
}
-static const char *get_generic_uri_path_noescapes(void) {
- static char noescapes[BELLE_SIP_NO_ESCAPES_SIZE] = {0};
- if (noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] == 0) {
+static const bctbx_noescape_rules_t *get_generic_uri_path_noescapes(void) {
+ static bctbx_noescape_rules_t noescapes= {0};
+ if (noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] == 0) {
/*
3.3. Path Component
@@ -621,25 +566,25 @@ static const char *get_generic_uri_path_noescapes(void) {
*/
/*unreserved*/
- noescapes_add_alfanums(noescapes);
+ bctbx_noescape_rules_add_alfanums(noescapes);
/*mark*/
- noescapes_add_list(noescapes, "-_.!~*'()");
+ bctbx_noescape_rules_add_list(noescapes, "-_.!~*'()");
/*pchar*/
- noescapes_add_list(noescapes, ":@&=+$,");
+ bctbx_noescape_rules_add_list(noescapes, ":@&=+$,");
/*;*/
- noescapes_add_list(noescapes, ";");
- noescapes_add_list(noescapes, "/");
+ bctbx_noescape_rules_add_list(noescapes, ";");
+ bctbx_noescape_rules_add_list(noescapes, "/");
- noescapes[BELLE_SIP_NO_ESCAPES_SIZE-1] = 1; // initialized
+ noescapes[BCTBX_NOESCAPE_RULES_USER_INDEX] = 1; // initialized
}
- return noescapes;
+ return (const bctbx_noescape_rules_t*)&noescapes;/*gcc asks for a cast, clang not*/
}
char* belle_generic_uri_to_escaped_query(const char* buff) {
- return belle_sip_escape(buff, get_generic_uri_query_noescapes());
+ return bctbx_escape(buff, *get_generic_uri_query_noescapes());
}
char* belle_generic_uri_to_escaped_path(const char* buff) {
- return belle_sip_escape(buff, get_generic_uri_path_noescapes());
+ return bctbx_escape(buff, *get_generic_uri_path_noescapes());
}
char* belle_sip_string_to_backslash_less_unescaped_string(const char* buff) {
@@ -731,7 +676,7 @@ belle_sip_list_t *belle_sip_parse_directory(const char *path, const char *file_t
}
/* loop on all directory files */
- errno = 0;
+ errno = 0;
ent = readdir(dir);
while (ent != NULL) {
/* filter on file type if given */
diff --git a/src/bodyhandler.c b/src/bodyhandler.c
index d723571..3cfeb56 100644
--- a/src/bodyhandler.c
+++ b/src/bodyhandler.c
@@ -154,8 +154,9 @@ int belle_sip_body_handler_send_chunk(belle_sip_body_handler_t *obj, belle_sip_m
if (obj->expected_size!=0){
to_send=MIN(*size,obj->expected_size-obj->transfered_size);
}
- if (to_send==0) {
- // Ane eWouldBlock error added a call to the function, nothing to send so return
+ if (to_send==0 && obj->transfered_size==obj->expected_size) {
+ // An eWouldBlock error added a call to the function, nothing to send so return
+ // In some case to_send=0 because not buffer is available but sendings not finished.
belle_sip_message("body handler [%p] : Nothing to send",obj);
*size=0;
return BELLE_SIP_STOP;
diff --git a/src/channel.c b/src/channel.c
index 4aa32fd..82f0016 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -22,7 +22,7 @@
#include <ctype.h>
#include <wchar.h>
-#ifdef ANDROID
+#ifdef __ANDROID__
#include "wakelock_internal.h"
#endif
@@ -32,10 +32,9 @@
#define BELLE_SIP_CHANNEL_INVOKE_SENDING_LISTENERS(channel,msg) \
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_sending, channel, msg)
-
#define BELLE_SIP_CHANNEL_INVOKE_STATE_LISTENERS(channel,state) \
- BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state) \
- BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(channel->state_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state)
+ BELLE_SIP_INVOKE_LISTENERS_REVERSE_ARG1_ARG2(channel->full_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state) \
+ BELLE_SIP_INVOKE_LISTENERS_REVERSE_ARG1_ARG2(channel->state_listeners, belle_sip_channel_listener_t, on_state_changed, channel, state)
static void channel_prepare_continue(belle_sip_channel_t *obj);
@@ -126,6 +125,10 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer);
belle_sip_object_unref(obj->inactivity_timer);
}
+ if (obj->dns_ttl_timer) {
+ belle_sip_main_loop_remove_source(obj->stack->ml, obj->dns_ttl_timer);
+ belle_sip_object_unref(obj->dns_ttl_timer);
+ }
if (obj->public_ip) belle_sip_free(obj->public_ip);
if (obj->outgoing_messages) belle_sip_list_free_with_data(obj->outgoing_messages,belle_sip_object_unref);
if (obj->incoming_messages) belle_sip_list_free_with_data(obj->incoming_messages,belle_sip_object_unref);
@@ -371,9 +374,10 @@ static int check_body(belle_sip_channel_t *obj){
obj->input_stream.content_length= content_length_header ? belle_sip_header_content_length_get_content_length(content_length_header) : 0;
- if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg,belle_sip_response_t) || BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg,belle_sip_request_t)){
- expect_body=obj->input_stream.content_length>0;
- }else{/*http*/
+ expect_body=obj->input_stream.content_length>0;
+
+ if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg,belle_http_response_t) || BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg,belle_http_request_t)){
+ /*http chunked mode handling*/
if (belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t)!=NULL){
belle_sip_header_t *transfer_encoding=belle_sip_message_get_header(msg,"Transfer-Encoding");
@@ -1012,6 +1016,12 @@ static void belle_sip_channel_handle_error(belle_sip_channel_t *obj){
int belle_sip_channel_notify_timeout(belle_sip_channel_t *obj){
const int too_long=60;
+
+ if (obj->state != BELLE_SIP_CHANNEL_READY){
+ /*no need to notify the timeout if the channel is already in error or retry state*/
+ return FALSE;
+ }
+
if ((int)(belle_sip_time_ms() - obj->last_recv_time) >= (too_long * 1000)){
belle_sip_message("A timeout related to this channel occured and no message received during last %i seconds. This channel is suspect, moving to error state",too_long);
channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
@@ -1373,8 +1383,9 @@ static void channel_process_queue(belle_sip_channel_t *obj){
belle_sip_message_t *msg;
belle_sip_object_ref(obj);/* we need to ref ourself because code below may trigger our destruction*/
- if (obj->out_state!=OUTPUT_STREAM_IDLE)
+ if (obj->out_state!=OUTPUT_STREAM_IDLE) {
_send_message(obj);
+ }
while((msg=channel_pop_outgoing(obj))!=NULL && obj->state==BELLE_SIP_CHANNEL_READY && obj->out_state==OUTPUT_STREAM_IDLE) {
send_message(obj, msg);
@@ -1411,16 +1422,57 @@ void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr
channel_process_queue(obj);
}
-static void channel_res_done(void *data, const char *name, struct addrinfo *ai_list){
+static int channel_dns_ttl_timeout(void *data, unsigned int event) {
+ belle_sip_channel_t *obj = (belle_sip_channel_t *)data;
+ belle_sip_message("Channel [%p]: DNS TTL timeout reached.", obj);
+ obj->dns_ttl_timedout = TRUE;
+ return BELLE_SIP_STOP;
+}
+
+static bool_t addrinfo_in_list(const struct addrinfo *ai, const struct addrinfo *list) {
+ const struct addrinfo *item = list;
+ bool_t in_list = FALSE;
+ while (item != NULL) {
+ if ((ai->ai_family == item->ai_family) && (bctbx_sockaddr_equals(ai->ai_addr, item->ai_addr))) {
+ in_list = TRUE;
+ break;
+ }
+ item = item->ai_next;
+ }
+ return in_list;
+}
+
+static void channel_res_done(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
belle_sip_channel_t *obj=(belle_sip_channel_t*)data;
if (obj->resolver_ctx){
belle_sip_object_unref(obj->resolver_ctx);
obj->resolver_ctx=NULL;
}
if (ai_list){
- obj->peer_list=obj->current_peer=ai_list;
- channel_set_state(obj,BELLE_SIP_CHANNEL_RES_DONE);
+ if (!obj->current_peer) {
+ obj->peer_list=obj->current_peer=ai_list;
+ channel_set_state(obj,BELLE_SIP_CHANNEL_RES_DONE);
+ } else {
+ if (addrinfo_in_list(obj->current_peer, ai_list)) {
+ belle_sip_message("channel[%p]: DNS resolution returned the currently used address, continue using it", obj);
+ obj->peer_list = ai_list;
+ channel_set_state(obj, BELLE_SIP_CHANNEL_READY);
+ } else {
+ belle_sip_message("channel[%p]: DNS resolution returned an address different than the one being used, reconnect to the new address", obj);
+ obj->peer_list = obj->current_peer = ai_list;
+ belle_sip_channel_close(obj);
+ belle_sip_main_loop_do_later(obj->stack->ml, (belle_sip_callback_t)channel_connect_next, belle_sip_object_ref(obj));
+ channel_set_state(obj, BELLE_SIP_CHANNEL_RETRY);
+ }
+ }
channel_prepare_continue(obj);
+ if (!obj->dns_ttl_timer ) {
+ obj->dns_ttl_timer = belle_sip_main_loop_create_timeout(obj->stack->ml, channel_dns_ttl_timeout, obj, ttl * 1000, "Channel DNS TTL timer");
+ } else {
+ /* Restart the timer for new period. */
+ belle_sip_source_set_timeout(obj->dns_ttl_timer, ttl * 1000);
+ belle_sip_main_loop_add_source(obj->stack->ml, obj->dns_ttl_timer);
+ }
}else{
belle_sip_error("%s: DNS resolution failed for %s", __FUNCTION__, name);
channel_set_state(obj,BELLE_SIP_CHANNEL_ERROR);
@@ -1531,7 +1583,14 @@ belle_sip_channel_t *belle_sip_channel_find_from_list(belle_sip_list_t *l, int a
return chan;
}
-#ifdef ANDROID
+void belle_sip_channel_check_dns_reusability(belle_sip_channel_t *obj) {
+ if (obj->dns_ttl_timedout) {
+ obj->dns_ttl_timedout = FALSE;
+ belle_sip_channel_resolve(obj);
+ }
+}
+
+#ifdef __ANDROID__
unsigned long belle_sip_begin_background_task(const char *name, belle_sip_background_task_end_callback_t cb, void *data){
return wake_lock_acquire(name);
diff --git a/src/channel.h b/src/channel.h
index f88e7ec..efcb302 100644
--- a/src/channel.h
+++ b/src/channel.h
@@ -112,6 +112,7 @@ struct belle_sip_channel{
belle_sip_channel_input_stream_t input_stream;
belle_sip_list_t* incoming_messages;
belle_sip_source_t *inactivity_timer;
+ belle_sip_source_t *dns_ttl_timer;
uint64_t last_recv_time;
int simulated_recv_return; /* used to simulate network error. 0= no data (disconnected) >0= do nothing -1= network error, 1500 special number to silently discard incoming buffer*/
unsigned long bg_task_id;
@@ -124,6 +125,7 @@ struct belle_sip_channel{
unsigned char soft_error; /*set when this channel enters ERROR state because of error detected in upper layer */
int stop_logging_buffer; /*log buffer content only if this is non binary data, and stop it at the first occurence*/
bool_t closed_by_remote; /*If the channel has been remotely closed*/
+ bool_t dns_ttl_timedout;
};
#define BELLE_SIP_CHANNEL(obj) BELLE_SIP_CAST(obj,belle_sip_channel_t)
@@ -205,7 +207,12 @@ void belle_sip_channel_force_close(belle_sip_channel_t *obj);
int belle_sip_channel_notify_timeout(belle_sip_channel_t *obj);
/*Used by transaction layer to report a server having internal errors, so that we can retry with another IP (in case of DNS SRV)*/
-BELLESIP_INTERNAL_EXPORT void belle_sip_channel_notify_server_error(belle_sip_channel_t *obj);
+BELLESIP_EXPORT void belle_sip_channel_notify_server_error(belle_sip_channel_t *obj);
+
+/*
+ * Check if the DNS TTL has expired. If this is the case, set the channel status to RES_IN_PROGRESS.
+ */
+void belle_sip_channel_check_dns_reusability(belle_sip_channel_t *obj);
BELLE_SIP_END_DECLS
diff --git a/src/dialog.c b/src/dialog.c
index 35d223a..a7c8293 100644
--- a/src/dialog.c
+++ b/src/dialog.c
@@ -17,6 +17,7 @@
*/
#include "belle_sip_internal.h"
+#include <bctoolbox/defs.h>
static void belle_sip_dialog_init_200Ok_retrans(belle_sip_dialog_t *obj, belle_sip_response_t *resp);
static int belle_sip_dialog_handle_200Ok(belle_sip_dialog_t *obj, belle_sip_response_t *msg);
@@ -54,7 +55,7 @@ static void belle_sip_dialog_uninit(belle_sip_dialog_t *obj){
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_dialog_t);
-BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_dialog_t)
+BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_dialog_t)
BELLE_SIP_VPTR_INIT(belle_sip_dialog_t, belle_sip_object_t,TRUE),
(belle_sip_object_destroy_t)belle_sip_dialog_uninit,
NULL,
@@ -146,7 +147,7 @@ static int belle_sip_dialog_init_as_uas(belle_sip_dialog_t *obj, belle_sip_reque
/*remote party already set */
obj->local_party=(belle_sip_header_address_t*)belle_sip_object_ref(to);
-
+
return 0;
}
@@ -180,7 +181,7 @@ static int belle_sip_dialog_init_as_uac(belle_sip_dialog_t *obj, belle_sip_reque
&& belle_sip_uri_is_secure(requri)){
obj->is_secure=TRUE;
}
-
+
obj->local_cseq=belle_sip_header_cseq_get_seq_number(cseq);
/*call id is already set */
/*local_tag is already set*/
@@ -189,7 +190,7 @@ static int belle_sip_dialog_init_as_uac(belle_sip_dialog_t *obj, belle_sip_reque
if (strcmp(belle_sip_request_get_method(req),"INVITE")==0){
set_last_out_invite(obj,req);
}
-
+
return 0;
}
@@ -208,7 +209,7 @@ int belle_sip_dialog_expired(const belle_sip_dialog_t *dialog){
static int belle_sip_dialog_schedule_expiration(belle_sip_dialog_t *dialog, belle_sip_message_t *request){
belle_sip_header_expires_t *expires = belle_sip_message_get_header_by_type(request, belle_sip_header_expires_t);
int expires_value;
-
+
if (!expires) return BELLE_SIP_CONTINUE;
expires_value = belle_sip_header_expires_get_expires(expires);
if (dialog->expiration_timer){
@@ -218,7 +219,7 @@ static int belle_sip_dialog_schedule_expiration(belle_sip_dialog_t *dialog, bell
}
belle_sip_message("belle_sip_dialog_schedule_expiration() dialog=%p expires_value=%i", dialog, expires_value);
if (expires_value == 0) return BELLE_SIP_STOP;
- dialog->expiration_timer = belle_sip_main_loop_create_timeout(dialog->provider->stack->ml,
+ dialog->expiration_timer = belle_sip_main_loop_create_timeout(dialog->provider->stack->ml,
(belle_sip_source_func_t) belle_sip_dialog_on_expired,
dialog,
expires_value * 1000,
@@ -282,7 +283,7 @@ int belle_sip_dialog_establish(belle_sip_dialog_t *obj, belle_sip_request_t *req
belle_sip_error("No to in response.");
return -1;
}
-
+
if (!obj->is_server) {
belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
const belle_sip_list_t* elem;
@@ -301,7 +302,7 @@ int belle_sip_dialog_establish(belle_sip_dialog_t *obj, belle_sip_request_t *req
obj->route_set=belle_sip_list_prepend(obj->route_set,belle_sip_object_ref(belle_sip_header_route_create(
(belle_sip_header_address_t*)elem->data)));
}
-
+
check_route_set(obj->route_set);
/*via might be unknown at dialog creation*/
if (strcasecmp(belle_sip_header_via_get_protocol(via),"TLS")==0
@@ -360,11 +361,11 @@ static void belle_sip_dialog_init_200Ok_retrans(belle_sip_dialog_t *obj, belle_s
obj->timer_200Ok=belle_sip_timeout_source_new((belle_sip_source_func_t)dialog_on_200Ok_timer,obj,cfg->T1);
belle_sip_object_set_name((belle_sip_object_t*)obj->timer_200Ok,"dialog_200Ok_timer");
belle_sip_main_loop_add_source(obj->provider->stack->ml,obj->timer_200Ok);
-
+
obj->timer_200Ok_end=belle_sip_timeout_source_new((belle_sip_source_func_t)dialog_on_200Ok_end,obj,cfg->T1*64);
belle_sip_object_set_name((belle_sip_object_t*)obj->timer_200Ok_end,"dialog_200Ok_timer_end");
belle_sip_main_loop_add_source(obj->provider->stack->ml,obj->timer_200Ok_end);
-
+
obj->last_200Ok=(belle_sip_response_t*)belle_sip_object_ref(resp);
}
@@ -389,13 +390,13 @@ void belle_sip_dialog_stop_200Ok_retrans(belle_sip_dialog_t *obj){
/* returns true if the dialog is terminated by the NOTIFY request or response*/
static int belle_sip_dialog_should_terminate_by_notify(belle_sip_dialog_t *obj, belle_sip_transaction_t* transaction, int as_uas){
int should_terminate = FALSE;
-
+
if (obj->type == BELLE_SIP_DIALOG_SUBSCRIBE_NOTIFY) {
belle_sip_request_t *req=belle_sip_transaction_get_request(transaction);
belle_sip_response_t *resp=belle_sip_transaction_get_response(transaction);
belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t);
int code = resp ? belle_sip_response_get_status_code(resp) : 0;
-
+
if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) {
if (as_uas){
/*terminate the dialog when the application replies the 200 Ok*/
@@ -445,10 +446,10 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
int is_notify = strcmp(belle_sip_request_get_method(req),"NOTIFY")==0;
belle_sip_message("Dialog [%p]: now updated by transaction [%p].",obj, transaction);
-
+
if (resp)
code=belle_sip_response_get_status_code(resp);
-
+
if (as_uas && code == 491) { /**/
belle_sip_message("Dialog [%p]: don't update last transaction by transaction [%p].",obj, transaction);
} else {
@@ -460,7 +461,7 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
belle_sip_header_privacy_t *privacy_header=belle_sip_message_get_header_by_type(req,belle_sip_header_privacy_t);
SET_OBJECT_PROPERTY(obj,privacy,privacy_header);
}
-
+
/*first update local/remote cseq*/
if (as_uas) {
belle_sip_header_cseq_t* cseq=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_cseq_t);
@@ -470,7 +471,7 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
/*else ACK is handled by transaction, not dialog*/
}
-
+
switch (obj->state){
case BELLE_SIP_DIALOG_NULL:
/*always establish a dialog*/
@@ -480,7 +481,8 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
set_state(obj,BELLE_SIP_DIALOG_EARLY);
break;
}/* no break for code >200 because need to call belle_sip_dialog_establish_full*/
- }/* no break*/
+ }
+ BCTBX_NO_BREAK; /*intentionally no break*/
case BELLE_SIP_DIALOG_EARLY:
/*don't terminate dialog for UPDATE*/
if (code>=300 && (is_invite || is_subscribe)) {
@@ -524,7 +526,7 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
belle_sip_header_contact_t *ct;
if (as_uas){
ct=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t);
-
+
}else{
if (is_invite)
set_last_out_invite(obj,req);
@@ -533,7 +535,7 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
if (ct){
belle_sip_dialog_update_remote_target(obj, ct);
}
-
+
}
if (is_invite){
if (code>=200 && code<300){
@@ -590,7 +592,7 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
/*ignore*/
break;
}
-
+
end:
if (delete_dialog) belle_sip_dialog_delete(obj);
else {
@@ -617,7 +619,7 @@ belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
belle_sip_error("belle_sip_dialog_new(): no from tag!");
return NULL;
}
-
+
to = belle_sip_message_get_header_by_type(t->request,belle_sip_header_to_t);
if (to == NULL){
belle_sip_error("belle_sip_dialog_new(): no to in request!");
@@ -647,7 +649,7 @@ belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
obj->provider=t->provider;
obj->pending_trans_checking_enabled=1;
obj->call_id=(belle_sip_header_call_id_t*)belle_sip_object_ref(call_id);
-
+
if (strcmp(belle_sip_request_get_method(t->request),"INVITE") == 0){
obj->type = BELLE_SIP_DIALOG_INVITE;
}else if (strcmp(belle_sip_request_get_method(t->request),"SUBSCRIBE") == 0){
@@ -655,10 +657,10 @@ belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
}else{
belle_sip_error("belle_sip_dialog_new(): unsupported request [%s] for creating a dialog.", belle_sip_request_get_method(t->request));
}
-
+
belle_sip_object_ref(t);
obj->last_transaction=t;
-
+
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t)){
obj->remote_tag=belle_sip_strdup(from_tag);
obj->local_tag=belle_sip_strdup(BELLE_SIP_SERVER_TRANSACTION(t)->to_tag);
@@ -677,7 +679,7 @@ belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
}
belle_sip_dialog_init_as_uac(obj,belle_sip_transaction_get_request(t));
}
-
+
belle_sip_message("New %s dialog [%p] , local tag [%s], remote tag [%s]"
,obj->is_server?"server":"client"
@@ -692,7 +694,7 @@ belle_sip_request_t *belle_sip_dialog_create_ack(belle_sip_dialog_t *obj, unsign
belle_sip_header_cseq_t *cseqh;
belle_sip_request_t *invite=obj->last_out_invite;
belle_sip_request_t *ack;
-
+
if (!invite){
belle_sip_error("No INVITE to ACK.");
return NULL;
@@ -734,12 +736,12 @@ belle_sip_request_t *belle_sip_dialog_create_ack(belle_sip_dialog_t *obj, unsign
static belle_sip_request_t *create_request(belle_sip_dialog_t *obj, const char *method, int full){
belle_sip_request_t *req;
char* from_tag=NULL, *to_tag=NULL;
-
+
if (!obj->remote_target){
belle_sip_error("dialog [%p]: no remote_target set, unable to create request.", obj);
return NULL;
}
-
+
if (!belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(obj->local_party), "tag")) {
/*special case for dialog created by server transaction*/
from_tag = obj->local_tag;
@@ -757,7 +759,7 @@ static belle_sip_request_t *create_request(belle_sip_dialog_t *obj, const char *
belle_sip_header_to_create(obj->remote_party,to_tag),
belle_sip_header_via_new(),
0);
-
+
if (full && obj->route_set) {
belle_sip_message_add_headers((belle_sip_message_t*)req,obj->route_set);
}
@@ -784,7 +786,7 @@ static int dialog_can_create_request(belle_sip_dialog_t *obj, const char *method
belle_sip_request_t * belle_sip_dialog_create_queued_request(belle_sip_dialog_t *obj, const char *method){
belle_sip_request_t *req;
-
+
if (!dialog_can_create_request(obj, method)) return NULL;
if (strcmp(method,"INVITE")==0 || strcmp(method,"SUBSCRIBE")==0){
/*we don't allow requests that can update the dialog's state to be sent asynchronously*/
@@ -805,7 +807,7 @@ static void belle_sip_dialog_update_local_cseq(belle_sip_dialog_t *obj, const ch
belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, const char *method){
belle_sip_request_t *req;
-
+
if (!dialog_can_create_request(obj, method)) return NULL;
/*don't prevent to send a BYE in any case */
if ( obj->pending_trans_checking_enabled
@@ -819,7 +821,7 @@ belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, co
} /*else UPDATE transaction can be send in // */
}
belle_sip_dialog_update_local_cseq(obj,method);
-
+
req=create_request(obj,method,TRUE);
return req;
}
@@ -848,25 +850,25 @@ static belle_sip_request_t *_belle_sip_dialog_create_request_from(belle_sip_dial
const char *method=belle_sip_request_get_method(initial_req);
belle_sip_header_content_length_t* content_lenth;
belle_sip_list_t* headers;
-
+
if (queued) req=belle_sip_dialog_create_queued_request(obj,method);
else req=belle_sip_dialog_create_request(obj,method);
-
+
if (req==NULL) return NULL;
-
+
content_lenth = belle_sip_message_get_header_by_type(initial_req,belle_sip_header_content_length_t);
/*first copy non system headers*/
headers = belle_sip_message_get_all_headers(BELLE_SIP_MESSAGE(initial_req));
belle_sip_list_for_each2(headers,(void (*)(void *, void *))copy_non_system_headers,req);
belle_sip_list_free(headers);
-
+
/*replicate via user parameters, if any, useful for 'alias' parameter in SUBSCRIBE requests*/
{
belle_sip_header_via_t *orig_via=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(initial_req),belle_sip_header_via_t);
belle_sip_header_via_t *new_via=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_via_t);
belle_sip_parameters_copy_parameters_from(BELLE_SIP_PARAMETERS(new_via),BELLE_SIP_PARAMETERS(orig_via));
}
-
+
/*copy body*/
if (content_lenth && belle_sip_header_content_length_get_content_length(content_lenth)>0) {
belle_sip_message_set_body(BELLE_SIP_MESSAGE(req),belle_sip_message_get_body(BELLE_SIP_MESSAGE(initial_req)),belle_sip_header_content_length_get_content_length(content_lenth));
@@ -884,7 +886,7 @@ belle_sip_request_t *belle_sip_dialog_create_queued_request_from(belle_sip_dialo
void belle_sip_dialog_delete(belle_sip_dialog_t *obj){
size_t dropped_transactions;
-
+
if (obj->expiration_timer){
belle_sip_main_loop_remove_source(obj->provider->stack->ml, obj->expiration_timer);
belle_sip_object_unref(obj->expiration_timer);
@@ -990,7 +992,7 @@ int belle_sip_dialog_match(belle_sip_dialog_t *obj, belle_sip_message_t *msg, in
call_id_value=belle_sip_header_call_id_get_call_id(call_id);
from_tag=belle_sip_header_from_get_tag(from);
to_tag=belle_sip_header_to_get_tag(to);
-
+
return _belle_sip_dialog_match(obj,call_id_value,as_uas ? to_tag : from_tag, as_uas ? from_tag : to_tag);
}
@@ -999,7 +1001,7 @@ int _belle_sip_dialog_match(belle_sip_dialog_t *obj, const char *call_id, const
/*Dialog created by notify matching subscription are still in NULL state if (obj->state==BELLE_SIP_DIALOG_NULL) belle_sip_fatal("_belle_sip_dialog_match() must not be used for dialog in null state.");*/
dcid=belle_sip_header_call_id_get_call_id(obj->call_id);
return strcmp(dcid,call_id)==0
- && strcmp(obj->local_tag,local_tag)==0
+ && strcmp(obj->local_tag,local_tag)==0
&& obj->remote_tag /* handle 180 without to tag */ && strcmp(obj->remote_tag,remote_tag)==0;
}
@@ -1080,7 +1082,7 @@ int belle_sip_dialog_is_authorized_transaction(const belle_sip_dialog_t *dialog,
const char* last_transaction_request;
if (strcasecmp(method,"BYE")==0)
return TRUE; /*don't reject a BYE*/
-
+
last_transaction_request = belle_sip_request_get_method(belle_sip_transaction_get_request(dialog->last_transaction));
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(dialog->last_transaction,belle_sip_client_transaction_t)
&& strcmp(last_transaction_request,"SUBSCRIBE")==0 && strcmp(method,"NOTIFY")==0){
@@ -1103,9 +1105,9 @@ void belle_sip_dialog_queue_client_transaction(belle_sip_dialog_t *dialog, belle
static void _belle_sip_dialog_process_queue(belle_sip_dialog_t* dialog){
belle_sip_client_transaction_t *tr=NULL;
-
+
if (dialog->state==BELLE_SIP_DIALOG_TERMINATED || belle_sip_dialog_request_pending(dialog)) goto end;
-
+
dialog->queued_ct=belle_sip_list_pop_front(dialog->queued_ct,(void**)&tr);
if (tr){
belle_sip_message("Dialog [%p]: sending queued request.",dialog);
diff --git a/src/dns.c b/src/dns.c
index 7e766b5..0594e93 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -112,11 +112,12 @@
#include <resolv.h>
#endif
-#ifdef ANDROID
+#ifdef __ANDROID__
#include <sys/system_properties.h>
#endif
#include <bctoolbox/port.h>
+#include <bctoolbox/defs.h>
/*
* C O M P I L E R V E R S I O N & F E A T U R E D E T E C T I O N
@@ -243,7 +244,9 @@
#if DNS_GNUC_PREREQ(0,0,0) && !DNS_GNUC_PREREQ(4,6,0)
#define HAVE_STATIC_ASSERT 0 /* glibc doesn't check GCC version */
#else
-#define HAVE_STATIC_ASSERT (defined static_assert)
+#if (defined static_assert)
+#define HAVE_STATIC_ASSERT 1
+#endif
#endif
#endif
@@ -414,11 +417,15 @@ const char *dns_strerror(int error) {
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef HAVE___ATOMIC_FETCH_ADD
-#define HAVE___ATOMIC_FETCH_ADD (defined __ATOMIC_RELAXED)
+#if (defined __ATOMIC_RELAXED)
+#define HAVE___ATOMIC_FETCH_ADD 1
+#endif
#endif
#ifndef HAVE___ATOMIC_FETCH_SUB
-#define HAVE___ATOMIC_FETCH_SUB HAVE___ATOMIC_FETCH_ADD
+#if (defined __ATOMIC_RELAXED)
+#define HAVE___ATOMIC_FETCH_SUB 1
+#endif
#endif
#ifndef DNS_ATOMIC_FETCH_ADD
@@ -787,7 +794,9 @@ DNS_NOTUSED static size_t dns_strnlcpy(char *dst, size_t lim, const char *src, s
} /* dns_strnlcpy() */
-#define DNS_HAVE_SOCKADDR_UN (defined AF_UNIX && !defined _WIN32)
+#if (defined AF_UNIX && !defined _WIN32)
+#define DNS_HAVE_SOCKADDR_UN 1
+#endif
static size_t dns_af_len(int af) {
static const size_t table[AF_MAX] = {
@@ -4965,7 +4974,7 @@ int dns_resconf_loadwin(struct dns_resolv_conf *resconf) {
}
#endif /* dns_resconf_loadwin() */
-#ifdef ANDROID
+#ifdef __ANDROID__
int dns_resconf_loadandroid(struct dns_resolv_conf *resconf) {
char dns[PROP_VALUE_MAX];
char prop_name[PROP_NAME_MAX];
@@ -6261,11 +6270,15 @@ static void dns_socketclose(int *fd, const struct dns_options *opts) {
#endif
#ifndef HAVE_SOCK_CLOEXEC
-#define HAVE_SOCK_CLOEXEC (defined SOCK_CLOEXEC)
+#if (defined SOCK_CLOEXEC)
+#define HAVE_SOCK_CLOEXEC 1
+#endif
#endif
#ifndef HAVE_SOCK_NONBLOCK
-#define HAVE_SOCK_NONBLOCK (defined SOCK_NONBLOCK)
+#if (defined SOCK_NONBLOCK)
+#define HAVE_SOCK_NONBLOCK 1
+#endif
#endif
#define DNS_SO_MAXTRY 7
@@ -6285,7 +6298,7 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) {
#endif
if (-1 == (fd = socket(local->sa_family, type|flags, 0)))
goto soerr;
-
+
if (local->sa_family == AF_INET6){
int value=0;
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
@@ -6406,6 +6419,7 @@ struct dns_socket {
struct dns_packet *answer;
size_t alen, apos;
+ int ip_differ; /*set when remote address and response from which it is received are different*/
}; /* struct dns_socket */
@@ -6471,7 +6485,7 @@ static void dns_so_closefds(struct dns_socket *so, int which) {
static void dns_so_destroy(struct dns_socket *);
static struct dns_socket *dns_so_init(struct dns_socket *so, const struct sockaddr *local, int type, const struct dns_options *opts, int *error) {
- static const struct dns_socket so_initializer = { .opts = DNS_OPTS_INITIALIZER, .udp = -1, .tcp = -1, };
+ static const struct dns_socket so_initializer = { .opts = DNS_OPTS_INITIALIZER, .udp = -1, .tcp = -1};
*so = so_initializer;
so->type = type;
@@ -6736,8 +6750,9 @@ static int dns_so_tcp_recv(struct dns_socket *so) {
#endif
-int dns_so_check(struct dns_socket *so) {
- struct sockaddr_storage reset_ss;
+int dns_so_check(struct dns_socket *so) {
+ struct sockaddr_storage tmp_ss;
+ socklen_t tmp_ss_len = sizeof(tmp_ss);
int error;
long n;
@@ -6746,23 +6761,41 @@ retry:
case DNS_SO_UDP_INIT:
so->state++;
case DNS_SO_UDP_CONN:
- memset(&reset_ss, 0, sizeof(reset_ss));
- connect(so->udp, (struct sockaddr *)&reset_ss, sizeof(reset_ss)); // Reset the previous connection
- if (0 != connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote)))
- goto soerr;
+ memset(&tmp_ss, 0, sizeof(tmp_ss));
+ connect(so->udp, (struct sockaddr *)&tmp_ss, sizeof(tmp_ss)); // Reset the previous connection
+ if (so->opts.udp_uses_connect){
+ if (0 != connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote)))
+ goto soerr;
+ }
so->state++;
case DNS_SO_UDP_SEND:
- if (0 > (n = send(so->udp, (void *)so->query->data, so->query->end, 0)))
- goto soerr;
+ if (so->opts.udp_uses_connect){
+ if (0 > (n = send(so->udp, (void *)so->query->data, so->query->end, 0)))
+ goto soerr;
+ }else{
+ if (0 > (n = sendto(so->udp, (void *)so->query->data, so->query->end, 0, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote))))
+ goto soerr;
+ }
so->stat.udp.sent.bytes += n;
so->stat.udp.sent.count++;
so->state++;
case DNS_SO_UDP_RECV:
- if (0 > (n = recv(so->udp, (void *)so->answer->data, so->answer->size, 0)))
- goto soerr;
+ if (so->opts.udp_uses_connect){
+ if (0 > (n = recv(so->udp, (void *)so->answer->data, so->answer->size, 0)))
+ goto soerr;
+ }else{
+ memset(&tmp_ss, 0, sizeof(tmp_ss));
+ tmp_ss_len = sizeof(tmp_ss);
+ if (0 > (n = recvfrom(so->udp, (void *)so->answer->data, so->answer->size, 0, (struct sockaddr *)&tmp_ss, &tmp_ss_len)))
+ goto soerr;
+ if (memcmp(&tmp_ss, &so->remote, tmp_ss_len) != 0){
+ so->ip_differ = 1;
+ }
+
+ }
so->stat.udp.rcvd.bytes += n;
so->stat.udp.rcvd.count++;
@@ -8120,6 +8153,10 @@ void dns_res_enable_search(struct dns_resolver *res, unsigned char enable) {
res->search_enabled = enable;
}
+int dns_res_was_asymetric(struct dns_resolver *res){
+ return res->so.ip_differ;
+}
+
/*
* A D D R I N F O R O U T I N E S
@@ -10045,4 +10082,3 @@ int main(int argc, char **argv) {
#elif DNS_GNUC_PREREQ(4,6,0)
#pragma GCC diagnostic pop
#endif
-
diff --git a/src/dns.h b/src/dns.h
index d4b1dca..ac390ae 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -960,7 +960,7 @@ int dns_resconf_load_struct_res_state_nameservers(struct dns_resolv_conf *rescon
DNS_PUBLIC int dns_resconf_loadwin(struct dns_resolv_conf *);
#endif
-#ifdef ANDROID
+#ifdef __ANDROID__
DNS_PUBLIC int dns_resconf_loadandroid(struct dns_resolv_conf *resconf);
#endif
@@ -1098,6 +1098,7 @@ struct dns_options {
DNS_SYSPOLL,
DNS_LIBEVENT,
} events;
+ int udp_uses_connect;
}; /* struct dns_options */
@@ -1202,6 +1203,8 @@ DNS_PUBLIC void dns_res_sethints(struct dns_resolver *, struct dns_hints *);
DNS_PUBLIC void dns_res_enable_search(struct dns_resolver *, unsigned char enable);
+DNS_PUBLIC int dns_res_was_asymetric(struct dns_resolver *);
+
/*
* A D D R I N F O I N T E R F A C E
diff --git a/src/grammars/belle_sip_message.g b/src/grammars/belle_sip_message.g
index 92fa0fd..a77c1de 100644
--- a/src/grammars/belle_sip_message.g
+++ b/src/grammars/belle_sip_message.g
@@ -81,7 +81,7 @@ options {
#include "belle-sip/message.h"
#include "belle-sip/http-message.h"
#include "parserutils.h"
-BELLESIP_INTERNAL_EXPORT void belle_sip_header_address_set_quoted_displayname(belle_sip_header_address_t* address,const char* value);
+BELLESIP_EXPORT void belle_sip_header_address_set_quoted_displayname(belle_sip_header_address_t* address,const char* value);
}
@rulecatch
@@ -668,24 +668,43 @@ header_address returns [belle_sip_header_address_t* ret]
header_address_base[belle_sip_header_address_t* obj] returns [belle_sip_header_address_t* ret]
@init { $ret=obj; }
: ( name_addr_with_generic_uri[BELLE_SIP_HEADER_ADDRESS($ret)]
-| addr_spec_with_generic_uri[BELLE_SIP_HEADER_ADDRESS($ret)]) { if (!belle_sip_header_address_get_uri($ret)
- &&
- !belle_sip_header_address_get_absolute_uri(($ret))) {
- belle_sip_object_unref($ret);
- $ret=NULL;
- }
- };
+| addr_spec_with_generic_uri[BELLE_SIP_HEADER_ADDRESS($ret)]) { if (!belle_sip_header_address_get_uri($ret) && !belle_sip_header_address_get_absolute_uri(($ret))) {
+ belle_sip_object_unref($ret);
+ $ret=NULL;
+ }
+ };
catch [ANTLR3_RECOGNITION_EXCEPTION]
{
- belle_sip_object_unref($ret);
- $ret=NULL;
-}
+ belle_sip_debug("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
+ if ($ret) belle_sip_object_unref($ret);
+ $ret=NULL;
+}
+
+fast_header_address returns [belle_sip_header_address_t* ret]
+ at init { $ret=belle_sip_header_address_new(); }
+ : ( fast_name_addr_with_generic_uri[BELLE_SIP_HEADER_ADDRESS($ret)]
+ | fast_addr_spec_with_generic_uri[BELLE_SIP_HEADER_ADDRESS($ret)]) { if (!belle_sip_header_address_get_uri($ret) && !belle_sip_header_address_get_absolute_uri(($ret))) {
+ belle_sip_object_unref($ret);
+ $ret=NULL;
+ }
+ };
+catch [ANTLR3_RECOGNITION_EXCEPTION]
+{
+ belle_sip_debug("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
+ if ($ret) belle_sip_object_unref($ret);
+ $ret=NULL;
+}
+
name_addr[belle_sip_header_address_t* object]
: (lws? display_name[object])? sp_laquot addr_spec[object] raquot_sp;
name_addr_with_generic_uri[belle_sip_header_address_t* object]
: (lws? display_name[object])? sp_laquot addr_spec_with_generic_uri[object] raquot_sp;
+fast_name_addr_with_generic_uri[belle_sip_header_address_t* object]
+ : (lws? display_name[object])? sp_laquot fast_addr_spec_with_generic_uri[object] raquot_sp;
+
+
addr_spec[belle_sip_header_address_t* object]
: lws? uri {belle_sip_header_address_set_uri(object,$uri.ret);} lws?;//| absoluteURI;
@@ -702,6 +721,18 @@ addr_spec_with_generic_uri[belle_sip_header_address_t* object]
}}
) lws?;
+ fast_addr_spec_with_generic_uri[belle_sip_header_address_t* object]
+ : lws? ( fast_uri {belle_sip_header_address_set_uri(object,$fast_uri.ret);}
+ |
+ generic_uri { if ( strcasecmp(belle_generic_uri_get_scheme($generic_uri.ret),"sip") != 0
+ && strcasecmp(belle_generic_uri_get_scheme($generic_uri.ret),"sips") != 0 ) {
+ belle_sip_header_address_set_absolute_uri(object,$generic_uri.ret);
+ } else {
+ belle_sip_message("Cannot parse a sip/sips uri as a generic uri");
+ belle_sip_object_unref($generic_uri.ret);
+ }}
+ ) lws?;
+
paramless_addr_spec[belle_sip_header_address_t* object]
: lws? paramless_uri {belle_sip_header_address_set_uri(object,$paramless_uri.ret);} lws? ;//| absoluteURI;
@@ -1508,8 +1539,107 @@ accept_sub_media_type {belle_sip_header_accept_set_subtype($header_accept::curre
accept_main_media_type: token;
accept_sub_media_type: token;
+//****************************Reason***********************************//
+/*
+Reason = "Reason" HCOLON reason-value *(COMMA reason-value)
+ reason-value = protocol *(SEMI reason-params)
+ protocol = "SIP" / "Q.850" / token
+ reason-params = protocol-cause / reason-text
+ / reason-extension
+ protocol-cause = "cause" EQUAL cause
+ cause = 1*DIGIT
+ reason-text = "text" EQUAL quoted-string
+ reason-extension = generic-param
+*/
+header_reason returns [belle_sip_header_reason_t* ret=NULL]
+scope { belle_sip_header_reason_t* current;belle_sip_header_reason_t* first; }
+ at init { $header_reason::current = NULL; $header_reason::first =NULL;}
+: {IS_TOKEN(Reason)}? token /*'Reason'*/ hcolon header_reason_param ( comma header_reason_param)* {$ret = $header_reason::first; };
+catch [ANTLR3_RECOGNITION_EXCEPTION]
+{
+ belle_sip_message("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
+ $ret = $header_reason::first;
+ if ($ret) belle_sip_object_unref($ret);
+ $ret=NULL;
+}
+header_reason_param
+scope { belle_sip_header_reason_t* prev;}
+ at init { if ($header_reason::current == NULL) {
+ $header_reason::first = $header_reason::current = belle_sip_header_reason_new();
+ $header_reason_param::prev=NULL;
+ } else {
+ belle_sip_header_t* header = BELLE_SIP_HEADER($header_reason::current);
+ $header_reason_param::prev=$header_reason::current;
+ belle_sip_header_set_next(header,(belle_sip_header_t*)($header_reason::current = belle_sip_header_reason_new()));
+ }
+ }
+ :header_reason_protocol {belle_sip_header_reason_set_protocol($header_reason::current,(const char*)$header_reason_protocol.text->chars);}
+ (semi generic_param [BELLE_SIP_PARAMETERS($header_reason::current)])*;
+header_reason_protocol
+ : token;
//*********************************************//
+
+/*
+AuthenticationInfo = "Authentication-Info" ":" auth-info
+ auth-info = 1#(nextnonce | [ message-qop ]
+ | [ response-auth ] | [ cnonce ]
+ | [nonce-count] )
+ nextnonce = "nextnonce" "=" nonce-value
+ response-auth = "rspauth" "=" response-digest
+ response-digest = <"> *LHEX <">
+*/
+
+header_authentication_info returns [belle_sip_header_authentication_info_t* ret=NULL]
+scope { belle_sip_header_authentication_info_t* current; }
+ at init {$header_authentication_info::current = belle_sip_header_authentication_info_new(); $ret=$header_authentication_info::current; }
+ : {IS_TOKEN( Authentication-Info)}? token /*' Authentication-Info'*/ hcolon auth_info ( comma auth_info)*;
+ catch [ANTLR3_RECOGNITION_EXCEPTION]
+{
+ belle_sip_message("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
+ belle_sip_object_unref($header_authentication_info::current);
+ $ret=NULL;
+}
+ auth_info
+ :
+ ( next_nonce { belle_sip_header_authentication_info_set_next_nonce($header_authentication_info::current,(char*)$next_nonce.ret);
+ belle_sip_free($next_nonce.ret);
+ }
+ |cnonce{
+ belle_sip_header_authentication_info_set_cnonce($header_authentication_info::current,(char*)$cnonce.ret);
+ belle_sip_free($cnonce.ret);
+ }
+ | authentication_info_message_qop{
+ belle_sip_header_authentication_info_set_qop($header_authentication_info::current,$authentication_info_message_qop.ret);
+ }
+ |nonce_count{
+ belle_sip_header_authentication_info_set_nonce_count($header_authentication_info::current,atoi((char*)$nonce_count.ret));
+ }
+ |rspauth {
+ belle_sip_header_authentication_info_set_rsp_auth($header_authentication_info::current,$rspauth.ret);
+ belle_sip_free($rspauth.ret);
+ }) ;
+
+qop_token
+ : {IS_TOKEN(qop)}? token/*'qop'*/;
+/*as defined by 3261*/
+authentication_info_message_qop returns [const char* ret=NULL]
+ : qop_token equal token { $ret = (const char*)$token.text->chars;};
+
+rspauth returns [char* ret=NULL]
+ : {IS_TOKEN(rspauth)}? token /*'nonce'*/ equal quoted_string{
+ $ret = _belle_sip_str_dup_and_unquote_string((char*)$quoted_string.text->chars);
+ };
+next_nonce returns [char* ret=NULL]
+ : {IS_TOKEN(nextnonce)}? token /*'nonce'*/ equal nonce_value{
+ $ret = _belle_sip_str_dup_and_unquote_string((char*)$nonce_value.text->chars);
+ };
+
+quoted_algorithm returns [char* ret=NULL]
+ : {IS_TOKEN(nextnonce)}? token /*'nonce'*/ equal nonce_value{
+ $ret = _belle_sip_str_dup_and_unquote_string((char*)$nonce_value.text->chars);
+ };
+//**********************************************//
header returns [belle_sip_header_t* ret=NULL]
: header_extension_base[FALSE] {$ret=$header_extension_base.ret;};
@@ -1575,6 +1705,20 @@ catch [ANTLR3_RECOGNITION_EXCEPTION]
$ret=NULL;
}
+fast_uri returns [belle_sip_uri_t* ret=NULL]
+scope { belle_sip_uri_t* current; }
+ at init { $fast_uri::current = belle_sip_uri_new(); }
+ : sip_schema[$fast_uri::current] ( ((userinfo[NULL])=>userinfo[$fast_uri::current] fast_hostport[$fast_uri::current]) | fast_hostport[$fast_uri::current] )
+ uri_parameters[$fast_uri::current]?
+ headers[$fast_uri::current]? {$ret = $fast_uri::current;};
+catch [ANTLR3_RECOGNITION_EXCEPTION]
+{
+ belle_sip_message("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
+ belle_sip_object_unref($fast_uri::current);
+ $ret=NULL;
+}
+
+
sip_token: {IS_TOKEN(sip)}? token;
sips_token: {IS_TOKEN(sips)}? token;
@@ -1604,6 +1748,12 @@ scope { belle_sip_uri_t* current; }
@init {$hostport::current=uri;}
: host ( COLON port {belle_sip_uri_set_port($hostport::current,$port.ret);})? {belle_sip_uri_set_host($hostport::current,$host.ret);};
+fast_hostport[belle_sip_uri_t* uri]
+scope { belle_sip_uri_t* current; }
+ at init {$fast_hostport::current=uri;}
+ : fast_host ( COLON port {belle_sip_uri_set_port($fast_hostport::current,$port.ret);})? {belle_sip_uri_set_host($fast_hostport::current,$fast_host.ret);};
+
+
uri_parameters[belle_sip_uri_t* uri]
scope { belle_sip_uri_t* current; }
@init {$uri_parameters::current=uri;}
@@ -1660,9 +1810,19 @@ hvalue : ( hnv_unreserved | unreserved | escaped )+;
hnv_unreserved : LSBRAQUET | RSBRAQUET | SLASH | QMARK | COLON | PLUS | DOLLARD ;
-//****************SIP end**********************/
-
+
+
+
+fast_host returns [const char* ret]
+scope { const char* current; }
+ at init {$fast_host::current=$ret=NULL;}
+ : (fast_hostname {$fast_host::current=(const char *)$fast_hostname.text->chars;}
+ /*| ipv4address {$fast_host::current=(const char *)$ipv4address.text->chars;} because cannot discriminate quickly betwenn 192.168.0.1 and 192.168.0.com*/
+ | ipv6reference {$fast_host::current=(const char *)$ipv6reference.ret;}) {$ret=$fast_host::current;};
+
+fast_hostname: alphanum ( alphanum | DASH | DOT )*;
+
//*************************common tokens*******************************/
user_unreserved : AND | EQUAL | PLUS | DOLLARD | COMMA | SEMI | QMARK | SLASH;
@@ -1671,14 +1831,14 @@ scope { const char* current; }
@init {$host::current=$ret=NULL;}
: (hostname {$host::current=(const char *)$hostname.text->chars;}
| ipv4address {$host::current=(const char *)$ipv4address.text->chars;}
- | ipv6reference ) {$ret=$host::current;};
+ | ipv6reference {$host::current=(const char *)$ipv6reference.ret;}) {$ret=$host::current;};
hostname : ( domainlabel DOT )* (toplabel)=>toplabel DOT? ;
domainlabel : alphanum | (alphanum ( alphanum | DASH )* alphanum) ;
toplabel : alpha | (alpha ( DASH? alphanum)+) ;
ipv4address : three_digit DOT three_digit DOT three_digit DOT three_digit ;
-ipv6reference : LSBRAQUET ipv6address RSBRAQUET {$host::current=(const char *)$ipv6address.text->chars;};
+ipv6reference returns [const char* ret=NULL] : LSBRAQUET ipv6address RSBRAQUET {$ret=(const char *)$ipv6address.text->chars;};
ipv6address : hexpart ( COLON ipv4address )? ;
hexpart : hexseq | hexseq COLON COLON ( hexseq )? | COLON COLON ( hexseq )?;
hexseq : hex4 ( COLON hex4)*;
diff --git a/src/http-provider.c b/src/http-provider.c
index 29a07e8..09d65cb 100644
--- a/src/http-provider.c
+++ b/src/http-provider.c
@@ -17,6 +17,8 @@
*/
+#include <bctoolbox/defs.h>
+
#include "belle_sip_internal.h"
typedef struct belle_http_channel_context belle_http_channel_context_t;
@@ -266,6 +268,7 @@ static void channel_state_changed(belle_sip_channel_listener_t *obj, belle_sip_c
break;
case BELLE_SIP_CHANNEL_ERROR:
http_channel_context_handle_io_error(ctx, chan);
+ BCTBX_NO_BREAK; /*intentionally no break*/
case BELLE_SIP_CHANNEL_DISCONNECTED:
if (!chan->force_close) provider_remove_channel(ctx->provider,chan);
break;
@@ -492,7 +495,7 @@ int belle_http_provider_set_tls_crypto_config(belle_http_provider_t *obj, belle_
void belle_http_provider_set_recv_error(belle_http_provider_t *obj, int recv_error) {
belle_sip_list_t *it;
-
+
for(it=obj->tcp_channels;it!=NULL;it=it->next){
belle_sip_channel_t *chan = (belle_sip_channel_t*)it->data;
chan->simulated_recv_return=recv_error;
@@ -504,4 +507,3 @@ void belle_http_provider_set_recv_error(belle_http_provider_t *obj, int recv_err
chan->base.notify_required=(recv_error<=0);
}
}
-
diff --git a/src/ict.c b/src/ict.c
index e6a3eb6..4d8443a 100644
--- a/src/ict.c
+++ b/src/ict.c
@@ -16,10 +16,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/**
+/**
* INVITE client transaction implementation.
**/
+#include <bctoolbox/defs.h>
+
#include "belle_sip_internal.h"
@@ -104,7 +106,7 @@ static void ict_on_response(belle_sip_ict_t *obj, belle_sip_response_t *resp){
switch (base->state){
case BELLE_SIP_TRANSACTION_CALLING:
belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_PROCEEDING);
- /* no break*/
+ BCTBX_NO_BREAK; /*intentionally no break*/
case BELLE_SIP_TRANSACTION_PROCEEDING:
if (code>=300){
belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_COMPLETED);
@@ -140,6 +142,8 @@ static void ict_on_response(belle_sip_ict_t *obj, belle_sip_response_t *resp){
static int ict_on_timer_A(belle_sip_ict_t *obj){
belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
+ if (!base->channel) return BELLE_SIP_STOP;
+
switch(base->state){
case BELLE_SIP_TRANSACTION_CALLING:
{
@@ -152,7 +156,7 @@ static int ict_on_timer_A(belle_sip_ict_t *obj){
default:
break;
}
-
+
return BELLE_SIP_CONTINUE;
}
@@ -175,7 +179,7 @@ static void ict_send_request(belle_sip_ict_t *obj){
const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base);
belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_CALLING);
-
+
if (!belle_sip_channel_is_reliable(base->channel)){
obj->timer_A=belle_sip_timeout_source_new((belle_sip_source_func_t)ict_on_timer_A,obj,cfg->T1);
belle_sip_transaction_start_timer(base,obj->timer_A);
@@ -183,7 +187,7 @@ static void ict_send_request(belle_sip_ict_t *obj){
obj->timer_B=belle_sip_timeout_source_new((belle_sip_source_func_t)ict_on_timer_B,obj,cfg->T1*64);
belle_sip_transaction_start_timer(base,obj->timer_B);
-
+
belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->request);
}
@@ -212,4 +216,3 @@ belle_sip_ict_t *belle_sip_ict_new(belle_sip_provider_t *prov, belle_sip_request
belle_sip_client_transaction_init((belle_sip_client_transaction_t*)obj,prov,req);
return obj;
}
-
diff --git a/src/nist.c b/src/nist.c
index 46290cf..a3b2fc4 100644
--- a/src/nist.c
+++ b/src/nist.c
@@ -16,10 +16,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/**
+/**
* non-INVITE server transaction implementation.
**/
+#include <bctoolbox/defs.h>
+
#include "belle_sip_internal.h"
static void nist_on_terminate(belle_sip_nist_t *obj){
@@ -63,7 +65,7 @@ static int nist_send_new_response(belle_sip_nist_t *obj, belle_sip_response_t *r
belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)resp);
break;
}
- /* no break nist can directly pass from TRYING to PROCEEDING*/
+ BCTBX_NO_BREAK; /* no break nist can directly pass from TRYING to PROCEEDING*/
case BELLE_SIP_TRANSACTION_PROCEEDING:
if (code>=200){
nist_set_completed(obj);
diff --git a/src/parserutils.h b/src/parserutils.h
index 06fb725..9b756c5 100644
--- a/src/parserutils.h
+++ b/src/parserutils.h
@@ -20,9 +20,13 @@
#include "port.h"
+static BELLESIP_INLINE int belle_sip_strcasecmp(const char*a, const char* b) {
+ if (!a || !b) return 0;
+ return strcasecmp(a,b) == 0;
+}
+
#define IS_TOKEN(token) \
- (INPUT->toStringTT(INPUT,LT(1),LT(strlen(#token)))->chars ?\
- strcasecmp(#token,(const char*)(INPUT->toStringTT(INPUT,LT(1),LT(strlen(#token)))->chars)) == 0:0)
+ belle_sip_strcasecmp(#token,(const char*)INPUT->toStringTT(INPUT,LT(1),LT(strlen(#token)))->chars)
#define IS_HEADER_NAMED(name,compressed_name) (IS_TOKEN(compressed_name) || IS_TOKEN(name))
@@ -33,10 +37,10 @@
#define ANTLR3_LOG_EXCEPTION() belle_sip_message("[\%s] reason [\%s] at line[\%u] position[\%d]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message,EXCEPTION->line,EXCEPTION->charPositionInLine);
-BELLESIP_INTERNAL_EXPORT belle_sip_header_t* belle_sip_header_get_next(const belle_sip_header_t* headers);
-BELLESIP_INTERNAL_EXPORT void belle_sip_header_set_next(belle_sip_header_t* header,belle_sip_header_t* next);
+BELLESIP_EXPORT belle_sip_header_t* belle_sip_header_get_next(const belle_sip_header_t* headers);
+BELLESIP_EXPORT void belle_sip_header_set_next(belle_sip_header_t* header,belle_sip_header_t* next);
-BELLESIP_INTERNAL_EXPORT char* belle_sip_to_unescaped_string(const char* buff);
+BELLESIP_EXPORT char* belle_sip_to_unescaped_string(const char* buff);
belle_sip_param_pair_t* belle_sip_param_pair_new(const char* name,const char* value);
char* _belle_sip_str_dup_and_unquote_string(const char* quoted_string);
@@ -49,7 +53,7 @@ char* _belle_sip_str_dup_and_unquote_string(const char* quoted_string);
remove any \
* */
-BELLESIP_INTERNAL_EXPORT char* belle_sip_string_to_backslash_less_unescaped_string(const char* buff);
-BELLESIP_INTERNAL_EXPORT char* belle_sip_display_name_to_backslashed_escaped_string(const char* buff);
+BELLESIP_EXPORT char* belle_sip_string_to_backslash_less_unescaped_string(const char* buff);
+BELLESIP_EXPORT char* belle_sip_display_name_to_backslashed_escaped_string(const char* buff);
#endif
diff --git a/src/port.c b/src/port.c
index ba7d897..4056af9 100644
--- a/src/port.c
+++ b/src/port.c
@@ -191,7 +191,7 @@ int belle_sip_thread_key_delete(belle_sip_thread_key_t key){
current_thread_data = NULL;
return 0;
#else
- return TlsFree(key) ? 0 : -1;
+ return TlsFree((DWORD)key) ? 0 : -1;
#endif
}
@@ -244,7 +244,7 @@ int belle_sip_socket_set_dscp(belle_sip_socket_t sock, int ai_family, int dscp){
belle_sip_error("Cannot set DSCP because socket family is unspecified.");
return -1;
}
- retval = setsockopt(sock, proto, value_type, (const char*)&tos, sizeof(tos));
+ retval = bctbx_setsockopt(sock, proto, value_type, (const char*)&tos, sizeof(tos));
if (retval==-1)
belle_sip_error("Fail to set DSCP value on socket: %s",belle_sip_get_socket_error_string());
return retval;
@@ -255,9 +255,9 @@ int belle_sip_socket_set_dscp(belle_sip_socket_t sock, int ai_family, int dscp){
int belle_sip_socket_enable_dual_stack(belle_sip_socket_t sock){
int value=0;
- int err=setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
+ int err=bctbx_setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
if (err==-1){
- belle_sip_warning("belle_sip_socket_enable_dual_stack: setsockopt(IPV6_ONLY) failed: %s",belle_sip_get_socket_error_string());
+ belle_sip_warning("belle_sip_socket_enable_dual_stack: bctbx_setsockopt(IPV6_ONLY) failed: %s",belle_sip_get_socket_error_string());
}
return err;
}
diff --git a/src/port.h b/src/port.h
index 1b835d3..d80c48a 100644
--- a/src/port.h
+++ b/src/port.h
@@ -84,22 +84,12 @@
# endif
#endif
-#if defined(_WIN32) || defined(_WIN32) || defined(__WIN32) || defined(__WIN32__)
-#ifdef BELLESIP_INTERNAL_EXPORTS
-#define BELLESIP_INTERNAL_EXPORT __declspec(dllexport)
-#else
-#define BELLESIP_INTERNAL_EXPORT
-#endif
-#else
-#define BELLESIP_INTERNAL_EXPORT extern
-#endif
-
/*
* Socket abstraction layer
*/
-BELLESIP_INTERNAL_EXPORT int belle_sip_init_sockets(void);
-BELLESIP_INTERNAL_EXPORT void belle_sip_uninit_sockets(void);
+BELLESIP_EXPORT int belle_sip_init_sockets(void);
+BELLESIP_EXPORT void belle_sip_uninit_sockets(void);
int belle_sip_socket_set_nonblocking (belle_sip_socket_t sock);
int belle_sip_socket_set_dscp(belle_sip_socket_t sock, int ai_family, int dscp);
int belle_sip_socket_enable_dual_stack(belle_sip_socket_t sock);
@@ -166,7 +156,7 @@ typedef pthread_mutex_t belle_sip_mutex_t;
#endif
#ifndef BELLE_SIP_WINDOWS_DESKTOP
-BELLESIP_INTERNAL_EXPORT void belle_sip_sleep(unsigned int ms);
+BELLESIP_EXPORT void belle_sip_sleep(unsigned int ms);
#else
#define belle_sip_sleep Sleep
#endif
diff --git a/src/provider.c b/src/provider.c
index f73af8e..0cba9eb 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -20,8 +20,8 @@
#include "listeningpoint_internal.h"
#include "md5.h"
#include "belle-sip/message.h"
-
-typedef struct authorization_context {
+static void belle_sip_provider_update_or_create_auth_context(belle_sip_provider_t *p,belle_sip_header_call_id_t* call_id,belle_sip_header_www_authenticate_t* authenticate,belle_sip_uri_t *from_uri,const char* realm) ;
+struct authorization_context {
belle_sip_header_call_id_t* callid;
const char* scheme;
const char* realm;
@@ -32,7 +32,7 @@ typedef struct authorization_context {
const char* algorithm;
int nonce_count;
int is_proxy;
-}authorization_context_t;
+};
GET_SET_STRING(authorization_context,realm)
GET_SET_STRING(authorization_context,nonce)
@@ -49,7 +49,7 @@ static authorization_context_t* belle_sip_authorization_create(belle_sip_header_
belle_sip_object_ref(result->callid);
return result;
}
-static void belle_sip_authorization_destroy(authorization_context_t* object) {
+void belle_sip_authorization_destroy(authorization_context_t* object) {
DESTROY_STRING(object,scheme);
DESTROY_STRING(object,realm);
DESTROY_STRING(object,nonce);
@@ -210,7 +210,39 @@ static void belle_sip_provider_dispatch_response(belle_sip_provider_t* p, belle_
}
}
}
+ break;
}
+ default:
+ if (t!=NULL){
+ belle_sip_message_t* req = BELLE_SIP_MESSAGE(belle_sip_transaction_get_request((belle_sip_transaction_t*)t));
+ belle_sip_header_authentication_info_t *authentication_info = belle_sip_message_get_header_by_type(msg,belle_sip_header_authentication_info_t);
+ belle_sip_list_t *authorization_lst = NULL;
+ belle_sip_header_call_id_t *call_id = belle_sip_message_get_header_by_type(msg,belle_sip_header_call_id_t);
+ belle_sip_header_from_t *from = belle_sip_message_get_header_by_type(req,belle_sip_header_from_t);
+ belle_sip_uri_t *from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)from);
+ /*searching for authentication headers*/
+ authorization_lst = belle_sip_list_copy(belle_sip_message_get_headers(BELLE_SIP_MESSAGE(req),BELLE_SIP_AUTHORIZATION));
+ /*search for proxy authenticate*/
+ authorization_lst=belle_sip_list_concat(authorization_lst,belle_sip_list_copy(belle_sip_message_get_headers(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION)));
+ /*update auth contexts with authenticate headers from response*/
+ for (;authentication_info && authorization_lst!=NULL;authorization_lst=authorization_lst->next) {
+ belle_sip_header_authorization_t *authorization=BELLE_SIP_HEADER_AUTHORIZATION(authorization_lst->data);
+ belle_sip_header_www_authenticate_t *www_authenticate = belle_sip_auth_helper_create_www_authenticate(authorization);
+ belle_sip_header_www_authenticate_set_nonce(www_authenticate, belle_sip_header_authentication_info_get_next_nonce(authentication_info));
+ belle_sip_message( "Updating auth context for ream [%s] next nonce is going to be [%s]"
+ , belle_sip_header_www_authenticate_get_realm(www_authenticate)
+ , belle_sip_header_authentication_info_get_next_nonce(authentication_info));
+ belle_sip_provider_update_or_create_auth_context(p
+ , call_id
+ , www_authenticate
+ , from_uri
+ ,belle_sip_header_www_authenticate_get_realm(www_authenticate));
+ belle_sip_object_unref(www_authenticate);
+ }
+ if (authorization_lst)
+ belle_sip_list_free(authorization_lst);
+ }
+
}
if (t){ /*In some re-connection case, specially over udp, transaction may be found, but without associated channel*/
if (t->base.channel == NULL) {
@@ -801,7 +833,10 @@ belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, co
lp=(belle_sip_listening_point_t*)l->data;
if (strcasecmp(belle_sip_listening_point_get_transport(lp),hop->transport)==0){
chan=belle_sip_listening_point_get_channel(lp,hop);
- if (chan) return chan;
+ if (chan) {
+ belle_sip_channel_check_dns_reusability(chan);
+ return chan;
+ }
candidate=lp;
}
}
@@ -1013,6 +1048,7 @@ static void authorization_context_fill_from_auth(authorization_context_t* auth_c
}
}
+
static belle_sip_list_t* belle_sip_provider_get_auth_context_by_realm_or_call_id(belle_sip_provider_t *p,belle_sip_header_call_id_t* call_id,belle_sip_uri_t *from_uri,const char* realm) {
belle_sip_list_t* auth_context_lst=NULL;
belle_sip_list_t* result=NULL;
@@ -1089,6 +1125,7 @@ static void belle_sip_provider_update_or_create_auth_context(belle_sip_provider
return;
}
+
int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_request_t* request, belle_sip_response_t *resp,
belle_sip_uri_t *from_uri, belle_sip_list_t** auth_infos, const char* realm) {
belle_sip_header_call_id_t* call_id;
diff --git a/src/refresher.c b/src/refresher.c
index b01416b..46c04cb 100644
--- a/src/refresher.c
+++ b/src/refresher.c
@@ -16,6 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <bctoolbox/defs.h>
+
#include "belle_sip_internal.h"
#include "belle-sip/refresher.h"
@@ -111,7 +113,7 @@ static void process_dialog_terminated(belle_sip_listener_t *user_ctx, const bell
* so there is no need to reschedule a retry here.*/
belle_sip_warning("Refresher [%p] still started but expired, retrying",refresher);
if (refresher->listener) refresher->listener(refresher,refresher->user_data,481, "dialod terminated", TRUE);
-
+
}
}
@@ -258,7 +260,7 @@ static void process_response_event(belle_sip_listener_t *user_ctx, const belle_s
if (refresher->state==started) {
if (!refresher->first_acknoleged_request)
belle_sip_object_ref(refresher->first_acknoleged_request = request);
- if (is_contact_address_acurate(refresher,request)) {
+ if (is_contact_address_acurate(refresher,request) || !belle_sip_provider_nat_helper_enabled(client_transaction->base.provider)) {
schedule_timer(refresher); /*re-arm timer*/
} else {
belle_sip_message("belle_sip_refresher_start(): refresher [%p] is resubmitting request because contact sent was not correct in original request.",refresher);
@@ -336,7 +338,7 @@ static void process_response_event(belle_sip_listener_t *user_ctx, const belle_s
return; /*do not notify this kind of error*/
}
}
- /*intentionally no break*/
+ BCTBX_NO_BREAK; /*intentionally no break*/
case 505:
case 501:
/*irrecoverable errors, probably no need to retry later*/
@@ -534,8 +536,8 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
belle_sip_message_set_header((belle_sip_message_t*)request, (belle_sip_header_t*)belle_sip_provider_create_call_id(prov));
break;
- } /*else nop, error case*/
-
+ }
+ BCTBX_NO_BREAK; /*else nop, error case*/
}
default: {
belle_sip_error("Unexpected dialog state [%s] for dialog [%p], cannot refresh [%s]"
@@ -574,7 +576,7 @@ static int belle_sip_refresher_refresh_internal(belle_sip_refresher_t* refresher
client_transaction = belle_sip_provider_create_client_transaction(prov,request);
client_transaction->base.is_internal=1;
-
+
if (request == refresher->first_acknoleged_request) { /*request is now ref by transaction so no need to keepo it*/
belle_sip_object_unref(refresher->first_acknoleged_request);
refresher->first_acknoleged_request = NULL;
diff --git a/src/transaction.c b/src/transaction.c
index 17ffc46..08492fb 100644
--- a/src/transaction.c
+++ b/src/transaction.c
@@ -57,21 +57,23 @@ BELLESIP_EXPORT const char *belle_sip_transaction_get_method(const belle_sip_tra
static void transaction_end_background_task(belle_sip_transaction_t *obj){
if (obj->bg_task_id){
- belle_sip_message("channel [%p]: ending transaction background task with id=[%lx].",obj,obj->bg_task_id);
+ belle_sip_message("transaction [%p]: ending transaction background task with id=[%lx].",obj,obj->bg_task_id);
belle_sip_end_background_task(obj->bg_task_id);
obj->bg_task_id=0;
}
}
static void transaction_background_task_ended(belle_sip_transaction_t *obj){
- belle_sip_warning("channel [%p]: transaction background task has to be ended now, but work isn't finished.",obj);
+ belle_sip_warning("transaction [%p]: transaction background task has to be ended now, but work isn't finished.",obj);
transaction_end_background_task(obj);
}
static void transaction_begin_background_task(belle_sip_transaction_t *obj){
if (obj->bg_task_id==0){
- obj->bg_task_id=belle_sip_begin_background_task("belle-sip transaction",(void (*)(void*))transaction_background_task_ended, obj);
- if (obj->bg_task_id) belle_sip_message("channel [%p]: starting transaction background task with id=[%lx].",obj,obj->bg_task_id);
+ char *transaction = bctbx_strdup_printf("belle-sip transaction(%p)", obj);
+ obj->bg_task_id=belle_sip_begin_background_task(transaction,(void (*)(void*))transaction_background_task_ended, obj);
+ if (obj->bg_task_id) belle_sip_message("transaction [%p]: starting transaction background task with id=[%lx].",obj,obj->bg_task_id);
+ bctbx_free(transaction);
}
}
@@ -171,7 +173,7 @@ static void on_channel_state_changed(belle_sip_channel_listener_t *l, belle_sip_
t->channel = NULL;
}
belle_sip_object_unref(t);
-
+
break;
default:
/*ignored*/
@@ -277,7 +279,7 @@ void belle_sip_transaction_notify_timeout(belle_sip_transaction_t *t){
belle_sip_object_ref(t); /*take a ref in the case where the app calls belle_sip_transaction_terminate() within the timeout listener*/
if (strcmp(belle_sip_request_get_method(t->request),"REGISTER")==0){
if ( belle_sip_channel_notify_timeout(t->channel)==TRUE){
- belle_sip_warning("Transaction [%p] reporting timeout, reporting to channel.",t);
+ belle_sip_warning("Transaction [%p] has timeout, reported to channel.",t);
t->timed_out=TRUE;
}
}else {
@@ -489,13 +491,13 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
}
if (t->base.sent_by_dialog_queue){
-
+
/*it can be sent immediately, so update the request with latest cseq and route_set */
/*update route and contact just in case they changed*/
belle_sip_dialog_update_request(dialog,req);
} else if (t->base.request->dialog_queued){
/*this request was created by belle_sip_dialog_create_queued_request().*/
-
+
if (dialog == NULL){
belle_sip_error("belle_sip_client_transaction_send_request(): transaction [%p], cannot send"
" request because it was created in the context of a dialog that appears to be "
@@ -503,7 +505,7 @@ int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t
belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(t));
return -1;
}
-
+
if (belle_sip_dialog_request_pending(dialog) || dialog->queued_ct!=NULL){
/*it cannot be sent immediately, queue the transaction into dialog*/
belle_sip_message("belle_sip_client_transaction_send_request(): transaction [%p], cannot send request now because dialog [%p] is busy"
@@ -694,8 +696,8 @@ belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(b
contains a "Subscription-State" of "active" or "pending", it creates
a new subscription and a new dialog (unless they have already been
created by a matching response, as described above).
-
-
+
+
*/
int belle_sip_client_transaction_is_notify_matching_pending_subscribe(belle_sip_client_transaction_t *trans
@@ -704,32 +706,32 @@ int belle_sip_client_transaction_is_notify_matching_pending_subscribe(belle_sip_
belle_sip_header_event_t *sub_event, *notif_event;
belle_sip_header_call_id_t *sub_call_id, *notif_call_id;
const char* sub_from_tag, *notif_to_tag;
-
+
if (!belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(trans)))
|| strcmp("SUBSCRIBE", belle_sip_transaction_get_method(BELLE_SIP_TRANSACTION(trans)))!=0) return 0;
-
-
+
+
if (strcmp("NOTIFY",belle_sip_request_get_method(notify)) != 0) {
belle_sip_error("belle_sip_client_transaction_is_notify_matching_pending_subscribe for dialog [%p], requires a notify request",notify);
}
-
+
subscription = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(trans));
sub_event = belle_sip_message_get_header_by_type(subscription, belle_sip_header_event_t);
if (!sub_event || !belle_sip_header_event_get_package_name(sub_event))
return 0;
-
+
notif_event = belle_sip_message_get_header_by_type(notify, belle_sip_header_event_t);
if (!notif_event || !belle_sip_header_event_get_package_name(notif_event))
return 0;
-
+
sub_call_id = belle_sip_message_get_header_by_type(subscription, belle_sip_header_call_id_t);
notif_call_id = belle_sip_message_get_header_by_type(notify, belle_sip_header_call_id_t);
sub_from_tag = belle_sip_header_from_get_tag(belle_sip_message_get_header_by_type(subscription, belle_sip_header_from_t));
notif_to_tag = belle_sip_header_to_get_tag(belle_sip_message_get_header_by_type(notify, belle_sip_header_to_t));
-
+
return strcmp(belle_sip_header_call_id_get_call_id(sub_call_id),belle_sip_header_call_id_get_call_id(notif_call_id))==0
&& sub_from_tag && notif_to_tag && strcmp(sub_from_tag,notif_to_tag)==0
&& strcasecmp(belle_sip_header_event_get_package_name(sub_event),belle_sip_header_event_get_package_name(notif_event))==0;
-
+
}
diff --git a/src/transports/stream_channel.c b/src/transports/stream_channel.c
index c03539a..503bcef 100644
--- a/src/transports/stream_channel.c
+++ b/src/transports/stream_channel.c
@@ -22,7 +22,7 @@
static void set_tcp_nodelay(belle_sip_socket_t sock){
int tmp=1;
- int err=setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,(char*)&tmp,sizeof(tmp));
+ int err=bctbx_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,(char*)&tmp,sizeof(tmp));
if (err == -1){
belle_sip_warning ("Fail to set TCP_NODELAY: %s.", belle_sip_get_socket_error_string());
}
@@ -124,16 +124,16 @@ int stream_channel_connect(belle_sip_stream_channel_t *obj, const struct addrinf
tmp=1;
obj->base.ai_family=ai->ai_family;
- sock=socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
+ sock=bctbx_socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
if (sock==(belle_sip_socket_t)-1){
belle_sip_error("Could not create socket: %s",belle_sip_get_socket_error_string());
return -1;
}
- err=setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,(char*)&tmp,sizeof(tmp));
+ err=bctbx_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,(char*)&tmp,sizeof(tmp));
if (err!=0){
- belle_sip_error("setsockopt TCP_NODELAY failed: [%s]",belle_sip_get_socket_error_string());
+ belle_sip_error("bctbx_setsockopt TCP_NODELAY failed: [%s]",belle_sip_get_socket_error_string());
}
belle_sip_socket_set_nonblocking(sock);
if (ai->ai_family==AF_INET6){
@@ -187,14 +187,14 @@ int finalize_stream_connection(belle_sip_stream_channel_t *obj, unsigned int rev
return -1;
}
- err=getsockopt(sock,SOL_SOCKET,SO_ERROR,(void*)&errnum,&optlen);
+ err=bctbx_getsockopt(sock,SOL_SOCKET,SO_ERROR,(void*)&errnum,&optlen);
if (err!=0){
belle_sip_error("Failed to retrieve connection status for fd [%i]: cause [%s]",sock,belle_sip_get_socket_error_string());
return -1;
}else{
if (errnum==0){
/*obtain bind address for client*/
- err=getsockname(sock,addr,slen);
+ err=bctbx_getsockname(sock,addr,slen);
if (err<0){
belle_sip_error("Failed to retrieve sockname for fd [%i]: cause [%s]",sock,belle_sip_get_socket_error_string());
return -1;
@@ -261,7 +261,7 @@ belle_sip_channel_t * belle_sip_stream_channel_new_child(belle_sip_stack_t *stac
int err;
int optval=1;
- err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ err = bctbx_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char*)&optval, sizeof (optval));
if (err == -1){
belle_sip_warning ("Fail to set SIP/TCP address reusable: %s.", belle_sip_get_socket_error_string());
@@ -269,8 +269,8 @@ belle_sip_channel_t * belle_sip_stream_channel_new_child(belle_sip_stack_t *stac
set_tcp_nodelay(sock);
- if (getsockname(sock,(struct sockaddr*)&localaddr,&local_len)==-1){
- belle_sip_error("getsockname() failed: %s",belle_sip_get_socket_error_string());
+ if (bctbx_getsockname(sock,(struct sockaddr*)&localaddr,&local_len)==-1){
+ belle_sip_error("bctbx_getsockname() failed: %s",belle_sip_get_socket_error_string());
return NULL;
}
diff --git a/src/transports/stream_channel.h b/src/transports/stream_channel.h
index 169ae0b..12b2af4 100644
--- a/src/transports/stream_channel.h
+++ b/src/transports/stream_channel.h
@@ -43,7 +43,7 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_END
void belle_sip_stream_channel_init_client(belle_sip_stream_channel_t *obj, belle_sip_stack_t *stack, const char *bindip, int localport,const char *peer_cname, const char *dest, int port);
-BELLESIP_INTERNAL_EXPORT belle_sip_channel_t * belle_sip_stream_channel_new_client(belle_sip_stack_t *stack, const char *bindip, int localport, const char *peer_cname, const char *name, int port);
+BELLESIP_EXPORT belle_sip_channel_t * belle_sip_stream_channel_new_client(belle_sip_stack_t *stack, const char *bindip, int localport, const char *peer_cname, const char *name, int port);
belle_sip_channel_t * belle_sip_stream_channel_new_child(belle_sip_stack_t *stack, belle_sip_socket_t sock, struct sockaddr *remote_addr, socklen_t slen);
void stream_channel_close(belle_sip_stream_channel_t *obj);
@@ -55,5 +55,5 @@ int stream_channel_recv(belle_sip_stream_channel_t *obj, void *buf, size_t bufle
/*for testing purpose*/
-BELLESIP_INTERNAL_EXPORT void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream);
+BELLESIP_EXPORT void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream);
#endif /* STREAM_CHANNEL_H_ */
diff --git a/src/transports/stream_listeningpoint.c b/src/transports/stream_listeningpoint.c
index 13c89c1..3c33c13 100644
--- a/src/transports/stream_listeningpoint.c
+++ b/src/transports/stream_listeningpoint.c
@@ -70,6 +70,8 @@ static belle_sip_socket_t create_server_socket(const char *addr, int * port, int
if (*port==-1) *port=0; /*random port for bind()*/
+ belle_sip_set_socket_api(NULL);
+
snprintf(portnum,sizeof(portnum),"%i",*port);
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
@@ -81,13 +83,13 @@ static belle_sip_socket_t create_server_socket(const char *addr, int * port, int
return -1;
}
*family=res->ai_family;
- sock=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
+ sock=bctbx_socket(res->ai_family,res->ai_socktype,res->ai_protocol);
if (sock==(belle_sip_socket_t)-1){
belle_sip_error("Cannot create TCP socket: %s",belle_sip_get_socket_error_string());
freeaddrinfo(res);
return -1;
}
- err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ err = bctbx_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char*)&optval, sizeof (optval));
if (err == -1){
belle_sip_warning ("Fail to set SIP/TCP address reusable: %s.", belle_sip_get_socket_error_string());
@@ -108,14 +110,14 @@ static belle_sip_socket_t create_server_socket(const char *addr, int * port, int
if (*port==0){
struct sockaddr_storage saddr;
socklen_t saddr_len=sizeof(saddr);
- err=getsockname(sock,(struct sockaddr*)&saddr,&saddr_len);
+ err=bctbx_getsockname(sock,(struct sockaddr*)&saddr,&saddr_len);
if (err==0){
err=bctbx_getnameinfo((struct sockaddr*)&saddr,saddr_len,NULL,0,portnum,sizeof(portnum),NI_NUMERICSERV|NI_NUMERICHOST);
if (err==0){
*port=atoi(portnum);
belle_sip_message("Random TCP port is %i",*port);
}else belle_sip_error("TCP bind failed, getnameinfo(): %s",gai_strerror(err));
- }else belle_sip_error("TCP bind failed, getsockname(): %s",belle_sip_get_socket_error_string());
+ }else belle_sip_error("TCP bind failed, bctbx_getsockname(): %s",belle_sip_get_socket_error_string());
}
err=listen(sock,64);
diff --git a/src/transports/tls_channel.c b/src/transports/tls_channel.c
index e4a7d50..a5e2620 100644
--- a/src/transports/tls_channel.c
+++ b/src/transports/tls_channel.c
@@ -413,7 +413,7 @@ static int tls_channel_connect_to(belle_sip_channel_t *obj, const struct addrinf
return -1;
}
-static void http_proxy_res_done(void *data, const char *name, struct addrinfo *ai_list){
+static void http_proxy_res_done(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
belle_sip_tls_channel_t *obj=(belle_sip_tls_channel_t*)data;
if (obj->http_proxy_resolver_ctx){
belle_sip_object_unref(obj->http_proxy_resolver_ctx);
diff --git a/src/transports/udp_listeningpoint.c b/src/transports/udp_listeningpoint.c
index 2b27be2..55bb2aa 100644
--- a/src/transports/udp_listeningpoint.c
+++ b/src/transports/udp_listeningpoint.c
@@ -70,6 +70,9 @@ static belle_sip_socket_t create_udp_socket(const char *addr, int *port, int *fa
if (*port==-1) *port=0; /*random port for bind()*/
+ belle_sip_set_socket_api(NULL);
+
+
snprintf(portnum,sizeof(portnum),"%i",*port);
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_DGRAM;
@@ -81,13 +84,13 @@ static belle_sip_socket_t create_udp_socket(const char *addr, int *port, int *fa
return -1;
}
*family=res->ai_family;
- sock=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
+ sock=bctbx_socket(res->ai_family,res->ai_socktype,res->ai_protocol);
if (sock==-1){
belle_sip_error("Cannot create UDP socket: %s",belle_sip_get_socket_error_string());
freeaddrinfo(res);
return -1;
}
- err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ err = bctbx_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char*)&optval, sizeof (optval));
if (err == -1){
belle_sip_warning ("Fail to set SIP/UDP address reusable: %s.", belle_sip_get_socket_error_string());
@@ -96,7 +99,7 @@ static belle_sip_socket_t create_udp_socket(const char *addr, int *port, int *fa
belle_sip_socket_enable_dual_stack(sock);
}
- err=bctbx_bind(sock,res->ai_addr,(socklen_t)res->ai_addrlen);
+ err=bctbx_bind(sock,res->ai_addr,(socklen_t)res->ai_addrlen);
if (err==-1){
belle_sip_error("udp bind() failed for %s port %i: %s",addr,*port,belle_sip_get_socket_error_string());
belle_sip_close_socket(sock);
@@ -107,14 +110,14 @@ static belle_sip_socket_t create_udp_socket(const char *addr, int *port, int *fa
if (*port==0){
struct sockaddr_storage saddr;
socklen_t saddr_len=sizeof(saddr);
- err=getsockname(sock,(struct sockaddr*)&saddr,&saddr_len);
+ err=bctbx_getsockname(sock,(struct sockaddr*)&saddr,&saddr_len);
if (err==0){
err=bctbx_getnameinfo((struct sockaddr*)&saddr,saddr_len,NULL,0,portnum,sizeof(portnum),NI_NUMERICSERV|NI_NUMERICHOST);
if (err==0){
*port=atoi(portnum);
belle_sip_message("Random UDP port is %i",*port);
}else belle_sip_error("udp bind failed, getnameinfo(): %s",gai_strerror(err));
- }else belle_sip_error("udp bind failed, getsockname(): %s",belle_sip_get_socket_error_string());
+ }else belle_sip_error("udp bind failed, bctbx_getsockname(): %s",belle_sip_get_socket_error_string());
}
return sock;
}
diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt
index d0cd98d..fa16b09 100644
--- a/tester/CMakeLists.txt
+++ b/tester/CMakeLists.txt
@@ -41,6 +41,7 @@ set(SOURCE_FILES_C
belle_sip_tester.c
belle_sip_tester.h
belle_sip_uri_tester.c
+ belle_sip_fast_uri_tester.c
cast_test.c
register_tester.h
)
@@ -51,8 +52,8 @@ if (IOS)
endif()
string(REPLACE ";" " " LINK_FLAGS_STR "${LINK_FLAGS}")
-apply_compile_flags(SOURCE_FILES_C "CPP" "C")
-apply_compile_flags(SOURCE_FILES_OBJC "CPP" "OBJC")
+bc_apply_compile_flags(SOURCE_FILES_C STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
+bc_apply_compile_flags(SOURCE_FILES_OBJC STRICT_OPTIONS_CPP STRICT_OPTIONS_OBJC)
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
add_library(belle_sip_tester_static STATIC ${SOURCE_FILES_C})
@@ -110,8 +111,9 @@ else()
set(OBJECT_DESCRIBE_SOURCES describe.c)
- apply_compile_flags(OBJECT_DESCRIBE_SOURCES "CPP" "C")
+ bc_apply_compile_flags(OBJECT_DESCRIBE_SOURCES STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
add_executable(belle_sip_object_describe ${USE_BUNDLE} ${OBJECT_DESCRIBE_SOURCES})
+ set_target_properties(belle_sip_object_describe PROPERTIES LINKER_LANGUAGE CXX)
if(NOT "${LINK_FLAGS_STR}" STREQUAL "")
set_target_properties(belle_sip_object_describe PROPERTIES LINK_FLAGS "${LINK_FLAGS_STR}")
endif()
@@ -120,8 +122,9 @@ else()
set(PARSE_SOURCES parse.c)
- apply_compile_flags(PARSE_SOURCES "CPP" "C")
+ bc_apply_compile_flags(PARSE_SOURCES STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
add_executable(belle_sip_parse ${USE_BUNDLE} ${PARSE_SOURCES})
+ set_target_properties(belle_sip_parse PROPERTIES LINKER_LANGUAGE CXX)
if(NOT "${LINK_FLAGS_STR}" STREQUAL "")
set_target_properties(belle_sip_parse PROPERTIES LINK_FLAGS "${LINK_FLAGS_STR}")
endif()
diff --git a/tester/Makefile.am b/tester/Makefile.am
index bad6d64..45de779 100644
--- a/tester/Makefile.am
+++ b/tester/Makefile.am
@@ -3,6 +3,8 @@ if ENABLE_TESTS
noinst_PROGRAMS=belle_sip_tester belle_sip_object_describe belle_sip_parse belle_http_get belle_sip_resolve
+EXTRA_DIST= belle_sip_base_uri_tester.c
+
belle_sip_tester_SOURCES= \
auth_helper_tester.c \
belle_generic_uri_tester.c \
@@ -17,6 +19,7 @@ belle_sip_tester_SOURCES= \
belle_sip_resolver_tester.c \
belle_sip_tester.c belle_sip_tester.h\
belle_sip_uri_tester.c \
+ belle_sip_fast_uri_tester.c \
cast_test.c \
register_tester.h
diff --git a/tester/belle_sip_uri_tester.c b/tester/belle_sip_base_uri_tester.c
similarity index 98%
copy from tester/belle_sip_uri_tester.c
copy to tester/belle_sip_base_uri_tester.c
index 5b2abeb..20d3c91 100644
--- a/tester/belle_sip_uri_tester.c
+++ b/tester/belle_sip_base_uri_tester.c
@@ -39,7 +39,7 @@ static void testSIMPLEURI(void) {
static void testCOMPLEXURI(void) {
belle_sip_uri_t* L_tmp;
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto at titi.com:5060;transport=tcp");
+ belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto at 1titi.com:5060;transport=tcp");
char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
L_tmp = belle_sip_uri_parse(l_raw_uri);
@@ -48,7 +48,7 @@ static void testCOMPLEXURI(void) {
belle_sip_free(l_raw_uri);
BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto");
BC_ASSERT_EQUAL(belle_sip_uri_get_port(L_uri), 5060, int, "%d");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
+ BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "1titi.com");
BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "tcp");
belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
@@ -402,7 +402,7 @@ transp.-param (2) o - - o o o
lr-param -- o - - - o o
other-param -- o o o o o o
headers -- - - - o - o*/
-void testUriComponentsChecker(void) {
+static void testUriComponentsChecker(void) {
belle_sip_uri_t* uri = belle_sip_uri_parse("sip:hostonly");
BC_ASSERT_TRUE(belle_sip_uri_check_components_from_request_uri(uri));
belle_sip_object_unref(uri);
@@ -435,7 +435,7 @@ void testUriComponentsChecker(void) {
}
}
-void test_escaping_bad_chars(void){
+static void test_escaping_bad_chars(void){
char bad_uri[13] = { 'h', 'e', 'l', 'l', 'o', (char)0xa0, (char)0xc8, 'w', 'o', 'r', 'l', 'd', 0x0 };
char *escaped = belle_sip_uri_to_escaped_username(bad_uri);
const char *expected="hello%a0%c8world";
@@ -501,5 +501,3 @@ static test_t uri_tests[] = {
TEST_NO_TAG("Empty password", test_empty_password),
};
-test_suite_t sip_uri_test_suite = {"SIP URI", NULL, NULL, belle_sip_tester_before_each, belle_sip_tester_after_each,
- sizeof(uri_tests) / sizeof(uri_tests[0]), uri_tests};
diff --git a/tester/belle_sip_fast_uri_tester.c b/tester/belle_sip_fast_uri_tester.c
new file mode 100644
index 0000000..ef2e15f
--- /dev/null
+++ b/tester/belle_sip_fast_uri_tester.c
@@ -0,0 +1,62 @@
+
+/*
+ belle-sip - SIP (RFC3261) library.
+ Copyright (C) 2010 Belledonne Communications SARL
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "belle-sip/belle-sip.h"
+#include "belle_sip_tester.h"
+#include "belle_sip_internal.h"
+
+#include <inttypes.h>
+
+#define belle_sip_uri_parse belle_sip_fast_uri_parse
+
+/*test body*/
+#include "belle_sip_base_uri_tester.c"
+
+#undef belle_sip_uri_parse
+
+static void perf(void) {
+ uint64_t t1, t2, start=bctbx_get_cur_time_ms();
+ int i=0;
+ for (i=0;i<1000;i++) {
+ belle_sip_uri_t * uri = belle_sip_uri_parse("sip:+331231231231 at sip.exmaple.org;user=phone");
+ belle_sip_object_unref(uri);
+ }
+
+ t1 = bctbx_get_cur_time_ms() - start;
+ start=bctbx_get_cur_time_ms();
+ belle_sip_message("t1 = %" PRIu64 "",t1);
+
+ for (i=0;i<1000;i++) {
+ belle_sip_uri_t * uri = belle_sip_fast_uri_parse("sip:+331231231231 at sip.exmaple.org;user=phone");
+ belle_sip_object_unref(uri);
+ }
+ t2 = bctbx_get_cur_time_ms() - start;
+ belle_sip_message("t2 = %" PRIu64 "",t2);
+#ifdef __APPLE__ /*antlr3.4 seems much more sensitive to belle_sip_fast_uri_parse optimisation than 3.2, so reserving this test to apple platform where antlr3.2 is unlikely to be found*/
+ BC_ASSERT_GREATER(((float)(t1-t2))/(float)(t1), 0.4, float, "%f");
+#endif
+}
+static test_t tests[] ={TEST_NO_TAG("perf", perf)};
+
+
+test_suite_t fast_sip_uri_test_suite = {"FAST SIP URI", NULL, NULL, belle_sip_tester_before_each, belle_sip_tester_after_each,
+ sizeof(uri_tests) / sizeof(uri_tests[0]), uri_tests};
+
+test_suite_t perf_sip_uri_test_suite = {"FAST SIP URI 2", NULL, NULL, belle_sip_tester_before_each, belle_sip_tester_after_each,
+ sizeof(tests) / sizeof(tests[0]), tests};
diff --git a/tester/belle_sip_headers_tester.c b/tester/belle_sip_headers_tester.c
index 3a53b52..b0a019b 100644
--- a/tester/belle_sip_headers_tester.c
+++ b/tester/belle_sip_headers_tester.c
@@ -741,7 +741,7 @@ static void test_address_with_error_header(void) {
static void test_address_header(void) {
belle_sip_uri_t* L_uri;
char* L_raw;
- belle_sip_header_address_t* laddress = belle_sip_header_address_parse("\"toto\" <sip:liblinphone_tester at 81.56.11.2:5060>");
+ belle_sip_header_address_t* laddress = belle_sip_header_address_fast_parse("\"toto\" <sip:liblinphone_tester at 81.56.11.2:5060>");
BC_ASSERT_PTR_NOT_NULL(laddress);
L_raw = belle_sip_object_to_string(BELLE_SIP_OBJECT(laddress));
BC_ASSERT_PTR_NOT_NULL(L_raw);
@@ -768,6 +768,15 @@ static void test_address_header(void) {
BC_ASSERT_STRING_EQUAL("\"to\\to\"",belle_sip_header_address_get_displayname(laddress));
belle_sip_object_unref(BELLE_SIP_OBJECT(laddress));
+ laddress = belle_sip_header_address_parse("sips:example.com;transport=tls;maddr=sip1.example.com");
+ BC_ASSERT_PTR_NOT_NULL(laddress);
+ L_raw = belle_sip_object_to_string(BELLE_SIP_OBJECT(laddress));
+ BC_ASSERT_PTR_NOT_NULL(L_raw);
+ belle_sip_object_unref(BELLE_SIP_OBJECT(laddress));
+ laddress = belle_sip_header_address_parse(L_raw);
+ belle_sip_free(L_raw);
+ BC_ASSERT_STRING_EQUAL("sip1.example.com",belle_sip_uri_get_maddr_param(belle_sip_header_address_get_uri(laddress)));
+ belle_sip_object_unref(BELLE_SIP_OBJECT(laddress));
}
@@ -775,7 +784,7 @@ static void test_address_header(void) {
static void test_address_header_with_tel_uri(void) {
belle_generic_uri_t* L_uri;
char* L_raw;
- belle_sip_header_address_t* laddress = belle_sip_header_address_parse("\"toto\" <tel:123456>");
+ belle_sip_header_address_t* laddress = belle_sip_header_address_fast_parse("\"toto\" <tel:123456>");
BC_ASSERT_PTR_NOT_NULL(laddress);
L_raw = belle_sip_object_to_string(BELLE_SIP_OBJECT(laddress));
BC_ASSERT_PTR_NOT_NULL(L_raw);
@@ -791,6 +800,27 @@ static void test_address_header_with_tel_uri(void) {
belle_sip_object_unref(BELLE_SIP_OBJECT(laddress));
}
+static void test_address_header_with_urn(void) {
+ belle_generic_uri_t* L_uri;
+ char* L_raw;
+ belle_sip_header_address_t* laddress = belle_sip_header_address_fast_parse("urn:service:sos");
+ BC_ASSERT_PTR_NOT_NULL(laddress);
+ L_raw = belle_sip_object_to_string(BELLE_SIP_OBJECT(laddress));
+ BC_ASSERT_PTR_NOT_NULL(L_raw);
+ belle_sip_object_unref(BELLE_SIP_OBJECT(laddress));
+ laddress = belle_sip_header_address_parse(L_raw);
+ belle_sip_free(L_raw);
+
+ BC_ASSERT_PTR_NULL(belle_sip_header_address_get_displayname(laddress));
+ L_uri = belle_sip_header_address_get_absolute_uri(laddress);
+
+ BC_ASSERT_PTR_NOT_NULL(belle_generic_uri_get_scheme(L_uri));
+ BC_ASSERT_STRING_EQUAL(belle_generic_uri_get_scheme(L_uri), "urn");
+ BC_ASSERT_PTR_NOT_NULL(belle_generic_uri_get_opaque_part(L_uri));
+ BC_ASSERT_STRING_EQUAL(belle_generic_uri_get_opaque_part(L_uri), "service:sos");
+ belle_sip_object_unref(BELLE_SIP_OBJECT(laddress));
+}
+
static void test_very_long_address_header(void) {
belle_sip_uri_t* L_uri;
const char* raw = "<sip:jehan at sip.linphone.org"
@@ -1133,10 +1163,69 @@ static void test_accept_header(void) {
BC_ASSERT_PTR_NULL(belle_sip_header_accept_parse("nimportequoi"));
}
+static void test_reason_header(void) {
+ belle_sip_header_reason_t *L_tmp, *l_next;
+ belle_sip_header_reason_t* L_reason = BELLE_SIP_HEADER_REASON(belle_sip_header_create("Reason", "Q.850 ;cause=16 ;text=\"Busy Everywhere\""));
+ char* l_raw_header;
+
+ BC_ASSERT_STRING_EQUAL(belle_sip_header_reason_get_text(L_reason),"Busy Everywhere");
+ belle_sip_header_reason_set_text(L_reason, "Terminated");
+ l_raw_header = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_reason));
+
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_reason));
+ L_tmp = belle_sip_header_reason_parse(l_raw_header);
+ L_reason = BELLE_SIP_HEADER_REASON(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
+
+ BC_ASSERT_STRING_EQUAL(belle_sip_header_reason_get_text(L_reason),"Terminated");
+ BC_ASSERT_STRING_EQUAL(belle_sip_header_reason_get_protocol(L_reason),"Q.850");
+ BC_ASSERT_EQUAL(belle_sip_header_reason_get_cause(L_reason),16 , int,"%d");
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_reason));
+ belle_sip_free(l_raw_header);
+
+ L_reason = belle_sip_header_reason_parse("Reason: SIP ;cause=600 ;text=\"Busy Everywhere\", SIP ;cause=580 ;text=\"Precondition Failure\"");
+ l_next =BELLE_SIP_HEADER_REASON(belle_sip_header_get_next(BELLE_SIP_HEADER(L_reason)));
+ BC_ASSERT_PTR_NOT_NULL(l_next);
+ BC_ASSERT_EQUAL(belle_sip_header_reason_get_cause(l_next),580 , int,"%d");
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_reason));
+
+
+ BC_ASSERT_PTR_NULL(belle_sip_header_reason_parse("nimportequoi"));
+}
+static void test_authentication_info_header(void) {
+ belle_sip_header_authentication_info_t *L_tmp;
+ belle_sip_header_authentication_info_t* L_authentication_info = BELLE_SIP_HEADER_AUTHENTICATION_INFO(belle_sip_header_create("Authentication-Info"
+ , "nextnonce=\"47364c23432d2e131a5fb210812c\""
+ ", qop=auth"));
+ char* l_raw_header;
+
+ BC_ASSERT_STRING_EQUAL(belle_sip_header_authentication_info_get_next_nonce(L_authentication_info),"47364c23432d2e131a5fb210812c");
+ belle_sip_header_authentication_info_set_next_nonce(L_authentication_info, "31a5fb210812c47364c23432d2e1");
+ l_raw_header = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_authentication_info));
+
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_authentication_info));
+ L_tmp = belle_sip_header_authentication_info_parse(l_raw_header);
+ L_authentication_info = BELLE_SIP_HEADER_AUTHENTICATION_INFO(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
+
+ BC_ASSERT_STRING_EQUAL(belle_sip_header_authentication_info_get_next_nonce(L_authentication_info),"31a5fb210812c47364c23432d2e1");
+ BC_ASSERT_STRING_EQUAL(belle_sip_header_authentication_info_get_qop(L_authentication_info),"auth");
+
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_authentication_info));
+ belle_sip_free(l_raw_header);
+
+
+ L_authentication_info = belle_sip_header_authentication_info_parse("Authentication-Info:nextnonce=\"WRSE5VkUg7kOjnP5sBZZzsxrsOQ8Eyp6ZNttXIA=\", qop=auth , rspauth=\"5e8518291c1320989df6966405e0b3d1\", cnonce=\"05bc00e63a7794182f9425da9266d00d\", nc=00000001");
+ BC_ASSERT_EQUAL(belle_sip_header_authentication_info_get_nonce_count(L_authentication_info),1, int, "%i");
+ belle_sip_object_unref(BELLE_SIP_OBJECT(L_authentication_info));
+
+ BC_ASSERT_PTR_NULL(belle_sip_header_authentication_info_parse("nimportequoi"));
+}
test_t headers_tests[] = {
TEST_NO_TAG("Address", test_address_header),
TEST_NO_TAG("Address tel uri", test_address_header_with_tel_uri),
+ TEST_NO_TAG("Address urn", test_address_header_with_urn),
TEST_NO_TAG("Header address (very long)", test_very_long_address_header),
TEST_NO_TAG("Address with error", test_address_with_error_header),
TEST_NO_TAG("Allow", test_allow_header),
@@ -1175,7 +1264,9 @@ test_t headers_tests[] = {
TEST_NO_TAG("Header event", test_event_header),
TEST_NO_TAG("Header Supported", test_supported_header),
TEST_NO_TAG("Header Content-Disposition", test_content_disposition_header),
- TEST_NO_TAG("Header Accept", test_accept_header)
+ TEST_NO_TAG("Header Accept", test_accept_header),
+ TEST_NO_TAG("Header Reason", test_reason_header),
+ TEST_NO_TAG("Header Authentication-Info", test_authentication_info_header)
};
test_suite_t headers_test_suite = {"Headers", NULL, NULL, belle_sip_tester_before_each, belle_sip_tester_after_each,
diff --git a/tester/belle_sip_register_tester.c b/tester/belle_sip_register_tester.c
index 8de8c53..d12b6d7 100644
--- a/tester/belle_sip_register_tester.c
+++ b/tester/belle_sip_register_tester.c
@@ -766,7 +766,7 @@ static void process_message_response_event(void *user_ctx, const belle_sip_respo
}
}
}
-static belle_sip_request_t* send_message(belle_sip_request_t *initial_request, const char* realm){
+static belle_sip_request_t* send_message_to(belle_sip_request_t *initial_request, const char* realm, belle_sip_uri_t *outbound){
int i;
int io_error_count=0;
belle_sip_request_t *message_request=NULL;
@@ -793,41 +793,54 @@ static belle_sip_request_t* send_message(belle_sip_request_t *initial_request, c
// belle_sip_header_set_name(BELLE_SIP_HEADER(h), BELLE_SIP_PROXY_AUTHORIZATION);
// }
clone_request = (belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)message_request));
- belle_sip_client_transaction_send_request_to(belle_sip_provider_create_client_transaction(prov,message_request),NULL);
+ belle_sip_client_transaction_send_request_to(belle_sip_provider_create_client_transaction(prov,message_request),outbound);
for(i=0; i<2 && io_error_count==0 &&is_register_ok==0;i++)
belle_sip_stack_sleep(stack,5000);
return clone_request;
}
-static void reuse_nonce(void) {
+
+static void reuse_nonce_base(const char* outbound) {
belle_sip_request_t *register_request;
- size_t initial_auth_context_count=belle_sip_list_size(prov->auth_contexts);
- register_request=register_user_at_domain(stack, prov, "tcp",1,"marie","sip.linphone.org",NULL);
+ size_t initial_auth_context_count=0;/*belle_sip_list_size(prov->auth_contexts);*/
+ char outbound_uri[256];
+ /*reset auth context*/
+ prov->auth_contexts = belle_sip_list_free_with_data(prov->auth_contexts,(void(*)(void*))belle_sip_authorization_destroy);
+
+ if (outbound)
+ snprintf(outbound_uri, sizeof(outbound_uri),"sip:%s",outbound);
+
+ register_request=register_user_at_domain(stack, prov, "tcp",1,"marie",outbound,NULL);
+
if (register_request) {
belle_sip_header_authorization_t * h = NULL;
belle_sip_request_t *message_request;
- listener_callbacks.process_dialog_terminated=process_dialog_terminated;
- listener_callbacks.process_io_error=process_io_error;
- listener_callbacks.process_request_event=process_request_event;
- listener_callbacks.process_response_event=process_message_response_event;
- listener_callbacks.process_timeout=process_timeout;
- listener_callbacks.process_transaction_terminated=process_transaction_terminated;
- listener_callbacks.process_auth_requested=process_auth_requested;
- listener_callbacks.listener_destroyed=NULL;
- listener=belle_sip_listener_create_from_callbacks(&listener_callbacks,NULL);
-
- belle_sip_provider_add_sip_listener(prov,BELLE_SIP_LISTENER(listener));
+ belle_sip_listener_callbacks_t cbs;
+ belle_sip_listener_t *reuse_nonce_listener;
+ cbs.process_dialog_terminated=process_dialog_terminated;
+ cbs.process_io_error=process_io_error;
+ cbs.process_request_event=process_request_event;
+ cbs.process_response_event=process_message_response_event;
+ cbs.process_timeout=process_timeout;
+ cbs.process_transaction_terminated=process_transaction_terminated;
+ cbs.process_auth_requested=process_auth_requested;
+ cbs.listener_destroyed=NULL;
+ reuse_nonce_listener=belle_sip_listener_create_from_callbacks(&cbs,NULL);
+
+ belle_sip_provider_add_sip_listener(prov,BELLE_SIP_LISTENER(reuse_nonce_listener));
/*currently only one nonce should have been used (the one for the REGISTER)*/
BC_ASSERT_EQUAL((unsigned int)belle_sip_list_size(prov->auth_contexts), (unsigned int)initial_auth_context_count+1,unsigned int,"%u");
/*this should reuse previous nonce*/
- message_request=send_message(register_request, auth_domain);
+ message_request=send_message_to(register_request, auth_domain,outbound?belle_sip_uri_parse(outbound_uri):NULL);
BC_ASSERT_EQUAL(is_register_ok, 404,int,"%d");
h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
));
- if (BC_ASSERT_PTR_NOT_NULL(h)) {
+ if (BC_ASSERT_PTR_NOT_NULL(h)
+ && belle_sip_header_authorization_get_qop(h)
+ && strcmp(belle_sip_header_authorization_get_qop(h),"auth")==0) {
char * first_nonce_used;
BC_ASSERT_EQUAL(2, belle_sip_header_authorization_get_nonce_count(h),int,"%d");
first_nonce_used = belle_sip_strdup(belle_sip_header_authorization_get_nonce(h));
@@ -837,7 +850,7 @@ static void reuse_nonce(void) {
/*new nonce should be created when not using outbound proxy realm*/
- message_request=send_message(register_request, NULL);
+ message_request=send_message_to(register_request, NULL,outbound?belle_sip_uri_parse(outbound_uri):NULL);
BC_ASSERT_EQUAL(is_register_ok, 407,int,"%d");
h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
@@ -847,7 +860,7 @@ static void reuse_nonce(void) {
/*new nonce should be created here too*/
- message_request=send_message(register_request, "wrongrealm");
+ message_request=send_message_to(register_request, "wrongrealm",outbound?belle_sip_uri_parse(outbound_uri):NULL);
BC_ASSERT_EQUAL(is_register_ok, 407,int,"%d");
h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
@@ -856,23 +869,106 @@ static void reuse_nonce(void) {
belle_sip_object_unref(message_request);
- /*first nonce created should be reused*/
- message_request=send_message(register_request, auth_domain);
- BC_ASSERT_EQUAL(is_register_ok, 404,int,"%d");
+ /*first nonce created should be reused. this test is only for qop = auth*/
+ message_request=send_message_to(register_request, auth_domain,outbound?belle_sip_uri_parse(outbound_uri):NULL);
+
h = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(
BELLE_SIP_MESSAGE(message_request), belle_sip_header_proxy_authorization_t
));
- if (BC_ASSERT_PTR_NOT_NULL(h)) {
+ if (BC_ASSERT_PTR_NOT_NULL(h)
+ && belle_sip_header_authorization_get_qop(h)
+ && strcmp(belle_sip_header_authorization_get_qop(h),"auth")==0) {
+ BC_ASSERT_EQUAL(is_register_ok, 404,int,"%d");
BC_ASSERT_EQUAL(3, belle_sip_header_authorization_get_nonce_count(h),int,"%d");
}
belle_sip_object_unref(message_request);
- belle_sip_provider_remove_sip_listener(prov,BELLE_SIP_LISTENER(listener));
+ belle_sip_provider_remove_sip_listener(prov,BELLE_SIP_LISTENER(reuse_nonce_listener));
unregister_user(stack,prov,register_request,1);
belle_sip_object_unref(register_request);
}
}
+static void reuse_nonce(void) {
+ reuse_nonce_base("sip.linphone.org");
+}
+#define NONCE_SIZE 32
+void register_process_request_event(char *nonce, const belle_sip_request_event_t *event) {
+ belle_sip_request_t *req = belle_sip_request_event_get_request(event);
+ belle_sip_header_authorization_t *authorization;
+ int response_code = 407;
+ char *uri_as_string= belle_sip_uri_to_string(belle_sip_request_get_uri(req));
+ belle_sip_response_t * response_msg;
+ belle_sip_server_transaction_t *trans=belle_sip_provider_create_server_transaction(prov, req);
+
+ if (strcasecmp(belle_sip_request_get_method(req), "REGISTER") == 0) {
+ response_code=401;
+ }
+
+ if ( (authorization = belle_sip_message_get_header_by_type(req,belle_sip_header_authorization_t))
+ || (authorization = BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(req,belle_sip_header_proxy_authorization_t)))) {
+ char ha1[33], ha2[33], response[33];
+ belle_sip_auth_helper_compute_ha1(belle_sip_header_authorization_get_username(authorization)
+ , belle_sip_header_authorization_get_realm(authorization)
+ ,"secret", ha1);
+ belle_sip_auth_helper_compute_ha2(belle_sip_request_get_method(req)
+ , uri_as_string, ha2);
+ belle_sip_auth_helper_compute_response(ha1,nonce, ha2, response);
+ if (strcmp(response, belle_sip_header_authorization_get_response(authorization)) == 0) {
+ belle_sip_message("Auth sucessfull");
+ if (strcasecmp(belle_sip_request_get_method(req), "MESSAGE") == 0) {
+ response_code = 404;
+ } else {
+ response_code = 200;
+ }
+ }
+ }
+
+ belle_sip_random_token((nonce), NONCE_SIZE);
+ response_msg = belle_sip_response_create_from_request(req, response_code);
+
+ if (response_code == 407 || response_code == 401 ) {
+ belle_sip_header_www_authenticate_t *www_authenticate = 401?belle_sip_header_www_authenticate_new():BELLE_SIP_HEADER_WWW_AUTHENTICATE(belle_sip_header_proxy_authenticate_new());
+
+
+ belle_sip_header_www_authenticate_set_realm(www_authenticate, "sip.linphone.org");
+ belle_sip_header_www_authenticate_set_domain(www_authenticate, "sip:sip.linphone.org");
+ belle_sip_header_www_authenticate_set_scheme(www_authenticate, "Digest");
+ belle_sip_header_www_authenticate_set_nonce(www_authenticate,nonce);
+ belle_sip_message_add_header(BELLE_SIP_MESSAGE(response_msg), BELLE_SIP_HEADER(www_authenticate));
+ } else {
+ belle_sip_header_authentication_info_t* authentication_info = belle_sip_header_authentication_info_new();
+ belle_sip_header_authentication_info_set_next_nonce(authentication_info, nonce);
+ belle_sip_message_add_header(BELLE_SIP_MESSAGE(response_msg), BELLE_SIP_HEADER(authentication_info));
+ }
+
+ belle_sip_server_transaction_send_response(trans,response_msg);
+}
+static void test_register_with_next_nonce(void) {
+ belle_sip_listening_point_t *server_lp = belle_sip_stack_create_listening_point(stack,"0.0.0.0",bctbx_random()%20000 +1024,"TCP");
+ char nonce [NONCE_SIZE];
+ belle_sip_listener_t *server_listener;
+ char listening_uri[256];
+ belle_sip_listener_callbacks_t cbs;
+ belle_sip_random_token((nonce), sizeof(nonce));
+
+ cbs.process_dialog_terminated=NULL;
+ cbs.process_io_error=NULL;
+ cbs.process_request_event=(void (*)(void *user_ctx, const belle_sip_request_event_t *event))register_process_request_event;
+ cbs.process_response_event=NULL;
+ cbs.process_timeout=NULL;
+ cbs.process_transaction_terminated=NULL;
+ cbs.process_auth_requested=NULL;
+ cbs.listener_destroyed=NULL;
+ server_listener=belle_sip_listener_create_from_callbacks(&cbs,nonce);
+ belle_sip_provider_add_sip_listener(prov,server_listener);
+ belle_sip_provider_add_listening_point(prov,server_lp);
+ snprintf(listening_uri,sizeof(listening_uri), "127.0.0.1:%i;transport=tcp",belle_sip_listening_point_get_port(server_lp));
+
+ reuse_nonce_base(listening_uri);
+ belle_sip_provider_remove_sip_listener(prov, server_listener);
+ belle_sip_provider_remove_listening_point(prov, server_lp);
+}
test_t register_tests[] = {
TEST_NO_TAG("Stateful UDP", stateful_register_udp),
@@ -901,7 +997,8 @@ test_t register_tests[] = {
TEST_NO_TAG("Register with DNS SRV failover TLS", register_dns_srv_tls),
TEST_NO_TAG("Register with DNS SRV failover TLS with http proxy", register_dns_srv_tls_with_http_proxy),
TEST_NO_TAG("Register with DNS load-balancing", register_dns_load_balancing),
- TEST_NO_TAG("Nonce reutilization", reuse_nonce)
+ TEST_NO_TAG("Nonce reutilization", reuse_nonce),
+ TEST_NO_TAG("Next Nonce", test_register_with_next_nonce)
};
test_suite_t register_test_suite = {"Register", register_before_all, register_after_all, NULL,
diff --git a/tester/belle_sip_resolver_tester.c b/tester/belle_sip_resolver_tester.c
index d401820..4e7fa85 100644
--- a/tester/belle_sip_resolver_tester.c
+++ b/tester/belle_sip_resolver_tester.c
@@ -85,7 +85,7 @@ static void destroy_endpoint(endpoint_t *endpoint) {
belle_sip_uninit_sockets();
}
-static void a_resolve_done(void *data, const char *name, struct addrinfo *ai_list) {
+static void a_resolve_done(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl) {
endpoint_t *client = (endpoint_t *)data;
BELLESIP_UNUSED(name);
client->resolve_done = 1;
@@ -96,7 +96,7 @@ static void a_resolve_done(void *data, const char *name, struct addrinfo *ai_lis
client->resolve_ko = 1;
}
-static void srv_resolve_done(void *data, const char *name, belle_sip_list_t *srv_list) {
+static void srv_resolve_done(void *data, const char *name, belle_sip_list_t *srv_list, uint32_t ttl) {
endpoint_t *client = (endpoint_t *)data;
BELLESIP_UNUSED(name);
client->resolve_done = 1;
diff --git a/tester/belle_sip_tester.c b/tester/belle_sip_tester.c
index c7b061a..7744b81 100644
--- a/tester/belle_sip_tester.c
+++ b/tester/belle_sip_tester.c
@@ -94,6 +94,8 @@ void belle_sip_tester_init(void(*ftester_printf)(int level, const char *fmt, va_
ipv6_available=_belle_sip_tester_ipv6_available();
bc_tester_add_suite(&cast_test_suite);
bc_tester_add_suite(&sip_uri_test_suite);
+ bc_tester_add_suite(&fast_sip_uri_test_suite);
+ bc_tester_add_suite(&perf_sip_uri_test_suite);
bc_tester_add_suite(&generic_uri_test_suite);
bc_tester_add_suite(&headers_test_suite);
bc_tester_add_suite(&core_test_suite);
@@ -155,6 +157,9 @@ void belle_sip_tester_after_each(void) {
}
int belle_sip_tester_set_log_file(const char *filename) {
+ bctbx_log_handler_t *filehandler;
+ char* dir;
+ char* base;
if (log_file) {
fclose(log_file);
}
@@ -163,13 +168,19 @@ int belle_sip_tester_set_log_file(const char *filename) {
belle_sip_error("Cannot open file [%s] for writing logs because [%s]", filename, strerror(errno));
return -1;
}
+ dir = bctbx_dirname(filename);
+ base = bctbx_basename(filename);
belle_sip_message("Redirecting traces to file [%s]", filename);
- belle_sip_set_log_file(log_file);
+ filehandler = bctbx_create_file_log_handler(0, dir, base, log_file);
+ bctbx_add_log_handler(filehandler);
+ bctbx_add_log_handler(filehandler);
+ if (dir) bctbx_free(dir);
+ if (base) bctbx_free(base);
return 0;
}
-#if !defined(ANDROID) && !defined(TARGET_OS_IPHONE) && !(defined(BELLE_SIP_WINDOWS_PHONE) || defined(BELLE_SIP_WINDOWS_UNIVERSAL))
+#if !defined(__ANDROID__) && !defined(TARGET_OS_IPHONE) && !(defined(BELLE_SIP_WINDOWS_PHONE) || defined(BELLE_SIP_WINDOWS_UNIVERSAL))
static const char* belle_sip_helper =
"\t\t\t--verbose\n"
@@ -202,7 +213,8 @@ int main (int argc, char *argv[]) {
if (env_domain) {
test_domain=env_domain;
}
-
+ bctbx_init_logger(TRUE);
+
for(i=1;i<argc;++i){
if (strcmp(argv[i],"--verbose")==0){
belle_sip_set_log_level(BELLE_SIP_LOG_DEBUG);
@@ -238,6 +250,7 @@ int main (int argc, char *argv[]) {
ret = bc_tester_start(argv[0]);
belle_sip_tester_uninit();
+ bctbx_uninit_logger();
return ret;
}
diff --git a/tester/belle_sip_tester.h b/tester/belle_sip_tester.h
index 58bd126..4fa562c 100644
--- a/tester/belle_sip_tester.h
+++ b/tester/belle_sip_tester.h
@@ -32,6 +32,8 @@ extern "C" {
extern test_suite_t cast_test_suite;
extern test_suite_t generic_uri_test_suite;
extern test_suite_t sip_uri_test_suite;
+extern test_suite_t fast_sip_uri_test_suite;
+extern test_suite_t perf_sip_uri_test_suite;
extern test_suite_t headers_test_suite;
extern test_suite_t core_test_suite;
extern test_suite_t sdp_test_suite;
diff --git a/tester/belle_sip_tester_windows.cpp b/tester/belle_sip_tester_windows.cpp
index d8e470d..d4b52be 100644
--- a/tester/belle_sip_tester_windows.cpp
+++ b/tester/belle_sip_tester_windows.cpp
@@ -46,7 +46,7 @@ static void nativeOutputTraceHandler(int lev, const char *fmt, va_list args)
}
}
-static void belleSipNativeOutputTraceHandler(const char *domain, BctbxLogLevel lev, const char *fmt, va_list args)
+static void belleSipNativeOutputTraceHandler(void *info, const char *domain, BctbxLogLevel lev, const char *fmt, va_list args)
{
nativeOutputTraceHandler((int)lev, fmt, args);
}
@@ -103,6 +103,7 @@ bool NativeTester::run(Platform::String^ suiteName, Platform::String^ caseName,
std::wstring wscasename = caseName->Data();
char csuitename[MAX_SUITE_NAME_SIZE] = { 0 };
char ccasename[MAX_SUITE_NAME_SIZE] = { 0 };
+ bctbx_log_handler_t *log_handler = bctbx_create_log_handler(belleSipNativeOutputTraceHandler, NULL, NULL);
wcstombs(csuitename, wssuitename.c_str(), sizeof(csuitename));
wcstombs(ccasename, wscasename.c_str(), sizeof(ccasename));
@@ -112,7 +113,7 @@ bool NativeTester::run(Platform::String^ suiteName, Platform::String^ caseName,
else {
belle_sip_set_log_level(BELLE_SIP_LOG_ERROR);
}
- belle_sip_set_log_handler(belleSipNativeOutputTraceHandler);
+ bctbx_add_log_handler(log_handler);
return bc_tester_run_tests(wssuitename == all ? 0 : csuitename, wscasename == all ? 0 : ccasename, NULL) != 0;
}
diff --git a/tester/belle_sip_uri_tester.c b/tester/belle_sip_uri_tester.c
index 5b2abeb..c5c30f9 100644
--- a/tester/belle_sip_uri_tester.c
+++ b/tester/belle_sip_uri_tester.c
@@ -1,505 +1,32 @@
/*
belle-sip - SIP (RFC3261) library.
- Copyright (C) 2010 Belledonne Communications SARL
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
+ Copyright (C) 2017 Belledonne Communications SARL
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include "belle-sip/belle-sip.h"
#include "belle_sip_tester.h"
#include "belle_sip_internal.h"
-static void testSIMPLEURI(void) {
- belle_sip_uri_t* L_tmp;
- belle_sip_uri_t* L_uri = belle_sip_uri_parse("sip:sip.titi.com");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_tmp = belle_sip_uri_parse(l_raw_uri);
- L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
- belle_sip_free(l_raw_uri);
-
- BC_ASSERT_PTR_NULL(belle_sip_uri_get_user(L_uri));
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "sip.titi.com");
- BC_ASSERT_PTR_NULL(belle_sip_uri_get_transport_param(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void testCOMPLEXURI(void) {
- belle_sip_uri_t* L_tmp;
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto at titi.com:5060;transport=tcp");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_tmp = belle_sip_uri_parse(l_raw_uri);
- L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto");
- BC_ASSERT_EQUAL(belle_sip_uri_get_port(L_uri), 5060, int, "%d");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "tcp");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void testIPV6URI_base(const char* ip6) {
- belle_sip_uri_t* L_tmp;
- belle_sip_uri_t * L_uri;
- char* l_raw_uri;
- char uri[256];
- snprintf(uri,sizeof(uri),"sip:toto@[%s]:5060;transport=tcp",ip6);
- L_uri = belle_sip_uri_parse(uri);
- l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_tmp = belle_sip_uri_parse(l_raw_uri);
- L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto");
- BC_ASSERT_EQUAL(belle_sip_uri_get_port(L_uri), 5060, int, "%d");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri),ip6);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "tcp");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void testIPV6URI(void) {
- testIPV6URI_base("fe80::1");
- testIPV6URI_base("2a01:e35:1387:1020:6233:4bff:fe0b:5663");
- testIPV6URI_base("2a01:e35:1387:1020:6233::5663");
- testIPV6URI_base("::1");
-}
-
-static void testSIPSURI(void) {
-
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sips:linphone.org");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
- BC_ASSERT_EQUAL(belle_sip_uri_is_secure(L_uri), 1, int, "%d");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse("sip:linphone.org");
- BC_ASSERT_EQUAL(belle_sip_uri_is_secure(L_uri), 0, int, "%d");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void test_ip_host(void) {
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:192.168.0.1");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "192.168.0.1");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void test_lr(void) {
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:192.168.0.1;lr");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "192.168.0.1");
- BC_ASSERT_EQUAL(belle_sip_uri_has_lr_param(L_uri), 1, int, "%d");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-
-}
-
-static void test_maddr(void) {
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:192.168.0.1;lr;maddr=linphone.org");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_maddr_param(L_uri), "linphone.org");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-
-}
-
-static void test_user_passwd(void) {
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto:tata at bla;");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user_password(L_uri), "tata");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-
-}
-
-
-static void test_uri_parameters (void) {
- char* l_raw_uri;
- belle_sip_uri_t* L_tmp;
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:192.168.0.1;ttl=12");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-
- L_uri = belle_sip_uri_parse("sip:maddr=@192.168.0.1;lr;maddr=192.168.0.1;user=ip;ttl=140;transport=sctp;method=INVITE;rport=5060");
- l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
-
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_tmp = belle_sip_uri_parse(l_raw_uri);
- L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
-
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_maddr_param(L_uri), "192.168.0.1");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user_param(L_uri), "ip");
- BC_ASSERT_EQUAL(belle_sip_uri_get_ttl_param(L_uri),140, int, "%d");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "sctp");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_method_param(L_uri), "INVITE");
-
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void test_headers(void) {
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:192.168.0.1?toto=titi");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
- if (!BC_ASSERT_PTR_NOT_NULL(belle_sip_uri_get_header(L_uri,"toto"))) return;
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_header(L_uri,"toto"), "titi");
-
- BC_ASSERT_PTR_NULL(belle_sip_uri_get_header(L_uri,"bla"));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse("sip:192.168.0.1?toto=titi&header2=popo&header3=");
- l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
-
- if (!BC_ASSERT_PTR_NOT_NULL(belle_sip_uri_get_header(L_uri,"toto"))) return;
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_header(L_uri,"header2"), "popo");
- belle_sip_object_unref(L_uri);
-}
-static void test_escaped_headers(void) {
- const char* raw_uri_2= "sip:eNgwBpkNcH6EdTHlX0cq8 at toto.com?"
- "P-Group-Id=Fu0hHIQ23H4hveVT:New%20Group"
- "&P-Expert-Profile-Id=zKQOBOB2jTmUOjkB:New%20Group"
- "&P-Reverse-Charging=0&P-Campaign-Id=none"
- "&P-Embed-Url=https://toto.com/caller/?1.4.0-dev-42-91bdf0c%26id%3DFu0hHIQ23H4hveVT%26CAMPAIGN_ID%3Dnone";
-
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto at sip.linhone.org?User-to-User=323a313030363a3230385a48363039313941364b4342463845495936%3Bencoding%3Dhex");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_uri = belle_sip_uri_parse(l_raw_uri);
- belle_sip_free(l_raw_uri);
- if (!BC_ASSERT_PTR_NOT_NULL(belle_sip_uri_get_header(L_uri,"User-to-User"))) return;
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_header(L_uri,"User-to-User"), "323a313030363a3230385a48363039313941364b4342463845495936;encoding=hex");
- belle_sip_object_unref(L_uri);
-
- L_uri = belle_sip_uri_parse(raw_uri_2);
- l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_free(l_raw_uri);
- if (!BC_ASSERT_PTR_NOT_NULL(belle_sip_uri_get_header(L_uri,"P-Embed-Url"))) return;
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_header(L_uri,"P-Embed-Url"), "https://toto.com/caller/?1.4.0-dev-42-91bdf0c&id=Fu0hHIQ23H4hveVT&CAMPAIGN_ID=none");
- belle_sip_object_unref(L_uri);
-
-
-}
-
-static void testSIMPLEURI_error(void) {
- belle_sip_uri_t* L_uri = belle_sip_uri_parse("siptcom");
- BC_ASSERT_PTR_NULL(L_uri);
-
-}
-
-static void test_escaped_username(void) {
- belle_sip_uri_t* L_tmp;
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto%40linphone.org at titi.com");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_tmp = belle_sip_uri_parse(l_raw_uri);
- L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto at linphone.org");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void test_escaped_passwd(void) {
- belle_sip_uri_t* L_tmp;
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sips:%22jehan%22%20%3cjehan%40sip2.linphone.org:544%3e at sip.linphone.org");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_tmp = belle_sip_uri_parse(l_raw_uri);
- L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "\"jehan\" <jehan at sip2.linphone.org");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "sip.linphone.org");
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_user_password(L_uri), "544>");
-
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-
-}
+/*test body*/
+#include "belle_sip_base_uri_tester.c"
-static void test_escaped_parameter(void) {
- belle_sip_uri_t* L_tmp;
- belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:toto at titi.com;pa%3Dram=aa%40bb:5060[];o%40");
- char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
- L_tmp = belle_sip_uri_parse(l_raw_uri);
- L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
- belle_sip_free(l_raw_uri);
- BC_ASSERT_STRING_EQUAL(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(L_uri), "pa=ram"), "aa at bb:5060[]");
- BC_ASSERT_TRUE(belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(L_uri), "o@"));
- BC_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
- belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
-}
-
-static void test_uri_equals(void) {
- belle_sip_uri_t* a;
- belle_sip_uri_t* b;
-/*
- * The URIs within each of the following sets are equivalent:
-
- sip:%61lice at atlanta.com;transport=TCP
- sip:alice at AtLanTa.CoM;Transport=tcp
-*/
- a = belle_sip_uri_parse("sip:%61lice at atlanta.com;transport=TCP");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:alice at AtLanTa.CoM;Transport=tcp");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_TRUE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
- /*
- sip:carol at chicago.com
- sip:carol at chicago.com;newparam=5
- sip:carol at chicago.com;security=on
-*/
- a = belle_sip_uri_parse("sip:carol at chicago.com");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:carol at chicago.com;newparam=5");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_TRUE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
-/*
-
- sip:biloxi.com;transport=tcp;method=REGISTER?to=sip:bob%40biloxi.com
- sip:biloxi.com;method=REGISTER;transport=tcp?to=sip:bob%40biloxi.com
-*/
- a = belle_sip_uri_parse("sip:biloxi.com;transport=tcp;method=REGISTER?to=sip:bob%40biloxi.com");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:biloxi.com;method=REGISTER;transport=tcp?to=sip:bob%40biloxi.com");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_TRUE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
- /*
- sip:alice at atlanta.com?subject=project%20x&priority=urgent
- sip:alice at atlanta.com?priority=urgent&subject=project%20x
-
- The URIs within each of the following sets are not equivalent:
-
- SIP:ALICE at AtLanTa.CoM;Transport=udp (different usernames)
- sip:alice at AtLanTa.CoM;Transport=UDP
-*/
- a = belle_sip_uri_parse("sip:ALICE at AtLanTa.CoM;Transport=udp");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:alice at AtLanTa.CoM;Transport=UDP");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_FALSE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
- /*
- sip:bob at biloxi.com (can resolve to different ports)
- sip:bob at biloxi.com:5060
-*/
- a = belle_sip_uri_parse("sip:ALICE at AtLanTa.CoM;Transport=udp");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:alice at AtLanTa.CoM;Transport=UDP");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_FALSE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
- /*
- sip:bob at biloxi.com (can resolve to different transports)
- sip:bob at biloxi.com;transport=udp
-*/
- a = belle_sip_uri_parse("sip:bob at biloxi.com");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:bob at biloxi.com;transport=udp");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_FALSE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
-/* sip:bob at biloxi.com (can resolve to different port and transports)
- sip:bob at biloxi.com:6000;transport=tcp
-*/
- a = belle_sip_uri_parse("sip:bob at biloxi.com");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:bob at biloxi.com:6000;transport=tcp");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_FALSE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
-
- a = belle_sip_uri_parse("sip:bob at biloxi.com");
- if (!BC_ASSERT_PTR_NOT_NULL(a)) return;
- b = belle_sip_uri_parse("sip:boba at biloxi.com");
- if (!BC_ASSERT_PTR_NOT_NULL(b)) return;
- BC_ASSERT_FALSE(belle_sip_uri_equals(a,b));
- belle_sip_object_unref(a);
- belle_sip_object_unref(b);
-
- /* sip:carol at chicago.com (different header component)
- sip:carol at chicago.com?Subject=next%20meeting
-
- sip:bob at phone21.boxesbybob.com (even though that's what
- sip:bob at 192.0.2.4 phone21.boxesbybob.com resolves to)
-
- Note that equality is not transitive:
-
- o sip:carol at chicago.com and sip:carol at chicago.com;security=on are
- equivalent
-
- o sip:carol at chicago.com and sip:carol at chicago.com;security=off
- are equivalent
-
- o sip:carol at chicago.com;security=on and
- sip:carol at chicago.com;security=off are not equivalent
- Rosenberg, et. al. Standards Track [Page 155]
-
- RFC 3261 SIP: Session Initiation Protocol June 2002
-
- */
-
-
-}
-
-/*
- * From 19.1.1 SIP and SIPS URI Components
- * dialog
- reg./redir. Contact/
- default Req.-URI To From Contact R-R/Route external
-user -- o o o o o o
-password -- o o o o o o
-host -- m m m m m m
-port (1) o - - o o o
-user-param ip o o o o o o
-method INVITE - - - - - o
-maddr-param -- o - - o o o
-ttl-param 1 o - - o - o
-transp.-param (2) o - - o o o
-lr-param -- o - - - o o
-other-param -- o o o o o o
-headers -- - - - o - o*/
-void testUriComponentsChecker(void) {
- belle_sip_uri_t* uri = belle_sip_uri_parse("sip:hostonly");
- BC_ASSERT_TRUE(belle_sip_uri_check_components_from_request_uri(uri));
- belle_sip_object_unref(uri);
-
- {
- belle_sip_header_from_t* header = belle_sip_header_from_parse("From: sip:linphone.org:5061");
- BC_ASSERT_FALSE(belle_sip_uri_check_components_from_context(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)),NULL,"From"));
- belle_sip_object_unref(header);
- }
- {
- belle_sip_header_to_t* header = belle_sip_header_to_parse("To: sip:linphone.org?header=interdit");
- BC_ASSERT_FALSE(belle_sip_uri_check_components_from_context(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)),NULL,"To"));
- belle_sip_object_unref(header);
- }
- {
- belle_sip_header_contact_t* header = belle_sip_header_contact_parse("Contact: <sip:linphone.org;lr>");
- BC_ASSERT_FALSE(belle_sip_uri_check_components_from_context(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)),"REGISTER","Contact"));
- BC_ASSERT_TRUE(belle_sip_uri_check_components_from_context(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)),NULL,"Contact"));
- belle_sip_object_unref(header);
- }
- {
- belle_sip_header_record_route_t* header = belle_sip_header_record_route_parse("Record-Route: <sip:linphone.org;ttl=interdit>");
- BC_ASSERT_FALSE(belle_sip_uri_check_components_from_context(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header)),NULL,"Record-Route"));
- belle_sip_object_unref(header);
- }
- {
- belle_sip_uri_t* uri = belle_sip_uri_parse("sip:linphone.org:5061?header=toto");
- BC_ASSERT_TRUE(belle_sip_uri_check_components_from_context(uri,NULL,"Any"));
- belle_sip_object_unref(uri);
- }
-}
-
-void test_escaping_bad_chars(void){
- char bad_uri[13] = { 'h', 'e', 'l', 'l', 'o', (char)0xa0, (char)0xc8, 'w', 'o', 'r', 'l', 'd', 0x0 };
- char *escaped = belle_sip_uri_to_escaped_username(bad_uri);
- const char *expected="hello%a0%c8world";
-
- BC_ASSERT_STRING_EQUAL(escaped, expected);
-
- belle_sip_free(escaped);
-}
-
-
-static belle_sip_header_address_t* test_header_address_parsing(const char* address, int expect_fail){
- belle_sip_header_address_t* header_address = belle_sip_header_address_parse(address);
- if( expect_fail == TRUE ){
- BC_ASSERT_PTR_NULL(header_address);
- } else {
- BC_ASSERT_PTR_NOT_NULL(header_address);
- }
- return header_address;
-}
-
-static void test_empty_password(void){
- const char *address_fail = "sip:France:@+123456789";
- const char *address_valid = "sip:France:@toto";
- const char* passwd;
- belle_sip_header_address_t* headerAddr;
- belle_sip_uri_t* uri;
-
- (void)test_header_address_parsing(address_fail, TRUE);
-
- headerAddr = test_header_address_parsing(address_valid, FALSE);
-
- BC_ASSERT_PTR_NOT_NULL(headerAddr);
-
- uri = belle_sip_header_address_get_uri(headerAddr);
- BC_ASSERT_PTR_NOT_NULL(uri);
-
- passwd = belle_sip_uri_get_user_password(uri);
- BC_ASSERT_PTR_EQUAL(passwd, NULL);
-
- if (headerAddr) belle_sip_object_unref(headerAddr);
-}
+test_suite_t sip_uri_test_suite = {"SIP URI", NULL, NULL, belle_sip_tester_before_each, belle_sip_tester_after_each,
+ sizeof(uri_tests) / sizeof(uri_tests[0]), uri_tests};
-static test_t uri_tests[] = {
- TEST_NO_TAG("Simple URI", testSIMPLEURI),
- TEST_NO_TAG("Complex URI", testCOMPLEXURI),
- TEST_NO_TAG("Escaped username", test_escaped_username),
- TEST_NO_TAG("Escaped username with bad chars", test_escaping_bad_chars),
- TEST_NO_TAG("Escaped parameter", test_escaped_parameter),
- TEST_NO_TAG("Escaped passwd", test_escaped_passwd),
- TEST_NO_TAG("User passwd", test_user_passwd),
- TEST_NO_TAG("IP host", test_ip_host),
- TEST_NO_TAG("lr", test_lr),
- TEST_NO_TAG("maddr", test_maddr),
- TEST_NO_TAG("headers", test_headers),
- TEST_NO_TAG("Escaped headers", test_escaped_headers),
- TEST_NO_TAG("URI parameters", test_uri_parameters),
- TEST_NO_TAG("SIPS URI", testSIPSURI),
- TEST_NO_TAG("URI equals", test_uri_equals),
- TEST_NO_TAG("Simple URI error", testSIMPLEURI_error),
- TEST_NO_TAG("IPv6 URI", testIPV6URI),
- TEST_NO_TAG("URI components", testUriComponentsChecker),
- TEST_NO_TAG("Empty password", test_empty_password),
-};
-test_suite_t sip_uri_test_suite = {"SIP URI", NULL, NULL, belle_sip_tester_before_each, belle_sip_tester_after_each,
- sizeof(uri_tests) / sizeof(uri_tests[0]), uri_tests};
diff --git a/tester/get.c b/tester/get.c
index cde7821..fe31ed8 100644
--- a/tester/get.c
+++ b/tester/get.c
@@ -32,6 +32,8 @@ static belle_sip_stack_t *stack=NULL;
static void process_response(void *data, const belle_http_response_event_t *event){
belle_http_response_t *resp=event->response;
const char *body=belle_sip_message_get_body(BELLE_SIP_MESSAGE(resp));
+ fprintf(stdout,"Got response:\n");
+
if (body){
fprintf(stdout,"%s",body);
}
@@ -66,12 +68,14 @@ int main(int argc, char *argv[]){
if (argc<2){
usage(argv[0]);
}
+ bctbx_init_logger(1);
for (i = 2; i < argc; ++i){
if (strcmp(argv[i], "--ca-path") == 0){
i++;
ca_path = argv[i];
}else if (strcmp(argv[i], "--debug")==0){
- belle_sip_set_log_level(BELLE_SIP_LOG_DEBUG);
+ fprintf(stderr, "Logs are enabled.\n");
+ bctbx_set_log_level(BCTBX_LOG_DOMAIN,BCTBX_LOG_DEBUG);
}else if (strcmp(argv[i], "--no-tls-check")==0){
check_tls = 0;
}else{
diff --git a/tester/parse.c b/tester/parse.c
index b67f273..1f757e3 100644
--- a/tester/parse.c
+++ b/tester/parse.c
@@ -80,21 +80,21 @@ int main(int argc, char *argv[]){
close(fd);
belle_sip_set_log_level(BELLE_SIP_LOG_DEBUG);
- for (i=0;i<st.st_size;){
- size_t read;
+ for (i=0;i<(int)st.st_size;){
+ size_t nbread;
if (strcasecmp(protocol,"sip")==0 || strcasecmp(protocol,"http")==0){
belle_sip_message_t *msg;
uint64_t begin,end;
begin=belle_sip_time_ms();
- msg=belle_sip_message_parse_raw(str+i,st.st_size-i,&read);
+ msg=belle_sip_message_parse_raw(str+i,st.st_size-i,&nbread);
end=belle_sip_time_ms();
if (msg){
- printf("Successfully parsed %s message of %i bytes in %i ms.\n",protocol,(int)read, (int)(end-begin));
+ printf("Successfully parsed %s message of %i bytes in %i ms.\n",protocol,(int)nbread, (int)(end-begin));
}else{
fprintf(stderr,"Failed to parse message.\n");
break;
}
- i+=read;
+ i+=(int)nbread;
}else if (strcasecmp(protocol,"sdp")==0){
belle_sdp_session_description_t *sdp=belle_sdp_session_description_parse(str);
if (sdp){
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/belle-sip.git
More information about the Pkg-voip-commits
mailing list