diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml new file mode 100644 index 00000000..1e69d705 --- /dev/null +++ b/.github/workflows/mingw.yml @@ -0,0 +1,96 @@ +name: mingw + +on: [push] + +jobs: + build: + name: build + + strategy: + matrix: + os: [windows-latest] + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: [Release, Debug] + BUILD_SHARED_LIBS: [OFF] + + defaults: + run: + shell: cmd + + runs-on: ${{ matrix.os }} + env: + BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + SOURCE_DIR: ${{github.workspace}}\.cache\source + TOOSL_DIR: ${{github.workspace}}\.cache\tools + INSTALL_DIR: ${{github.workspace}}\.cache\install_mingw_2022_02_15 + + steps: + - uses: actions/checkout@v2 + #with: + #fetch-depth: 0 + + - name: pacman + env: + PATH: C:\msys64\usr\bin + run: | + C:\msys64\usr\bin\pacman.exe -S --noconfirm ^ + mingw-w64-x86_64-cmake ^ + mingw-w64-x86_64-make ^ + mingw-w64-x86_64-nsis ^ + mingw-w64-x86_64-gcc ^ + mingw-w64-x86_64-zlib ^ + mingw-w64-x86_64-openssl ^ + mingw-w64-x86_64-libevent ^ + mingw-w64-x86_64-sqlite3 ^ + mingw-w64-x86_64-hiredis ^ + mingw-w64-x86_64-postgresql ^ + git base-devel + + - name: make_directory + run: | + cmake -E make_directory ${{env.SOURCE_DIR}} + cmake -E make_directory ${{env.TOOSL_DIR}} + cmake -E make_directory ${{env.INSTALL_DIR}} + + - name: Cache installed + uses: actions/cache@v2 + id: cache-installed + with: + path: | + ${{env.INSTALL_DIR}} + key: coturn-cache-installed-mingw + + - name: build coturn + working-directory: ${{github.workspace}} + env: + MSYSTEM: MINGW64 + PATH: C:\msys64\mingw64\bin;C:\msys64\usr\bin + run: | + cmake -E make_directory build + cd build + cmake .. -G"MinGW Makefiles" ^ + -DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} ^ + -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} ^ + -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install + cmake --build . --config ${{matrix.BUILD_TYPE}} + cmake --build . --config ${{matrix.BUILD_TYPE}} --target install + + - name: Package + if: ${{ matrix.BUILD_TYPE == 'Release' }} + working-directory: ${{github.workspace}}\build + run: | + copy /Y ${{env.INSTALL_DIR}}\bin\*.dll install\bin + copy /Y ${{env.INSTALL_DIR}}\lib\*.dll install\bin + copy /Y ${{env.RUNVCPKG_VCPKG_ROOT}}\installed\${{env.RUNVCPKG_VCPKG_TRIPLET_OUT}}\bin\*.dll install\bin + 7z a coturn_windows_mingw.zip ${{github.workspace}}\build\install\* + cmake --build . --config ${{matrix.BUILD_TYPE}} --target package + + - name: update + if: ${{ matrix.BUILD_TYPE == 'Release' }} + uses: actions/upload-artifact@v2 + with: + name: coturn_mingw_${{ matrix.os }} + path: | + ${{github.workspace}}\build\coturn_windows_mingw.zip + ${{github.workspace}}\build\coturn*.exe + ${{github.workspace}}\build\coturn*.md5 diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml new file mode 100644 index 00000000..bf4f160e --- /dev/null +++ b/.github/workflows/msvc.yml @@ -0,0 +1,110 @@ +name: msvc + +on: [push] + +jobs: + compile: + name: ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} + + strategy: + matrix: + BUILD_TYPE: [Release, Debug] + BUILD_SHARED_LIBS: [OFF, ON] + #VCPKG_PLATFORM_TOOLSET: [v143, v142, v141] + CMAKE_GENERATOR_PLATFORM: [x64, Win32] + os: [windows-latest] + include: + # MSVC 2022 + - triplet: x64-windows + VCPKG_PLATFORM_TOOLSET: v143 + CMAKE_GENERATOR_PLATFORM: x64 + + - triplet: x86-windows + VCPKG_PLATFORM_TOOLSET: v143 + CMAKE_GENERATOR_PLATFORM: Win32 + + # MSVC 2019 + - triplet: x86-windows + VCPKG_PLATFORM_TOOLSET: v142 + CMAKE_GENERATOR_PLATFORM: Win32 + + # MSVC 2017 + - triplet: x86-windows + VCPKG_PLATFORM_TOOLSET: v141 + CMAKE_GENERATOR_PLATFORM: Win32 + + runs-on: ${{matrix.os}} + + env: + SOURCE_DIR: ${{github.workspace}}\.cache\source + TOOLS_DIR: ${{github.workspace}}\.cache\tools + INSTALL_DIR: ${{github.workspace}}\.cache\install_msvc_${{matrix.triplet}}_${{matrix.BUILD_TYPE}} + VCPKGGITCOMMITID: acc3bcf76b84ae5041c86ab55fe138ae7b8255c7 + VCPKG_PLATFORM_TOOLSET: ${{matrix.VCPKG_PLATFORM_TOOLSET}} + CMAKE_GENERATOR_PLATFORM: ${{matrix.CMAKE_GENERATOR_PLATFORM}} + + defaults: + run: + shell: cmd + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: make directory + run: | + cmake -E make_directory ${{env.SOURCE_DIR}} + cmake -E make_directory ${{env.TOOLS_DIR}} + cmake -E make_directory ${{env.INSTALL_DIR}} + + - name: Cache installed + uses: actions/cache@v2 + id: cache-installed + with: + path: | + ${{env.INSTALL_DIR}} + key: coturn-cache-installed-${{matrix.os}}-vc${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.triplet}}-${{matrix.BUILD_TYPE}} + + - name: run-vcpkg + uses: lukka/run-vcpkg@v10 + with: + # If not using a submodule for vcpkg sources, this specifies which commit + # id must be checkout from a Git repo. It must not set if using a submodule + # for vcpkg. + vcpkgGitCommitId: '${{ env.VCPKGGITCOMMITID }}' + # Since the cache must be invalidated when content of the vcpkg.json file changes, let's + # compute its hash and append this to the computed cache's key. + appendedCacheKey: coturn-msvc-${{matrix.os}}-vc${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.triplet}}-${{matrix.BUILD_TYPE}}-${{env.VCPKGGITCOMMITID}} + + - name: build coturn + run: | + cmake -E make_directory ${{github.workspace}}/build + cd ${{github.workspace}}/build + cmake ${{github.workspace}} ^ + -A ${{matrix.CMAKE_GENERATOR_PLATFORM}} ^ + -T ${{matrix.VCPKG_PLATFORM_TOOLSET}} ^ + -DWITH_MYSQL=OFF ^ + -DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} ^ + -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} ^ + -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install ^ + -DCMAKE_TOOLCHAIN_FILE=${{env.VCPKG_ROOT}}/scripts/buildsystems/vcpkg.cmake + cmake --build . --config ${{matrix.BUILD_TYPE}} + cmake --build . --config ${{matrix.BUILD_TYPE}} --target install + + - name: Package + if: ${{ matrix.BUILD_TYPE == 'Release' }} + working-directory: ${{github.workspace}}\build + run: | + 7z a coturn_windows_msvc.zip ${{github.workspace}}\build\install\* + cmake --build . --config ${{matrix.BUILD_TYPE}} --target package + + - name: update + if: ${{ matrix.BUILD_TYPE == 'Release' }} + uses: actions/upload-artifact@v2 + with: + name: coturn_msvc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_SHARED_LIBS}} + path: | + ${{github.workspace}}\build\coturn_windows_msvc.zip + ${{github.workspace}}\build\coturn*.exe + ${{github.workspace}}\build\coturn*.md5 diff --git a/.gitignore b/.gitignore index e97aac64..6177c410 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,18 @@ /Makefile /bin/ -build +*build*/ include lib sqlite examples/ca/CA.pl .vscode +.idea +.vs/ # This file is used to ignore files which are generated # ---------------------------------------------------------------------------- +*.bak *~ *.autosave *.a @@ -80,4 +83,3 @@ Thumbs.db # -------- *.dll *.exe - diff --git a/CMakeLists.txt b/CMakeLists.txt index 57c6c00d..4a87168b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,15 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin cmake_minimum_required(VERSION 3.5) project(coturn) +#set(CMAKE_INCLUDE_CURRENT_DIR ON) +#set(CMAKE_C_STANDARD 11) +#set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) # TODO: Modify this when the version is released -SET(BUILD_VERSION "4.5.2") +SET(BUILD_VERSION "4.6.0") option(FUZZER "Build oss-fuzz fuzzing" OFF) @@ -34,7 +37,12 @@ IF(EXISTS "${CMAKE_SOURCE_DIR}/.git") SET(BUILD_VERSION ${GIT_VERSION}) ENDIF() ENDIF() -message("BUILD_VERSION:${BUILD_VERSION}") +string(FIND ${BUILD_VERSION} / BUILD_VERSION_POS REVERSE) +if(BUILD_VERSION_POS GREATER -1) + math(EXPR BUILD_VERSION_POS "${BUILD_VERSION_POS} + 1") + string(SUBSTRING ${BUILD_VERSION} ${BUILD_VERSION_POS} -1 BUILD_VERSION) +endif() +message("BUILD_VERSION:${BUILD_VERSION};${_BUILD_VERSION}") set(VERSION ${BUILD_VERSION}) if(NOT DEFINED CMAKE_BUILD_TYPE) @@ -55,11 +63,20 @@ IF(MSVC) ENDIF(WIN32_USE_MP) add_compile_options("$<$:/utf-8>") add_compile_options("$<$:/utf-8>") + add_definitions(-D_CRT_SECURE_NO_WARNINGS) ENDIF(MSVC) -IF(APPLE) - add_compile_definitions("TURN_NO_THREAD_BARRIERS=1") -ENDIF() +SET(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libs") +if (BUILD_SHARED_LIBS) + add_definitions(-DBUILD_SHARED_LIBS) + if (CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW) + # Just setting CMAKE_POSITION_INDEPENDENT_CODE should be enough to set + # -fPIC for GCC but sometimes it still doesn't get set, so make sure it + # does. + add_definitions("-fPIC") + endif() + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif(BUILD_SHARED_LIBS) include(CMakePackageConfigHelpers) include(GNUInstallDirs) @@ -68,18 +85,6 @@ include(CheckIncludeFile) include(CheckIncludeFileCXX) include(CheckFunctionExists) -# Create install runtime target -add_custom_target(install-runtime - COMMAND - "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=Runtime - -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake" -) -# Create uninstall runtime target -add_custom_target(uninstall-runtime - COMMAND - "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=Runtime - -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" -) # Create will be delete files CONFIGURE_FILE( "${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" @@ -92,6 +97,19 @@ ADD_CUSTOM_TARGET(uninstall add_subdirectory(src) +OPTION(BUILD_TEST "Build test" OFF) +if(BUILD_TEST) + add_subdirectory(test) +endif(BUILD_TEST) + +CONFIGURE_FILE( + "${CMAKE_SOURCE_DIR}/cmake/coturnConfig.cmake.in" + "${CMAKE_BINARY_DIR}/coturnConfig.cmake" + IMMEDIATE @ONLY) +install(FILES "${CMAKE_BINARY_DIR}/coturnConfig.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/coturn" + COMPONENT Development) + install(DIRECTORY man DESTINATION . COMPONENT Runtime) install(DIRECTORY turndb/ @@ -115,11 +133,11 @@ install(FILES examples/etc/turnserver.conf RENAME turnserver.conf.default ) install(DIRECTORY - examples/etc - examples/scripts - DESTINATION share/examples/turnserver - PATTERN "rfc5769.sh" EXCLUDE + examples + DESTINATION share + COMPONENT examples ) +include(cmake/CMakeCPack.cmake) if(FUZZER) if (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang") diff --git a/cmake/CMakeCPack.cmake b/cmake/CMakeCPack.cmake new file mode 100644 index 00000000..1f38c3ad --- /dev/null +++ b/cmake/CMakeCPack.cmake @@ -0,0 +1,91 @@ +# Author: Kang Lin + +configure_file("${CMAKE_SOURCE_DIR}/cmake/CMakeCPackOptions.cmake.in" + "${CMAKE_BINARY_DIR}/CMakeCPackOptions.cmake" @ONLY) +set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_BINARY_DIR}/CMakeCPackOptions.cmake") + +# Generate .txt license file for CPack (PackageMaker requires a file extension) +configure_file(${CMAKE_SOURCE_DIR}/LICENSE ${CMAKE_BINARY_DIR}/LICENSE.txt @ONLY) + +SET(CPACK_BINARY_ZIP "ON") + +set(CPACK_SOURCE_IGNORE_FILES + ${CMAKE_SOURCE_DIR}/build + ${CMAKE_SOURCE_DIR}/.cache + ${CMAKE_SOURCE_DIR}/.git + ${CMAKE_SOURCE_DIR}/.github + ${CMAKE_SOURCE_DIR}/.gitignore + ${CMAKE_SOURCE_DIR}/.dockerignore + ${CMAKE_SOURCE_DIR}/CMakeCache.txt) + +set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}") +set(CPACK_TOPLEVEL_TAG "${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}") +string(TOLOWER ${CMAKE_PROJECT_NAME} CMAKE_PROJECT_NAME_lower) +set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME_lower}_${BUILD_VERSION}_${CPACK_SYSTEM_NAME}") +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME_lower}_${BUILD_VERSION}_${CPACK_SYSTEM_NAME}") +#set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/package) + +set(CPACK_PACKAGE_NAME "coturn") +set(CPACK_PACKAGE_VENDOR "coturn") +set(CPACK_PACKAGE_VERSION ${BUILD_VERSION}) +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "coturn: Free open source implementation of TURN and STUN Server") +#set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md") +#set(CPACK_RESOURCE_FILE_WELCOME ) +set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_BINARY_DIR}/LICENSE.txt") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/coturn/coturn") +set(CPACK_PACKAGE_CONTACT "misi ") + +set(CPACK_PACKAGE_INSTALL_DIRECTORY "coturn") +set(CPACK_PACKAGE_CHECKSUM "MD5") + +############### Debian ################### +if(UNIX) + set(CPACK_BINARY_DEB ON) +endif() +set(CPACK_DEBIAN_PACKAGE_SOURCE coturn) +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "misi ") +#set(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR}) +set(CPACK_DEBIAN_PACKAGE_SECTION "main") +set(CPACK_DEBIAN_PACKAGE_PREDEPENDS "debhelper (>= 6), cmake (>= 2.8.0), dh-systemd (>= 1.5)") +#set(CMAKE_INSTALL_RPATH ) +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) +#set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY ">=") +#set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA +# "${CMAKE_CURRENT_SOURCE_DIR}/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm") +############### Debian ################### + +#set(CPACK_PACKAGE_EXECUTABLES turnadmin turnclient) +#set(CPACK_CREATE_DESKTOP_LINKS turnadmin turnclient) + +############### NSIS ################### +if(WIN32) + set(CPACK_BINARY_NSIS ON) +endif() +#set(CPACK_NSIS_INSTALL_ROOT "$LOCALAPPDATA") +set(CPACK_NSIS_MODIFY_PATH ON) +set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) +#set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources\\\\coturn_Install.bmp") +#set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources\\\\coturn_Icon_96px.ico") +#set(CPACK_NSIS_MUI_UNICON "${CMAKE_SOURCE_DIR}/resource\\\\coturn_Icon_96px.ico") +############### NSIS ################### + +#set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE ) +set(CPACK_COMPONENTS_ALL Runtime Development) + +SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT Runtime) +include(InstallRequiredSystemLibraries) +include(CPackComponent) +include(CPack) + +cpack_add_component(Development + DISPLAY_NAME "Development" + DESCRIPTION "Development" + DEPENDS Runtime + ) + +cpack_add_component(Runtime + DISPLAY_NAME "Runtime" + DESCRIPTION "Runtime" + ) \ No newline at end of file diff --git a/cmake/CMakeCPackOptions.cmake.in b/cmake/CMakeCPackOptions.cmake.in new file mode 100644 index 00000000..f72e595d --- /dev/null +++ b/cmake/CMakeCPackOptions.cmake.in @@ -0,0 +1,12 @@ +# Author: Kang Lin + +# This file is configured at cmake time, and loaded at cpack time. +# To pass variables to cpack from cmake, they must be configured in this file. + +if("${CPACK_GENERATOR}" STREQUAL "PackageMaker") + if(CMAKE_PACKAGE_QTGUI) + set(CPACK_PACKAGE_DEFAULT_LOCATION "/Applications") + else() + set(CPACK_PACKAGE_DEFAULT_LOCATION "/usr") + endif() +endif() diff --git a/cmake/coturnConfig.cmake.in b/cmake/coturnConfig.cmake.in new file mode 100644 index 00000000..0172521a --- /dev/null +++ b/cmake/coturnConfig.cmake.in @@ -0,0 +1,51 @@ +# - Try to find coturn +# +# Usage from an external project: +# In your CMakeLists.txt, add these lines: +# +# find_package(coturn) +# target_link_libraries(MY_TARGET_NAME ${coturn_LIBRARIES}) +# +# This file will define the following variables: +# coturn_FOUND: True if find coturn, other false +# coturn_LIBRARIES: The list of all imported targets for coturn components +# +# Author: Kang Lin + +include(FindPackageHandleStandardArgs) + +if (NOT coturn_FIND_COMPONENTS) + set(coturn_FIND_COMPONENTS + turncommon + turnclient + turn_server + ) +endif() + +get_filename_component(_coturn_module_paths "${CMAKE_CURRENT_LIST_DIR}" ABSOLUTE) + +set(_coturn_FIND_PARTS_REQUIRED) +if (coturn_FIND_REQUIRED) + set(_coturn_FIND_PARTS_REQUIRED REQUIRED) +endif() +set(_coturn_FIND_PARTS_QUIET) +if (coturn_FIND_QUIETLY) + set(_coturn_FIND_PARTS_QUIET QUIET) +endif() + +foreach(module ${coturn_FIND_COMPONENTS}) + find_package(${module} + ${_coturn_FIND_PARTS_QUIET} + ${_coturn_FIND_PARTS_REQUIRED} + PATHS ${_coturn_module_paths} NO_DEFAULT_PATH + ) + if(${module}_FOUND) + list(APPEND coturn_LIBRARIES coturn::${module}) + endif() + list(APPEND required "${module}_FOUND") +endforeach() + +# Run checks via find_package_handle_standard_args +find_package_handle_standard_args(coturn + FOUND_VAR coturn_FOUND + REQUIRED_VARS ${required}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a762cf14..8d6ca26f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(coturn) diff --git a/src/apps/CMakeLists.txt b/src/apps/CMakeLists.txt index 4d1c558c..58477968 100644 --- a/src/apps/CMakeLists.txt +++ b/src/apps/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin add_subdirectory(common) add_subdirectory(natdiscovery) diff --git a/src/apps/common/CMakeLists.txt b/src/apps/common/CMakeLists.txt index af5ad635..b3f45ace 100644 --- a/src/apps/common/CMakeLists.txt +++ b/src/apps/common/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turncommon) @@ -15,18 +15,39 @@ set(HEADER_FILES stun_buffer.h ) -if(NOT WIN32) - set(COMMON_LIBS pthread) +if(MSVC) + list(APPEND COMMON_INCLUDE_DIR $) + list(APPEND SOURCE_FILES win/getopt.c) + list(APPEND HEADER_FILES win/getopt.h) endif() -set(libevent_components core extra openssl) -if(NOT WIN32) - list(APPEND libevent_components pthreads) + +if(MSVC OR MINGW) + list(APPEND COMMON_DEFINED WINDOWS) + list(APPEND COMMON_LIBS Ws2_32 netapi32) endif() -find_package(Libevent COMPONENTS ${libevent_components}) + +find_package(OpenSSL REQUIRED COMPONENTS Crypto SSL) +list(APPEND COMMON_LIBS OpenSSL::SSL OpenSSL::Crypto) + +if(MSVC) + find_package(pthreads REQUIRED) + list(APPEND COMMON_LIBS PThreads4W::PThreads4W) +else() + find_package(Threads REQUIRED) + list(APPEND COMMON_LIBS Threads::Threads) +endif() + +find_package(Libevent CONFIG) if(Libevent_FOUND) - foreach(_libevent_com ${libevent_components}) - list(APPEND COMMON_LIBS Libevent::${_libevent_com}) - endforeach() + list(APPEND COMMON_LIBS libevent::core libevent::extra libevent::openssl) +else() + find_package(Libevent MODULE) + if(Libevent_FOUND) + list(APPEND COMMON_LIBS ${Libevent_LIBRARIES}) + list(APPEND COMMON_INCLUDE_DIR ${Libevent_INCLUDE_DIRS}) + else() + message(FATAL_ERROR "Must set Libevent") + endif() endif() find_package(hiredis) @@ -37,18 +58,15 @@ if(hiredis_FOUND) else() list(APPEND COMMON_DEFINED TURN_NO_HIREDIS) endif() - -find_package(OpenSSL REQUIRED Crypto SSL) -list(APPEND COMMON_LIBS OpenSSL::Crypto) -list(APPEND COMMON_LIBS OpenSSL::SSL) - message("COMMON_LIBS:${COMMON_LIBS}") -add_library(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES}) +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES}) target_link_libraries(${PROJECT_NAME} PUBLIC ${COMMON_LIBS}) target_compile_definitions(${PROJECT_NAME} PUBLIC ${COMMON_DEFINED}) -target_compile_options(${PROJECT_NAME} PUBLIC -Wno-deprecated-declarations) +target_compile_options(${PROJECT_NAME} PUBLIC + $<$:-Wno-deprecated-declarations> + $<$:-Wno-deprecated-declarations>) # See: http://www.it1352.com/478094.html target_include_directories(${PROJECT_NAME} PUBLIC @@ -60,8 +78,11 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${COMMON_INCLUDE_DIR} ) -# Install head files set_target_properties(${PROJECT_NAME} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib + PUBLIC_HEADER "${HEADER_FILES}" # Install header files VERSION ${VERSION} ) @@ -72,26 +93,31 @@ INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Runtime ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + COMPONENT Development + PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/turn" + COMPONENT Development INCLUDES DESTINATION - ${CMAKE_INSTALL_INCLUDEDIR} - ${CMAKE_INSTALL_INCLUDEDIR}/turn - ${CMAKE_INSTALL_INCLUDEDIR}/turn/client + "${CMAKE_INSTALL_INCLUDEDIR}/turn" ) export(TARGETS ${PROJECT_NAME} - APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake + APPEND FILE "${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + NAMESPACE coturn:: ) # Install cmake configure files install(EXPORT ${PROJECT_NAME}Config - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" + NAMESPACE coturn:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/coturn" + COMPONENT Development ) # Install cmake version configure file if(DEFINED VERSION) write_basic_package_version_file( "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - VERSION ${VERSION} + VERSION "${VERSION}" COMPATIBILITY AnyNewerVersion) install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/coturn" + COMPONENT Development) endif() diff --git a/src/apps/common/apputils.c b/src/apps/common/apputils.c index 8877e8c9..fa149d44 100644 --- a/src/apps/common/apputils.c +++ b/src/apps/common/apputils.c @@ -35,18 +35,39 @@ #include +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) + #include + #include + #include +#endif +#if defined(__unix__) || defined(unix) + #include + #include + #include + #include +#endif + +#if defined(WINDOWS) + #include +#endif + +#if defined(_MSC_VER) + #include +#else + #include +#endif + #include #include #include #include -#include -#include -#include -#include +#include +#include +#include #include -#include #if !defined(TURN_NO_SCTP) && defined(TURN_SCTP_INCLUDE) #include TURN_SCTP_INCLUDE @@ -60,7 +81,7 @@ int IS_TURN_SERVER = 0; int socket_set_nonblocking(evutil_socket_t fd) { -#if defined(WIN32) +#if defined(WINDOWS) unsigned long nonblocking = 1; ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking); #else @@ -76,7 +97,12 @@ void read_spare_buffer(evutil_socket_t fd) { if(fd >= 0) { static char buffer[65536]; +#if defined(WINDOWS) + //TODO: add set no-block? by Kang Lin + recv(fd, buffer, sizeof(buffer), 0); +#else recv(fd, buffer, sizeof(buffer), MSG_DONTWAIT); +#endif } } @@ -115,6 +141,29 @@ int set_sock_buf_size(evutil_socket_t fd, int sz0) return 0; } +int socket_init() +{ +#if defined(WINDOWS) + { + WORD wVersionRequested; + WSADATA wsaData; + int e; + + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); + + e = WSAStartup(wVersionRequested, &wsaData); + if (e != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WSAStartup failed with error: %d\n", e); + return 1; + } + } +#endif + return 0; +} + int socket_tcp_set_keepalive(evutil_socket_t fd,SOCKET_TYPE st) { UNUSED_ARG(st); @@ -147,7 +196,7 @@ int socket_set_reusable(evutil_socket_t fd, int flag, SOCKET_TYPE st) return -1; else { -#if defined(WIN32) +#if defined(WINDOWS) int use_reuseaddr = IS_TURN_SERVER; #else int use_reuseaddr = 1; @@ -691,12 +740,15 @@ int handle_socket_error(void) { * Must close connection. */ return 0; +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) case EHOSTDOWN: /* Host is down. * Just ignore, might be an attacker * sending fake ICMP messages. */ return 1; +#endif case ECONNRESET: case ECONNREFUSED: /* Connection reset by peer. */ @@ -731,6 +783,259 @@ char *skip_blanks(char* s) return s; } +#if defined(_MSC_VER) + +LARGE_INTEGER getFILETIMEoffset() +{ + SYSTEMTIME s; + FILETIME f; + LARGE_INTEGER t; + + s.wYear = 1970; + s.wMonth = 1; + s.wDay = 1; + s.wHour = 0; + s.wMinute = 0; + s.wSecond = 0; + s.wMilliseconds = 0; + SystemTimeToFileTime(&s, &f); + t.QuadPart = f.dwHighDateTime; + t.QuadPart <<= 32; + t.QuadPart |= f.dwLowDateTime; + return (t); +} + +int clock_gettime(int X, struct timeval* tv) +{ + LARGE_INTEGER t; + FILETIME f; + double microseconds; + static LARGE_INTEGER offset; + static double frequencyToMicroseconds; + static int initialized = 0; + static BOOL usePerformanceCounter = FALSE; + + if (!initialized) { + LARGE_INTEGER performanceFrequency; + initialized = 1; + usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency); + if (usePerformanceCounter) { + QueryPerformanceCounter(&offset); + frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.; + } + else { + offset = getFILETIMEoffset(); + frequencyToMicroseconds = 10.; + } + } + if (usePerformanceCounter) QueryPerformanceCounter(&t); + else { + GetSystemTimeAsFileTime(&f); + t.QuadPart = f.dwHighDateTime; + t.QuadPart <<= 32; + t.QuadPart |= f.dwLowDateTime; + } + + t.QuadPart -= offset.QuadPart; + microseconds = (double)t.QuadPart / frequencyToMicroseconds; + t.QuadPart = microseconds; + tv->tv_sec = t.QuadPart / 1000000; + tv->tv_usec = t.QuadPart % 1000000; + return 0; +} + +int gettimeofday(struct timeval* tp, void* tzp) +{ + time_t clock; + struct tm tm; + SYSTEMTIME wtm; + + GetLocalTime(&wtm); + tm.tm_year = wtm.wYear - 1900; + tm.tm_mon = wtm.wMonth - 1; + tm.tm_mday = wtm.wDay; + tm.tm_hour = wtm.wHour; + tm.tm_min = wtm.wMinute; + tm.tm_sec = wtm.wSecond; + tm.tm_isdst = -1; + clock = mktime(&tm); + tp->tv_sec = clock; + tp->tv_usec = wtm.wMilliseconds * 1000; + + return (0); +} + +char* dirname(char* path) +{ + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + + errno_t err = _splitpath_s(path, + drive, _MAX_DRIVE, + dir, _MAX_DIR, + NULL, 0, + NULL, 0); + if (err) + { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "split path fail: %d", err); + return NULL; + } + + int n = strlen(drive) + strlen(dir); + if (n > 0) + path[n] = 0; + else + return NULL; + return path; +} +#endif + +#if defined(WINDOWS) +int getdomainname(char* name, size_t len) +{ + DSROLE_PRIMARY_DOMAIN_INFO_BASIC* info; + DWORD dw; + + dw = DsRoleGetPrimaryDomainInformation(NULL, + DsRolePrimaryDomainInfoBasic, + (PBYTE*)&info); + if (dw != ERROR_SUCCESS) + { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "DsRoleGetPrimaryDomainInformation: %u\n", dw); + return -1; + } + + do { + if (info->DomainForestName) + { + char* pszOut = NULL; + int nOutSize = 0; + if (_WTA(info->DomainForestName, wcslen(info->DomainForestName), &pszOut, &nOutSize)) + { + int n = nOutSize - 1; + if (nOutSize > len - 1) + { + n = len - 1; + } + strncpy(name, pszOut, n); + name[n] = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainForestName: %s\n", pszOut); + } + else + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); + + free(pszOut); + break; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainForestName is NULL\n"); + } + + if (info->DomainNameDns) + { + char* pszOut = NULL; + int nOutSize = 0; + if (_WTA(info->DomainNameDns, wcslen(info->DomainNameDns), &pszOut, &nOutSize)) + { + int n = nOutSize - 1; + if (nOutSize > len - 1) + { + n = len - 1; + } + strncpy(name, pszOut, n); + name[n] = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameDns: %s\n", pszOut); + } + else + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); + + free(pszOut); + break; + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameDns is NULL\n"); + } + + if (info->DomainNameFlat) + { + char* pszOut = NULL; + int nOutSize = 0; + if (_WTA(info->DomainNameFlat, wcslen(info->DomainNameFlat), &pszOut, &nOutSize)) + { + int n = nOutSize - 1; + if (nOutSize > len - 1) + { + n = len - 1; + } + strncpy(name, pszOut, n); + name[n] = 0; + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameFlat: %s\n", pszOut); + } + else + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail"); + + free(pszOut); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameFlat is NULL\n"); + return -2; + } + } while (0); + + DsRoleFreeMemory(info); + return 0; +} + +/*! + * \brief convert char to wchar + * + * \param pszInBuf: input buffer of wchar string + * \param nInSize: size of wchar string + * \param pszOutBuf: output buffer of char string + * \param pnOutSize: size of char string + * \return + */ +wchar_t* _ATW(__in char* pszInBuf, __in int nInSize, __out wchar_t** pszOutBuf, __out int* pnOutSize) +{ + if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0) return NULL; + // Get buffer size + *pnOutSize = MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0); + if (*pnOutSize == 0) return NULL; + (*pnOutSize)++; + *pszOutBuf = malloc((*pnOutSize) * sizeof(wchar_t)); + memset((void*)*pszOutBuf, 0, sizeof(wchar_t) * (*pnOutSize)); + if (MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize) == 0) + { + free(*pszOutBuf); + return NULL; + } + else return *pszOutBuf; +} + +/*! + * \brief convert wchar to char + * + * \param pszInBuf: input buffer of char string + * \param nInSize: size of char string + * \param pszOutBuf: output buffer of wchar string + * \param pnOutSize: size of wchar string + * \return + */ +char* _WTA(__in wchar_t* pszInBuf, __in int nInSize, __out char** pszOutBuf, __out int* pnOutSize) +{ + if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0) return NULL; + *pnOutSize = WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0, NULL, NULL); + if (*pnOutSize == 0) return NULL; + (*pnOutSize)++; + *pszOutBuf = malloc(*pnOutSize * sizeof(char)); + memset((void*)*pszOutBuf, 0, sizeof(char) * (*pnOutSize)); + if (WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize, NULL, NULL) == 0) + { + free(*pszOutBuf); + return NULL; + } + else return *pszOutBuf; +} + +#endif + //////////////////// Config file search ////////////////////// #define Q(x) #x @@ -751,18 +1056,29 @@ static char *c_execdir=NULL; void set_execdir(void) { /* On some systems, this may give us the execution path */ - char *_var = getenv("_"); - if(_var && *_var) { + char *_var = NULL; +#if defined(_MSC_VER) + char szPath[MAX_PATH]; + if (!GetModuleFileNameA(NULL, szPath, MAX_PATH)) + { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "GetModuleFileName failed(%d)\n", GetLastError()); + return; + } + _var = szPath; +#elif defined(__unix__) + _var = getenv("_"); +#endif + if (_var && *_var) { _var = strdup(_var); - char *edir=_var; - if(edir[0]!='.') - edir = strstr(edir,"/"); - if(edir && *edir) - edir = dirname(edir); + char *edir = _var; + if (edir[0] != '.') + edir = strstr(edir, "/"); + if (edir && *edir) + edir = dirname(edir); else - edir = dirname(_var); - if(c_execdir) - free(c_execdir); + edir = dirname(_var); + if (c_execdir) + free(c_execdir); c_execdir = strdup(edir); free(_var); } @@ -880,10 +1196,12 @@ char* find_config_file(const char *config_file, int print_file_name) void ignore_sigpipe(void) { +#if defined(__linux__) || defined(__APPLE__) /* Ignore SIGPIPE from TCP sockets */ if(signal(SIGPIPE, SIG_IGN) == SIG_ERR) { perror("Cannot set SIGPIPE handler"); } +#endif } static uint64_t turn_getRandTime(void) { @@ -899,16 +1217,34 @@ static uint64_t turn_getRandTime(void) { return current_mstime; } +void turn_srandom(void) +{ +#if defined(WINDOWS) + srand((unsigned int)(turn_getRandTime() + (unsigned int)((long)(&turn_getRandTime)))); +#else + srandom((unsigned int)(turn_getRandTime() + (unsigned int)((long)(&turn_getRandTime)))); +#endif +} + unsigned long set_system_parameters(int max_resources) { - srandom((unsigned int) (turn_getRandTime() + (unsigned int)((long)(&turn_getRandTime)))); + turn_srandom(); + setlocale(LC_ALL, "C"); build_base64_decoding_table(); ignore_sigpipe(); - if(max_resources) { + if (max_resources) { +#if defined(WINDOWS) + int num = 0; + //TODO: get max socket? by KangLin + + num = _getmaxstdio(); + return num; +#elif defined(__linux__) || defined(__APPLE__) + struct rlimit rlim; if(getrlimit(RLIMIT_NOFILE, &rlim)<0) { perror("Cannot get system limit"); @@ -919,11 +1255,35 @@ unsigned long set_system_parameters(int max_resources) } return (unsigned long)rlim.rlim_cur; } + +#endif } return 0; } +unsigned long get_system_number_of_cpus() +{ +#if defined(WINDOWS) + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %d\n", sysInfo.dwNumberOfProcessors); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is 0x%X\n", sysInfo.dwActiveProcessorMask); + return sysInfo.dwNumberOfProcessors; +#else + #if defined(_SC_NPROCESSORS_ONLN) + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %d \n", sysconf(_SC_NPROCESSORS_CONF)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is %d\n", sysconf(_SC_NPROCESSORS_ONLN)); + return sysconf(_SC_NPROCESSORS_CONF); + #else + //GNU way + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System cpu num is %d\n", get_nprocs_conf()); + TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "System enable num is %d\n", get_nprocs()); + return get_nprocs_conf(); + #endif +#endif +} + ////////////////////// Base 64 //////////////////////////// static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', diff --git a/src/apps/common/apputils.h b/src/apps/common/apputils.h index b6faad97..909025bd 100644 --- a/src/apps/common/apputils.h +++ b/src/apps/common/apputils.h @@ -159,7 +159,7 @@ typedef struct _oauth_key_data_raw oauth_key_data_raw; ///////////////////////// Sockets /////////////////////////////// -#if defined(WIN32) +#if defined(WINDOWS) /** Do the platform-specific call needed to close a socket returned from socket() or accept(). */ #define socket_closesocket(s) closesocket(s) @@ -173,6 +173,7 @@ void read_spare_buffer(evutil_socket_t fd); int set_sock_buf_size(evutil_socket_t fd, int sz); +int socket_init(); int socket_set_reusable(evutil_socket_t fd, int reusable, SOCKET_TYPE st); int sock_bind_to_device(evutil_socket_t fd, const unsigned char* ifname); int socket_set_nonblocking(evutil_socket_t fd); @@ -198,6 +199,7 @@ int get_raw_socket_ttl(evutil_socket_t fd, int family); void ignore_sigpipe(void); unsigned long set_system_parameters(int max_resources); +unsigned long get_system_number_of_cpus(); ///////////////////////// MTU ////////////////////////// @@ -216,6 +218,22 @@ int get_socket_mtu(evutil_socket_t fd, int family, int verbose); char *skip_blanks(char* s); +#if defined(_MSC_VER) + #define CLOCK_REALTIME 0 + int clock_gettime(int X, struct timeval* tv); + int gettimeofday(struct timeval* tp, void* tzp); + + char* dirname(char* path); +#endif + +#if defined(WINDOWS) + int getdomainname(char* name, size_t len); + // wchar convert to char + char* _WTA(__in wchar_t* pszInBufBuf, __in int nInSize, __out char** pszOutBuf, __out int* pnOutSize); + // char convert to wchar + wchar_t* _ATW(__in char* pszInBuf, __in int nInSize, __out wchar_t** pszOutBuf, __out int* pnOutSize); +#endif + ////////////////// File search //////////////////////// char* find_config_file(const char *config_file, int print_file_name); @@ -246,6 +264,10 @@ void convert_oauth_key_data_raw(const oauth_key_data_raw *raw, oauth_key_data *o struct event_base *turn_event_base_new(void); +//////////// Random ///////////////////// + +void turn_srandom(void); + /////////////////////////////////////////////////////// #ifdef __cplusplus diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 0982d31d..e6074b33 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -38,7 +38,11 @@ #include -#include +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) + #include +#endif + #include #include @@ -48,6 +52,8 @@ ////////// LOG TIME OPTIMIZATION /////////// +static volatile int _log_file_line_set = 0; + static volatile turn_time_t log_start_time = 0; volatile int _log_time_value_set = 0; volatile turn_time_t _log_time_value = 0; @@ -157,6 +163,8 @@ static char* str_fac[]={"LOG_AUTH","LOG_CRON","LOG_DAEMON", "LOG_AUTHPRIV","LOG_SYSLOG", 0}; +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) static int int_fac[]={LOG_AUTH , LOG_CRON , LOG_DAEMON , LOG_KERN , LOG_LOCAL0 , LOG_LOCAL1 , LOG_LOCAL2 , LOG_LOCAL3 , LOG_LOCAL4 , LOG_LOCAL5 , @@ -176,18 +184,21 @@ static int str_to_syslog_facility(char *s) } return -1; } - +#endif void set_syslog_facility(char *val) { if(val == NULL){ return; } +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) int tmp = str_to_syslog_facility(val); if(tmp == -1){ TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: invalid syslog-facility value (%s); ignored.\n", val); return; } syslog_facility = tmp; +#endif } #if defined(TURN_LOG_FUNC_IMPL) @@ -292,6 +303,11 @@ void set_logfile(const char *fn) } } +void set_log_file_line(int set) +{ + _log_file_line_set = set; +} + void reset_rtpprintf(void) { log_lock(); @@ -361,9 +377,12 @@ static void set_log_file_name_func(char *base, char *f, size_t fsz) static void sighup_callback_handler(int signum) { +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) if(signum == SIGHUP) { to_reset_log_file = 1; } +#endif } static void set_rtpfile(void) @@ -377,7 +396,12 @@ static void set_rtpfile(void) if(to_syslog) { return; } else if (!_rtpfile) { + +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) signal(SIGHUP, sighup_callback_handler); +#endif + if(log_fn_base[0]) { if(!strcmp(log_fn_base,"syslog")) { _rtpfile = stdout; @@ -516,6 +540,8 @@ void rollover_logfile(void) static int get_syslog_level(TURN_LOG_LEVEL level) { +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) switch(level) { case TURN_LOG_LEVEL_CONTROL: return LOG_NOTICE; @@ -527,9 +553,21 @@ static int get_syslog_level(TURN_LOG_LEVEL level) ; }; return LOG_INFO; +#endif + return level; } -void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) +#if defined(WINDOWS) +void err(int eval, const char *format, ...) +{ + va_list args; + va_start(args, format); + TURN_LOG_FUNC(eval, format, args); + va_end(args); +} +#endif + +void turn_log_func_default(char* file, int line, TURN_LOG_LEVEL level, const char* format, ...) { va_list args; va_start(args,format); @@ -546,8 +584,28 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) } else { so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); } - so_far += snprintf(s + so_far, sizeof(s)-100, (level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); - so_far += vsnprintf(s + so_far,sizeof(s) - (so_far+1), format, args); + if (_log_file_line_set) + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "%s(%d):", file, line); + + switch (level) + { + case TURN_LOG_LEVEL_DEBUG: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "DEBUG: "); + break; + case TURN_LOG_LEVEL_INFO: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "INFO: "); + break; + case TURN_LOG_LEVEL_CONTROL: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "CONTROL: "); + break; + case TURN_LOG_LEVEL_WARNING: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "WARNING: "); + break; + case TURN_LOG_LEVEL_ERROR: + so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "ERROR: "); + break; + } + so_far += vsnprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far+1), format, args); if(so_far > MAX_RTPPRINTF_BUFFER_SIZE+1) { so_far=MAX_RTPPRINTF_BUFFER_SIZE+1; @@ -556,7 +614,15 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) fwrite(s, so_far, 1, stdout); /* write to syslog or to log file */ if(to_syslog) { - syslog(syslog_facility|get_syslog_level(level),"%s",s); + +#if defined(WINDOWS) + //TODO: add event tracing: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing + // windows10: https://docs.microsoft.com/en-us/windows/win32/tracelogging/trace-logging-portal + printf("%s", s); +#else + syslog(syslog_facility | get_syslog_level(level), "%s", s); +#endif + } else { log_lock(); set_rtpfile(); diff --git a/src/apps/common/ns_turn_utils.h b/src/apps/common/ns_turn_utils.h index e5f65398..b1d7f3b3 100644 --- a/src/apps/common/ns_turn_utils.h +++ b/src/apps/common/ns_turn_utils.h @@ -32,8 +32,13 @@ #define __TURN_ULIB__ #if !defined(TURN_LOG_FUNC) -//#define TURN_LOG_FUNC(level, ...) printf (__VA_ARGS__) -#define TURN_LOG_FUNC turn_log_func_default +#define TURN_LOG_FUNC(level, ...) turn_log_func_default(__FILE__, __LINE__, level, __VA_ARGS__) +#endif + +#if defined(WINDOWS) + #ifndef err + void err(int eval, const char *format, ...); + #endif #endif #include "ns_turn_ioaddr.h" @@ -45,7 +50,8 @@ extern "C" { //////////////////////// LOG ////////////////////////// typedef enum { - TURN_LOG_LEVEL_INFO = 0, + TURN_LOG_LEVEL_DEBUG = 0, + TURN_LOG_LEVEL_INFO, TURN_LOG_LEVEL_CONTROL, TURN_LOG_LEVEL_WARNING, TURN_LOG_LEVEL_ERROR @@ -65,12 +71,11 @@ void set_syslog_facility(char *val); void set_turn_log_timestamp_format(char* new_format); -void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...); +void turn_log_func_default(char* file, int line, TURN_LOG_LEVEL level, const char* format, ...); void addr_debug_print(int verbose, const ioa_addr *addr, const char* s); /* Log */ - extern volatile int _log_time_value_set; extern volatile turn_time_t _log_time_value; extern int use_new_log_timestamp_format; @@ -80,6 +85,7 @@ int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args); void reset_rtpprintf(void); void set_logfile(const char *fn); void rollover_logfile(void); +void set_log_file_line(int set); /////////////////////////////////////////////////////// diff --git a/src/apps/common/stun_buffer.c b/src/apps/common/stun_buffer.c index fe128f33..ff7818b1 100644 --- a/src/apps/common/stun_buffer.c +++ b/src/apps/common/stun_buffer.c @@ -146,7 +146,7 @@ int stun_is_channel_message(stun_buffer* buf, uint16_t* chnumber, int is_padding size_t blen = (size_t)buf->len; int ret = stun_is_channel_message_str(buf->buf, &blen, chnumber, is_padding_mandatory); if(ret) { - buf->len=(ssize_t)blen; + buf->len = blen; } return ret; } diff --git a/src/apps/common/win/getopt.c b/src/apps/common/win/getopt.c new file mode 100644 index 00000000..0ed0dd25 --- /dev/null +++ b/src/apps/common/win/getopt.c @@ -0,0 +1,562 @@ +/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#ifndef __CYGWIN__ +#define __progname __argv[0] +#else +extern char __declspec(dllimport) *__progname; +#endif + +#ifdef __CYGWIN__ +static char EMSG[] = ""; +#else +#define EMSG "" +#endif + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +static void +_vwarnx(const char *fmt,va_list ap) +{ + (void)fprintf(stderr,"%s: ",__progname); + if (fmt != NULL) + (void)vfprintf(stderr,fmt,ap); + (void)fprintf(stderr,"\n"); +} + +static void +warnx(const char *fmt,...) +{ + va_list ap; + va_start(ap,fmt); + _vwarnx(fmt,ap); + va_end(ap); +} + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; + +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ + long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) + + current_argv = place; + match = -1; + ambiguous = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; + } + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +#undef IDENTICAL_INTERPRETATION +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + const char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + * + * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or + * optreset != 0 for GNU compatibility. + */ + if (posixly_correct == -1 || optreset != 0) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/src/apps/common/win/getopt.h b/src/apps/common/win/getopt.h new file mode 100644 index 00000000..f3f864bd --- /dev/null +++ b/src/apps/common/win/getopt.h @@ -0,0 +1,105 @@ +#ifndef __GETOPT_H__ +/** + * DISCLAIMER + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the w64 mingw-runtime package. + * + * The w64 mingw-runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#define __GETOPT_H__ + +/* All the headers include this file. */ +#include + +#if defined( WINGETOPT_SHARED_LIB ) +# if defined( BUILDING_WINGETOPT_DLL ) +# define WINGETOPT_API __declspec(dllexport) +# else +# define WINGETOPT_API __declspec(dllimport) +# endif +#else +# define WINGETOPT_API +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +WINGETOPT_API extern int optind; /* index of first non-option in argv */ +WINGETOPT_API extern int optopt; /* single option character, as parsed */ +WINGETOPT_API extern int opterr; /* flag to enable built-in diagnostics... */ + /* (user may set to zero, to suppress) */ + +WINGETOPT_API extern char *optarg; /* pointer to argument of current option */ + +extern int getopt(int nargc, char * const *nargv, const char *options); + +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset +extern int optreset; +#endif +#ifdef __cplusplus +} +#endif +/* + * POSIX requires the `getopt' API to be specified in `unistd.h'; + * thus, `unistd.h' includes this header. However, we do not want + * to expose the `getopt_long' or `getopt_long_only' APIs, when + * included in this manner. Thus, close the standard __GETOPT_H__ + * declarations block, and open an additional __GETOPT_LONG_H__ + * specific block, only when *not* __UNISTD_H_SOURCED__, in which + * to declare the extended API. + */ +#endif /* !defined(__GETOPT_H__) */ + +#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option /* specification for a long form option... */ +{ + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ +}; + +enum /* permitted values for its `has_arg' field... */ +{ + no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ +}; + +extern int getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +extern int getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +/* + * Previous MinGW implementation had... + */ +#ifndef HAVE_DECL_GETOPT +/* + * ...for the long form API only; keep this for compatibility. + */ +# define HAVE_DECL_GETOPT 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ diff --git a/src/apps/natdiscovery/CMakeLists.txt b/src/apps/natdiscovery/CMakeLists.txt index c7df4d1e..63607aed 100644 --- a/src/apps/natdiscovery/CMakeLists.txt +++ b/src/apps/natdiscovery/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnutils_natdiscovery) @@ -8,7 +8,15 @@ set(SOURCE_FILES add_executable(${PROJECT_NAME} ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE turnclient) +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) +install(DIRECTORY + $/ + DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) diff --git a/src/apps/natdiscovery/natdiscovery.c b/src/apps/natdiscovery/natdiscovery.c index fc70f53a..d783d80e 100644 --- a/src/apps/natdiscovery/natdiscovery.c +++ b/src/apps/natdiscovery/natdiscovery.c @@ -28,12 +28,16 @@ * SUCH DAMAGE. */ -#include #include #include #include #include +#if defined(WINDOWS) +#include +#else #include +#include +#endif #include "ns_turn_utils.h" #include "apputils.h" @@ -627,6 +631,7 @@ int main(int argc, char **argv) int first=1; ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr, local_addr, local2_addr; + if (socket_init()) return -1; set_logfile("stdout"); set_system_parameters(0); diff --git a/src/apps/oauth/CMakeLists.txt b/src/apps/oauth/CMakeLists.txt index 18ce9380..e26e739a 100644 --- a/src/apps/oauth/CMakeLists.txt +++ b/src/apps/oauth/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnutils_oauth) @@ -8,7 +8,15 @@ set(SOURCE_FILES add_executable(${PROJECT_NAME} ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE turnclient) +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) +install(DIRECTORY + $/ + DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index 7eb368bf..f005a860 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -28,11 +28,14 @@ * SUCH DAMAGE. */ +#if defined(__unix__) +#include +#endif + #include #include #include #include -#include #include #include diff --git a/src/apps/peer/CMakeLists.txt b/src/apps/peer/CMakeLists.txt index 3ff80574..7489767d 100644 --- a/src/apps/peer/CMakeLists.txt +++ b/src/apps/peer/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnutils_peer) @@ -8,7 +8,15 @@ set(SOURCE_FILES add_executable(${PROJECT_NAME} ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE turnclient) +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) +install(DIRECTORY + $/ + DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) diff --git a/src/apps/peer/mainudpserver.c b/src/apps/peer/mainudpserver.c index 2c500d78..c083b045 100644 --- a/src/apps/peer/mainudpserver.c +++ b/src/apps/peer/mainudpserver.c @@ -36,7 +36,11 @@ #include #include #include +#if defined(_MSC_VER) +#include +#else #include +#endif //////////////// local definitions ///////////////// @@ -60,6 +64,8 @@ int main(int argc, char **argv) int c; char ifname[1025] = "\0"; + if (socket_init()) return -1; + IS_TURN_SERVER = 1; set_logfile("stdout"); diff --git a/src/apps/peer/udpserver.c b/src/apps/peer/udpserver.c index 3ac34d25..cdbbd3e4 100644 --- a/src/apps/peer/udpserver.c +++ b/src/apps/peer/udpserver.c @@ -63,7 +63,7 @@ static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg) static int udp_create_server_socket(server_type* server, const char* ifname, const char *local_address, int port) { - FUNCSTART; + if(server && server->verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Start\n"); if(!server) return -1; @@ -96,7 +96,7 @@ static int udp_create_server_socket(server_type* server, event_add(udp_ev,NULL); - FUNCEND; + if(server && server->verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "End\n"); return 0; } diff --git a/src/apps/peer/udpserver.h b/src/apps/peer/udpserver.h index bd482c49..6dd1b035 100644 --- a/src/apps/peer/udpserver.h +++ b/src/apps/peer/udpserver.h @@ -46,11 +46,6 @@ extern "C" { struct server_info; typedef struct server_info server_type; -/////////////////////////////////////////////////// - -#define FUNCSTART if(server && server->verbose) turn_log_func_default(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__) -#define FUNCEND if(server && server->verbose) turn_log_func_default(TURN_LOG_LEVEL_INFO,"%s:%d:end\n",__FUNCTION__,__LINE__) - /////////////////////////////////////////////////////// struct server_info { diff --git a/src/apps/relay/CMakeLists.txt b/src/apps/relay/CMakeLists.txt index 9b1061cb..09026ad8 100644 --- a/src/apps/relay/CMakeLists.txt +++ b/src/apps/relay/CMakeLists.txt @@ -1,8 +1,17 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnserver) -set(HEAD_FILES +check_function_exists("pthread_barrier_init" HAVE_THREAD_BARRIERS) +if(NOT HAVE_THREAD_BARRIERS) + list(APPEND turnserver_DEFINED TURN_NO_THREAD_BARRIERS) +endif() + +if(MSVC OR MINGW) + list(APPEND turnserver_LIBS Iphlpapi) +endif() + +set(HEADER_FILES tls_listener.h mainrelay.h turn_admin_server.h @@ -34,7 +43,7 @@ find_package(SQLite) if(SQLite_FOUND) list(APPEND turnserver_LIBS SQLite::sqlite) list(APPEND SOURCE_FILES dbdrivers/dbd_sqlite.c) - list(APPEND HEAD_FILES dbdrivers/dbd_sqlite.h) + list(APPEND HEADER_FILES dbdrivers/dbd_sqlite.h) else() list(APPEND turnserver_DEFINED TURN_NO_SQLITE) endif() @@ -43,42 +52,57 @@ find_package(PostgreSQL) if(PostgreSQL_FOUND) list(APPEND turnserver_LIBS PostgreSQL::pq) list(APPEND SOURCE_FILES dbdrivers/dbd_pgsql.c) - list(APPEND HEAD_FILES dbdrivers/dbd_pgsql.h) + list(APPEND HEADER_FILES dbdrivers/dbd_pgsql.h) else() list(APPEND turnserver_DEFINED TURN_NO_PQ) endif() -find_package(MySQL) -if(MySQL_FOUND) +option(WITH_MYSQL "Use mysql" ON) +if(WITH_MYSQL) + find_package(MySQL) + if(MySQL_FOUND) list(APPEND turnserver_LIBS MySQL::mysql) list(APPEND SOURCE_FILES dbdrivers/dbd_mysql.c) - list(APPEND HEAD_FILES dbdrivers/dbd_mysql.h) + list(APPEND HEADER_FILES dbdrivers/dbd_mysql.h) + else() + list(APPEND turnserver_DEFINED TURN_NO_MYSQL) + endif() else() list(APPEND turnserver_DEFINED TURN_NO_MYSQL) endif() -find_package(mongo) -if(mongo_FOUND) +if(WIN32) + find_package(mongoc-1.0) + if(mongoc-1.0_FOUND) + list(APPEND turnserver_LIBS mongo::mongoc_shared) + list(APPEND SOURCE_FILES dbdrivers/dbd_mongo.c) + list(APPEND HEADER_FILES dbdrivers/dbd_mongo.h) + else() + list(APPEND turnserver_DEFINED TURN_NO_MONGO) + endif() +else() + find_package(mongo) + if(mongo_FOUND) list(APPEND turnserver_LIBS mongo) list(APPEND SOURCE_FILES dbdrivers/dbd_mongo.c) - list(APPEND HEAD_FILES dbdrivers/dbd_mongo.h) -else() + list(APPEND HEADER_FILES dbdrivers/dbd_mongo.h) + else() list(APPEND turnserver_DEFINED TURN_NO_MONGO) + endif() endif() find_package(hiredis) if(hiredis_FOUND) list(APPEND turnserver_LIBS hiredis::hiredis) list(APPEND SOURCE_FILES dbdrivers/dbd_redis.c) - list(APPEND HEAD_FILES dbdrivers/dbd_redis.h) + list(APPEND HEADER_FILES dbdrivers/dbd_redis.h) else() list(APPEND turnserver_DEFINED TURN_NO_HIREDIS) endif() -if(NOT APPLE) +if(UNIX) find_package(libsystemd) - if(libsystemd_FOUND) - else() + if(NOT libsystemd_FOUND) list(APPEND turnserver_DEFINED TURN_NO_SYSTEMD) endif() else() @@ -88,28 +112,49 @@ endif() find_package(Prometheus) if(Prometheus_FOUND) list(APPEND SOURCE_FILES prom_server.c) - list(APPEND HEAD_FILES prom_server.h) + list(APPEND HEADER_FILES prom_server.h) else() list(APPEND turnserver_DEFINED TURN_NO_PROMETHEUS) endif() list(APPEND turnserver_DEFINED TURN_NO_SCTP) -add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEAD_FILES}) +message("turnserver_LIBS:${turnserver_LIBS}") + +add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE turn_server ${turnserver_LIBS}) target_include_directories(${PROJECT_NAME} PRIVATE ${turnserver_include_dirs}) target_compile_definitions(${PROJECT_NAME} PRIVATE ${turnserver_DEFINED}) - -add_custom_target(turnadmin ALL - COMMAND - ${CMAKE_COMMAND} -E create_symlink $ turnadmin - DEPENDS ${PROJECT_NAME}) +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) -INSTALL(FILES $/turnadmin +install(DIRECTORY + $/ + DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) + +if(WIN32) + add_custom_target(turnadmin ALL + COMMAND + ${CMAKE_COMMAND} -E copy $ $/turnadmin.exe + DEPENDS ${PROJECT_NAME}) + INSTALL(FILES $/turnadmin.exe DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime) +else() + add_custom_target(turnadmin ALL + COMMAND + ${CMAKE_COMMAND} -E create_symlink $ $/turnadmin + DEPENDS ${PROJECT_NAME}) + INSTALL(FILES $/turnadmin + DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) +endif() diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.c b/src/apps/relay/dbdrivers/dbd_sqlite.c index 69aecbfb..b30051cf 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.c +++ b/src/apps/relay/dbdrivers/dbd_sqlite.c @@ -36,8 +36,12 @@ #include +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) #include +#include #include +#endif #include @@ -48,7 +52,11 @@ static pthread_cond_t rc_cond = PTHREAD_COND_INITIALIZER; static int read_threads = 0; static int write_level = 0; +#if defined(WINDOWS) +static pthread_t write_thread = {0}; +#else static pthread_t write_thread = 0; +#endif static void sqlite_lock(int write) { @@ -57,14 +65,29 @@ static void sqlite_lock(int write) int can_move = 0; while (!can_move) { pthread_mutex_lock(&rc_mutex); +#if defined(WINDOWS) + pthread_t zero = { 0 }; +#endif if (write) { - if (((write_thread == 0) && (read_threads < 1)) || (write_thread == pths)) { + if (( +#if defined(WINDOWS) + pthread_equal(write_thread, zero) +#else + write_thread == 0 +#endif + && (read_threads < 1)) || pthread_equal(write_thread, pths)) { can_move = 1; ++write_level; write_thread = pths; } } else { - if ((!write_thread) || (write_thread == pths)) { + if (( +#if defined(WINDOWS) + pthread_equal(write_thread, zero)) +#else + !write_thread) +#endif + || pthread_equal(write_thread, pths)) { can_move = 1; ++read_threads; } @@ -81,7 +104,12 @@ static void sqlite_unlock(int write) pthread_mutex_lock(&rc_mutex); if (write) { if (!(--write_level)) { +#if defined(WINDOWS) + pthread_t zero = { 0 }; + write_thread = zero; +#else write_thread = 0; +#endif pthread_cond_broadcast(&rc_cond); } } else { @@ -121,6 +149,8 @@ static int donot_print_connection_success = 0; static void fix_user_directory(char *dir0) { char *dir = dir0; while(*dir == ' ') ++dir; +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) if(*dir == '~') { char *home=getenv("HOME"); if(!home) { @@ -143,6 +173,7 @@ static void fix_user_directory(char *dir0) { strncpy(dir0,dir_fixed,sz); free(dir_fixed); } +#endif } static void init_sqlite_database(sqlite3 *sqliteconnection) { diff --git a/src/apps/relay/dtls_listener.c b/src/apps/relay/dtls_listener.c index 1485c0ea..61f1e5bf 100644 --- a/src/apps/relay/dtls_listener.c +++ b/src/apps/relay/dtls_listener.c @@ -41,6 +41,11 @@ /* #define REQUEST_CLIENT_CERT */ /////////////////////////////////////////////////// +#if defined(WINDOWS) + //TODO: test it! + /* Type to represent a port. */ + typedef uint16_t in_port_t; +#endif #define FUNCSTART if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__) #define FUNCEND if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:end\n",__FUNCTION__,__LINE__) @@ -390,15 +395,20 @@ static int handle_udp_packet(dtls_listener_relay_server_type *server, { uint8_t saddr[129]; uint8_t rsaddr[129]; - long thrid = (long) pthread_self(); addr_to_string(get_local_addr_from_ioa_socket(chs),saddr); addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr); + long thrid = 0; +#ifdef WINDOWS + thrid = GetCurrentThreadId(); +#else + thrid = (long)pthread_self(); +#endif TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: 111.111: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d\n", - __FUNCTION__, thrid, (long) amap, - (long) (chs->sockets_container), (char*) saddr, - (char*) rsaddr, (long) s, (int) (chs->done), - (int) (chs->tobeclosed)); + __FUNCTION__, thrid, (long)amap, + (long)(chs->sockets_container), (char*)saddr, + (char*)rsaddr, (long)s, (int)(chs->done), + (int)(chs->tobeclosed)); } } @@ -413,16 +423,22 @@ static int handle_udp_packet(dtls_listener_relay_server_type *server, { uint8_t saddr[129]; uint8_t rsaddr[129]; - long thrid = (long) pthread_self(); + addr_to_string(get_local_addr_from_ioa_socket(chs),saddr); addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr); + long thrid = 0; +#ifdef WINDOWS + thrid = GetCurrentThreadId(); +#else + thrid = (long)pthread_self(); +#endif TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: 111.222: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d, st=%d, sat=%d\n", - __FUNCTION__, thrid, (long) amap, - (long) (chs->sockets_container), (char*) saddr, - (char*) rsaddr, (long) chs, (int) (chs->done), - (int) (chs->tobeclosed), (int) (chs->st), - (int) (chs->sat)); + __FUNCTION__, thrid, (long)amap, + (long)(chs->sockets_container), (char*)saddr, + (char*)rsaddr, (long)chs, (int)(chs->done), + (int)(chs->tobeclosed), (int)(chs->st), + (int)(chs->sat)); } } @@ -643,9 +659,12 @@ static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg) addr_set_any(&(server->sm.m.sm.nd.src_addr)); ssize_t bsize = 0; - +#if defined(WINDOWS) + //TODO: implement it!!! + int flags = 0; +#else int flags = MSG_DONTWAIT; - +#endif bsize = udp_recvfrom(fd, &(server->sm.m.sm.nd.src_addr), &(server->addr), (char*)ioa_network_buffer_data(elem), (int)ioa_network_buffer_get_capacity_udp(), &(server->sm.m.sm.nd.recv_ttl), &(server->sm.m.sm.nd.recv_tos), @@ -665,8 +684,13 @@ static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg) #if defined(MSG_ERRQUEUE) +#if defined(WINDOWS) + //TODO: implement it!!! + int eflags = MSG_ERRQUEUE; +#else //Linux int eflags = MSG_ERRQUEUE | MSG_DONTWAIT; +#endif static char buffer[65535]; uint32_t errcode = 0; ioa_addr orig_addr; diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index 75907941..d82b4397 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -110,8 +110,7 @@ static struct headers_list * post_parse(char *data, size_t data_len) memcpy(post_data, data, data_len); char *fmarker = NULL; char *fsplit = strtok_r(post_data, "&", &fmarker); - struct headers_list *list = (struct headers_list*)malloc(sizeof(struct headers_list)); - memset(list,0,sizeof(struct headers_list)); + struct headers_list *list = (struct headers_list*)calloc(sizeof(struct headers_list), 1); while (fsplit != NULL) { char *vmarker = NULL; char *key = strtok_r(fsplit, "=", &vmarker); @@ -164,14 +163,12 @@ static struct http_request* parse_http_request_1(struct http_request* ret, char* const char *query = evhttp_uri_get_query(uri); if(query) { - struct evkeyvalq* kv = (struct evkeyvalq*)malloc(sizeof(struct evkeyvalq)); - memset(kv,0,sizeof(struct evkeyvalq)); + struct evkeyvalq* kv = (struct evkeyvalq*)calloc(sizeof(struct evkeyvalq), 1); if(evhttp_parse_query_str(query, kv)<0) { free(ret); ret = NULL; } else { - ret->headers = (struct http_headers*)malloc(sizeof(struct http_headers)); - memset(ret->headers,0,sizeof(struct http_headers)); + ret->headers = (struct http_headers*)calloc(sizeof(struct http_headers), 1); ret->headers->uri_headers = kv; } } @@ -186,8 +183,7 @@ static struct http_request* parse_http_request_1(struct http_request* ret, char* char *body = strstr(s+1,"\r\n\r\n"); if(body && body[0]) { if(!ret->headers) { - ret->headers = (struct http_headers*)malloc(sizeof(struct http_headers)); - memset(ret->headers,0,sizeof(struct http_headers)); + ret->headers = (struct http_headers*)calloc(sizeof(struct http_headers), 1); } ret->headers->post_headers = post_parse(body,strlen(body)); } @@ -207,8 +203,7 @@ struct http_request* parse_http_request(char* request) { if(request) { - ret = (struct http_request*)malloc(sizeof(struct http_request)); - memset(ret,0,sizeof(struct http_request)); + ret = (struct http_request*)calloc(sizeof(struct http_request), 1); if(strstr(request,"GET ") == request) { ret->rtype = HRT_GET; @@ -326,8 +321,8 @@ struct str_buffer { struct str_buffer* str_buffer_new(void) { - struct str_buffer* ret = (struct str_buffer*)malloc(sizeof(struct str_buffer)); - memset(ret,0,sizeof(struct str_buffer)); + struct str_buffer* ret = (struct str_buffer*)calloc(sizeof(struct str_buffer), 1); + ret->buffer = (char*)malloc(1); ret->buffer[0] = 0; ret->capacity = 1; diff --git a/src/apps/relay/libtelnet.c b/src/apps/relay/libtelnet.c index d765eae6..1fdf8269 100644 --- a/src/apps/relay/libtelnet.c +++ b/src/apps/relay/libtelnet.c @@ -21,7 +21,7 @@ #include /* Win32 compatibility */ -#if defined(_WIN32) +#if defined(WINDOWS) # define vsnprintf _vsnprintf # define __func__ __FUNCTION__ # define ZLIB_WINAPI 1 @@ -134,7 +134,7 @@ static const size_t _buffer_sizes_count = sizeof(_buffer_sizes) / #define Q_BUFFER_GROWTH_QUANTUM 4 /* error generation function */ -static telnet_error_t _error(telnet_t *telnet, unsigned line, +static telnet_error_t telnet_error(telnet_t *telnet, unsigned line, const char* func, telnet_error_t err, int fatal, const char *fmt, ...) { telnet_event_t ev; @@ -169,26 +169,26 @@ telnet_error_t _init_zlib(telnet_t *telnet, int deflate, int err_fatal) { /* if compression is already enabled, fail loudly */ if (telnet->z != 0) - return _error(telnet, __LINE__, __func__, TELNET_EBADVAL, + return telnet_error(telnet, __LINE__, __func__, TELNET_EBADVAL, err_fatal, "cannot initialize compression twice"); /* allocate zstream box */ if ((z= (z_stream *)calloc(1, sizeof(z_stream))) == 0) - return _error(telnet, __LINE__, __func__, TELNET_ENOMEM, err_fatal, + return telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, err_fatal, "malloc() failed: %s", strerror(errno)); /* initialize */ if (deflate) { if ((rs = deflateInit(z, Z_DEFAULT_COMPRESSION)) != Z_OK) { free(z); - return _error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, + return telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, err_fatal, "deflateInit() failed: %s", zError(rs)); } telnet->flags |= TELNET_PFLAG_DEFLATE; } else { if ((rs = inflateInit(z)) != Z_OK) { free(z); - return _error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, + return telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, err_fatal, "inflateInit() failed: %s", zError(rs)); } telnet->flags &= ~TELNET_PFLAG_DEFLATE; @@ -221,7 +221,7 @@ static void _send(telnet_t *telnet, const char *buffer, while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) { /* compress */ if ((rs = deflate(telnet->z, Z_SYNC_FLUSH)) != Z_OK) { - _error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, + telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, "deflate() failed: %s", zError(rs)); deflateEnd(telnet->z); free(telnet->z); @@ -336,7 +336,7 @@ static INLINE void _set_rfc1143(telnet_t *telnet, unsigned char telopt, if ((qtmp = (telnet_rfc1143_t *)realloc(telnet->q, sizeof(telnet_rfc1143_t) * (telnet->q_size + Q_BUFFER_GROWTH_QUANTUM))) == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "realloc() failed: %s", strerror(errno)); return; } @@ -404,13 +404,13 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) { case Q_WANTNO: _set_rfc1143(telnet, telopt, Q_US(q), Q_NO); NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "DONT answered by WILL"); break; case Q_WANTNO_OP: _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "DONT answered by WILL"); break; case Q_WANTYES: @@ -462,13 +462,13 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) { case Q_WANTNO: _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "WONT answered by DO"); break; case Q_WANTNO_OP: _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "WONT answered by DO"); break; case Q_WANTYES: @@ -537,7 +537,7 @@ static int _environ_telnet(telnet_t *telnet, unsigned char type, if ((unsigned)buffer[0] != TELNET_ENVIRON_SEND && (unsigned)buffer[0] != TELNET_ENVIRON_IS && (unsigned)buffer[0] != TELNET_ENVIRON_INFO) { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "telopt %d subneg has invalid command", type); return 0; } @@ -561,14 +561,14 @@ static int _environ_telnet(telnet_t *telnet, unsigned char type, /* very second byte must be VAR or USERVAR, if present */ if ((unsigned)buffer[1] != TELNET_ENVIRON_VAR && (unsigned)buffer[1] != TELNET_ENVIRON_USERVAR) { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "telopt %d subneg missing variable type", type); return 0; } /* ensure last byte is not an escape byte (makes parsing later easier) */ if ((unsigned)buffer[size - 1] == TELNET_ENVIRON_ESC) { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "telopt %d subneg ends with ESC", type); return 0; } @@ -587,7 +587,7 @@ static int _environ_telnet(telnet_t *telnet, unsigned char type, /* allocate argument array, bail on error */ if ((values = (struct telnet_environ_t *)calloc(count, sizeof(struct telnet_environ_t))) == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "calloc() failed: %s", strerror(errno)); return 0; } @@ -678,7 +678,7 @@ static int _mssp_telnet(telnet_t *telnet, char* buffer, size_t size) { /* first byte must be a VAR */ if ((unsigned)buffer[0] != TELNET_MSSP_VAR) { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "MSSP subnegotiation has invalid data"); return 0; } @@ -693,7 +693,7 @@ static int _mssp_telnet(telnet_t *telnet, char* buffer, size_t size) { /* allocate argument array, bail on error */ if ((values = (struct telnet_environ_t *)calloc(count, sizeof(struct telnet_environ_t))) == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "calloc() failed: %s", strerror(errno)); return 0; } @@ -720,7 +720,7 @@ static int _mssp_telnet(telnet_t *telnet, char* buffer, size_t size) { values[i].value = last; ++i; } else { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "invalid MSSP subnegotiation data"); free(values); return 0; @@ -750,7 +750,7 @@ static int _zmp_telnet(telnet_t *telnet, const char* buffer, size_t size) { /* make sure this is a valid ZMP buffer */ if (size == 0 || buffer[size - 1] != 0) { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "incomplete ZMP frame"); return 0; } @@ -761,7 +761,7 @@ static int _zmp_telnet(telnet_t *telnet, const char* buffer, size_t size) { /* allocate argument array, bail on error */ if ((argv = (const char **)calloc(argc, sizeof(const char *))) == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "calloc() failed: %s", strerror(errno)); return 0; } @@ -789,7 +789,7 @@ static int _ttype_telnet(telnet_t *telnet, const char* buffer, size_t size) { /* make sure request is not empty */ if (size == 0) { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "incomplete TERMINAL-TYPE request"); return 0; } @@ -797,7 +797,7 @@ static int _ttype_telnet(telnet_t *telnet, const char* buffer, size_t size) { /* make sure request has valid command type */ if (buffer[0] != TELNET_TTYPE_IS && buffer[0] != TELNET_TTYPE_SEND) { - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "TERMINAL-TYPE request has invalid type"); return 0; } @@ -808,7 +808,7 @@ static int _ttype_telnet(telnet_t *telnet, const char* buffer, size_t size) { /* allocate space for name */ if ((name = (char *)malloc(size)) == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno)); return 0; } @@ -948,7 +948,7 @@ static telnet_error_t _buffer_byte(telnet_t *telnet, /* overflow -- can't grow any more */ if (i >= _buffer_sizes_count - 1) { - _error(telnet, __LINE__, __func__, TELNET_EOVERFLOW, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EOVERFLOW, 0, "subnegotiation buffer size limit reached"); return TELNET_EOVERFLOW; } @@ -956,7 +956,7 @@ static telnet_error_t _buffer_byte(telnet_t *telnet, /* (re)allocate buffer */ new_buffer = (char *)realloc(telnet->buffer, _buffer_sizes[i + 1]); if (new_buffer == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "realloc() failed"); return TELNET_ENOMEM; } @@ -1141,7 +1141,7 @@ static void _process(telnet_t *telnet, const char *buffer, size_t size) { * given command as an IAC code. */ default: - _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "unexpected byte after IAC inside SB: %d", byte); @@ -1204,7 +1204,7 @@ void telnet_recv(telnet_t *telnet, const char *buffer, _process(telnet, inflate_buffer, sizeof(inflate_buffer) - telnet->z->avail_out); else - _error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, + telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, "inflate() failed: %s", zError(rs)); /* prepare output buffer for next run */ @@ -1481,7 +1481,7 @@ int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va) { if (rs >= sizeof(buffer)) { output = (char*)malloc(rs + 1); if (output == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno)); va_end(va2); return -1; @@ -1550,7 +1550,7 @@ int telnet_raw_vprintf(telnet_t *telnet, const char *fmt, va_list va) { if (rs >= sizeof(buffer)) { output = (char*)malloc(rs + 1); if (output == 0) { - _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, + telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno)); va_end(va2); return -1; diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 5edcecf9..9ed32da0 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -35,6 +35,15 @@ #include "prom_server.h" #endif +#if defined(WINDOWS) + #include + + #define WORKING_BUFFER_SIZE 15000 + #define MAX_TRIES 3 + + #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) + #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) +#endif #if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) #undef OPENSSL_VERSION_NUMBER @@ -83,102 +92,155 @@ char HTTP_ALPN[128] = "http/1.1"; #define DEFAULT_GENERAL_RELAY_SERVERS_NUMBER (1) turn_params_t turn_params = { -NULL, /* tls_ctx */ -NULL, /* dtls_ctx */ -DH_2066, "", "", "", -"turn_server_cert.pem","turn_server_pkey.pem", "", "", -0,0,0, -#if !TLS_SUPPORTED + //////////////// OpenSSL group ////////////////////// + NULL, /* tls_ctx */ + NULL, /* dtls_ctx */ + DH_2066, /*dh_key_size*/ + + "", /*cipher_list*/ + "", /*ec_curve_name*/ + + "", /*ca_cert_file*/ + "turn_server_cert.pem", /*cert_file*/ + "turn_server_pkey.pem", /*pkey_file*/ + "", /*tls_password*/ + "", /*dh_file*/ + + 0, /*no_tlsv1*/ + 0, /*no_tlsv1_1*/ + 0, /*no_tlsv1_2*/ + /*no_tls*/ + #if !TLS_SUPPORTED 1, -#else + #else 0, -#endif - -#if !DTLS_SUPPORTED + #endif + /*no_dtls*/ + #if !DTLS_SUPPORTED 1, -#else + #else 0, -#endif + #endif -NULL, PTHREAD_MUTEX_INITIALIZER, + NULL, /*tls_ctx_update_ev*/ + {0, NULL}, /*tls_mutex*/ -//////////////// Common params //////////////////// + //////////////// Common params //////////////////// TURN_VERBOSE_NONE, /* verbose */ 0, /* turn_daemon */ 0, /* no_software_attribute */ 0, /* web_admin_listen_on_workers */ - 0, /* do_not_use_config_file */ -"/var/run/turnserver.pid", /* pidfile */ -"", /* acme_redirect */ -DEFAULT_STUN_PORT, /* listener_port*/ -DEFAULT_STUN_TLS_PORT, /* tls_listener_port */ -0, /* alt_listener_port */ -0, /* alt_tls_listener_port */ -0, /* tcp_proxy_port */ -1, /* rfc5780 */ -0, /* no_udp */ -0, /* no_tcp */ -0, /* tcp_use_proxy */ -0, /* no_tcp_relay */ -0, /* no_udp_relay */ -"", -{"",""},0, -{ - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,NULL,NULL,NULL -}, -{NULL, 0},{NULL, 0}, -NEV_UNKNOWN, -{ "Unknown", "UDP listening socket per session", "UDP thread per network endpoint", "UDP thread per CPU core" }, -//////////////// Relay servers ////////////////////////////////// -LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"", -0,NULL,0,NULL,DEFAULT_GENERAL_RELAY_SERVERS_NUMBER,0, -////////////// Auth server ///////////////////////////////////// -"","",0, -/////////////// AUX SERVERS //////////////// -{NULL,0,{0,NULL}},0, -/////////////// ALTERNATE SERVERS //////////////// -{NULL,0,{0,NULL}},{NULL,0,{0,NULL}}, -/////////////// stop server //////////////// -0, -/////////////// MISC PARAMS //////////////// -0, /* stun_only */ -0, /* no_stun */ -0, /* secure_stun */ -0, /* server_relay */ -0, /* fingerprint */ -':', /* rest_api_separator */ -STUN_DEFAULT_NONCE_EXPIRATION_TIME, /* stale_nonce */ -STUN_DEFAULT_MAX_ALLOCATE_LIFETIME, /* max_allocate_lifetime */ -STUN_DEFAULT_CHANNEL_LIFETIME, /* channel_lifetime */ -STUN_DEFAULT_PERMISSION_LIFETIME, /* permission_lifetime */ -0, /* mobility */ -TURN_CREDENTIALS_NONE, /* ct */ -0, /* use_auth_secret_with_timestamp */ -0, /* max_bps */ -0, /* bps_capacity */ -0, /* bps_capacity_allocated */ -0, /* total_quota */ -0, /* user_quota */ -#if !defined(TURN_NO_PROMETHEUS) -0, /* prometheus disabled by default */ -DEFAULT_PROM_SERVER_PORT, /* prometheus port */ -0, /* prometheus username labelling disabled by default when prometheus is enabled */ -#endif -///////////// Users DB ////////////// -{ (TURN_USERDB_TYPE)0, {"\0","\0"}, {0,NULL, {NULL,0}} }, -///////////// CPUs ////////////////// -DEFAULT_CPUS_NUMBER, -///////// Encryption ///////// -"", /* secret_key_file */ -"", /* secret_key */ -ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4, /* allocation_default_address_family */ -0, /* no_auth_pings */ -0, /* no_dynamic_ip_list */ -0, /* no_dynamic_realms */ -0, /* log_binding */ -0, /* no_stun_backward_compatibility */ -0 /* response_origin_only_with_rfc5780 */ + 0, /* do_not_use_config_file */ + + "/var/run/turnserver.pid", /* pidfile */ + "", /* acme_redirect */ + + //////////////// Listener server ///////////////// + + DEFAULT_STUN_PORT, /* listener_port*/ + DEFAULT_STUN_TLS_PORT, /* tls_listener_port */ + 0, /* alt_listener_port */ + 0, /* alt_tls_listener_port */ + 0, /* tcp_proxy_port */ + 1, /* rfc5780 */ + + 0, /* no_udp */ + 0, /* no_tcp */ + 0, /* tcp_use_proxy */ + + 0, /* no_tcp_relay */ + 0, /* no_udp_relay */ + + "", /*listener_ifname*/ + + {"", ""}, /*redis_statsdb*/ + 0, /*use_redis_statsdb*/ + { + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,NULL,NULL,NULL + }, /*listener*/ + {NULL, 0}, /*ip_whitelist*/ + {NULL, 0}, /*ip_blacklist*/ + NEV_UNKNOWN, /*net_engine_version*/ + { "Unknown", + "UDP listening socket per session", + "UDP thread per network endpoint", + "UDP thread per CPU core" }, /*net_engine_version_txt*/ + + //////////////// Relay servers ////////////////////////////////// + LOW_DEFAULT_PORTS_BOUNDARY, /*min_port*/ + HIGH_DEFAULT_PORTS_BOUNDARY,/*max_port*/ + + 0, /*check_origin*/ + + 0, /*no_multicast_peers*/ + 0, /*allow_loopback_peers*/ + + "", /*relay_ifname*/ + 0, /*relays_number*/ + NULL, /*relay_addrs*/ + 0, /*default_relays*/ + + NULL, /*external_ip*/ + DEFAULT_GENERAL_RELAY_SERVERS_NUMBER, /*general_relay_servers_number*/ + 0, /*udp_relay_servers_number*/ + + ////////////// Auth server ///////////////////////////////////// + "","",0, + + /////////////// AUX SERVERS //////////////// + {NULL,0,{0,NULL}}, /*aux_servers_list*/ + 0, /*udp_self_balance*/ + + /////////////// ALTERNATE SERVERS //////////////// + {NULL,0,{0,NULL}}, /*alternate_servers_list*/ + {NULL,0,{0,NULL}}, /*tls_alternate_servers_list*/ + + /////////////// stop server //////////////// + 0, /*stop_turn_server*/ + + /////////////// MISC PARAMS //////////////// + 0, /* stun_only */ + 0, /* no_stun */ + 0, /* secure_stun */ + 0, /* server_relay */ + 0, /* fingerprint */ + ':', /* rest_api_separator */ + STUN_DEFAULT_NONCE_EXPIRATION_TIME, /* stale_nonce */ + STUN_DEFAULT_MAX_ALLOCATE_LIFETIME, /* max_allocate_lifetime */ + STUN_DEFAULT_CHANNEL_LIFETIME, /* channel_lifetime */ + STUN_DEFAULT_PERMISSION_LIFETIME, /* permission_lifetime */ + 0, /* mobility */ + TURN_CREDENTIALS_NONE, /* ct */ + 0, /* use_auth_secret_with_timestamp */ + 0, /* max_bps */ + 0, /* bps_capacity */ + 0, /* bps_capacity_allocated */ + 0, /* total_quota */ + 0, /* user_quota */ + #if !defined(TURN_NO_PROMETHEUS) + 0, /* prometheus disabled by default */ + DEFAULT_PROM_SERVER_PORT, /* prometheus port */ + 0, /* prometheus username labelling disabled by default when prometheus is enabled */ + #endif + + ///////////// Users DB ////////////// + { (TURN_USERDB_TYPE)0, {"\0","\0"}, {0,NULL, {NULL,0}} }, + + ///////////// CPUs ////////////////// + DEFAULT_CPUS_NUMBER, + + ///////// Encryption ///////// + "", /* secret_key_file */ + "", /* secret_key */ + ALLOCATION_DEFAULT_ADDRESS_FAMILY_IPV4, /* allocation_default_address_family */ + 0, /* no_auth_pings */ + 0, /* no_dynamic_ip_list */ + 0, /* no_dynamic_realms */ + + 0, /* log_binding */ + 0, /* no_stun_backward_compatibility */ + 0 /* response_origin_only_with_rfc5780 */ }; //////////////// OpenSSL Init ////////////////////// @@ -193,13 +255,16 @@ static void openssl_setup(void); */ //////////// Common static process params //////// - +#if defined(WINDOWS) +//TODO: implement it!!! +#else static gid_t procgroupid = 0; static uid_t procuserid = 0; static gid_t procgroupid_set = 0; static uid_t procuserid_set = 0; static char procusername[1025]="\0"; static char procgroupname[1025]="\0"; +#endif ////////////// Configuration functionality //////////////////////////////// @@ -211,7 +276,231 @@ static void reload_ssl_certs(evutil_socket_t sock, short events, void *args); static int make_local_listeners_list(void) { int ret = 0; +#if defined(WINDOWS) + DWORD dwSize = 0; + DWORD dwRetVal = 0; + + unsigned int i = 0; + + // Set the flags to pass to GetAdaptersAddresses + ULONG flags = GAA_FLAG_INCLUDE_PREFIX; + + // default to unspecified address family (both) + ULONG family = AF_UNSPEC; + + LPVOID lpMsgBuf = NULL; + + PIP_ADAPTER_ADDRESSES pAddresses = NULL; + ULONG outBufLen = 0; + ULONG Iterations = 0; + + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL; + PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL; + IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL; + IP_ADAPTER_PREFIX *pPrefix = NULL; + + // Allocate a 15 KB buffer to start with. + outBufLen = WORKING_BUFFER_SIZE; + + do { + + pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); + if (pAddresses == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); + return -1; + } + + dwRetVal = + GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); + + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + FREE(pAddresses); + pAddresses = NULL; + } + else { + break; + } + + Iterations++; + + } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); + + if (dwRetVal == NO_ERROR) { + // If successful, output some information from the data we received + pCurrAddresses = pAddresses; + while (pCurrAddresses) { + /* + printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n", + pCurrAddresses->Length); + printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex); + printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);//*/ + + pUnicast = pCurrAddresses->FirstUnicastAddress; + if (pUnicast != NULL) { + //printf("\tNumber of Unicast Addresses:\n"); + for (i = 0; pUnicast != NULL; pUnicast = pUnicast->Next) + { + char saddr[INET6_ADDRSTRLEN] = ""; + if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 + { + if (!inet_ntop(PF_INET, + &((struct sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, + saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } + else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 + { + if (!inet_ntop(PF_INET6, + &((struct sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, + saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } + else + continue; + + //printf("\t\tIP: %s\n", saddr); + + add_listener_addr(saddr); + + if (MIB_IF_TYPE_LOOPBACK != pCurrAddresses->IfType) + ret++; + } + } + /* + else + printf("\tNo Unicast Addresses\n"); + + pAnycast = pCurrAddresses->FirstAnycastAddress; + if (pAnycast) { + for (i = 0; pAnycast != NULL; i++) + pAnycast = pAnycast->Next; + printf("\tNumber of Anycast Addresses: %d\n", i); + } + else + printf("\tNo Anycast Addresses\n"); + + pMulticast = pCurrAddresses->FirstMulticastAddress; + if (pMulticast) { + for (i = 0; pMulticast != NULL; i++) + pMulticast = pMulticast->Next; + printf("\tNumber of Multicast Addresses: %d\n", i); + } + else + printf("\tNo Multicast Addresses\n"); + + pDnServer = pCurrAddresses->FirstDnsServerAddress; + if (pDnServer) { + for (i = 0; pDnServer != NULL; i++) + pDnServer = pDnServer->Next; + printf("\tNumber of DNS Server Addresses: %d\n", i); + } + else + printf("\tNo DNS Server Addresses\n"); + + printf("\tDNS Suffix: %wS\n", pCurrAddresses->DnsSuffix); + printf("\tDescription: %wS\n", pCurrAddresses->Description); + printf("\tFriendly name: %wS\n", pCurrAddresses->FriendlyName); + + if (pCurrAddresses->PhysicalAddressLength != 0) { + printf("\tPhysical address: "); + for (i = 0; i < (int)pCurrAddresses->PhysicalAddressLength; + i++) { + if (i == (pCurrAddresses->PhysicalAddressLength - 1)) + printf("%.2X\n", + (int)pCurrAddresses->PhysicalAddress[i]); + else + printf("%.2X-", + (int)pCurrAddresses->PhysicalAddress[i]); + } + } + printf("\tFlags: %ld\n", pCurrAddresses->Flags); + printf("\tMtu: %lu\n", pCurrAddresses->Mtu); + char* pType = NULL; + + switch (pCurrAddresses->IfType) + { + case MIB_IF_TYPE_ETHERNET: + pType = "ETHERNET"; + break; + case MIB_IF_TYPE_PPP: + pType = "PPP"; + break; + case MIB_IF_TYPE_LOOPBACK: + pType = "LOOPBACK"; + break; + case MIB_IF_TYPE_SLIP: + pType = "ATM"; + break; + case IF_TYPE_IEEE80211: + pType = "WIFI"; + break; + } + printf("\tIfType: %ld (%s)\n", pCurrAddresses->IfType, pType); + printf("\tOperStatus: %ld\n", pCurrAddresses->OperStatus); + printf("\tIpv6IfIndex (IPv6 interface): %u\n", + pCurrAddresses->Ipv6IfIndex); + printf("\tZoneIndices (hex): "); + for (i = 0; i < 16; i++) + printf("%lx ", pCurrAddresses->ZoneIndices[i]); + printf("\n"); + + printf("\tTransmit link speed: %I64u\n", pCurrAddresses->TransmitLinkSpeed); + printf("\tReceive link speed: %I64u\n", pCurrAddresses->ReceiveLinkSpeed); + + pPrefix = pCurrAddresses->FirstPrefix; + if (pPrefix) { + for (i = 0; pPrefix != NULL; i++) + pPrefix = pPrefix->Next; + printf("\tNumber of IP Adapter Prefix entries: %d\n", i); + } + else + printf("\tNumber of IP Adapter Prefix entries: 0\n"); + + printf("\n");//*/ + + pCurrAddresses = pCurrAddresses->Next; + } + } + else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Call to GetAdaptersAddresses failed with error: %d\n", + dwRetVal); + if (dwRetVal == ERROR_NO_DATA) + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "\tNo addresses were found for the requested parameters\n"); + else { + + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + // Default language + (LPTSTR)& lpMsgBuf, 0, NULL)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\tError: %s", lpMsgBuf); + LocalFree(lpMsgBuf); + if (pAddresses) + FREE(pAddresses); + return -2; + } + } + } + + if (pAddresses) { + FREE(pAddresses); + } + +#else struct ifaddrs * ifs = NULL; struct ifaddrs * ifa = NULL; @@ -254,12 +543,116 @@ static int make_local_listeners_list(void) } freeifaddrs(ifs); } +#endif return ret; } static int make_local_relays_list(int allow_local, int family) { + int counter = 0; + +#if defined(WINDOWS) + DWORD dwRetVal = 0; + // Set the flags to pass to GetAdaptersAddresses + ULONG flags = GAA_FLAG_INCLUDE_PREFIX; + + // default to unspecified address family (both) + ULONG fm = AF_UNSPEC; + + LPVOID lpMsgBuf = NULL; + + PIP_ADAPTER_ADDRESSES pAddresses = NULL; + ULONG outBufLen = 0; + ULONG Iterations = 0; + + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + + // Allocate a 15 KB buffer to start with. + outBufLen = WORKING_BUFFER_SIZE; + + do { + + pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); + if (pAddresses == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); + return -1; + } + + dwRetVal = + GetAdaptersAddresses(fm, flags, NULL, pAddresses, &outBufLen); + + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + FREE(pAddresses); + pAddresses = NULL; + } + else { + break; + } + + Iterations++; + + } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); + + if (dwRetVal == NO_ERROR) { + // If successful, output some information from the data we received + pCurrAddresses = pAddresses; + while (pCurrAddresses) { + /* + printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n", + pCurrAddresses->Length); + printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex); + printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);//*/ + + pUnicast = pCurrAddresses->FirstUnicastAddress; + if (pUnicast != NULL) { + //printf("\tNumber of Unicast Addresses:\n"); + for (; pUnicast != NULL; pUnicast = pUnicast->Next) { + if (!allow_local && (MIB_IF_TYPE_LOOPBACK == pCurrAddresses->IfType)) + continue; + + char saddr[INET6_ADDRSTRLEN] = ""; + if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 + { + if (family != AF_INET) + continue; + if (!inet_ntop(PF_INET, &((struct sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } + else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 + { + if (family != AF_INET6) + continue; + + if (!inet_ntop(PF_INET6, &((struct sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; + } + else + continue; + + if (add_relay_addr(saddr) > 0) { + counter += 1; + } + } + } + pCurrAddresses = pCurrAddresses->Next; + } + } + + if (pAddresses) { + FREE(pAddresses); + } +#else struct ifaddrs * ifs = NULL; struct ifaddrs * ifa = NULL; @@ -267,8 +660,6 @@ static int make_local_relays_list(int allow_local, int family) getifaddrs(&ifs); - int counter = 0; - if (ifs) { for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) { @@ -316,17 +707,120 @@ static int make_local_relays_list(int allow_local, int family) } freeifaddrs(ifs); } +#endif return counter; } int get_a_local_relay(int family, ioa_addr *relay_addr) { - struct ifaddrs * ifs = NULL; - + int ret = -1; int allow_local = 0; - int ret = -1; +#if defined(WINDOWS) + DWORD dwRetVal = 0; + // Set the flags to pass to GetAdaptersAddresses + ULONG flags = GAA_FLAG_INCLUDE_PREFIX; + + // default to unspecified address family (both) + ULONG fm = AF_UNSPEC; + + LPVOID lpMsgBuf = NULL; + + PIP_ADAPTER_ADDRESSES pAddresses = NULL; + ULONG outBufLen = 0; + ULONG Iterations = 0; + + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + + outBufLen = WORKING_BUFFER_SIZE; + + do { + + pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); + if (pAddresses == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, + "Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n"); + return -1; + } + + dwRetVal = + GetAdaptersAddresses(fm, flags, NULL, pAddresses, &outBufLen); + + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + FREE(pAddresses); + pAddresses = NULL; + } + else { + break; + } + + Iterations++; + + } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES)); + + if (dwRetVal == NO_ERROR) { + galr_start: + // If successful, output some information from the data we received + pCurrAddresses = pAddresses; + while (pCurrAddresses) { + pUnicast = pCurrAddresses->FirstUnicastAddress; + if (pUnicast != NULL) { + //printf("\tNumber of Unicast Addresses:\n"); + for (; pUnicast != NULL; pUnicast = pUnicast->Next) { + if (!allow_local && (MIB_IF_TYPE_LOOPBACK == pCurrAddresses->IfType)) + continue; + + char saddr[INET6_ADDRSTRLEN] = ""; + if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) // IPV4 + { + if (family != AF_INET) + continue; + if (!inet_ntop(PF_INET, &((struct sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "169.254.") == saddr) + continue; + if (!strcmp(saddr, "0.0.0.0")) + continue; + } + else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) // IPV6 + { + if (family != AF_INET6) + continue; + + if (!inet_ntop(PF_INET6, &((struct sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, saddr, INET6_ADDRSTRLEN)) + continue; + if (strstr(saddr, "fe80") == saddr) + continue; + if (!strcmp(saddr, "::")) + continue; +} + else + continue; + + if (make_ioa_addr((const uint8_t*)saddr, 0, relay_addr) < 0) { + continue; + } else { + ret = 0; + break; + } + } + } + pCurrAddresses = pCurrAddresses->Next; + } + + if (ret < 0 && !allow_local) { + allow_local = 1; + goto galr_start; + } + } + + if (pAddresses) { + FREE(pAddresses); + } +#else + struct ifaddrs * ifs = NULL; char saddr[INET6_ADDRSTRLEN] = ""; @@ -397,8 +891,8 @@ int get_a_local_relay(int family, ioa_addr *relay_addr) freeifaddrs(ifs); } - return -1; +#endif } ////////////////////////////////////////////////// @@ -1128,7 +1622,7 @@ void generate_aes_128_key(char* filePath, unsigned char* returnedKey){ for(i = 0; i < 16; i++){ fputc(key[i], fptr); } - strcpy((char*)returnedKey, key); + STRCPY((char*)returnedKey, key); fclose(fptr); @@ -1317,6 +1811,9 @@ static void set_option(int c, char *value) case WEB_ADMIN_LISTEN_ON_WORKERS_OPT: turn_params.web_admin_listen_on_workers = get_bool_value(value); break; +#if defined(WINDOWS) + //TODO: implement it!!! +#else case PROC_USER_OPT: { struct passwd* pwd = getpwnam(value); if(!pwd) { @@ -1341,6 +1838,7 @@ static void set_option(int c, char *value) } } break; +#endif case 'i': STRCPY(turn_params.relay_ifname, value); break; @@ -2231,6 +2729,9 @@ static void set_network_engine(void) static void drop_privileges(void) { +#if defined(WINDOWS) + //TODO: implement it!!! +#else setgroups(0, NULL); if(procgroupid_set) { if(getgid() != procgroupid) { @@ -2257,15 +2758,16 @@ static void drop_privileges(void) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Keep UID: %s(%lu)\n", procusername, (unsigned long)procuserid); } } +#endif } static void init_domain(void) { #if !defined(TURN_NO_GETDOMAINNAME) - if(getdomainname(turn_params.domain,sizeof(turn_params.domain)-1)<0) { - turn_params.domain[0]=0; - } else if(!strcmp(turn_params.domain,"(none)")) { - turn_params.domain[0]=0; + if (getdomainname(turn_params.domain, sizeof(turn_params.domain) - 1) < 0) { + turn_params.domain[0] = 0; + } else if (!strcmp(turn_params.domain, "(none)")) { + turn_params.domain[0] = 0; } #endif } @@ -2276,6 +2778,8 @@ int main(int argc, char **argv) IS_TURN_SERVER = 1; + TURN_MUTEX_INIT(&turn_params.tls_mutex); + set_execdir(); init_super_memory(); @@ -2341,25 +2845,23 @@ int main(int argc, char **argv) turn_params.no_dtls = 1; #endif -#if defined(_SC_NPROCESSORS_ONLN) - { - turn_params.cpus = (long)sysconf(_SC_NPROCESSORS_CONF); - - if(turn_params.cpusMAX_NUMBER_OF_GENERAL_RELAY_SERVERS) + else if (turn_params.cpus > MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) turn_params.cpus = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; turn_params.general_relay_servers_number = (turnserver_id)turn_params.cpus; } -#endif - - memset(&turn_params.default_users_db,0,sizeof(default_users_db_t)); + memset(&turn_params.default_users_db, 0, sizeof(default_users_db_t)); turn_params.default_users_db.ram_db.static_accounts = ur_string_map_create(free); - if(strstr(argv[0],"turnadmin")) + if(strstr(argv[0], "turnadmin")) return adminmain(argc,argv); // Zero pass apply the log options. read_config_file(argc,argv,0); @@ -2555,6 +3057,12 @@ int main(int argc, char **argv) } } + if (socket_init()) return -1; + +#if defined(WINDOWS) + + //TODO: implement deamon!!! use windows server +#else if(turn_params.turn_daemon) { #if !defined(TURN_HAS_DAEMON) pid_t pid = fork(); @@ -2611,11 +3119,16 @@ int main(int argc, char **argv) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "pid file created: %s\n", s); } } +#endif setup_server(); +#if defined(WINDOWS) + //TODO: implement it!!! add windows server +#else struct event *ev = evsignal_new(turn_params.listener.event_base, SIGUSR2, reload_ssl_certs, NULL); event_add(ev, NULL); +#endif drop_privileges(); #if !defined(TURN_NO_PROMETHEUS) @@ -2645,7 +3158,7 @@ int main(int argc, char **argv) #if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0 //array larger than anything that OpenSSL may need: -static pthread_mutex_t mutex_buf[256]; +static TURN_MUTEX_DECLARE(mutex_buf[256]); static int mutex_buf_initialized = 0; void coturn_locking_function(int mode, int n, const char *file, int line); @@ -2654,9 +3167,9 @@ void coturn_locking_function(int mode, int n, const char *file, int line) { UNUSED_ARG(line); if(mutex_buf_initialized && (n < CRYPTO_num_locks())) { if (mode & CRYPTO_LOCK) - pthread_mutex_lock(&(mutex_buf[n])); + TURN_MUTEX_LOCK(&(mutex_buf[n])); else - pthread_mutex_unlock(&(mutex_buf[n])); + TURN_MUTEX_UNLOCK(&(mutex_buf[n])); } } @@ -2670,7 +3183,7 @@ void coturn_id_function(CRYPTO_THREADID *ctid) static int THREAD_setup(void) { int i; for (i = 0; i < CRYPTO_num_locks(); i++) { - pthread_mutex_init(&(mutex_buf[i]), NULL); + TURN_MUTEX_INIT(&(mutex_buf[i])); } mutex_buf_initialized = 1; @@ -2679,7 +3192,6 @@ static int THREAD_setup(void) { return 1; } -int THREAD_cleanup(void); int THREAD_cleanup(void) { int i; @@ -2689,7 +3201,7 @@ int THREAD_cleanup(void) { CRYPTO_THREADID_set_callback(NULL); CRYPTO_set_locking_callback(NULL); for (i = 0; i < CRYPTO_num_locks(); i++) { - pthread_mutex_destroy(&(mutex_buf[i])); + TURN_MUTEX_DESTROY(&(mutex_buf[i])); } mutex_buf_initialized = 0; @@ -2700,7 +3212,6 @@ static int THREAD_setup(void) { return 1; } -int THREAD_cleanup(void); int THREAD_cleanup(void){ return 1; } @@ -3193,7 +3704,7 @@ static void openssl_setup(void) static void openssl_load_certificates(void) { - pthread_mutex_lock(&turn_params.tls_mutex); + TURN_MUTEX_LOCK(&turn_params.tls_mutex); if(!turn_params.no_tls) { #if OPENSSL_VERSION_NUMBER < 0x10100000L set_ctx(&turn_params.tls_ctx,"TLS", TLSv1_2_server_method()); /*openssl-1.0.2 version specific API */ @@ -3258,7 +3769,7 @@ static void openssl_load_certificates(void) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list); #endif } - pthread_mutex_unlock(&turn_params.tls_mutex); + TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); } static void reload_ssl_certs(evutil_socket_t sock, short events, void *args) diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 7eaa9be3..0c997a55 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -35,12 +35,9 @@ #include #include #include -#include #include -#include -#include + #include -#include #include #include @@ -48,13 +45,21 @@ #include #include -#include #include + +#include + +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) +#include +#include +#include #include #include #include #include +#endif #include #include @@ -197,7 +202,7 @@ typedef struct _turn_params_ { int no_dtls; struct event *tls_ctx_update_ev; - pthread_mutex_t tls_mutex; + TURN_MUTEX_DECLARE(tls_mutex) //////////////// Common params //////////////////// @@ -251,7 +256,6 @@ typedef struct _turn_params_ { vint allow_loopback_peers; char relay_ifname[1025]; - size_t relays_number; char **relay_addrs; int default_relays; @@ -280,6 +284,7 @@ typedef struct _turn_params_ { turn_server_addrs_list_t alternate_servers_list; turn_server_addrs_list_t tls_alternate_servers_list; +/////////////// stop server //////////////// int stop_turn_server; ////////////// MISC PARAMS //////////////// diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 2693f256..c270549e 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -103,13 +103,13 @@ static void barrier_wait_func(const char* func, int line) /////////////// Bandwidth ////////////////// -static pthread_mutex_t mutex_bps; +static TURN_MUTEX_DECLARE(mutex_bps); static band_limit_t allocate_bps(band_limit_t bps, int positive) { band_limit_t ret = 0; if(bps>0) { - pthread_mutex_lock(&mutex_bps); + TURN_MUTEX_LOCK(&mutex_bps); if(positive) { @@ -136,7 +136,7 @@ static band_limit_t allocate_bps(band_limit_t bps, int positive) } } - pthread_mutex_unlock(&mutex_bps); + TURN_MUTEX_UNLOCK(&mutex_bps); } return ret; @@ -145,42 +145,42 @@ static band_limit_t allocate_bps(band_limit_t bps, int positive) band_limit_t get_bps_capacity_allocated(void) { band_limit_t ret = 0; - pthread_mutex_lock(&mutex_bps); + TURN_MUTEX_LOCK(&mutex_bps); ret = turn_params.bps_capacity_allocated; - pthread_mutex_unlock(&mutex_bps); + TURN_MUTEX_UNLOCK(&mutex_bps); return ret; } band_limit_t get_bps_capacity(void) { band_limit_t ret = 0; - pthread_mutex_lock(&mutex_bps); + TURN_MUTEX_LOCK(&mutex_bps); ret = turn_params.bps_capacity; - pthread_mutex_unlock(&mutex_bps); + TURN_MUTEX_UNLOCK(&mutex_bps); return ret; } void set_bps_capacity(band_limit_t value) { - pthread_mutex_lock(&mutex_bps); + TURN_MUTEX_LOCK(&mutex_bps); turn_params.bps_capacity = value; - pthread_mutex_unlock(&mutex_bps); + TURN_MUTEX_UNLOCK(&mutex_bps); } band_limit_t get_max_bps(void) { band_limit_t ret = 0; - pthread_mutex_lock(&mutex_bps); + TURN_MUTEX_LOCK(&mutex_bps); ret = turn_params.max_bps; - pthread_mutex_unlock(&mutex_bps); + TURN_MUTEX_UNLOCK(&mutex_bps); return ret; } void set_max_bps(band_limit_t value) { - pthread_mutex_lock(&mutex_bps); + TURN_MUTEX_LOCK(&mutex_bps); turn_params.max_bps = value; - pthread_mutex_unlock(&mutex_bps); + TURN_MUTEX_UNLOCK(&mutex_bps); } /////////////// AUX SERVERS //////////////// @@ -215,7 +215,7 @@ static void add_alt_server(const char *saddr, int default_port, turn_server_addr if(saddr && list) { ioa_addr addr; - turn_mutex_lock(&(list->m)); + TURN_MUTEX_LOCK(&(list->m)); if(make_ioa_addr_from_full_string((const uint8_t*)saddr, default_port, &addr)!=0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n",saddr); @@ -229,7 +229,7 @@ static void add_alt_server(const char *saddr, int default_port, turn_server_addr } } - turn_mutex_unlock(&(list->m)); + TURN_MUTEX_UNLOCK(&(list->m)); } } @@ -239,7 +239,7 @@ static void del_alt_server(const char *saddr, int default_port, turn_server_addr ioa_addr addr; - turn_mutex_lock(&(list->m)); + TURN_MUTEX_LOCK(&(list->m)); if(make_ioa_addr_from_full_string((const uint8_t*)saddr, default_port, &addr)!=0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n",saddr); @@ -279,7 +279,7 @@ static void del_alt_server(const char *saddr, int default_port, turn_server_addr } } - turn_mutex_unlock(&(list->m)); + TURN_MUTEX_UNLOCK(&(list->m)); } } @@ -334,13 +334,13 @@ static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb turn_params_t *params = args->params; /* No mutex with "e" as these are only used in the same event loop */ - pthread_mutex_lock(&turn_params.tls_mutex); + TURN_MUTEX_LOCK(&turn_params.tls_mutex); replace_one_ssl_ctx(&e->tls_ctx, params->tls_ctx); #if DTLS_SUPPORTED replace_one_ssl_ctx(&e->dtls_ctx, params->dtls_ctx); #endif struct event *next = args->next; - pthread_mutex_unlock(&turn_params.tls_mutex); + TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); if (next != NULL) event_active(next, EV_READ, 0); @@ -361,10 +361,10 @@ void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params) struct event_base *base = e->event_base; if (base != NULL) { struct event *ev = event_new(base, -1, EV_PERSIST, (event_callback_fn)update_ssl_ctx, (void *)args); - pthread_mutex_lock(&turn_params.tls_mutex); + TURN_MUTEX_LOCK(&turn_params.tls_mutex); args->next = params->tls_ctx_update_ev; params->tls_ctx_update_ev = ev; - pthread_mutex_unlock(&turn_params.tls_mutex); + TURN_MUTEX_UNLOCK(&turn_params.tls_mutex); } } @@ -479,16 +479,16 @@ static struct relay_server* get_relay_server(turnserver_id id) { return rs; } -static pthread_mutex_t auth_message_counter_mutex = PTHREAD_MUTEX_INITIALIZER; +static TURN_MUTEX_DECLARE(auth_message_counter_mutex); static authserver_id auth_message_counter = 1; void send_auth_message_to_auth_server(struct auth_message *am) { - pthread_mutex_lock(&auth_message_counter_mutex); + TURN_MUTEX_LOCK(&auth_message_counter_mutex); if(auth_message_counter>=authserver_number) auth_message_counter = 1; else if(auth_message_counter<1) auth_message_counter = 1; authserver_id sn = auth_message_counter++; - pthread_mutex_unlock(&auth_message_counter_mutex); + TURN_MUTEX_UNLOCK(&auth_message_counter_mutex); struct evbuffer *output = bufferevent_get_output(authserver[sn].out_buf); if(evbuffer_add(output,am,sizeof(struct auth_message))<0) { @@ -591,7 +591,7 @@ static int send_socket_to_relay(turnserver_id id, uint64_t cid, stun_tid *tid, i int ret = -1; struct message_to_relay sm; - memset(&sm,0, sizeof(struct message_to_relay)); + memset(&sm, 0, sizeof(struct message_to_relay)); sm.t = rmt; ioa_socket_handle s_to_delete = s; @@ -691,7 +691,7 @@ int send_session_cancellation_to_relay(turnsession_id sid) int ret = 0; struct message_to_relay sm; - memset(&sm,0,sizeof(struct message_to_relay)); + memset(&sm, 0, sizeof(struct message_to_relay)); sm.t = RMT_CANCEL_SESSION; turnserver_id id = (turnserver_id)(sid / TURN_SESSION_ID_FACTOR); @@ -912,7 +912,7 @@ static void listener_receive_message(struct bufferevent *bev, void *ptr) TURN_LOG_LEVEL_ERROR, "%s: Wrong general relay number: %d, total %d\n", __FUNCTION__,(int)ri,(int)get_real_general_relay_servers_number()); - } else if(general_relay_servers[ri]->thr == pthread_self()) { + } else if(pthread_equal(general_relay_servers[ri]->thr, pthread_self())) { relay_thread_index=ri; break; } @@ -1724,7 +1724,7 @@ static void* run_auth_server_thread(void *arg) } else { - memset(as,0,sizeof(struct auth_server)); + memset(as, 0, sizeof(struct auth_server)); as->id = id; @@ -1785,7 +1785,7 @@ static void* run_admin_server_thread(void *arg) static void setup_admin_server(void) { - memset(&adminserver,0,sizeof(struct admin_server)); + memset(&adminserver, 0, sizeof(struct admin_server)); adminserver.listen_fd = -1; adminserver.verbose = turn_params.verbose; @@ -1799,9 +1799,14 @@ static void setup_admin_server(void) void setup_server(void) { +#if defined(WINDOWS) + evthread_use_windows_threads(); +#else evthread_use_pthreads(); +#endif - pthread_mutex_init(&mutex_bps, NULL); + TURN_MUTEX_INIT(&mutex_bps); + TURN_MUTEX_INIT(&auth_message_counter_mutex); authserver_number = 1 + (authserver_id)(turn_params.cpus / 2); @@ -1870,7 +1875,7 @@ void setup_server(void) void init_listener(void) { - memset(&turn_params.listener,0,sizeof(struct listener_server)); + memset(&turn_params.listener, 0, sizeof(struct listener_server)); } /////////////////////////////// diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 9fe6b94f..f2ee98c4 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -920,8 +920,7 @@ ioa_socket_handle create_unbound_relay_ioa_socket(ioa_engine_handle e, int famil return NULL; } - ret = (ioa_socket*)malloc(sizeof(ioa_socket)); - memset(ret,0,sizeof(ioa_socket)); + ret = (ioa_socket*)calloc(sizeof(ioa_socket), 1); ret->magic = SOCKET_MAGIC; @@ -1364,8 +1363,7 @@ ioa_socket_handle create_ioa_socket_from_fd(ioa_engine_handle e, return NULL; } - ret = (ioa_socket*)malloc(sizeof(ioa_socket)); - memset(ret,0,sizeof(ioa_socket)); + ret = (ioa_socket*)calloc(sizeof(ioa_socket), 1); ret->magic = SOCKET_MAGIC; @@ -1640,7 +1638,7 @@ ioa_socket_handle detach_ioa_socket(ioa_socket_handle s) ioa_network_buffer_delete(s->e, s->defer_nbh); - ret = (ioa_socket*)malloc(sizeof(ioa_socket)); + ret = (ioa_socket*)calloc(sizeof(ioa_socket), 1); if(!ret) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"%s: Cannot allocate new socket structure\n",__FUNCTION__); if(udp_fd>=0) @@ -1967,7 +1965,10 @@ static int socket_readerr(evutil_socket_t fd, ioa_addr *orig_addr) return -1; #if defined(CMSG_SPACE) && defined(MSG_ERRQUEUE) && defined(IP_RECVERR) - + #ifdef _MSC_VER + //TODO: implement it!!! + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "The socket_readerr is not implement in _MSC_VER"); + #else uint8_t ecmsg[TURN_CMSG_SZ+1]; int flags = MSG_ERRQUEUE; int len = 0; @@ -2000,6 +2001,7 @@ static int socket_readerr(evutil_socket_t fd, ioa_addr *orig_addr) } while((len>0)&&(try_cycle++read_cb) { ioa_net_data nd; - memset(&nd,0,sizeof(ioa_net_data)); + memset(&nd, 0, sizeof(ioa_net_data)); addr_cpy(&(nd.src_addr),&remote_addr); nd.nbh = buf_elem; nd.recv_ttl = ttl; @@ -3862,7 +3864,7 @@ const char* get_ioa_socket_tls_method(ioa_socket_handle s) #define TURN_SM_SIZE (1024<<11) struct _super_memory { - pthread_mutex_t mutex_sm; + TURN_MUTEX_DECLARE(mutex_sm) char **super_memory; size_t *sm_allocated; size_t sm_total_sz; @@ -3873,11 +3875,10 @@ struct _super_memory { static void init_super_memory_region(super_memory_t *r) { if(r) { - memset(r,0,sizeof(super_memory_t)); + memset(r, 0, sizeof(super_memory_t)); r->super_memory = (char**)malloc(sizeof(char*)); - r->super_memory[0] = (char*)malloc(TURN_SM_SIZE); - memset(r->super_memory[0],0,TURN_SM_SIZE); + r->super_memory[0] = (char*)calloc(1, TURN_SM_SIZE); r->sm_allocated = (size_t*)malloc(sizeof(size_t*)); r->sm_allocated[0] = 0; @@ -3886,9 +3887,9 @@ static void init_super_memory_region(super_memory_t *r) r->sm_chunk = 0; while(r->id == 0) - r->id = (uint32_t)random(); + r->id = (uint32_t)turn_random(); - pthread_mutex_init(&r->mutex_sm, NULL); + TURN_MUTEX_INIT(&r->mutex_sm); } } @@ -3913,12 +3914,11 @@ void* allocate_super_memory_region_func(super_memory_t *r, size_t size, const ch void *ret = NULL; if(!r) { - ret = malloc(size); - memset(ret, 0, size); + ret = calloc(1, size); return ret; } - pthread_mutex_lock(&r->mutex_sm); + TURN_MUTEX_LOCK(&r->mutex_sm); size = ((size_t)((size+sizeof(void*))/(sizeof(void*)))) * sizeof(void*); @@ -3947,8 +3947,7 @@ void* allocate_super_memory_region_func(super_memory_t *r, size_t size, const ch if(!region) { r->sm_chunk += 1; r->super_memory = (char**)realloc(r->super_memory,(r->sm_chunk+1) * sizeof(char*)); - r->super_memory[r->sm_chunk] = (char*)malloc(TURN_SM_SIZE); - memset(r->super_memory[r->sm_chunk],0,TURN_SM_SIZE); + r->super_memory[r->sm_chunk] = (char*)calloc(1, TURN_SM_SIZE); r->sm_allocated = (size_t*)realloc(r->sm_allocated,(r->sm_chunk+1) * sizeof(size_t*)); r->sm_allocated[r->sm_chunk] = 0; region = r->super_memory[r->sm_chunk]; @@ -3966,11 +3965,10 @@ void* allocate_super_memory_region_func(super_memory_t *r, size_t size, const ch } } - pthread_mutex_unlock(&r->mutex_sm); + TURN_MUTEX_UNLOCK(&r->mutex_sm); if(!ret) { - ret = malloc(size); - memset(ret, 0, size); + ret = calloc(1, size); } return ret; diff --git a/src/apps/relay/turn_admin_server.c b/src/apps/relay/turn_admin_server.c index b9cf98f0..e14d2ef1 100644 --- a/src/apps/relay/turn_admin_server.c +++ b/src/apps/relay/turn_admin_server.c @@ -32,11 +32,32 @@ #include #include #include + +#if defined(_MSC_VER) +#include +#else #include +#endif + +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) +#include +#include +#include +#include +#endif + +#include + +#include +#include + +#include #include "libtelnet.h" -#include +#include +#include #include #include @@ -652,8 +673,12 @@ static void cli_print_configuration(struct cli_session* cs) cli_print_flag(cs,turn_params.mobility,"mobility",1); cli_print_flag(cs,turn_params.udp_self_balance,"udp-self-balance",0); cli_print_str(cs,turn_params.pidfile,"pidfile",0); +#if defined(WINDOWS) + //TODO: implement it!!! +#else cli_print_uint(cs,(unsigned long)getuid(),"process user ID",0); cli_print_uint(cs,(unsigned long)getgid(),"process group ID",0); +#endif { char wd[1025]; @@ -1143,8 +1168,7 @@ static void cliserver_input_handler(struct evconnlistener *l, evutil_socket_t fd addr_debug_print(adminserver.verbose, (ioa_addr*)sa,"CLI connected to"); - struct cli_session *clisession = (struct cli_session*)malloc(sizeof(struct cli_session)); - memset(clisession,0,sizeof(struct cli_session)); + struct cli_session *clisession = (struct cli_session*)calloc(sizeof(struct cli_session), 1); clisession->rp = get_realm(NULL); @@ -2057,9 +2081,12 @@ static void write_pc_page(ioa_socket_handle s) https_print_flag(sb,turn_params.mobility,"mobility","mobility"); https_print_flag(sb,turn_params.udp_self_balance,"udp-self-balance",0); https_print_str(sb,turn_params.pidfile,"pidfile",0); +#if defined(WINDOWS) + //TODO: implement it!!! +#else https_print_uint(sb,(unsigned long)getuid(),"process user ID",0); https_print_uint(sb,(unsigned long)getgid(),"process group ID",0); - +#endif { char wd[1025]; if(getcwd(wd,sizeof(wd)-1)) { @@ -3283,8 +3310,7 @@ static void handle_logon_request(ioa_socket_handle s, struct http_request* hr) struct admin_session* as = (struct admin_session*)s->special_session; if(!as) { - as = (struct admin_session*)malloc(sizeof(struct admin_session)); - memset(as,0,sizeof(struct admin_session)); + as = (struct admin_session*)calloc(sizeof(struct admin_session), 1); s->special_session = as; s->special_session_size = sizeof(struct admin_session); } diff --git a/src/apps/relay/turn_ports.c b/src/apps/relay/turn_ports.c index 113eb125..e2cf5c56 100644 --- a/src/apps/relay/turn_ports.c +++ b/src/apps/relay/turn_ports.c @@ -90,8 +90,8 @@ static void turnports_randomize(turnports* tp) { unsigned int i=0; unsigned int cycles=size*10; for(i=0;ilow + (uint16_t)(((unsigned long)random())%((unsigned long)size))); - uint16_t port2 = (uint16_t)(tp->low + (uint16_t)(((unsigned long)random())%((unsigned long)size))); + uint16_t port1 = (uint16_t)(tp->low + (uint16_t)(((unsigned long)turn_random())%((unsigned long)size))); + uint16_t port2 = (uint16_t)(tp->low + (uint16_t)(((unsigned long)turn_random())%((unsigned long)size))); if(port1!=port2) { int pos1=tp->status[port1]; int pos2=tp->status[port2]; diff --git a/src/apps/relay/userdb.c b/src/apps/relay/userdb.c index 9c8f79d1..d67ba6ca 100644 --- a/src/apps/relay/userdb.c +++ b/src/apps/relay/userdb.c @@ -32,11 +32,21 @@ #include #include #include -#include +#include +#include +#include -#include +#ifndef _MSC_VER +#include +#endif + +#include + +#include +#include #include +#include #include "userdb.h" #include "dbdrivers/dbdriver.h" @@ -54,7 +64,7 @@ static realm_params_t *default_realm_params_ptr = NULL; static ur_string_map *realms = NULL; -static turn_mutex o_to_realm_mutex; +static TURN_MUTEX_DECLARE(o_to_realm_mutex); static ur_string_map *o_to_realm = NULL; static secrets_list_t realms_list; @@ -1065,8 +1075,8 @@ void run_db_test(void) static pthread_rwlock_t* whitelist_rwlock = NULL; static pthread_rwlock_t* blacklist_rwlock = NULL; #else -static turn_mutex whitelist_mutex; -static turn_mutex blacklist_mutex; +static TURN_MUTEX_DECLARE(whitelist_mutex); +static TURN_MUTEX_DECLARE(blacklist_mutex); #endif static ip_range_list_t* ipwhitelist = NULL; @@ -1081,8 +1091,8 @@ void init_dynamic_ip_lists(void) blacklist_rwlock = (pthread_rwlock_t*) malloc(sizeof(pthread_rwlock_t)); pthread_rwlock_init(blacklist_rwlock, NULL); #else - turn_mutex_init(&whitelist_mutex); - turn_mutex_init(&blacklist_mutex); + TURN_MUTEX_INIT(&whitelist_mutex); + TURN_MUTEX_INIT(&blacklist_mutex); #endif } @@ -1092,7 +1102,7 @@ void ioa_lock_whitelist(ioa_engine_handle e) #if !defined(TURN_NO_RWLOCK) pthread_rwlock_rdlock(whitelist_rwlock); #else - turn_mutex_lock(&whitelist_mutex); + TURN_MUTEX_LOCK(&whitelist_mutex); #endif } void ioa_unlock_whitelist(ioa_engine_handle e) @@ -1101,7 +1111,7 @@ void ioa_unlock_whitelist(ioa_engine_handle e) #if !defined(TURN_NO_RWLOCK) pthread_rwlock_unlock(whitelist_rwlock); #else - turn_mutex_unlock(&whitelist_mutex); + TURN_MUTEX_UNLOCK(&whitelist_mutex); #endif } static void ioa_wrlock_whitelist(ioa_engine_handle e) @@ -1110,7 +1120,7 @@ static void ioa_wrlock_whitelist(ioa_engine_handle e) #if !defined(TURN_NO_RWLOCK) pthread_rwlock_wrlock(whitelist_rwlock); #else - turn_mutex_lock(&whitelist_mutex); + TURN_MUTEX_LOCK(&whitelist_mutex); #endif } const ip_range_list_t* ioa_get_whitelist(ioa_engine_handle e) @@ -1125,7 +1135,7 @@ void ioa_lock_blacklist(ioa_engine_handle e) #if !defined(TURN_NO_RWLOCK) pthread_rwlock_rdlock(blacklist_rwlock); #else - turn_mutex_lock(&blacklist_mutex); + TURN_MUTEX_LOCK(&blacklist_mutex); #endif } void ioa_unlock_blacklist(ioa_engine_handle e) @@ -1134,7 +1144,7 @@ void ioa_unlock_blacklist(ioa_engine_handle e) #if !defined(TURN_NO_RWLOCK) pthread_rwlock_unlock(blacklist_rwlock); #else - turn_mutex_unlock(&blacklist_mutex); + TURN_MUTEX_UNLOCK(&blacklist_mutex); #endif } static void ioa_wrlock_blacklist(ioa_engine_handle e) @@ -1143,7 +1153,7 @@ static void ioa_wrlock_blacklist(ioa_engine_handle e) #if !defined(TURN_NO_RWLOCK) pthread_rwlock_wrlock(blacklist_rwlock); #else - turn_mutex_lock(&blacklist_mutex); + TURN_MUTEX_LOCK(&blacklist_mutex); #endif } const ip_range_list_t* ioa_get_blacklist(ioa_engine_handle e) @@ -1154,8 +1164,7 @@ const ip_range_list_t* ioa_get_blacklist(ioa_engine_handle e) ip_range_list_t* get_ip_list(const char *kind) { - ip_range_list_t *ret = (ip_range_list_t*) malloc(sizeof(ip_range_list_t)); - memset(ret,0,sizeof(ip_range_list_t)); + ip_range_list_t *ret = (ip_range_list_t*) calloc(sizeof(ip_range_list_t), 1); const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->get_ip_list && !turn_params.no_dynamic_ip_list) { diff --git a/src/apps/rfc5769/CMakeLists.txt b/src/apps/rfc5769/CMakeLists.txt index 492e1947..27b94a95 100644 --- a/src/apps/rfc5769/CMakeLists.txt +++ b/src/apps/rfc5769/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnutils_rfc5769check) @@ -8,7 +8,15 @@ set(SOURCE_FILES add_executable(${PROJECT_NAME} ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE turnclient) +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) +install(DIRECTORY + $/ + DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) diff --git a/src/apps/rfc5769/rfc5769check.c b/src/apps/rfc5769/rfc5769check.c index d0c05a7f..2b4efd31 100644 --- a/src/apps/rfc5769/rfc5769check.c +++ b/src/apps/rfc5769/rfc5769check.c @@ -28,12 +28,16 @@ * SUCH DAMAGE. */ -#include #include #include #include #include + +#if defined(_MSC_VER) +#include +#else #include +#endif #include "ns_turn_utils.h" #include "apputils.h" diff --git a/src/apps/stunclient/CMakeLists.txt b/src/apps/stunclient/CMakeLists.txt index 3e64b3b9..637839d9 100644 --- a/src/apps/stunclient/CMakeLists.txt +++ b/src/apps/stunclient/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnutils_stunclient) @@ -8,7 +8,15 @@ set(SOURCE_FILES add_executable(${PROJECT_NAME} ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE turnclient) +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) +install(DIRECTORY + $/ + DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) diff --git a/src/apps/stunclient/stunclient.c b/src/apps/stunclient/stunclient.c index af90ec11..8478eb92 100644 --- a/src/apps/stunclient/stunclient.c +++ b/src/apps/stunclient/stunclient.c @@ -28,12 +28,18 @@ * SUCH DAMAGE. */ -#include #include #include #include #include -#include +#if defined(_MSC_VER) + #include +#else + #include + #if !defined(WINDOWS) + #include + #endif +#endif #include "ns_turn_utils.h" #include "apputils.h" @@ -415,6 +421,8 @@ int main(int argc, char **argv) int c=0; int forceRfc5780 = 0; + if (socket_init()) return -1; + set_logfile("stdout"); set_system_parameters(0); diff --git a/src/apps/uclient/CMakeLists.txt b/src/apps/uclient/CMakeLists.txt index 86e6eefd..f46d9758 100644 --- a/src/apps/uclient/CMakeLists.txt +++ b/src/apps/uclient/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnutils_uclient) @@ -10,7 +10,15 @@ set(SOURCE_FILES add_executable(${PROJECT_NAME} ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE turnclient) +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) +install(DIRECTORY + $/ + DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime + ) \ No newline at end of file diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index e5e48f92..034c1b69 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -38,9 +38,12 @@ #include #include #include -#include -#include "ns_turn_openssl.h" +#if defined(_MSC_VER) +#include +#else +#include +#endif /////////////// extern definitions ///////////////////// @@ -169,6 +172,24 @@ int main(int argc, char **argv) char rest_api_separator = ':'; int use_null_cipher=0; +#if defined(WINDOWS) + + WORD wVersionRequested; + WSADATA wsaData; + int err; + + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); + + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WSAStartup failed with error: %d\n", err); + return 1; + } +#endif + set_logfile("stdout"); set_execdir(); diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 1ed6663d..820b8ebc 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -28,7 +28,9 @@ * SUCH DAMAGE. */ +#if defined(__linux__) #include +#endif #include "apputils.h" #include "ns_turn_utils.h" @@ -37,8 +39,6 @@ #include "uclient.h" #include "session.h" -#include "ns_turn_openssl.h" - ///////////////////////////////////////// #define MAX_CONNECT_EFFORTS (77) @@ -60,14 +60,14 @@ static const size_t kALPNProtosLen = sizeof(kALPNProtos) - 1; int rare_event(void) { if(dos) - return (((unsigned long)random()) %1000 == 777); + return (((unsigned long)turn_random()) %1000 == 777); return 0; } int not_rare_event(void) { if(dos) - return ((((unsigned long)random()) %1000) < 200); + return ((((unsigned long)turn_random()) %1000) < 200); return 0; } @@ -85,7 +85,7 @@ static int get_allocate_address_family(ioa_addr *relay_addr) { static SSL* tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again, int connect_cycle) { - int ctxtype = (int)(((unsigned long)random())%root_tls_ctx_num); + int ctxtype = (int)(((unsigned long)turn_random())%root_tls_ctx_num); SSL *ssl; @@ -402,7 +402,7 @@ static int clnet_allocate(int verbose, } else if(rt) { ep = -1; } else if(!ep) { - ep = (((uint8_t)random()) % 2); + ep = (((uint8_t)turn_random()) % 2); ep = ep-1; } @@ -602,10 +602,10 @@ static int clnet_allocate(int verbose, int fd = clnet_info->fd; SSL* ssl = clnet_info->ssl; - int close_now = (int)(random()%2); + int close_now = (int)(turn_random()%2); if(close_now) { - int close_socket = (int)(random()%2); + int close_socket = (int)(turn_random()%2); if(ssl && !close_socket) { SSL_shutdown(ssl); SSL_free(ssl); @@ -659,7 +659,7 @@ static int clnet_allocate(int verbose, } if(dual_allocation && !mobility) { - int t = ((uint8_t)random())%3; + int t = ((uint8_t)turn_random())%3; if(t) { uint8_t field[4]; field[0] = (t==1) ? (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4 : (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; @@ -761,7 +761,7 @@ static int turn_channel_bind(int verbose, uint16_t *chn, int cb_sent = 0; if(negative_test) { - *chn = stun_set_channel_bind_request(&request_message, peer_addr, (uint16_t)random()); + *chn = stun_set_channel_bind_request(&request_message, peer_addr, (uint16_t)turn_random()); } else { *chn = stun_set_channel_bind_request(&request_message, peer_addr, *chn); } @@ -1036,19 +1036,19 @@ int start_connection(uint16_t clnet_remote_port0, if(extra_requests) { const char *sarbaddr = "164.156.178.190"; - if(random() % 2 == 0) + if(turn_random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr; make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr); int i; - int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; for(i=0;i0) addr_cpy(&arbaddr[i],&arbaddr[0]); - addr_set_port(&arbaddr[i], (unsigned short)random()); + addr_set_port(&arbaddr[i], (unsigned short)turn_random()); uint8_t *u=(uint8_t*)&(arbaddr[i].s4.sin_addr); - u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; + u[(unsigned short)turn_random()%4] = u[(unsigned short)turn_random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr[i],(uint8_t*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); @@ -1086,7 +1086,7 @@ int start_connection(uint16_t clnet_remote_port0, } } else { - int before=(random()%2 == 0); + int before=(turn_random()%2 == 0); if(before) { if (turn_create_permission(verbose, clnet_info, &peer_addr, 1) < 0) { @@ -1102,18 +1102,18 @@ int start_connection(uint16_t clnet_remote_port0, if(extra_requests) { const char *sarbaddr = "64.56.78.90"; - if(random() % 2 == 0) + if(turn_random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr[EXTRA_CREATE_PERMS]; make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr[0]); int i; - int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; for(i=0;i0) addr_cpy(&arbaddr[i],&arbaddr[0]); - addr_set_port(&arbaddr[i], (unsigned short)random()); + addr_set_port(&arbaddr[i], (unsigned short)turn_random()); uint8_t *u=(uint8_t*)&(arbaddr[i].s4.sin_addr); - u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; + u[(unsigned short)turn_random()%4] = u[(unsigned short)turn_random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr,(uint8_t*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); @@ -1274,19 +1274,19 @@ int start_c2c_connection(uint16_t clnet_remote_port0, if(extra_requests) { const char *sarbaddr = "164.156.178.190"; - if(random() % 2 == 0) + if(turn_random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr; make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr); int i; - int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; for(i=0;i0) addr_cpy(&arbaddr[i],&arbaddr[0]); - addr_set_port(&arbaddr[i], (unsigned short)random()); + addr_set_port(&arbaddr[i], (unsigned short)turn_random()); uint8_t *u=(uint8_t*)&(arbaddr[i].s4.sin_addr); - u[(unsigned short)random()%4] = u[(unsigned short)random()%4] + 1; + u[(unsigned short)turn_random()%4] = u[(unsigned short)turn_random()%4] + 1; //char sss[128]; //addr_to_string(&arbaddr[i],(uint8_t*)sss); //printf("%s: 111.111: %s\n",__FUNCTION__,sss); @@ -1341,16 +1341,16 @@ int start_c2c_connection(uint16_t clnet_remote_port0, if(extra_requests) { const char *sarbaddr = "64.56.78.90"; - if(random() % 2 == 0) + if(turn_random() % 2 == 0) sarbaddr = "2001::172"; ioa_addr arbaddr; make_ioa_addr((const uint8_t*)sarbaddr, 333, &arbaddr); int i; - int maxi = (unsigned short)random() % EXTRA_CREATE_PERMS; + int maxi = (unsigned short)turn_random() % EXTRA_CREATE_PERMS; for(i=0;ipinfo.tcp_conn_number; int i = (int)(elem->pinfo.tcp_conn_number-1); elem->pinfo.tcp_conn=(app_tcp_conn_info**)realloc(elem->pinfo.tcp_conn,elem->pinfo.tcp_conn_number*sizeof(app_tcp_conn_info*)); - elem->pinfo.tcp_conn[i]=(app_tcp_conn_info*)malloc(sizeof(app_tcp_conn_info)); - memset(elem->pinfo.tcp_conn[i],0,sizeof(app_tcp_conn_info)); + elem->pinfo.tcp_conn[i]=(app_tcp_conn_info*)calloc(sizeof(app_tcp_conn_info), 1); elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; elem->pinfo.tcp_conn[i]->cid = cid; diff --git a/src/apps/uclient/uclient.c b/src/apps/uclient/uclient.c index 9d5f86ed..3e497862 100644 --- a/src/apps/uclient/uclient.c +++ b/src/apps/uclient/uclient.c @@ -34,12 +34,11 @@ #include "ns_turn_utils.h" #include "session.h" +#if defined(__linux__) #include -#include - -#include "ns_turn_openssl.h" - #include +#endif +#include static int verbose_packets=0; @@ -197,11 +196,11 @@ int send_buffer(app_ur_conn_info *clnet_info, stun_buffer* message, int data_con char *buffer = (char*) (message->buf); if(negative_protocol_test && (message->len>0)) { - if(random()%10 == 0) { - int np = (int)((unsigned long)random()%10); + if(turn_random()%10 == 0) { + int np = (int)((unsigned long)turn_random()%10); while(np-->0) { - int pos = (int)((unsigned long)random()%(unsigned long)message->len); - int val = (int)((unsigned long)random()%256); + int pos = (int)((unsigned long)turn_random()%(unsigned long)message->len); + int val = (int)((unsigned long)turn_random()%256); message->buf[pos]=(uint8_t)val; } } @@ -700,7 +699,7 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info sar = stun_attr_get_next_str(elem->in_buffer.buf,elem->in_buffer.len,sar); } if(negative_test) { - tcp_data_connect(elem,(uint64_t)random()); + tcp_data_connect(elem,(uint64_t)turn_random()); } else { /* positive test */ tcp_data_connect(elem,cid); @@ -890,7 +889,7 @@ static int client_write(app_ur_session *elem) { if (!(elem->pinfo.tcp_conn) || !(elem->pinfo.tcp_conn_number)) { return -1; } - int i = (unsigned int)(random()) % elem->pinfo.tcp_conn_number; + int i = (unsigned int)(turn_random()) % elem->pinfo.tcp_conn_number; atc = elem->pinfo.tcp_conn[i]; if(!atc->tcp_data_bound) { printf("%s: Uninitialized atc: i=%d, atc=0x%lx\n",__FUNCTION__,i,(long)atc); @@ -1237,7 +1236,7 @@ static int refresh_channel(app_ur_session* elem, uint16_t method, uint32_t lt) stun_attr_add(&message, STUN_ATTRIBUTE_LIFETIME, (const char*) <, 4); if(dual_allocation && !mobility) { - int t = ((uint8_t)random())%3; + int t = ((uint8_t)turn_random())%3; if(t) { uint8_t field[4]; field[0] = (t==1) ? (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4 : (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; @@ -1528,7 +1527,7 @@ void start_mclient(const char *remote_address, int port, stime = current_time; for(i=0;ito_send_timems = current_mstime + 1000 + ((uint32_t)random())%5000; + elems[i]->to_send_timems = current_mstime + 1000 + ((uint32_t)turn_random())%5000; } tot_messages = elems[0]->tot_msgnum * total_clients; @@ -1612,7 +1611,7 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) if(((method == STUN_METHOD_ALLOCATE) || (method == STUN_METHOD_REFRESH)) || !(clnet_info->key_set)) { - cok=((unsigned short)random())%3; + cok=((unsigned short)turn_random())%3; clnet_info->cok = cok; oauth_token otoken; encoded_oauth_token etoken; @@ -1621,7 +1620,7 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) long halflifetime = OAUTH_SESSION_LIFETIME/2; long random_lifetime = 0; while(!random_lifetime) { - random_lifetime = random(); + random_lifetime = turn_random(); } if(random_lifetime<0) random_lifetime=-random_lifetime; random_lifetime = random_lifetime % halflifetime; diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 3bcc6446..ef8cdb26 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -1,9 +1,7 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turnclient) -find_package(OpenSSL REQUIRED) - set(HEADER_FILES ${CMAKE_SOURCE_DIR}/src/ns_turn_defs.h ${CMAKE_SOURCE_DIR}/src/client++/TurnMsgLib.h @@ -20,13 +18,16 @@ set(SOURCE_FILES ns_turn_msg.c ) -add_library(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES}) +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES}) -target_link_libraries(${PROJECT_NAME} PUBLIC turncommon OpenSSL::SSL OpenSSL::Crypto) +target_link_libraries(${PROJECT_NAME} PUBLIC turncommon) # Install head files set_target_properties(${PROJECT_NAME} PROPERTIES - PUBLIC_HEADER "${HEADER_FILES}" + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/ + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/ + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/ + PUBLIC_HEADER "${HEADER_FILES}" # Install head files VERSION ${VERSION} ) @@ -37,21 +38,27 @@ INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Runtime ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + COMPONENT Development PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/turn/client + COMPONENT Development INCLUDES DESTINATION - ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_INSTALL_INCLUDEDIR}/turn ${CMAKE_INSTALL_INCLUDEDIR}/turn/client + COMPONENT Development ) export(TARGETS ${PROJECT_NAME} APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake + NAMESPACE coturn:: ) # Install cmake configure files install(EXPORT ${PROJECT_NAME}Config - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" + NAMESPACE coturn:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/coturn" + COMPONENT Development ) + # Install cmake version configure file if(DEFINED VERSION) write_basic_package_version_file( @@ -59,5 +66,6 @@ if(DEFINED VERSION) VERSION ${VERSION} COMPATIBILITY AnyNewerVersion) install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/coturn" + COMPONENT Development) endif() diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index e8b94dd4..7171d52d 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -29,8 +29,11 @@ */ #include "ns_turn_ioaddr.h" -#include -#include + +#if defined(__unix__) || defined(unix) || defined(__APPLE__) \ + || defined(__DARWIN__) || defined(__MACH__) + #include +#endif ////////////////////////////////////////////////////////////// diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index 2d425e9e..341a6f71 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -96,8 +96,12 @@ int stun_method_str(uint16_t method, char *smethod) long turn_random(void) { long ret = 0; - if(!RAND_bytes((unsigned char *)&ret,sizeof(ret))) + if (!RAND_bytes((unsigned char*)&ret, sizeof(ret))) +#if defined(WINDOWS) + ret = rand(); +#else ret = random(); +#endif return ret; } @@ -107,7 +111,7 @@ static void turn_random_tid_size(void *id) if(!RAND_pseudo_bytes((unsigned char *)ar,12)) { size_t i; for(i=0;i<3;++i) { - ar[i] = (uint32_t)random(); + ar[i] = (uint32_t)turn_random(); } } } @@ -263,7 +267,7 @@ int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, c EVP_DigestUpdate(ctx,str,strl); EVP_DigestFinal(ctx,key,&keylen); EVP_MD_CTX_free(ctx); -#else // OPENSSL_VERSION_NUMBER < 0x10100000L +#else // OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER < 0x30000000L unsigned int keylen = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); #if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && ! defined(LIBRESSL_VERSION_NUMBER) @@ -1477,7 +1481,7 @@ int stun_attr_add_str(uint8_t* buf, size_t *len, uint16_t attr, const uint8_t* a if(alen>0) memcpy(attr_start+4,avalue,alen); // Write 0 padding to not leak data - memset(attr_start+4+alen, 0, paddinglen); + memset(attr_start + 4 + alen, 0, paddinglen); return 0; } @@ -1986,7 +1990,7 @@ int stun_check_message_integrity_by_key_str(turn_credential_type ct, uint8_t *bu if(!old_hmac) return -1; - if(bcmp(old_hmac,new_hmac,shasize)) + if(memcmp(old_hmac,new_hmac,shasize)) return 0; return +1; @@ -2429,7 +2433,7 @@ int decode_oauth_token_normal(const uint8_t *server_name, const encoded_oauth_to return -1; } - if(bcmp(check_mac,mac,mac_size)) { + if(memcmp(check_mac,mac,mac_size)) { OAUTH_ERROR("%s: token integrity check failed\n",__FUNCTION__); return -1; } @@ -2478,7 +2482,7 @@ static void generate_random_nonce(unsigned char *nonce, size_t sz) { if(!RAND_bytes(nonce, (int)sz)) { size_t i; for(i=0;i +#if defined(WINDOWS) +#include +#include +#include +#else #include #include #include #include #include +#include +#include +#endif + +#include #include #include #include #include #include -#include -#include #include #include #include diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 8c2261f1..5bad5def 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -1,4 +1,4 @@ -# Author: Kang Lin (kl222@126.com) +# Author: Kang Lin project(turn_server) @@ -19,7 +19,7 @@ set(HEADER_FILES ns_turn_session.h ) -add_library(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES}) +add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES}) target_link_libraries(${PROJECT_NAME} PUBLIC turnclient) @@ -30,6 +30,10 @@ target_include_directories(${PROJECT_NAME} PUBLIC # Install head files set_target_properties(${PROJECT_NAME} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib + PUBLIC_HEADER "${HEADER_FILES}" # Install head files VERSION ${VERSION} ) @@ -40,20 +44,28 @@ INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Runtime ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + COMPONENT Development + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/turn/server + COMPONENT Development INCLUDES DESTINATION - ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_INSTALL_INCLUDEDIR}/turn ${CMAKE_INSTALL_INCLUDEDIR}/turn/client + ${CMAKE_INSTALL_INCLUDEDIR}/turn/server + COMPONENT Development ) export(TARGETS ${PROJECT_NAME} + NAMESPACE coturn:: APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake ) # Install cmake configure files install(EXPORT ${PROJECT_NAME}Config - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" + NAMESPACE coturn:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/coturn" + COMPONENT Development ) + # Install cmake version configure file if(DEFINED VERSION) write_basic_package_version_file( @@ -61,5 +73,6 @@ if(DEFINED VERSION) VERSION ${VERSION} COMPATIBILITY AnyNewerVersion) install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/coturn" + COMPONENT Development) endif() diff --git a/src/server/ns_turn_allocation.c b/src/server/ns_turn_allocation.c index ac036ad3..a810f158 100644 --- a/src/server/ns_turn_allocation.c +++ b/src/server/ns_turn_allocation.c @@ -486,8 +486,7 @@ ch_info *ch_map_get(ch_map* map, uint16_t chnum, int new_chn) if(new_chn) { size_t old_sz_mem = old_sz * sizeof(ch_info*); a->extra_chns = (ch_info**)realloc(a->extra_chns,old_sz_mem + sizeof(ch_info*)); - a->extra_chns[old_sz] = (ch_info*)malloc(sizeof(ch_info)); - memset(a->extra_chns[old_sz],0,sizeof(ch_info)); + a->extra_chns[old_sz] = (ch_info*)calloc(sizeof(ch_info), 1); a->extra_sz += 1; return a->extra_chns[old_sz]; @@ -574,8 +573,7 @@ tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid } } } - tcp_connection *tc = (tcp_connection*)malloc(sizeof(tcp_connection)); - memset(tc,0,sizeof(tcp_connection)); + tcp_connection *tc = (tcp_connection*)calloc(sizeof(tcp_connection), 1); addr_cpy(&(tc->peer_addr),peer_addr); if(tid) memcpy(&(tc->tid),tid,sizeof(stun_tid)); diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index e592055f..d0537d39 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -49,6 +49,25 @@ typedef struct _ts_ur_super_session ts_ur_super_session; struct _tcp_connection; typedef struct _tcp_connection tcp_connection; +#if defined(_MSC_VER) + #ifndef strtok_r + #define strtok_r strtok_s + #endif + + #ifndef sleep + #define sleep(t) Sleep(t * 1000) + #endif + + #ifndef usleep + #define usleep Sleep + #endif + + #if !defined(ssize_t) && !defined(_SSIZE_T_) + #include + typedef SSIZE_T ssize_t; + #endif + +#endif ////////////// Mutexes ///////////////////// @@ -290,10 +309,6 @@ void handle_http_echo(ioa_socket_handle s); int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); -///////////// ACME ///////////////////// - -int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); - /////////////////////////////////////// #ifdef __cplusplus diff --git a/src/server/ns_turn_maps_rtcp.c b/src/server/ns_turn_maps_rtcp.c index 110e3fa5..d70177cd 100644 --- a/src/server/ns_turn_maps_rtcp.c +++ b/src/server/ns_turn_maps_rtcp.c @@ -176,8 +176,7 @@ static int rtcp_map_init(rtcp_map* map, ioa_engine_handle e) { } rtcp_map* rtcp_map_create(ioa_engine_handle e) { - rtcp_map *map=(rtcp_map*)malloc(sizeof(rtcp_map)); - memset(map,0,sizeof(rtcp_map)); + rtcp_map *map=(rtcp_map*)calloc(sizeof(rtcp_map), 1); if(rtcp_map_init(map,e)<0) { free(map); return NULL; @@ -193,9 +192,9 @@ rtcp_map* rtcp_map_create(ioa_engine_handle e) { int rtcp_map_put(rtcp_map* map, rtcp_token_type token, ioa_socket_handle s) { if(!rtcp_map_valid(map)) return -1; else { - rtcp_alloc_type *value=(rtcp_alloc_type*)malloc(sizeof(rtcp_alloc_type)); + rtcp_alloc_type *value=(rtcp_alloc_type*)calloc(sizeof(rtcp_alloc_type), 1); if(!value) return -1; - memset(value,0,sizeof(rtcp_alloc_type)); + value->s=s; value->t=turn_time() + RTCP_TIMEOUT; value->token=token; diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 648ffd32..d78586d6 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -213,7 +213,7 @@ void init_turn_server_addrs_list(turn_server_addrs_list_t *l) if(l) { l->addrs = NULL; l->size = 0; - turn_mutex_init(&(l->m)); + TURN_MUTEX_INIT(&(l->m)); } } @@ -794,8 +794,7 @@ static ts_ur_super_session* create_new_ss(turn_turnserver* server) { // //printf("%s: 111.111: session size=%lu\n",__FUNCTION__,(unsigned long)sizeof(ts_ur_super_session)); // - ts_ur_super_session *ss = (ts_ur_super_session*)malloc(sizeof(ts_ur_super_session)); - memset(ss,0,sizeof(ts_ur_super_session)); + ts_ur_super_session *ss = (ts_ur_super_session*)calloc(sizeof(ts_ur_super_session), 1); ss->server = server; get_default_realm_options(&(ss->realm_options)); put_session_into_map(ss); @@ -3642,9 +3641,9 @@ static int handle_turn_command(turn_turnserver *server, ts_ur_super_session *ss, } if(asl && asl->size) { - turn_mutex_lock(&(asl->m)); + TURN_MUTEX_LOCK(&(asl->m)); set_alternate_server(asl,get_local_addr_from_ioa_socket(ss->client_socket),&(server->as_counter),method,&tid,resp_constructed,&err_code,&reason,nbh); - turn_mutex_unlock(&(asl->m)); + TURN_MUTEX_UNLOCK(&(asl->m)); } } } diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index bc571796..4e86842b 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -47,7 +47,7 @@ extern "C" { struct _turn_server_addrs_list { ioa_addr *addrs; volatile size_t size; - turn_mutex m; + TURN_MUTEX_DECLARE(m) }; typedef struct _turn_server_addrs_list turn_server_addrs_list_t; diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 00000000..aa4a7885 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,20 @@ +{ + "name": "coturn", + "version-string": "4.6.0", + "dependencies": [ + { + "name": "pthreads", + "platform": "windows" + }, + { + "name": "libevent", + "features": [ "openssl", "thread" ] + }, + "openssl", + "sqlite3", + "libpq", + "hiredis", + "mongo-c-driver" + ] + +} \ No newline at end of file