From b41f211ece14b5657b0114f94718bf9262031d4e Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Wed, 3 Apr 2024 15:38:56 -0500 Subject: [PATCH] 2208 merge dnssd (#4479) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial commit * initial commit * added README.md * Update README.md * Add top level CMakeLists like another project in POCO framework. see #1 * Add CMakeLists to Avahi and Bonjour. (see #1) * Missing changing in top level CMakeLists correct. (see #1) * Add samples CMakeLists. (see #1) * Add temporary cmake find module for Avahi and Bonjour in cmake directory. (see #1) * Add mandatory requirement diff for POCO framework to DNSSD cmake can be work correctly. (see #1) * Update README.md Add cmake build way. * Update README.md Minor change. * Update README.md Removed ambiguous sentence. * Moved files * Add cmake modules * Add cmake modules * Remove modules * Correct linux cmake ci. * Exclude DNSSD from macos, windows. * Update CMakeLists.txt * Remove unused gitignore * Remove deprecated vs versions * Add vs160 and vs170 for DNSSD * Remove deprecated sln * Revert bad changes * Revert bad changes * chore: remove vs90 sln files * chore: remove vs90 x64 files * Revert "chore: remove vs90 sln files" This reverts commit 51d78f82f11d387506c016c9aab3b31e3c32ad23. * chore: add DNSSD to components * chore(DNSSD): disable in CI, update copyright and doc * fix(DNSSD): CMake on Apple platforms: fix finding library providing DNSSD. * fix(DNSSD): Handle kDNSServiceFlagsNonBrowsable that was removed in 1096.0.2 * chore: naming and code modernize review comments * enh(DNSSD): Define DNSSD_*_API for non-MSVC compilers. --------- Co-authored-by: Günter Obiltschnig Co-authored-by: Co-authored-by: Seyyed Soroosh Hosseinalipour Co-authored-by: Matej Kenda --- .github/workflows/ci.yml | 2 +- .github/workflows/codeql-buildscript.sh | 2 +- .gitignore | 1 + .gitmodules | 0 CMakeLists.txt | 11 + DNSSD/Avahi/CMakeLists.txt | 33 + DNSSD/Avahi/Makefile | 21 + DNSSD/Avahi/cmake/PocoDNSSDAvahiConfig.cmake | 5 + DNSSD/Avahi/dependencies | 3 + DNSSD/Avahi/include/Poco/DNSSD/Avahi/Avahi.h | 76 ++ .../Poco/DNSSD/Avahi/AvahiBrowserImpl.h | 86 ++ .../Poco/DNSSD/Avahi/AvahiResponderImpl.h | 134 +++ DNSSD/Avahi/src/AvahiBrowserImpl.cpp | 582 +++++++++++ DNSSD/Avahi/src/AvahiResponderImpl.cpp | 514 ++++++++++ DNSSD/Bonjour/Bonjour.progen | 19 + DNSSD/Bonjour/Bonjour_vs160.sln | 61 ++ DNSSD/Bonjour/Bonjour_vs160.vcxproj | 605 +++++++++++ DNSSD/Bonjour/Bonjour_vs160.vcxproj.filters | 39 + DNSSD/Bonjour/Bonjour_vs170.sln | 85 ++ DNSSD/Bonjour/Bonjour_vs170.vcxproj | 885 ++++++++++++++++ DNSSD/Bonjour/Bonjour_vs170.vcxproj.filters | 39 + DNSSD/Bonjour/Bonjour_vs90.sln | 37 + DNSSD/Bonjour/Bonjour_vs90.vcproj | 416 ++++++++ DNSSD/Bonjour/Bonjour_x64_vs90.sln | 37 + DNSSD/Bonjour/CMakeLists.txt | 33 + DNSSD/Bonjour/Makefile | 18 + .../cmake/PocoDNSSDBonjourConfig.cmake | 5 + DNSSD/Bonjour/dependencies | 3 + .../include/Poco/DNSSD/Bonjour/Bonjour.h | 76 ++ .../Poco/DNSSD/Bonjour/BonjourBrowserImpl.h | 79 ++ .../Poco/DNSSD/Bonjour/BonjourResponderImpl.h | 88 ++ .../include/Poco/DNSSD/Bonjour/EventLoop.h | 120 +++ DNSSD/Bonjour/src/BonjourBrowserImpl.cpp | 486 +++++++++ DNSSD/Bonjour/src/BonjourResponderImpl.cpp | 341 +++++++ DNSSD/Bonjour/src/EventLoop.cpp | 157 +++ DNSSD/CMakeLists.txt | 88 ++ DNSSD/DNSSD.progen | 18 + DNSSD/DNSSD_vs160.sln | 61 ++ DNSSD/DNSSD_vs160.vcxproj | 635 ++++++++++++ DNSSD/DNSSD_vs160.vcxproj.filters | 69 ++ DNSSD/DNSSD_vs170.sln | 85 ++ DNSSD/DNSSD_vs170.vcxproj | 915 +++++++++++++++++ DNSSD/DNSSD_vs170.vcxproj.filters | 69 ++ DNSSD/DNSSD_vs90.sln | 37 + DNSSD/DNSSD_vs90.vcproj | 436 ++++++++ DNSSD/DNSSD_x64_vs90.sln | 37 + DNSSD/Default/Makefile | 21 + DNSSD/Default/dependencies | 3 + DNSSD/LICENSE | 32 + DNSSD/Makefile | 20 + DNSSD/README.md | 49 + DNSSD/cmake/PocoDNSSDConfig.cmake | 4 + DNSSD/dependencies | 2 + DNSSD/doc/00100-DNSSDOverview.page | 208 ++++ .../doc/00200-DNSSDTutorialAndUserGuide.page | 406 ++++++++ DNSSD/include/Poco/DNSSD/DNSSD.h | 194 ++++ DNSSD/include/Poco/DNSSD/DNSSDBrowser.h | 346 +++++++ DNSSD/include/Poco/DNSSD/DNSSDException.h | 37 + DNSSD/include/Poco/DNSSD/DNSSDResponder.h | 193 ++++ DNSSD/include/Poco/DNSSD/DNSSDResponderImpl.h | 119 +++ DNSSD/include/Poco/DNSSD/Domain.h | 87 ++ DNSSD/include/Poco/DNSSD/Error.h | 89 ++ DNSSD/include/Poco/DNSSD/Record.h | 223 ++++ DNSSD/include/Poco/DNSSD/Service.h | 247 +++++ DNSSD/samples/CMakeLists.txt | 2 + DNSSD/samples/DNSSDBrowser/CMakeLists.txt | 7 + .../samples/DNSSDBrowser/DNSSDBrowser.progen | 13 + .../DNSSDBrowser/DNSSDBrowser_vs160.vcxproj | 646 ++++++++++++ .../DNSSDBrowser_vs160.vcxproj.filters | 13 + .../DNSSDBrowser/DNSSDBrowser_vs170.vcxproj | 955 +++++++++++++++++ .../DNSSDBrowser_vs170.vcxproj.filters | 13 + .../DNSSDBrowser/DNSSDBrowser_vs90.vcproj | 445 ++++++++ DNSSD/samples/DNSSDBrowser/Makefile | 23 + .../bin/Darwin/x86_64/DNSSDBrowser | Bin 0 -> 85712 bytes .../bin/Darwin/x86_64/DNSSDBrowserd | Bin 0 -> 211648 bytes .../samples/DNSSDBrowser/src/DNSSDBrowser.cpp | 436 ++++++++ DNSSD/samples/HTTPTimeServer/CMakeLists.txt | 7 + .../HTTPTimeServer/HTTPTimeServer.progen | 13 + .../HTTPTimeServer/HTTPTimeServer.properties | 13 + .../HTTPTimeServer_vs160.vcxproj | 649 ++++++++++++ .../HTTPTimeServer_vs160.vcxproj.filters | 21 + .../HTTPTimeServer_vs170.vcxproj | 958 ++++++++++++++++++ .../HTTPTimeServer_vs170.vcxproj.filters | 21 + .../HTTPTimeServer/HTTPTimeServer_vs90.vcproj | 450 ++++++++ DNSSD/samples/HTTPTimeServer/Makefile | 23 + .../bin/Darwin/x86_64/HTTPTimeServer | Bin 0 -> 37932 bytes .../bin/Darwin/x86_64/HTTPTimeServerd | Bin 0 -> 66260 bytes .../HTTPTimeServer/src/HTTPTimeServer.cpp | 248 +++++ DNSSD/samples/Makefile | 13 + DNSSD/samples/dependencies | 6 + DNSSD/samples/samples.progen | 6 + DNSSD/samples/samples_vs160.sln | 99 ++ DNSSD/samples/samples_vs170.sln | 141 +++ DNSSD/samples/samples_vs90.sln | 57 ++ DNSSD/samples/samples_x64_vs90.sln | 57 ++ DNSSD/src/DNSSDBrowser.cpp | 34 + DNSSD/src/DNSSDException.cpp | 28 + DNSSD/src/DNSSDResponder.cpp | 109 ++ DNSSD/src/DNSSDResponderImpl.cpp | 39 + DNSSD/src/Domain.cpp | 44 + DNSSD/src/Error.cpp | 44 + DNSSD/src/Record.cpp | 64 ++ DNSSD/src/Service.cpp | 80 ++ cmake/FindAvahi.cmake | 20 + cmake/FindBonjour.cmake | 49 + components | 3 + configure | 4 +- 107 files changed, 15678 insertions(+), 4 deletions(-) delete mode 100644 .gitmodules create mode 100644 DNSSD/Avahi/CMakeLists.txt create mode 100644 DNSSD/Avahi/Makefile create mode 100644 DNSSD/Avahi/cmake/PocoDNSSDAvahiConfig.cmake create mode 100644 DNSSD/Avahi/dependencies create mode 100644 DNSSD/Avahi/include/Poco/DNSSD/Avahi/Avahi.h create mode 100644 DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiBrowserImpl.h create mode 100644 DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiResponderImpl.h create mode 100644 DNSSD/Avahi/src/AvahiBrowserImpl.cpp create mode 100644 DNSSD/Avahi/src/AvahiResponderImpl.cpp create mode 100644 DNSSD/Bonjour/Bonjour.progen create mode 100644 DNSSD/Bonjour/Bonjour_vs160.sln create mode 100644 DNSSD/Bonjour/Bonjour_vs160.vcxproj create mode 100644 DNSSD/Bonjour/Bonjour_vs160.vcxproj.filters create mode 100644 DNSSD/Bonjour/Bonjour_vs170.sln create mode 100644 DNSSD/Bonjour/Bonjour_vs170.vcxproj create mode 100644 DNSSD/Bonjour/Bonjour_vs170.vcxproj.filters create mode 100644 DNSSD/Bonjour/Bonjour_vs90.sln create mode 100644 DNSSD/Bonjour/Bonjour_vs90.vcproj create mode 100644 DNSSD/Bonjour/Bonjour_x64_vs90.sln create mode 100644 DNSSD/Bonjour/CMakeLists.txt create mode 100644 DNSSD/Bonjour/Makefile create mode 100644 DNSSD/Bonjour/cmake/PocoDNSSDBonjourConfig.cmake create mode 100644 DNSSD/Bonjour/dependencies create mode 100644 DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/Bonjour.h create mode 100644 DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourBrowserImpl.h create mode 100644 DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourResponderImpl.h create mode 100644 DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/EventLoop.h create mode 100644 DNSSD/Bonjour/src/BonjourBrowserImpl.cpp create mode 100644 DNSSD/Bonjour/src/BonjourResponderImpl.cpp create mode 100644 DNSSD/Bonjour/src/EventLoop.cpp create mode 100644 DNSSD/CMakeLists.txt create mode 100644 DNSSD/DNSSD.progen create mode 100644 DNSSD/DNSSD_vs160.sln create mode 100644 DNSSD/DNSSD_vs160.vcxproj create mode 100644 DNSSD/DNSSD_vs160.vcxproj.filters create mode 100644 DNSSD/DNSSD_vs170.sln create mode 100644 DNSSD/DNSSD_vs170.vcxproj create mode 100644 DNSSD/DNSSD_vs170.vcxproj.filters create mode 100644 DNSSD/DNSSD_vs90.sln create mode 100644 DNSSD/DNSSD_vs90.vcproj create mode 100644 DNSSD/DNSSD_x64_vs90.sln create mode 100644 DNSSD/Default/Makefile create mode 100644 DNSSD/Default/dependencies create mode 100644 DNSSD/LICENSE create mode 100644 DNSSD/Makefile create mode 100644 DNSSD/README.md create mode 100644 DNSSD/cmake/PocoDNSSDConfig.cmake create mode 100644 DNSSD/dependencies create mode 100644 DNSSD/doc/00100-DNSSDOverview.page create mode 100644 DNSSD/doc/00200-DNSSDTutorialAndUserGuide.page create mode 100644 DNSSD/include/Poco/DNSSD/DNSSD.h create mode 100644 DNSSD/include/Poco/DNSSD/DNSSDBrowser.h create mode 100644 DNSSD/include/Poco/DNSSD/DNSSDException.h create mode 100644 DNSSD/include/Poco/DNSSD/DNSSDResponder.h create mode 100644 DNSSD/include/Poco/DNSSD/DNSSDResponderImpl.h create mode 100644 DNSSD/include/Poco/DNSSD/Domain.h create mode 100644 DNSSD/include/Poco/DNSSD/Error.h create mode 100644 DNSSD/include/Poco/DNSSD/Record.h create mode 100644 DNSSD/include/Poco/DNSSD/Service.h create mode 100644 DNSSD/samples/CMakeLists.txt create mode 100644 DNSSD/samples/DNSSDBrowser/CMakeLists.txt create mode 100644 DNSSD/samples/DNSSDBrowser/DNSSDBrowser.progen create mode 100644 DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj create mode 100644 DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj.filters create mode 100644 DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj create mode 100644 DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj.filters create mode 100644 DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs90.vcproj create mode 100644 DNSSD/samples/DNSSDBrowser/Makefile create mode 100755 DNSSD/samples/DNSSDBrowser/bin/Darwin/x86_64/DNSSDBrowser create mode 100755 DNSSD/samples/DNSSDBrowser/bin/Darwin/x86_64/DNSSDBrowserd create mode 100644 DNSSD/samples/DNSSDBrowser/src/DNSSDBrowser.cpp create mode 100644 DNSSD/samples/HTTPTimeServer/CMakeLists.txt create mode 100644 DNSSD/samples/HTTPTimeServer/HTTPTimeServer.progen create mode 100644 DNSSD/samples/HTTPTimeServer/HTTPTimeServer.properties create mode 100644 DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj create mode 100644 DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj.filters create mode 100644 DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj create mode 100644 DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj.filters create mode 100644 DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs90.vcproj create mode 100644 DNSSD/samples/HTTPTimeServer/Makefile create mode 100755 DNSSD/samples/HTTPTimeServer/bin/Darwin/x86_64/HTTPTimeServer create mode 100755 DNSSD/samples/HTTPTimeServer/bin/Darwin/x86_64/HTTPTimeServerd create mode 100644 DNSSD/samples/HTTPTimeServer/src/HTTPTimeServer.cpp create mode 100644 DNSSD/samples/Makefile create mode 100644 DNSSD/samples/dependencies create mode 100644 DNSSD/samples/samples.progen create mode 100644 DNSSD/samples/samples_vs160.sln create mode 100644 DNSSD/samples/samples_vs170.sln create mode 100644 DNSSD/samples/samples_vs90.sln create mode 100644 DNSSD/samples/samples_x64_vs90.sln create mode 100644 DNSSD/src/DNSSDBrowser.cpp create mode 100644 DNSSD/src/DNSSDException.cpp create mode 100644 DNSSD/src/DNSSDResponder.cpp create mode 100644 DNSSD/src/DNSSDResponderImpl.cpp create mode 100644 DNSSD/src/Domain.cpp create mode 100644 DNSSD/src/Error.cpp create mode 100644 DNSSD/src/Record.cpp create mode 100644 DNSSD/src/Service.cpp create mode 100644 cmake/FindAvahi.cmake create mode 100644 cmake/FindBonjour.cmake diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e737844a8..06a797f35 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -523,7 +523,7 @@ jobs: timeout_minutes: 90 max_attempts: 3 retry_on: any - command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT" + command: .\buildwin.ps1 -poco_base . -vs 170 -action build -linkmode all -config release -platform x64 -samples -tests -omit "Crypto,NetSSL_OpenSSL,Data/MySQL,Data/PostgreSQL,JWT,DNSSD,DNSSD/Avahi,DNSSD/Bonjour" # windows-2022-msvc-buildwin-win32: # runs-on: windows-2022 diff --git a/.github/workflows/codeql-buildscript.sh b/.github/workflows/codeql-buildscript.sh index a8f9a8cb1..1cbba9822 100644 --- a/.github/workflows/codeql-buildscript.sh +++ b/.github/workflows/codeql-buildscript.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash sudo apt-get -y update && sudo apt-get -y install cmake ninja-build libssl-dev unixodbc-dev libmysqlclient-dev redis-server -cmake -H. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all +cmake -H. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_DNSSD=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all diff --git a/.gitignore b/.gitignore index 152101e6f..c23f0eb35 100644 --- a/.gitignore +++ b/.gitignore @@ -131,6 +131,7 @@ lib/ lib64/ pocomsg.h **/UpgradeLog*.XML +/out/build/x64-Debug .vs/ vcpkg_installed/ diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29bb..000000000 diff --git a/CMakeLists.txt b/CMakeLists.txt index e7b9d15b7..36d95502f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,12 @@ option(ENABLE_JSON "Enable JSON" ON) option(ENABLE_MONGODB "Enable MongoDB" ON) option(ENABLE_DATA_SQLITE "Enable Data SQlite" ON) option(ENABLE_REDIS "Enable Redis" ON) +option(ENABLE_DNSSD "Enable DNSSD" OFF) +option(ENABLE_DNSSD_DEFAULT "Enable DNSSD Default" OFF) + +option(ENABLE_DNSSD_AVAHI "Enable DNSSD Avahi" OFF) +option(ENABLE_DNSSD_BONJOUR "Enable DNSSD Bonjour" OFF) + option(ENABLE_PROMETHEUS "Enable Prometheus" ON) option(ENABLE_PDF "Enable PDF" OFF) option(ENABLE_UTIL "Enable Util" ON) @@ -372,6 +378,11 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/Redis AND ENABLE_REDIS) list(APPEND Poco_COMPONENTS "Redis") endif() +if(ENABLE_DNSSD) + add_subdirectory(DNSSD) + list(APPEND Poco_COMPONENTS "DNSSD") +endif() + if(EXISTS ${PROJECT_SOURCE_DIR}/Prometheus AND ENABLE_PROMETHEUS) add_subdirectory(Prometheus) list(APPEND Poco_COMPONENTS "Prometheus") diff --git a/DNSSD/Avahi/CMakeLists.txt b/DNSSD/Avahi/CMakeLists.txt new file mode 100644 index 000000000..2c7236294 --- /dev/null +++ b/DNSSD/Avahi/CMakeLists.txt @@ -0,0 +1,33 @@ +set(LIBNAME "DNSSDAvahi") +set(POCO_LIBNAME "Poco${LIBNAME}") + +# Sources +file(GLOB SRCS_G "src/*.cpp") +POCO_SOURCES_AUTO( Avahi_SRCS ${SRCS_G}) + +# Headers +file(GLOB_RECURSE HDRS_G "include/*.h" ) +POCO_HEADERS_AUTO( Avahi_SRCS ${HDRS_G}) + +add_definitions( ${Avahi_CFLAGS} -DTHREADSAFE) + +add_library( "${LIBNAME}" ${LIB_MODE} ${Avahi_SRCS} ) +add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}") +set_target_properties( "${LIBNAME}" + PROPERTIES + VERSION ${SHARED_LIBRARY_VERSION} SOVERSION ${SHARED_LIBRARY_VERSION} + OUTPUT_NAME ${POCO_LIBNAME} + DEFINE_SYMBOL Avahi_EXPORTS + ) + +target_link_libraries( "${LIBNAME}" Foundation Net DNSSD ${AVAHI_LIBRARIES}) +target_include_directories( "${LIBNAME}" + PUBLIC + $ + $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src + ) +target_compile_definitions("${LIBNAME}" PUBLIC ${LIB_MODE_DEFINITIONS}) + +POCO_INSTALL("${LIBNAME}") +POCO_GENERATE_PACKAGE("${LIBNAME}") diff --git a/DNSSD/Avahi/Makefile b/DNSSD/Avahi/Makefile new file mode 100644 index 000000000..974131bdf --- /dev/null +++ b/DNSSD/Avahi/Makefile @@ -0,0 +1,21 @@ +# +# Makefile +# +# $Id: //poco/1.7/DNSSD/Avahi/Makefile#1 $ +# +# Makefile for Poco DNSSD Avahi +# + +include $(POCO_BASE)/build/rules/global + +SYSLIBS += -lavahi-common -lavahi-client + +objects = \ + AvahiResponderImpl AvahiBrowserImpl + +target = PocoDNSSDAvahi +target_version = 1 +target_libs = PocoNet PocoDNSSD PocoFoundation + +include $(POCO_BASE)/build/rules/lib + diff --git a/DNSSD/Avahi/cmake/PocoDNSSDAvahiConfig.cmake b/DNSSD/Avahi/cmake/PocoDNSSDAvahiConfig.cmake new file mode 100644 index 000000000..915c53eba --- /dev/null +++ b/DNSSD/Avahi/cmake/PocoDNSSDAvahiConfig.cmake @@ -0,0 +1,5 @@ +include(CMakeFindDependencyMacro) +find_dependency(PocoFoundation) +find_dependency(PocoNet) +find_dependency(PocoDNSSD) +include("${CMAKE_CURRENT_LIST_DIR}/PocoDNSSDAvahiTargets.cmake") diff --git a/DNSSD/Avahi/dependencies b/DNSSD/Avahi/dependencies new file mode 100644 index 000000000..5ab5fc352 --- /dev/null +++ b/DNSSD/Avahi/dependencies @@ -0,0 +1,3 @@ +Foundation +Net +DNSSD diff --git a/DNSSD/Avahi/include/Poco/DNSSD/Avahi/Avahi.h b/DNSSD/Avahi/include/Poco/DNSSD/Avahi/Avahi.h new file mode 100644 index 000000000..1b6fe1d9a --- /dev/null +++ b/DNSSD/Avahi/include/Poco/DNSSD/Avahi/Avahi.h @@ -0,0 +1,76 @@ +// +// Avahi.h +// +// $Id: //poco/1.7/DNSSD/Avahi/include/Poco/DNSSD/Avahi/Avahi.h#1 $ +// +// Library: DNSSD/Avahi +// Package: Implementation +// Module: Avahi +// +// Basic definitions for the Poco DNSSD Avahi library. +// This file must be the first file included by every other DNSSD Avahi +// header file. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Avahi_Avahi_INCLUDED +#define DNSSD_Avahi_Avahi_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" + + +// +// The following block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the Avahi_EXPORTS +// symbol defined on the command line. This symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// DNSSD_Avahi_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. +// +#if defined(_WIN32) && defined(POCO_DLL) + #if defined(Avahi_EXPORTS) + #define DNSSD_Avahi_API __declspec(dllexport) + #else + #define DNSSD_Avahi_API __declspec(dllimport) + #endif +#endif + + +#if !defined(DNSSD_Avahi_API) + #if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4) + #define DNSSD_Avahi_API __attribute__ ((visibility ("default"))) + #else + #define DNSSD_Avahi_API + #endif +#endif + + +#if defined(_MSC_VER) + #if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(Avahi_EXPORTS) + #pragma comment(lib, "PocoDNSSDAvahi" POCO_LIB_SUFFIX) + #endif +#endif + + +namespace Poco { +namespace DNSSD { + + +void DNSSD_Avahi_API initializeDNSSD(); + /// Initialize the DNSSD subsystem. + + +void DNSSD_Avahi_API uninitializeDNSSD(); + /// Uninitialize the DNSSD subsystem. + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_Avahi_Avahi_INCLUDED diff --git a/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiBrowserImpl.h b/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiBrowserImpl.h new file mode 100644 index 000000000..2ab34fe76 --- /dev/null +++ b/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiBrowserImpl.h @@ -0,0 +1,86 @@ +// +// AvahiBrowserImpl.h +// +// $Id: //poco/1.7/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiBrowserImpl.h#1 $ +// +// Library: DNSSD/Avahi +// Package: Implementation +// Module: AvahiBrowserImpl +// +// Definition of the AvahiBrowserImpl class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Avahi_AvahiBrowserImpl_INCLUDED +#define DNSSD_Avahi_AvahiBrowserImpl_INCLUDED + + +#include "Poco/DNSSD/Avahi/Avahi.h" +#include "Poco/DNSSD/DNSSDBrowser.h" +#include +#include + + +namespace Poco { +namespace DNSSD { +namespace Avahi { + + +class AvahiResponderImpl; + + +class DNSSD_Avahi_API AvahiBrowserImpl: public DNSSDBrowser + /// The DNSSDBrowser implementation for Avahi. +{ +public: + AvahiBrowserImpl(AvahiResponderImpl& responder); + /// Creates the AvahiBrowserImpl. + + ~AvahiBrowserImpl(); + /// Destroys the AvahiBrowserImpl. + + // DNSSDBrowser + BrowseHandle browse(const std::string& regType, const std::string& domain, int options, Poco::Int32 networkInterface); + BrowseHandle resolve(const Service& service, int options); + BrowseHandle enumerateBrowseDomains(Poco::Int32 networkInterface); + BrowseHandle enumerateRegistrationDomains(Poco::Int32 networkInterface); + BrowseHandle queryRecord(const std::string& name, Poco::UInt16 type, Poco::UInt16 clazz, int options, Poco::Int32 networkInterface); + BrowseHandle resolveHost(const std::string& host, int options, Poco::Int32 networkInterface); + void cancel(BrowseHandle& browseHandle); + + // Implementation + void onBrowseReply(AvahiServiceBrowser* browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char* name, const char* type, const char* domain, AvahiLookupResultFlags flags); + void onResolveReply(AvahiServiceResolver* resolver, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char* name, const char* type, const char* domain, const char* host, const AvahiAddress* a, uint16_t port, AvahiStringList* txt, AvahiLookupResultFlags flags); + void onEnumerateBrowseDomainsReply(AvahiDomainBrowser* browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char* domain, AvahiLookupResultFlags flags, bool isDefault); + void onEnumerateRegistrationDomainsReply(AvahiDomainBrowser* browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char* domain, AvahiLookupResultFlags flags, bool isDefault); + void onQueryRecordReply(AvahiRecordBrowser* browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char* name, uint16_t clazz, uint16_t type, const void* data, std::size_t size, AvahiLookupResultFlags flags); + +protected: + enum HandleTypes + { + DOMAIN_BROWSER_HANDLE, + SERVICE_BROWSER_HANDLE, + SERVICE_RESOLVER_HANDLE, + RECORD_BROWSER_HANDLE + }; + + static void parseTXTRecord(AvahiStringList* strList, Service::Properties& properties); + static void escape(const char* str, std::string& escaped); + +private: + typedef std::map AddressMap; + + AvahiResponderImpl& _responder; + AddressMap _addressMap; +}; + + +} } } // namespace Poco::DNSSD::Avahi + + +#endif // DNSSD_Avahi_AvahiBrowserImpl_INCLUDED diff --git a/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiResponderImpl.h b/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiResponderImpl.h new file mode 100644 index 000000000..b6889e514 --- /dev/null +++ b/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiResponderImpl.h @@ -0,0 +1,134 @@ +// +// AvahiResponderImpl.h +// +// $Id: //poco/1.7/DNSSD/Avahi/include/Poco/DNSSD/Avahi/AvahiResponderImpl.h#1 $ +// +// Library: DNSSD/Avahi +// Package: Implementation +// Module: AvahiResponderImpl +// +// Definition of the AvahiResponderImpl class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Avahi_AvahiResponderImpl_INCLUDED +#define DNSSD_Avahi_AvahiResponderImpl_INCLUDED + + +#include "Poco/DNSSD/Avahi/Avahi.h" +#include "Poco/DNSSD/Avahi/AvahiBrowserImpl.h" +#include "Poco/DNSSD/DNSSDResponderImpl.h" +#include "Poco/DNSSD/DNSSDResponder.h" +#include "Poco/ScopedLock.h" +#include "Poco/Mutex.h" +#include "Poco/Event.h" +#include "Poco/Thread.h" +#include "Poco/Runnable.h" +#include +#include +#include +#include + + +namespace Poco { +namespace DNSSD { +namespace Avahi { + + +class AvahiBrowserImpl; + +class DNSSD_Avahi_API AvahiResponderImpl: public Poco::DNSSD::DNSSDResponderImpl, public Poco::Runnable + /// The DNSSDResponderImpl implementation for Avahi. +{ +public: + typedef Poco::ScopedLock ScopedLock; + + AvahiResponderImpl(Poco::DNSSD::DNSSDResponder& owner); + /// Creates the AvahiResponder, using the given owner. + + ~AvahiResponderImpl(); + /// Destroys the AvahiResponderImpl. + + // DNSSDResponderImpl + DNSSDBrowser& browser(); + ServiceHandle registerService(const Service& service, int options); + void unregisterService(ServiceHandle& serviceHandle); + RecordHandle addRecord(ServiceHandle serviceHandle, const Record& record); + void updateRecord(ServiceHandle serviceHandle, RecordHandle recordHandle, const Record& record); + void removeRecord(ServiceHandle serviceHandle, RecordHandle& recordHandle); + void start(); + void stop(); + + // Runnable + void run(); + + // Implementation + static const char* describeError(int code); + /// Returns a human-readable string describing the error. + + void onClientStateChange(AvahiClientState state); + void onGroupStateChange(AvahiEntryGroup* avahiGroup, AvahiEntryGroupState state); + void lock(); + void unlock(); + +protected: + enum + { + START_TIMEOUT = 5000 // milliseconds + }; + + struct RecordInfo + { + Record record; + int id; + }; + typedef std::vector RecordVec; + + struct ServiceInfo + { + Service service; + RecordVec records; + int options; + }; + typedef std::map ServiceMap; + + void reregisterServices(); + void setupEntryGroup(AvahiEntryGroup* avahiGroup, const Service& service, const RecordVec& records, int options, bool rename); + static AvahiStringList* createTXTRecord(const Service::Properties& properties); + +private: + Poco::DNSSD::DNSSDResponder& _owner; + AvahiBrowserImpl _browser; + AvahiSimplePoll* _avahiPoll; + AvahiClient* _avahiClient; + Poco::Event _avahiClientReady; + ServiceMap _services; + bool _running; + int _nextRecordId; + Poco::Mutex _mutex; + Poco::Thread _pollThread; + + friend class AvahiBrowserImpl; +}; + + +class DNSSD_Avahi_API AvahiResponderImplFactory: public Poco::DNSSD::DNSSDResponderImplFactory + /// A factory for AvahiResponderImplFactory objects. +{ +public: + DNSSDResponderImpl* createResponderImpl(Poco::DNSSD::DNSSDResponder& owner) + { + return new AvahiResponderImpl(owner); + } +}; + + +} } } // namespace Poco::DNSSD::Avahi + + +#endif // DNSSD_Avahi_AvahiResponderImpl_INCLUDED diff --git a/DNSSD/Avahi/src/AvahiBrowserImpl.cpp b/DNSSD/Avahi/src/AvahiBrowserImpl.cpp new file mode 100644 index 000000000..fd08dddb1 --- /dev/null +++ b/DNSSD/Avahi/src/AvahiBrowserImpl.cpp @@ -0,0 +1,582 @@ +// +// AvahiBrowserImpl.cpp +// +// $Id: //poco/1.7/DNSSD/Avahi/src/AvahiBrowserImpl.cpp#1 $ +// +// Library: DNSSD/Avahi +// Package: Implementation +// Module: AvahiBrowserImpl +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Avahi/AvahiBrowserImpl.h" +#include "Poco/DNSSD/Avahi/AvahiResponderImpl.h" +#include "Poco/DNSSD/DNSSDException.h" +#include "Poco/NumberFormatter.h" +#include +#include +#include +#include + + +namespace Poco { +namespace DNSSD { +namespace Avahi { + + +extern "C" void onBrowseReply( + AvahiServiceBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* name, + const char* type, + const char* domain, + AvahiLookupResultFlags flags, + void* context) +{ + try + { + AvahiBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onBrowseReply(browser, interface, protocol, event, name, type, domain, flags); + } + catch (...) + { + } +} + + +extern "C" void onResolveReply( + AvahiServiceResolver* resolver, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiResolverEvent event, + const char* name, + const char* type, + const char* domain, + const char* host, + const AvahiAddress* a, + uint16_t port, + AvahiStringList* txt, + AvahiLookupResultFlags flags, + void* context) +{ + try + { + AvahiBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onResolveReply(resolver, interface, protocol, event, name, type, domain, host, a, port, txt, flags); + } + catch (...) + { + } +} + + +extern "C" void onEnumerateBrowseDomainsReply( + AvahiDomainBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* domain, + AvahiLookupResultFlags flags, + void* context) +{ + try + { + AvahiBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onEnumerateBrowseDomainsReply(browser, interface, protocol, event, domain, flags, false); + } + catch (...) + { + } +} + + +extern "C" void onEnumerateDefaultBrowseDomainsReply( + AvahiDomainBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* domain, + AvahiLookupResultFlags flags, + void* context) +{ + try + { + AvahiBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onEnumerateBrowseDomainsReply(browser, interface, protocol, event, domain, flags, true); + } + catch (...) + { + } + if (event == AVAHI_BROWSER_ALL_FOR_NOW || event == AVAHI_BROWSER_FAILURE) + { + avahi_domain_browser_free(browser); + } +} + + +extern "C" void onEnumerateRegistrationDomainsReply( + AvahiDomainBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* domain, + AvahiLookupResultFlags flags, + void* context) +{ + try + { + AvahiBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onEnumerateRegistrationDomainsReply(browser, interface, protocol, event, domain, flags, false); + } + catch (...) + { + } +} + + +extern "C" void onEnumerateDefaultRegistrationDomainsReply( + AvahiDomainBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* domain, + AvahiLookupResultFlags flags, + void* context) +{ + try + { + AvahiBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onEnumerateRegistrationDomainsReply(browser, interface, protocol, event, domain, flags, true); + } + catch (...) + { + } + if (event == AVAHI_BROWSER_ALL_FOR_NOW || event == AVAHI_BROWSER_FAILURE) + { + avahi_domain_browser_free(browser); + } +} + + +extern "C" void onQueryRecordReply( + AvahiRecordBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* name, + uint16_t clazz, + uint16_t type, + const void* data, + std::size_t size, + AvahiLookupResultFlags flags, + void* context) +{ + try + { + AvahiBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onQueryRecordReply(browser, interface, protocol, event, name, clazz, type, data, size, flags); + } + catch (...) + { + } +} + + +AvahiBrowserImpl::AvahiBrowserImpl(AvahiResponderImpl& responder): + _responder(responder) +{ +} + + +AvahiBrowserImpl::~AvahiBrowserImpl() +{ +} + + +BrowseHandle AvahiBrowserImpl::browse(const std::string& regType, const std::string& domain, int options, Poco::Int32 networkInterface) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + AvahiIfIndex ifIndex = networkInterface == 0 ? AVAHI_IF_UNSPEC : networkInterface; + AvahiServiceBrowser* browser = avahi_service_browser_new(_responder._avahiClient, ifIndex, AVAHI_PROTO_UNSPEC, regType.c_str(), domain.empty() ? NULL : domain.c_str(), (AvahiLookupFlags) 0, Poco::DNSSD::Avahi::onBrowseReply, this); + if (!browser) + { + int error = avahi_client_errno(_responder._avahiClient); + throw Poco::DNSSD::DNSSDException("Failed to browse for " + regType, AvahiResponderImpl::describeError(error), error); + } + return BrowseHandle(browser, SERVICE_BROWSER_HANDLE); +} + + +BrowseHandle AvahiBrowserImpl::resolve(const Service& service, int options) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + AvahiIfIndex ifIndex = service.networkInterface(); + AvahiServiceResolver* resolver = avahi_service_resolver_new(_responder._avahiClient, ifIndex, AVAHI_PROTO_UNSPEC, service.name().c_str(), service.type().c_str(), service.domain().c_str(), AVAHI_PROTO_UNSPEC, (AvahiLookupFlags) 0, Poco::DNSSD::Avahi::onResolveReply, this); + if (!resolver) + { + int error = avahi_client_errno(_responder._avahiClient); + throw Poco::DNSSD::DNSSDException("Failed to resolve service " + service.name(), AvahiResponderImpl::describeError(error), error); + } + return BrowseHandle(resolver, SERVICE_RESOLVER_HANDLE); +} + + +BrowseHandle AvahiBrowserImpl::enumerateBrowseDomains(Poco::Int32 networkInterface) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + AvahiIfIndex ifIndex = networkInterface == 0 ? AVAHI_IF_UNSPEC : networkInterface; + AvahiDomainBrowser* browser = avahi_domain_browser_new(_responder._avahiClient, ifIndex, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, (AvahiLookupFlags) 0, Poco::DNSSD::Avahi::onEnumerateBrowseDomainsReply, this); + if (!browser) + { + int error = avahi_client_errno(_responder._avahiClient); + throw Poco::DNSSD::DNSSDException("Failed to enumerate browse domains", AvahiResponderImpl::describeError(error), error); + } + AvahiDomainBrowser* defaultBrowser = avahi_domain_browser_new(_responder._avahiClient, ifIndex, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE_DEFAULT, (AvahiLookupFlags) 0, Poco::DNSSD::Avahi::onEnumerateDefaultBrowseDomainsReply, this); + if (!defaultBrowser) + { + int error = avahi_client_errno(_responder._avahiClient); + avahi_domain_browser_free(browser); + throw Poco::DNSSD::DNSSDException("Failed to enumerate default browse domains", AvahiResponderImpl::describeError(error), error); + } + return BrowseHandle(browser, DOMAIN_BROWSER_HANDLE); +} + + +BrowseHandle AvahiBrowserImpl::enumerateRegistrationDomains(Poco::Int32 networkInterface) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + AvahiIfIndex ifIndex = networkInterface == 0 ? AVAHI_IF_UNSPEC : networkInterface; + AvahiDomainBrowser* browser = avahi_domain_browser_new(_responder._avahiClient, ifIndex, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_REGISTER, (AvahiLookupFlags) 0, Poco::DNSSD::Avahi::onEnumerateRegistrationDomainsReply, this); + if (!browser) + { + int error = avahi_client_errno(_responder._avahiClient); + throw Poco::DNSSD::DNSSDException("Failed to enumerate registration domains", AvahiResponderImpl::describeError(error), error); + } + AvahiDomainBrowser* defaultBrowser = avahi_domain_browser_new(_responder._avahiClient, ifIndex, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_REGISTER_DEFAULT, (AvahiLookupFlags) 0, Poco::DNSSD::Avahi::onEnumerateDefaultRegistrationDomainsReply, this); + if (!defaultBrowser) + { + int error = avahi_client_errno(_responder._avahiClient); + avahi_domain_browser_free(browser); + throw Poco::DNSSD::DNSSDException("Failed to enumerate default registration domains", AvahiResponderImpl::describeError(error), error); + } + return BrowseHandle(browser, DOMAIN_BROWSER_HANDLE); +} + + +BrowseHandle AvahiBrowserImpl::queryRecord(const std::string& name, Poco::UInt16 type, Poco::UInt16 clazz, int options, Poco::Int32 networkInterface) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + AvahiIfIndex ifIndex = networkInterface == 0 ? AVAHI_IF_UNSPEC : networkInterface; + AvahiRecordBrowser* browser = avahi_record_browser_new(_responder._avahiClient, ifIndex, AVAHI_PROTO_UNSPEC, name.c_str(), clazz, type, (AvahiLookupFlags) 0, Poco::DNSSD::Avahi::onQueryRecordReply, this); + if (!browser) + { + int error = avahi_client_errno(_responder._avahiClient); + throw Poco::DNSSD::DNSSDException("Failed to query for record", AvahiResponderImpl::describeError(error), error); + } + return BrowseHandle(browser, RECORD_BROWSER_HANDLE); +} + + +BrowseHandle AvahiBrowserImpl::resolveHost(const std::string& host, int options, Poco::Int32 networkInterface) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + AddressMap::iterator it = _addressMap.find(host); + if (it != _addressMap.end()) + { + ResolveHostEventArgs args(BrowseHandle(), 0, host, it->second, networkInterface, 0); + hostResolved(this, args); + } + else + { + int err = AVAHI_ERR_DNS_NXDOMAIN; + Error error(networkInterface, err, AvahiResponderImpl::describeError(err)); + ErrorEventArgs args(BrowseHandle(), 0, error); + hostResolveError(this, args); + } + return BrowseHandle(); +} + + +void AvahiBrowserImpl::cancel(BrowseHandle& browseHandle) +{ + if (!browseHandle.isValid()) return; + + AvahiResponderImpl::ScopedLock lock(_responder); + + switch (browseHandle.subtype()) + { + case SERVICE_BROWSER_HANDLE: + avahi_service_browser_free(browseHandle.cast()); + break; + case SERVICE_RESOLVER_HANDLE: + avahi_service_resolver_free(browseHandle.cast()); + break; + case DOMAIN_BROWSER_HANDLE: + avahi_domain_browser_free(browseHandle.cast()); + break; + case RECORD_BROWSER_HANDLE: + avahi_record_browser_free(browseHandle.cast()); + break; + } + browseHandle.reset(); +} + + +void AvahiBrowserImpl::onBrowseReply( + AvahiServiceBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* name, + const char* type, + const char* domain, + AvahiLookupResultFlags flags) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) + { + int eventFlags(0); + Service service(interface, name, type, domain); + ServiceEventArgs args(BrowseHandle(browser), eventFlags, service); + if (event == AVAHI_BROWSER_NEW) + { + serviceFound(this, args); + } + else + { + serviceRemoved(this, args); + } + } + else if (event == AVAHI_BROWSER_FAILURE) + { + int err = avahi_client_errno(_responder._avahiClient); + Error error(interface, err, AvahiResponderImpl::describeError(err)); + ErrorEventArgs args(BrowseHandle(browser), 0, error); + browseError(this, args); + } +} + + +void AvahiBrowserImpl::onResolveReply( + AvahiServiceResolver* resolver, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiResolverEvent event, + const char* name, + const char* type, + const char* domain, + const char* host, + const AvahiAddress* a, + uint16_t port, + AvahiStringList* txt, + AvahiLookupResultFlags flags) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + if (event == AVAHI_RESOLVER_FOUND) + { + Poco::Net::IPAddress addr; + switch (a->proto) + { + case AVAHI_PROTO_INET: + addr = Poco::Net::IPAddress(&a->data.ipv4.address, sizeof(a->data.ipv4.address)); + break; +#if defined(POCO_HAVE_IPv6) + case AVAHI_PROTO_INET6: + addr = Poco::Net::IPAddress(&a->data.ipv6.address, sizeof(a->data.ipv6.address)); + break; +#endif + } + int eventFlags(0); + std::string fullName; + escape(name, fullName); + fullName += '.'; + fullName += type; + fullName += '.'; + fullName += domain; + fullName += '.'; + Service service(interface, name, fullName, type, domain, host, port); + _addressMap[service.host()] = addr; + parseTXTRecord(txt, service.properties()); + ServiceEventArgs args(BrowseHandle(resolver), eventFlags, service); + serviceResolved(this, args); + } + else if (event == AVAHI_RESOLVER_FAILURE) + { + int err = avahi_client_errno(_responder._avahiClient); + Error error(interface, err, AvahiResponderImpl::describeError(err)); + ErrorEventArgs args(BrowseHandle(resolver), 0, error); + resolveError(this, args); + } +} + + +void AvahiBrowserImpl::onEnumerateBrowseDomainsReply( + AvahiDomainBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* domain, + AvahiLookupResultFlags flags, + bool isDefault) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) + { + int eventFlags(0); + Poco::Int32 ifIndex = interface == AVAHI_IF_UNSPEC ? 0 : interface; + Domain dom(ifIndex, domain, isDefault); + DomainEventArgs args(BrowseHandle(browser), eventFlags, dom); + if (event == AVAHI_BROWSER_NEW) + { + browseDomainFound(this, args); + } + else + { + browseDomainRemoved(this, args); + } + } + else if (event == AVAHI_BROWSER_FAILURE) + { + int err = avahi_client_errno(_responder._avahiClient); + Error error(interface, err, AvahiResponderImpl::describeError(err)); + ErrorEventArgs args(BrowseHandle(browser), 0, error); + browseDomainError(this, args); + } +} + + +void AvahiBrowserImpl::onEnumerateRegistrationDomainsReply( + AvahiDomainBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* domain, + AvahiLookupResultFlags flags, + bool isDefault) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) + { + int eventFlags(0); + Poco::Int32 ifIndex = interface == AVAHI_IF_UNSPEC ? 0 : interface; + Domain dom(ifIndex, domain, isDefault); + DomainEventArgs args(BrowseHandle(browser), eventFlags, dom); + if (event == AVAHI_BROWSER_NEW) + { + registrationDomainFound(this, args); + } + else + { + registrationDomainRemoved(this, args); + } + } + else if (event == AVAHI_BROWSER_FAILURE) + { + int err = avahi_client_errno(_responder._avahiClient); + Error error(interface, err, AvahiResponderImpl::describeError(err)); + ErrorEventArgs args(BrowseHandle(browser), 0, error); + registrationDomainError(this, args); + } +} + + +void AvahiBrowserImpl::onQueryRecordReply( + AvahiRecordBrowser* browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char* name, + uint16_t clazz, + uint16_t type, + const void* data, + std::size_t size, + AvahiLookupResultFlags flags) +{ + AvahiResponderImpl::ScopedLock lock(_responder); + + if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) + { + int eventFlags(0); + Poco::Int32 ifIndex = interface == AVAHI_IF_UNSPEC ? 0 : interface; + Record record(ifIndex, name, type, clazz, size, data, 0); + RecordEventArgs args(BrowseHandle(browser), eventFlags, record); + if (event == AVAHI_BROWSER_NEW) + { + recordFound(this, args); + } + else + { + recordRemoved(this, args); + } + } + else if (event == AVAHI_BROWSER_FAILURE) + { + int err = avahi_client_errno(_responder._avahiClient); + Error error(interface, err, AvahiResponderImpl::describeError(err)); + ErrorEventArgs args(BrowseHandle(browser), 0, error); + recordError(this, args); + } +} + + +void AvahiBrowserImpl::parseTXTRecord(AvahiStringList* strList, Service::Properties& properties) +{ + while (strList) + { + char* key; + char* value; + std::size_t size; + avahi_string_list_get_pair(strList, &key, &value, &size); + properties.set(key, std::string(value ? value : "", size)); + avahi_free(key); + avahi_free(value); + strList = avahi_string_list_get_next(strList); + } +} + + +void AvahiBrowserImpl::escape(const char* str, std::string& escaped) +{ + while (*str) + { + if (*str <= ' ' || *str >= 127) + { + escaped += '\\'; + Poco::NumberFormatter::append0(escaped, static_cast(static_cast(*str)), 3); + } + else if (*str == '\\') + { + escaped += "\\\\"; + } + else if (*str == '.') + { + escaped += "\\."; + } + else + { + escaped += *str; + } + ++str; + } +} + + +} } } // namespace Poco::DNSSD::Avahi + diff --git a/DNSSD/Avahi/src/AvahiResponderImpl.cpp b/DNSSD/Avahi/src/AvahiResponderImpl.cpp new file mode 100644 index 000000000..dfa1249e4 --- /dev/null +++ b/DNSSD/Avahi/src/AvahiResponderImpl.cpp @@ -0,0 +1,514 @@ +// +// AvahiResponderImpl.cpp +// +// $Id: //poco/1.7/DNSSD/Avahi/src/AvahiResponderImpl.cpp#1 $ +// +// Library: DNSSD/Avahi +// Package: Implementation +// Module: AvahiResponderImpl +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Avahi/AvahiResponderImpl.h" +#include "Poco/DNSSD/DNSSDException.h" +#include "Poco/StringTokenizer.h" +#include +#include +#include + + +namespace Poco { +namespace DNSSD { +namespace Avahi { + + +extern "C" int avahiPollFunc(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) +{ + Poco::Mutex* pMutex = reinterpret_cast(userdata); + pMutex->unlock(); + int ret = poll(ufds, nfds, timeout); + pMutex->lock(); + return ret; +} + + +extern "C" void onClientStateChange(AvahiClient* avahiClient, AvahiClientState state, void* userdata) +{ + try + { + AvahiResponderImpl* pResponder = reinterpret_cast(userdata); + pResponder->onClientStateChange(state); + } + catch (...) + { + } +} + + +extern "C" void onGroupStateChange(AvahiEntryGroup* avahiGroup, AvahiEntryGroupState state, void* userdata) +{ + try + { + AvahiResponderImpl* pResponder = reinterpret_cast(userdata); + pResponder->onGroupStateChange(avahiGroup, state); + } + catch (...) + { + } +} + + +AvahiResponderImpl::AvahiResponderImpl(Poco::DNSSD::DNSSDResponder& owner): + _owner(owner), + _browser(*this), + _avahiPoll(0), + _avahiClient(0), + _running(false), + _nextRecordId(1) +{ + _avahiPoll = avahi_simple_poll_new(); + if (!_avahiPoll) throw DNSSDException("Cannot create Avahi simple poll object"); + avahi_simple_poll_set_func(_avahiPoll, Poco::DNSSD::Avahi::avahiPollFunc, &_mutex); + int error; + _avahiClient = avahi_client_new(avahi_simple_poll_get(_avahiPoll), AVAHI_CLIENT_NO_FAIL, Poco::DNSSD::Avahi::onClientStateChange, this, &error); + if (!_avahiClient) + { + avahi_simple_poll_free(_avahiPoll); + throw DNSSDException("Cannot create Avahi client", describeError(error), error); + } +} + + +AvahiResponderImpl::~AvahiResponderImpl() +{ + try + { + stop(); + avahi_client_free(_avahiClient); + avahi_simple_poll_free(_avahiPoll); + } + catch (...) + { + poco_unexpected(); + } +} + + +DNSSDBrowser& AvahiResponderImpl::browser() +{ + return _browser; +} + + +ServiceHandle AvahiResponderImpl::registerService(const Service& service, int options) +{ + ScopedLock lock(*this); + + AvahiEntryGroup* avahiGroup = avahi_entry_group_new(_avahiClient, Poco::DNSSD::Avahi::onGroupStateChange, this); + if (!avahiGroup) throw DNSSDException("Cannot create Avahi Entry Group"); + try + { + ServiceHandle serviceHandle(avahiGroup); + RecordVec records; + setupEntryGroup(avahiGroup, service, records, options, false); + _services[serviceHandle].options = options; + return serviceHandle; + } + catch (...) + { + avahi_entry_group_free(avahiGroup); + throw; + } +} + + +void AvahiResponderImpl::unregisterService(ServiceHandle& serviceHandle) +{ + ScopedLock lock(*this); + + ServiceMap::iterator it = _services.find(serviceHandle); + if (it != _services.end()) + { + _services.erase(it); + } + AvahiEntryGroup* avahiGroup = serviceHandle.cast(); + avahi_entry_group_free(avahiGroup); +} + + +RecordHandle AvahiResponderImpl::addRecord(ServiceHandle serviceHandle, const Record& record) +{ + ScopedLock lock(*this); + + ServiceMap::iterator it = _services.find(serviceHandle); + if (it != _services.end()) + { + RecordInfo recordInfo; + recordInfo.record = record; + recordInfo.id = _nextRecordId++; + it->second.records.push_back(recordInfo); + setupEntryGroup(serviceHandle.cast(), it->second.service, it->second.records, it->second.options, false); + return RecordHandle(reinterpret_cast(recordInfo.id)); + } + else throw Poco::InvalidArgumentException("Unknown ServiceHandle"); +} + + +void AvahiResponderImpl::updateRecord(ServiceHandle serviceHandle, RecordHandle recordHandle, const Record& record) +{ + ScopedLock lock(*this); + + ServiceMap::iterator it = _services.find(serviceHandle); + if (it != _services.end()) + { + bool found = false; + for (RecordVec::iterator itRec = it->second.records.begin(); itRec != it->second.records.end(); ++itRec) + { + if (itRec->id == static_cast(reinterpret_cast(recordHandle.cast()))) + { + itRec->record = record; + found = true; + break; + } + } + if (!found) throw Poco::NotFoundException("Record not found", record.name()); + setupEntryGroup(serviceHandle.cast(), it->second.service, it->second.records, it->second.options, false); + } + else throw Poco::InvalidArgumentException("Unknown ServiceHandle"); +} + + +void AvahiResponderImpl::removeRecord(ServiceHandle serviceHandle, RecordHandle& recordHandle) +{ + ScopedLock lock(*this); + + ServiceMap::iterator it = _services.find(serviceHandle); + if (it != _services.end()) + { + bool found = false; + for (RecordVec::iterator itRec = it->second.records.begin(); itRec != it->second.records.end(); ++itRec) + { + if (itRec->id == static_cast(reinterpret_cast(recordHandle.cast()))) + { + it->second.records.erase(itRec); + recordHandle.reset(); + found = true; + break; + } + } + if (!found) throw Poco::NotFoundException("Record not found"); + setupEntryGroup(serviceHandle.cast(), it->second.service, it->second.records, it->second.options, false); + } + else throw Poco::InvalidArgumentException("Unknown ServiceHandle"); +} + + +void AvahiResponderImpl::start() +{ + if (!_running) + { + if (!_pollThread.isRunning()) + { + _pollThread.start(*this); + } + if (!_avahiClientReady.tryWait(START_TIMEOUT)) + { + std::string state; + switch (avahi_client_get_state(_avahiClient)) + { + case AVAHI_CLIENT_S_REGISTERING: + state = "registering"; + break; + case AVAHI_CLIENT_S_RUNNING: + state = "running"; + break; + case AVAHI_CLIENT_S_COLLISION: + state = "collision"; + break; + case AVAHI_CLIENT_FAILURE: + state = "failure"; + break; + case AVAHI_CLIENT_CONNECTING: + state = "connecting"; + }; + throw DNSSDException("Avahi client not ready; current state", state); + } + _running = true; + } +} + + +void AvahiResponderImpl::stop() +{ + if (_running) + { + { + ScopedLock lock(*this); + avahi_simple_poll_quit(_avahiPoll); + } + _pollThread.join(); + _running = false; + } +} + + +const char* AvahiResponderImpl::describeError(int code) +{ + return avahi_strerror(code); +} + + +void AvahiResponderImpl::lock() +{ + _mutex.lock(); +} + + +void AvahiResponderImpl::unlock() +{ + _mutex.unlock(); +} + + +void AvahiResponderImpl::run() +{ + ScopedLock lock(*this); + avahi_simple_poll_loop(_avahiPoll); +} + + +void AvahiResponderImpl::setupEntryGroup(AvahiEntryGroup* avahiGroup, const Service& service, const RecordVec& records, int options, bool rename) +{ + avahi_entry_group_reset(avahiGroup); + AvahiStringList* txtList = createTXTRecord(service.properties()); + try + { + int ifIndex = service.networkInterface() == 0 ? AVAHI_IF_UNSPEC : service.networkInterface(); + std::string type = service.type(); + std::string subtypes; + std::string::size_type pos = type.find(','); + if (pos != std::string::npos) + { + subtypes.assign(type, pos + 1, type.size() - pos); + type.resize(pos); + } + std::string name(service.name()); + if (name.empty()) name = avahi_client_get_host_name(_avahiClient); + const char* domain = service.domain().empty() ? 0 : service.domain().c_str(); + const char* host = service.host().empty() ? 0 : service.host().c_str(); + + int error = rename ? AVAHI_ERR_COLLISION : avahi_entry_group_add_service_strlst( + avahiGroup, + ifIndex, + AVAHI_PROTO_UNSPEC, + (AvahiPublishFlags) 0, + name.c_str(), + type.c_str(), + domain, + host, + service.port(), + txtList + ); + while (error == AVAHI_ERR_COLLISION) + { + if (options & DNSSDResponder::REG_NO_AUTORENAME) throw DNSSDException("Cannot register service: " + name, describeError(error), error); + const char* newName = avahi_alternative_service_name(name.c_str()); + name = newName; + avahi_free(const_cast(newName)); + error = avahi_entry_group_add_service_strlst( + avahiGroup, + ifIndex, + AVAHI_PROTO_UNSPEC, + (AvahiPublishFlags) 0, + name.c_str(), + type.c_str(), + domain, + host, + service.port(), + txtList + ); + } + if (error) throw DNSSDException("Cannot add service to Avahi Entry Group: " + name, describeError(error), error); + + if (!subtypes.empty()) + { + Poco::StringTokenizer tok(subtypes, ",", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); + for (Poco::StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) + { + error = avahi_entry_group_add_service_subtype( + avahiGroup, + service.networkInterface(), + AVAHI_PROTO_UNSPEC, + (AvahiPublishFlags) 0, + name.c_str(), + type.c_str(), + domain, + it->c_str() + ); + if (error) throw DNSSDException("Cannot add service subtype to Avahi Entry Group", describeError(error), error); + } + } + + for (RecordVec::const_iterator it = records.begin(); it != records.end(); ++it) + { + error = avahi_entry_group_add_record( + avahiGroup, + ifIndex, + AVAHI_PROTO_UNSPEC, + (AvahiPublishFlags) 0, + it->record.name().c_str(), + it->record.clazz(), + it->record.type(), + it->record.ttl(), + it->record.data(), + it->record.length() + ); + if (error) throw DNSSDException("Cannot add record to Avahi Entry Group: " + it->record.name(), describeError(error), error); + } + + error = avahi_entry_group_commit(avahiGroup); + if (error) throw DNSSDException("Cannot commit Avahi Entry Group", describeError(error), error); + + ServiceHandle serviceHandle(avahiGroup); + _services[serviceHandle].service = Service(service.networkInterface(), name, "", service.type(), service.domain(), service.host(), service.port(), service.properties()); + + avahi_string_list_free(txtList); + } + catch (...) + { + avahi_entry_group_reset(avahiGroup); + avahi_string_list_free(txtList); + throw; + } +} + + +AvahiStringList* AvahiResponderImpl::createTXTRecord(const Service::Properties& properties) +{ + AvahiStringList* avahiList = 0; + Service::Properties::ConstIterator itVers = properties.find("txtvers"); + Service::Properties::ConstIterator itEnd = properties.end(); + std::string entry; + if (itVers != itEnd) + { + std::string entry(itVers->first); + entry += '='; + entry += itVers->second; + avahiList = avahi_string_list_new(entry.c_str(), NULL); + } + + Service::Properties::ConstIterator it = properties.begin(); + for (; it != itEnd; ++it) + { + if (it != itVers) + { + if (avahiList) + { + avahiList = avahi_string_list_add_pair_arbitrary(avahiList, it->first.c_str(), reinterpret_cast(it->second.empty() ? NULL : it->second.c_str()), it->second.size()); + } + else + { + std::string entry(it->first); + if (!it->second.empty()) + { + entry += '='; + entry += it->second; + } + avahiList = avahi_string_list_new(entry.c_str(), NULL); + } + } + } + + return avahiList; +} + + +void AvahiResponderImpl::onClientStateChange(AvahiClientState state) +{ + ScopedLock lock(*this); + + if (state == AVAHI_CLIENT_S_RUNNING) + { + _avahiClientReady.set(); + reregisterServices(); + } +} + + +void AvahiResponderImpl::onGroupStateChange(AvahiEntryGroup* avahiGroup, AvahiEntryGroupState state) +{ + ScopedLock lock(*this); + + ServiceHandle serviceHandle(avahiGroup); + ServiceMap::iterator it = _services.find(serviceHandle); + if (it != _services.end()) + { + if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) + { + DNSSDResponder::ServiceEventArgs args(serviceHandle, it->second.service); + _owner.serviceRegistered(this, args); + } + else if (state == AVAHI_ENTRY_GROUP_COLLISION) + { + if (it->second.options & DNSSDResponder::REG_NO_AUTORENAME) + { + int error = AVAHI_ERR_COLLISION; + DNSSDResponder::ErrorEventArgs args(serviceHandle, it->second.service, Error(it->second.service.networkInterface(), error, describeError(error))); + _owner.serviceRegistrationFailed(this, args); + } + else + { + setupEntryGroup(avahiGroup, it->second.service, it->second.records, it->second.options, true); + } + } + else if (state == AVAHI_ENTRY_GROUP_FAILURE) + { + int error = avahi_client_errno(_avahiClient); + DNSSDResponder::ErrorEventArgs args(serviceHandle, it->second.service, Error(it->second.service.networkInterface(), error, describeError(error))); + _owner.serviceRegistrationFailed(this, args); + } + } +} + + +void AvahiResponderImpl::reregisterServices() +{ + for (ServiceMap::iterator it = _services.begin(); it != _services.end(); ++it) + { + setupEntryGroup(it->first.cast(), it->second.service, it->second.records, it->second.options, false); + } +} + + +} } } // namespace Poco::DNSSD::Avahi + + +namespace Poco { +namespace DNSSD { + + +namespace +{ + Poco::DNSSD::Avahi::AvahiResponderImplFactory implFactory; +} + + +void initializeDNSSD() +{ + Poco::DNSSD::DNSSDResponder::registerImplFactory(implFactory); +} + + +void uninitializeDNSSD() +{ + Poco::DNSSD::DNSSDResponder::unregisterImplFactory(); +} + + +} } // namespace Poco::DNSSD + diff --git a/DNSSD/Bonjour/Bonjour.progen b/DNSSD/Bonjour/Bonjour.progen new file mode 100644 index 000000000..294cfd3a0 --- /dev/null +++ b/DNSSD/Bonjour/Bonjour.progen @@ -0,0 +1,19 @@ +vc.project.guid = D9257FF3-3A9A-41F6-B60E-D077EFF94186 +vc.project.name = Bonjour +vc.project.target = PocoDNSSDBonjour +vc.project.type = library +vc.project.pocobase = ..\\.. +vc.project.outdir = ${vc.project.pocobase} +vc.project.platforms = Win32, x64, WinCE +vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md +vc.project.prototype = ${vc.project.name}_vs90.vcproj +vc.project.compiler.include = ..\\..\\DNSSD\\include;..\\..\\Foundation\\include;..\\..\\Net\\include +vc.project.compiler.defines = +vc.project.compiler.defines.shared = ${vc.project.name}_EXPORTS +vc.project.compiler.defines.debug_shared = ${vc.project.compiler.defines.shared} +vc.project.compiler.defines.release_shared = ${vc.project.compiler.defines.shared} +vc.project.linker.dependencies = dnssd.lib +vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.x64 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.WinCE = ws2.lib iphlpapi.lib +vc.solution.create = true diff --git a/DNSSD/Bonjour/Bonjour_vs160.sln b/DNSSD/Bonjour/Bonjour_vs160.sln new file mode 100644 index 000000000..1b3d16f1c --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs160.sln @@ -0,0 +1,61 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bonjour", "Bonjour_vs160.vcxproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Build.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Build.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.ActiveCfg = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Build.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Deploy.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Build.0 = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/Bonjour/Bonjour_vs160.vcxproj b/DNSSD/Bonjour/Bonjour_vs160.vcxproj new file mode 100644 index 000000000..f44b55d63 --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs160.vcxproj @@ -0,0 +1,605 @@ + + + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + Bonjour + {D9257FF3-3A9A-41F6-B60E-D077EFF94186} + Bonjour + Win32Proj + + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + PocoDNSSDBonjourd + PocoDNSSDBonjourmdd + PocoDNSSDBonjourmtd + PocoDNSSDBonjour + PocoDNSSDBonjourmd + PocoDNSSDBonjourmt + PocoDNSSDBonjour64d + PocoDNSSDBonjourmdd + PocoDNSSDBonjourmtd + PocoDNSSDBonjour64 + PocoDNSSDBonjourmd + PocoDNSSDBonjourmt + + + ..\..\bin\ + obj\Bonjour\$(Configuration)\ + true + + + ..\..\bin\ + obj\Bonjour\$(Configuration)\ + false + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\bin64\ + obj64\Bonjour\$(Configuration)\ + true + + + ..\..\bin64\ + obj64\Bonjour\$(Configuration)\ + false + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin\PocoDNSSDBonjourd.dll + true + true + $(OutDir)$(TargetName).pdb + ..\..\lib;%(AdditionalLibraryDirectories) + Console + ..\..\lib\PocoDNSSDBonjourd.lib + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin\PocoDNSSDBonjour.dll + true + false + ..\..\lib;%(AdditionalLibraryDirectories) + Console + true + true + ..\..\lib\PocoDNSSDBonjour.lib + MachineX86 + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib\PocoDNSSDBonjourmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\lib\PocoDNSSDBonjourmt.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib\PocoDNSSDBonjourmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + + Default + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\lib\PocoDNSSDBonjourmd.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin64\PocoDNSSDBonjour64d.dll + true + true + $(OutDir)$(TargetName).pdb + ..\..\lib64;%(AdditionalLibraryDirectories) + Console + ..\..\lib64\PocoDNSSDBonjourd.lib + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin64\PocoDNSSDBonjour64.dll + true + false + ..\..\lib64;%(AdditionalLibraryDirectories) + Console + true + true + ..\..\lib64\PocoDNSSDBonjour.lib + MachineX64 + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmt.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmd.lib + + + + + + + + + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/Bonjour/Bonjour_vs160.vcxproj.filters b/DNSSD/Bonjour/Bonjour_vs160.vcxproj.filters new file mode 100644 index 000000000..64e885600 --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs160.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {cf44555e-cc84-43dd-b198-44d32a1381e6} + + + {b2627011-451a-4b49-b7f3-708ed1647cd3} + + + {c328392b-6d49-4985-a0b7-c0f9f2e730d3} + + + + + Implementation\Header Files + + + Implementation\Header Files + + + Implementation\Header Files + + + Implementation\Header Files + + + + + Implementation\Source Files + + + Implementation\Source Files + + + Implementation\Source Files + + + \ No newline at end of file diff --git a/DNSSD/Bonjour/Bonjour_vs170.sln b/DNSSD/Bonjour/Bonjour_vs170.sln new file mode 100644 index 000000000..d4dc21a88 --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs170.sln @@ -0,0 +1,85 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bonjour", "Bonjour_vs170.vcxproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 + release_static_mt|ARM64 = release_static_mt|ARM64 + debug_static_md|ARM64 = debug_static_md|ARM64 + release_static_md|ARM64 = release_static_md|ARM64 + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Build.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Build.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.ActiveCfg = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Build.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Deploy.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Build.0 = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/Bonjour/Bonjour_vs170.vcxproj b/DNSSD/Bonjour/Bonjour_vs170.vcxproj new file mode 100644 index 000000000..262ea4b7e --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs170.vcxproj @@ -0,0 +1,885 @@ + + + + + debug_shared + ARM64 + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + ARM64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + ARM64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + ARM64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + ARM64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + ARM64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + Bonjour + {D9257FF3-3A9A-41F6-B60E-D077EFF94186} + Bonjour + Win32Proj + + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + PocoDNSSDBonjourA64d + PocoDNSSDBonjourmdd + PocoDNSSDBonjourmtd + PocoDNSSDBonjourA64 + PocoDNSSDBonjourmd + PocoDNSSDBonjourmt + PocoDNSSDBonjourd + PocoDNSSDBonjourmdd + PocoDNSSDBonjourmtd + PocoDNSSDBonjour + PocoDNSSDBonjourmd + PocoDNSSDBonjourmt + PocoDNSSDBonjour64d + PocoDNSSDBonjourmdd + PocoDNSSDBonjourmtd + PocoDNSSDBonjour64 + PocoDNSSDBonjourmd + PocoDNSSDBonjourmt + + + ..\..\binA64\ + objA64\Bonjour\$(Configuration)\ + true + + + ..\..\binA64\ + objA64\Bonjour\$(Configuration)\ + false + + + ..\..\libA64\ + objA64\Bonjour\$(Configuration)\ + + + ..\..\libA64\ + objA64\Bonjour\$(Configuration)\ + + + ..\..\libA64\ + objA64\Bonjour\$(Configuration)\ + + + ..\..\libA64\ + objA64\Bonjour\$(Configuration)\ + + + ..\..\bin\ + obj\Bonjour\$(Configuration)\ + true + + + ..\..\bin\ + obj\Bonjour\$(Configuration)\ + false + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\lib\ + obj\Bonjour\$(Configuration)\ + + + ..\..\bin64\ + obj64\Bonjour\$(Configuration)\ + true + + + ..\..\bin64\ + obj64\Bonjour\$(Configuration)\ + false + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + ..\..\lib64\ + obj64\Bonjour\$(Configuration)\ + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\binA64\PocoDNSSDBonjourA64d.dll + true + true + $(OutDir)$(TargetName).pdb + ..\..\libA64;%(AdditionalLibraryDirectories) + Console + ..\..\libA64\PocoDNSSDBonjourd.lib + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\binA64\PocoDNSSDBonjourA64.dll + true + false + ..\..\libA64;%(AdditionalLibraryDirectories) + Console + true + true + ..\..\libA64\PocoDNSSDBonjour.lib + MachineARM64 + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\libA64\PocoDNSSDBonjourmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\libA64\PocoDNSSDBonjourmt.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\libA64\PocoDNSSDBonjourmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\libA64\PocoDNSSDBonjourmd.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin\PocoDNSSDBonjourd.dll + true + true + $(OutDir)$(TargetName).pdb + ..\..\lib;%(AdditionalLibraryDirectories) + Console + ..\..\lib\PocoDNSSDBonjourd.lib + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin\PocoDNSSDBonjour.dll + true + false + ..\..\lib;%(AdditionalLibraryDirectories) + Console + true + true + ..\..\lib\PocoDNSSDBonjour.lib + MachineX86 + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib\PocoDNSSDBonjourmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\lib\PocoDNSSDBonjourmt.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib\PocoDNSSDBonjourmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + + Default + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\lib\PocoDNSSDBonjourmd.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin64\PocoDNSSDBonjour64d.dll + true + true + $(OutDir)$(TargetName).pdb + ..\..\lib64;%(AdditionalLibraryDirectories) + Console + ..\..\lib64\PocoDNSSDBonjourd.lib + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;Bonjour_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\..\bin64\PocoDNSSDBonjour64.dll + true + false + ..\..\lib64;%(AdditionalLibraryDirectories) + Console + true + true + ..\..\lib64\PocoDNSSDBonjour.lib + MachineX64 + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmt.lib + + + + + Disabled + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\DNSSD\include;..\..\Foundation\include;..\..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\..\lib64\PocoDNSSDBonjourmd.lib + + + + + + + + + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/Bonjour/Bonjour_vs170.vcxproj.filters b/DNSSD/Bonjour/Bonjour_vs170.vcxproj.filters new file mode 100644 index 000000000..b3cefbb5a --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs170.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {b499a951-43a2-42e9-a50c-4d24706c15f5} + + + {3672f4ca-3574-44db-a470-1154d4d7882a} + + + {af80b2ee-d29e-4040-9abb-7e54c5d7dc57} + + + + + Implementation\Header Files + + + Implementation\Header Files + + + Implementation\Header Files + + + Implementation\Header Files + + + + + Implementation\Source Files + + + Implementation\Source Files + + + Implementation\Source Files + + + \ No newline at end of file diff --git a/DNSSD/Bonjour/Bonjour_vs90.sln b/DNSSD/Bonjour/Bonjour_vs90.sln new file mode 100644 index 000000000..574f9f962 --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs90.sln @@ -0,0 +1,37 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bonjour", "Bonjour_vs90.vcproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Build.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/Bonjour/Bonjour_vs90.vcproj b/DNSSD/Bonjour/Bonjour_vs90.vcproj new file mode 100644 index 000000000..8ebe7442a --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_vs90.vcproj @@ -0,0 +1,416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DNSSD/Bonjour/Bonjour_x64_vs90.sln b/DNSSD/Bonjour/Bonjour_x64_vs90.sln new file mode 100644 index 000000000..edcee47d3 --- /dev/null +++ b/DNSSD/Bonjour/Bonjour_x64_vs90.sln @@ -0,0 +1,37 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bonjour", "Bonjour_x64_vs90.vcproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Build.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.ActiveCfg = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Build.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Deploy.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Build.0 = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/Bonjour/CMakeLists.txt b/DNSSD/Bonjour/CMakeLists.txt new file mode 100644 index 000000000..9ebe086be --- /dev/null +++ b/DNSSD/Bonjour/CMakeLists.txt @@ -0,0 +1,33 @@ +set(LIBNAME "DNSSDBonjour") +set(POCO_LIBNAME "Poco${LIBNAME}") + +# Sources +file(GLOB SRCS_G "src/*.cpp") +POCO_SOURCES_AUTO( Bonjour_SRCS ${SRCS_G}) + +# Headers +file(GLOB_RECURSE HDRS_G "include/*.h" ) +POCO_HEADERS_AUTO( Bonjour_SRCS ${HDRS_G}) + +add_definitions( ${Bonjour_CFLAGS} -DTHREADSAFE) + +add_library( "${LIBNAME}" ${LIB_MODE} ${Bonjour_SRCS} ) +add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}") +set_target_properties( "${LIBNAME}" + PROPERTIES + VERSION ${SHARED_LIBRARY_VERSION} SOVERSION ${SHARED_LIBRARY_VERSION} + OUTPUT_NAME ${POCO_LIBNAME} + DEFINE_SYMBOL Bonjour_EXPORTS + ) + +target_link_libraries( "${LIBNAME}" Foundation Net DNSSD ${BONJOUR_LIBRARIES}) +target_include_directories( "${LIBNAME}" + PUBLIC + $ + $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src + ) +target_compile_definitions("${LIBNAME}" PUBLIC ${LIB_MODE_DEFINITIONS}) + +POCO_INSTALL("${LIBNAME}") +POCO_GENERATE_PACKAGE("${LIBNAME}") diff --git a/DNSSD/Bonjour/Makefile b/DNSSD/Bonjour/Makefile new file mode 100644 index 000000000..7987c97b4 --- /dev/null +++ b/DNSSD/Bonjour/Makefile @@ -0,0 +1,18 @@ +# +# Makefile +# +# $Id: //poco/1.7/DNSSD/Bonjour/Makefile#1 $ +# +# Makefile for Poco DNSSD Bonjour +# + +include $(POCO_BASE)/build/rules/global + +objects = \ + BonjourBrowserImpl BonjourResponderImpl EventLoop + +target = PocoDNSSDBonjour +target_version = 1 +target_libs = PocoNet PocoDNSSD PocoFoundation + +include $(POCO_BASE)/build/rules/lib diff --git a/DNSSD/Bonjour/cmake/PocoDNSSDBonjourConfig.cmake b/DNSSD/Bonjour/cmake/PocoDNSSDBonjourConfig.cmake new file mode 100644 index 000000000..76cfea8b9 --- /dev/null +++ b/DNSSD/Bonjour/cmake/PocoDNSSDBonjourConfig.cmake @@ -0,0 +1,5 @@ +include(CMakeFindDependencyMacro) +find_dependency(PocoFoundation) +find_dependency(PocoNet) +find_dependency(PocoDNSSD) +include("${CMAKE_CURRENT_LIST_DIR}/PocoDNSSDBonjourTargets.cmake") diff --git a/DNSSD/Bonjour/dependencies b/DNSSD/Bonjour/dependencies new file mode 100644 index 000000000..5ab5fc352 --- /dev/null +++ b/DNSSD/Bonjour/dependencies @@ -0,0 +1,3 @@ +Foundation +Net +DNSSD diff --git a/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/Bonjour.h b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/Bonjour.h new file mode 100644 index 000000000..149c7d9be --- /dev/null +++ b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/Bonjour.h @@ -0,0 +1,76 @@ +// +// Bonjour.h +// +// $Id: //poco/1.7/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/Bonjour.h#1 $ +// +// Library: DNSSD/Bonjour +// Package: Implementation +// Module: Bonjour +// +// Basic definitions for the Poco DNSSD Bonjour library. +// This file must be the first file included by every other DNSSD Bonjour +// header file. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Bonjour_Bonjour_INCLUDED +#define DNSSD_Bonjour_Bonjour_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" + + +// +// The following block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the Bonjour_EXPORTS +// symbol defined on the command line. This symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// DNSSD_Bonjour_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. +// +#if defined(_WIN32) && defined(POCO_DLL) + #if defined(Bonjour_EXPORTS) + #define DNSSD_Bonjour_API __declspec(dllexport) + #else + #define DNSSD_Bonjour_API __declspec(dllimport) + #endif +#endif + + +#if !defined(DNSSD_Bonjour_API) + #if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4) + #define DNSSD_Bonjour_API __attribute__ ((visibility ("default"))) + #else + #define DNSSD_Bonjour_API + #endif +#endif + + +#if defined(_MSC_VER) + #if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(Bonjour_EXPORTS) + #pragma comment(lib, "PocoDNSSDBonjour" POCO_LIB_SUFFIX) + #endif +#endif + + +namespace Poco { +namespace DNSSD { + + +void DNSSD_Bonjour_API initializeDNSSD(); + /// Initialize the DNSSD subsystem. + + +void DNSSD_Bonjour_API uninitializeDNSSD(); + /// Uninitialize the DNSSD subsystem. + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_Bonjour_Bonjour_INCLUDED diff --git a/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourBrowserImpl.h b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourBrowserImpl.h new file mode 100644 index 000000000..8acd77d32 --- /dev/null +++ b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourBrowserImpl.h @@ -0,0 +1,79 @@ +// +// BonjourBrowserImpl.h +// +// $Id: //poco/1.7/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourBrowserImpl.h#1 $ +// +// Library: DNSSD/Bonjour +// Package: Implementation +// Module: BonjourBrowserImpl +// +// Definition of the BonjourBrowserImpl class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Bonjour_BonjourBrowserImpl_INCLUDED +#define DNSSD_Bonjour_BonjourBrowserImpl_INCLUDED + + +#include "Poco/DNSSD/Bonjour/Bonjour.h" +#include "Poco/DNSSD/DNSSDBrowser.h" +#include "Poco/Timestamp.h" +#include "Poco/Event.h" +#include +#include + + +namespace Poco { +namespace DNSSD { +namespace Bonjour { + + +class EventLoop; + + +class DNSSD_Bonjour_API BonjourBrowserImpl: public DNSSDBrowser + /// The DNSSDBrowser implementation for Bonjour. +{ +public: + BonjourBrowserImpl(EventLoop& eventLoop); + /// Creates the BonjourBrowserImpl. + + ~BonjourBrowserImpl(); + /// Destroys the BonjourBrowserImpl. + + // DNSSDBrowser + BrowseHandle browse(const std::string& regType, const std::string& domain, int options, Poco::Int32 networkInterface) override; + BrowseHandle resolve(const Service& service, int options) override; + BrowseHandle enumerateBrowseDomains(Poco::Int32 networkInterface) override; + BrowseHandle enumerateRegistrationDomains(Poco::Int32 networkInterface) override; + BrowseHandle queryRecord(const std::string& name, Poco::UInt16 type, Poco::UInt16 clazz, int options, Poco::Int32 networkInterface) override; + BrowseHandle resolveHost(const std::string& host, int options, Poco::Int32 networkInterface) override; + void cancel(BrowseHandle& browseHandle) override; + + // Implementation + void onBrowseReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* serviceName, const char* regtype, const char* domain); + void onResolveReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* fullName, const char* host, uint16_t port, uint16_t txtLen, const unsigned char* txtRecord); + void onEnumerateBrowseDomainsReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* replyDomain); + void onEnumerateRegistrationDomainsReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* replyDomain); + void onQueryRecordReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* fullName, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void* rdata, uint32_t ttl); + void onResolveHostReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* hostname, const struct sockaddr* address, uint32_t ttl); + +protected: + static void parseTXTRecord(Poco::UInt16 length, const void* data, Service::Properties& properties); + +private: + using ServiceMap = std::map; + EventLoop& _eventLoop; + ServiceMap _serviceMap; +}; + + +} } } // namespace Poco::DNSSD::Bonjour + + +#endif // DNSSD_Bonjour_BonjourBrowserImpl_INCLUDED diff --git a/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourResponderImpl.h b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourResponderImpl.h new file mode 100644 index 000000000..7c22a4e30 --- /dev/null +++ b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourResponderImpl.h @@ -0,0 +1,88 @@ +// +// BonjourResponderImpl.h +// +// $Id: //poco/1.7/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/BonjourResponderImpl.h#1 $ +// +// Library: DNSSD/Bonjour +// Package: Implementation +// Module: BonjourResponderImpl +// +// Definition of the BonjourResponderImpl class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Bonjour_BonjourResponderImpl_INCLUDED +#define DNSSD_Bonjour_BonjourResponderImpl_INCLUDED + + +#include "Poco/DNSSD/Bonjour/Bonjour.h" +#include "Poco/DNSSD/Bonjour/BonjourBrowserImpl.h" +#include "Poco/DNSSD/Bonjour/EventLoop.h" +#include "Poco/DNSSD/DNSSDResponderImpl.h" +#include "Poco/DNSSD/DNSSDResponder.h" +#include "Poco/Thread.h" + + +namespace Poco { +namespace DNSSD { +namespace Bonjour { + + +class DNSSD_Bonjour_API BonjourResponderImpl: public Poco::DNSSD::DNSSDResponderImpl + /// The DNSSDResponderImpl implementation for Bonjour. +{ +public: + BonjourResponderImpl(Poco::DNSSD::DNSSDResponder& owner); + /// Creates the BonjourResponder, using the given owner. + + ~BonjourResponderImpl(); + /// Destroys the BonjourResponderImpl. + + // DNSSDResponderImpl + DNSSDBrowser& browser() override; + ServiceHandle registerService(const Service& service, int options) override; + void unregisterService(ServiceHandle& serviceHandle) override; + RecordHandle addRecord(ServiceHandle serviceHandle, const Record& record) override; + void updateRecord(ServiceHandle serviceHandle, RecordHandle recordHandle, const Record& record) override; + void removeRecord(ServiceHandle serviceHandle, RecordHandle& recordHandle) override; + void start() override; + void stop() override; + + // Implementation + static const char* describeError(int code); + /// Returns a human-readable string describing the error. + + void onRegisterServiceReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char* name, const char* regtype, const char* domain); + +protected: + static std::string createTXTRecord(const Service::Properties& properties); + +private: + Poco::DNSSD::DNSSDResponder& _owner; + EventLoop _eventLoop; + Poco::Thread _eventLoopThread; + BonjourBrowserImpl _browser; + bool _running; +}; + + +class DNSSD_Bonjour_API BonjourResponderImplFactory: public Poco::DNSSD::DNSSDResponderImplFactory + /// A factory for BonjourResponderImplFactory objects. +{ +public: + DNSSDResponderImpl* createResponderImpl(Poco::DNSSD::DNSSDResponder& owner) + { + return new BonjourResponderImpl(owner); + } +}; + + +} } } // namespace Poco::DNSSD::Bonjour + + +#endif // DNSSD_Bonjour_BonjourResponderImpl_INCLUDED diff --git a/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/EventLoop.h b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/EventLoop.h new file mode 100644 index 000000000..27f6d573d --- /dev/null +++ b/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/EventLoop.h @@ -0,0 +1,120 @@ +// +// EventLoop.h +// +// $Id: //poco/1.7/DNSSD/Bonjour/include/Poco/DNSSD/Bonjour/EventLoop.h#1 $ +// +// Library: DNSSD/Bonjour +// Package: Implementation +// Module: EventLoop +// +// Definition of the EventLoop class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Bonjour_EventLoop_INCLUDED +#define DNSSD_Bonjour_EventLoop_INCLUDED + + +#include "Poco/DNSSD/Bonjour/Bonjour.h" +#include "Poco/Runnable.h" +#include "Poco/Mutex.h" +#include "Poco/Event.h" +#include "Poco/Net/Socket.h" +#include +#include +#include + + +namespace Poco { +namespace DNSSD { +namespace Bonjour { + + +class DNSSD_Bonjour_API EventLoop: public Poco::Runnable + /// The EventLoop class monitors all sockets used by Bonjour (for the connection + /// between the client and the daemon) in a thread and drives the + /// Bonjour machinery. +{ +public: + typedef Poco::ScopedLock ScopedLock; + + enum + { + EVENTLOOP_TIMEOUT = 250 + }; + + EventLoop(); + /// Creates the EventLoop. + + ~EventLoop(); + /// Destroys the EventLoop. + + void add(DNSServiceRef sdRef); + /// Adds the reference to the eventloop, monitoring it for data. + + void remove(DNSServiceRef sdRef); + /// Removes and destroys the DNSServiceRef. + + void stop(); + /// Requests to stop event loop processing. + + void shutdown(); + /// Cleans up and frees all DNSServiceRefs. + /// + /// Must be called after the event loop thread has been stopped. + + void lock(); + /// Locks the internal mutex. + + void unlock(); + /// Unlocks the internal mutex. + +protected: + void run() override; + void removeImpl(DNSServiceRef sdRef); + +private: + using SockToRef = std::map; + using RefToSock = std::map; + using RefSet = std::set; + + RefToSock _refs; + SockToRef _sockets; + RefSet _invalidatedRefs; + bool _stop; + Poco::Event _refAdded; + Poco::Mutex _mutex; +}; + + +// +// inlines +// +inline void EventLoop::stop() +{ + _stop = true; + _refAdded.set(); +} + + +inline void EventLoop::lock() +{ + _mutex.lock(); +} + + +inline void EventLoop::unlock() +{ + _mutex.unlock(); +} + + +} } } // namespace Poco::DNSSD::Bonjour + + +#endif // DNSSD_Bonjour_EventLoop_INCLUDED diff --git a/DNSSD/Bonjour/src/BonjourBrowserImpl.cpp b/DNSSD/Bonjour/src/BonjourBrowserImpl.cpp new file mode 100644 index 000000000..caef4992c --- /dev/null +++ b/DNSSD/Bonjour/src/BonjourBrowserImpl.cpp @@ -0,0 +1,486 @@ +// +// BonjourBrowserImpl.cpp +// +// $Id: //poco/1.7/DNSSD/Bonjour/src/BonjourBrowserImpl.cpp#1 $ +// +// Library: DNSSD/Bonjour +// Package: Implementation +// Module: BonjourBrowserImpl +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Bonjour/BonjourBrowserImpl.h" +#include "Poco/DNSSD/Bonjour/BonjourResponderImpl.h" +#include "Poco/DNSSD/Bonjour/EventLoop.h" +#include "Poco/DNSSD/DNSSDException.h" +#include "Poco/ByteOrder.h" +#include + + +namespace Poco { +namespace DNSSD { +namespace Bonjour { + + +extern "C" void DNSSD_API onBrowseReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* serviceName, + const char* regtype, + const char* replyDomain, + void* context) +{ + try + { + BonjourBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onBrowseReply(sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain); + } + catch (...) + { + } +} + + +extern "C" void DNSSD_API onResolveReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* fullName, + const char* host, + uint16_t port, + uint16_t txtLen, +#if _DNS_SD_H+0 >= 1070600 + const unsigned char* txtRecord, +#else + const char* txtRecord, +#endif + void* context + ) +{ + try + { + BonjourBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onResolveReply(sdRef, flags, interfaceIndex, errorCode, fullName, host, port, txtLen, (const unsigned char*) txtRecord); + } + catch (...) + { + } +} + + +extern "C" void DNSSD_API onEnumerateBrowseDomainsReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* replyDomain, + void* context) +{ + try + { + BonjourBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onEnumerateBrowseDomainsReply(sdRef, flags, interfaceIndex, errorCode, replyDomain); + } + catch (...) + { + } +} + + +extern "C" void DNSSD_API onEnumerateRegistrationDomainsReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* replyDomain, + void* context) +{ + try + { + BonjourBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onEnumerateRegistrationDomainsReply(sdRef, flags, interfaceIndex, errorCode, replyDomain); + } + catch (...) + { + } +} + + +extern "C" void DNSSD_API onQueryRecordReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* fullName, + uint16_t rrtype, + uint16_t rrclass, + uint16_t rdlen, + const void* rdata, + uint32_t ttl, + void* context) +{ + try + { + BonjourBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onQueryRecordReply(sdRef, flags, interfaceIndex, errorCode, fullName, rrtype, rrclass, rdlen, rdata, ttl); + } + catch (...) + { + } +} + + +extern "C" void DNSSD_API onResolveHostReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* hostname, + const struct sockaddr* address, + uint32_t ttl, + void* context) +{ + try + { + BonjourBrowserImpl* pBrowser = reinterpret_cast(context); + pBrowser->onResolveHostReply(sdRef, flags, interfaceIndex, errorCode, hostname, address, ttl); + } + catch (...) + { + } +} + + +BonjourBrowserImpl::BonjourBrowserImpl(EventLoop& eventLoop): + _eventLoop(eventLoop) +{ +} + + +BonjourBrowserImpl::~BonjourBrowserImpl() +{ +} + + +BrowseHandle BonjourBrowserImpl::browse(const std::string& regType, const std::string& domain, int options, Poco::Int32 networkInterface) +{ + DNSServiceRef sdRef(nullptr); + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceBrowse(&sdRef, 0, networkInterface, regType.c_str(), domain.empty() ? 0 : domain.c_str(), Poco::DNSSD::Bonjour::onBrowseReply, this); + if (err == kDNSServiceErr_NoError) + { + _eventLoop.add(sdRef); + return BrowseHandle(sdRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to browse for " + regType, BonjourResponderImpl::describeError(err), err); +} + + +BrowseHandle BonjourBrowserImpl::resolve(const Service& service, int options) +{ + DNSServiceRef sdRef(0); + Poco::Int32 ifIndex = (options & RESOLVE_ON_ALL_INTERFACES) ? 0 : service.networkInterface(); + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceResolve(&sdRef, 0, ifIndex, service.name().c_str(), service.type().c_str(), service.domain().c_str(), Poco::DNSSD::Bonjour::onResolveReply, this); + if (err == kDNSServiceErr_NoError) + { + _serviceMap[sdRef] = service; + _eventLoop.add(sdRef); + return BrowseHandle(sdRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to resolve " + service.name(), BonjourResponderImpl::describeError(err), err); +} + + +BrowseHandle BonjourBrowserImpl::enumerateBrowseDomains(Poco::Int32 networkInterface) +{ + DNSServiceRef sdRef(0); + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceEnumerateDomains(&sdRef, kDNSServiceFlagsBrowseDomains, networkInterface, Poco::DNSSD::Bonjour::onEnumerateBrowseDomainsReply, this); + if (err == kDNSServiceErr_NoError) + { + _eventLoop.add(sdRef); + return BrowseHandle(sdRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to enumerate browse domains", BonjourResponderImpl::describeError(err), err); +} + + +BrowseHandle BonjourBrowserImpl::enumerateRegistrationDomains(Poco::Int32 networkInterface) +{ + DNSServiceRef sdRef(0); + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceEnumerateDomains(&sdRef, kDNSServiceFlagsRegistrationDomains, networkInterface, Poco::DNSSD::Bonjour::onEnumerateRegistrationDomainsReply, this); + if (err == kDNSServiceErr_NoError) + { + _eventLoop.add(sdRef); + return BrowseHandle(sdRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to enumerate registration domains", BonjourResponderImpl::describeError(err), err); +} + + +BrowseHandle BonjourBrowserImpl::queryRecord(const std::string& name, Poco::UInt16 type, Poco::UInt16 clazz, int options, Poco::Int32 networkInterface) +{ + DNSServiceRef sdRef(nullptr); + DNSServiceFlags flags(0); + if (options & BROWSE_FORCE_MULTICAST) flags |= kDNSServiceFlagsForceMulticast; + if (options & BROWSE_LONG_LIVED_QUERY) flags |= kDNSServiceFlagsLongLivedQuery; + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceQueryRecord(&sdRef, flags, networkInterface, name.c_str(), type, clazz, Poco::DNSSD::Bonjour::onQueryRecordReply, this); + if (err == kDNSServiceErr_NoError) + { + _eventLoop.add(sdRef); + return BrowseHandle(sdRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to query record " + name, BonjourResponderImpl::describeError(err), err); +} + + +BrowseHandle BonjourBrowserImpl::resolveHost(const std::string& host, int options, Poco::Int32 networkInterface) +{ + DNSServiceRef sdRef(0); + DNSServiceFlags flags(0); + if (options & BROWSE_FORCE_MULTICAST) flags |= kDNSServiceFlagsForceMulticast; + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceGetAddrInfo(&sdRef, flags, networkInterface, 0, host.c_str(), Poco::DNSSD::Bonjour::onResolveHostReply, this); + if (err == kDNSServiceErr_NoError) + { + _eventLoop.add(sdRef); + return BrowseHandle(sdRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to resolve host " + host, BonjourResponderImpl::describeError(err), err); +} + + +void BonjourBrowserImpl::cancel(BrowseHandle& browseHandle) +{ + DNSServiceRef sdRef = browseHandle.cast(); + ServiceMap::iterator it = _serviceMap.find(sdRef); + if (it != _serviceMap.end()) _serviceMap.erase(it); + _eventLoop.remove(sdRef); + browseHandle.reset(); +} + + +void BonjourBrowserImpl::onBrowseReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* serviceName, + const char* regtype, + const char* replyDomain) +{ + if (errorCode == kDNSServiceErr_NoError) + { + int eventFlags((flags & kDNSServiceFlagsMoreComing) ? BROWSE_MORE_COMING : 0); + Service service(interfaceIndex, serviceName, regtype, replyDomain); + ServiceEventArgs args(BrowseHandle(sdRef), eventFlags, service); + if (flags & kDNSServiceFlagsAdd) + { + serviceFound(this, args); + } + else + { + serviceRemoved(this, args); + } + } + else + { + Error error(interfaceIndex, errorCode, BonjourResponderImpl::describeError(errorCode)); + ErrorEventArgs args(BrowseHandle(sdRef), 0, error); + browseError(this, args); + } +} + + +void BonjourBrowserImpl::onResolveReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* fullName, + const char* host, + uint16_t port, + uint16_t txtLen, + const unsigned char* txtRecord) +{ + ServiceMap::iterator it = _serviceMap.find(sdRef); + _eventLoop.remove(sdRef); + if (errorCode == kDNSServiceErr_NoError) + { + if (it != _serviceMap.end()) + { + Service service(interfaceIndex, it->second.name(), fullName, it->second.type(), it->second.domain(), host, Poco::ByteOrder::fromNetwork(port)); + _serviceMap.erase(it); + parseTXTRecord(txtLen, txtRecord, service.properties()); + int eventFlags((flags & kDNSServiceFlagsMoreComing) ? BROWSE_MORE_COMING : 0); + ServiceEventArgs args(BrowseHandle(sdRef), eventFlags, service); + serviceResolved(this, args); + } + } + else + { + if (it != _serviceMap.end()) _serviceMap.erase(it); + Error error(interfaceIndex, errorCode, BonjourResponderImpl::describeError(errorCode)); + ErrorEventArgs args(BrowseHandle(sdRef), 0, error); + resolveError(this, args); + } +} + + +void BonjourBrowserImpl::onEnumerateBrowseDomainsReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* replyDomain) +{ + if (errorCode == kDNSServiceErr_NoError) + { + int eventFlags((flags & kDNSServiceFlagsMoreComing) ? BROWSE_MORE_COMING : 0); + Domain domain(interfaceIndex, replyDomain, (flags & kDNSServiceFlagsDefault) != 0); + DomainEventArgs args(BrowseHandle(sdRef), eventFlags, domain); + if (flags & kDNSServiceFlagsAdd) + { + browseDomainFound(this, args); + } + else + { + browseDomainRemoved(this, args); + } + } + else + { + Error error(interfaceIndex, errorCode, BonjourResponderImpl::describeError(errorCode)); + ErrorEventArgs args(BrowseHandle(sdRef), 0, error); + browseDomainError(this, args); + } +} + + +void BonjourBrowserImpl::onEnumerateRegistrationDomainsReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* replyDomain) +{ + if (errorCode == kDNSServiceErr_NoError) + { + int eventFlags((flags & kDNSServiceFlagsMoreComing) ? BROWSE_MORE_COMING : 0); + Domain domain(interfaceIndex, replyDomain, (flags & kDNSServiceFlagsDefault) != 0); + DomainEventArgs args(BrowseHandle(sdRef), eventFlags, domain); + if (flags & kDNSServiceFlagsAdd) + { + registrationDomainFound(this, args); + } + else + { + registrationDomainRemoved(this, args); + } + } + else + { + Error error(interfaceIndex, errorCode, BonjourResponderImpl::describeError(errorCode)); + ErrorEventArgs args(BrowseHandle(sdRef), 0, error); + registrationDomainError(this, args); + } +} + + +void BonjourBrowserImpl::onQueryRecordReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* fullName, + uint16_t rrtype, + uint16_t rrclass, + uint16_t rdlen, + const void* rdata, + uint32_t ttl) +{ + if (errorCode == kDNSServiceErr_NoError) + { + int eventFlags((flags & kDNSServiceFlagsMoreComing) ? BROWSE_MORE_COMING : 0); + Record record(interfaceIndex, fullName, rrtype, rrclass, rdlen, rdata, ttl); + RecordEventArgs args(BrowseHandle(sdRef), eventFlags, record); + if (flags & kDNSServiceFlagsAdd) + { + recordFound(this, args); + } + else + { + recordRemoved(this, args); + } + } + else + { + Error error(interfaceIndex, errorCode, BonjourResponderImpl::describeError(errorCode)); + ErrorEventArgs args(BrowseHandle(sdRef), 0, error); + recordError(this, args); + } +} + + +void BonjourBrowserImpl::onResolveHostReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* hostname, const struct sockaddr* address, uint32_t ttl) +{ + _eventLoop.remove(sdRef); + if (errorCode == kDNSServiceErr_NoError) + { + Poco::Net::IPAddress addr; + switch (address->sa_family) + { + case AF_INET: + addr = Poco::Net::IPAddress(&reinterpret_cast(address)->sin_addr, sizeof(in_addr)); + break; +#if defined(POCO_HAVE_IPv6) + case AF_INET6: + addr = Poco::Net::IPAddress(&reinterpret_cast(address)->sin6_addr, sizeof(in6_addr)); + break; +#endif + } + int eventFlags((flags & kDNSServiceFlagsMoreComing) ? BROWSE_MORE_COMING : 0); + std::string host(hostname); + ResolveHostEventArgs args(BrowseHandle(sdRef), eventFlags, host, addr, interfaceIndex, ttl); + hostResolved(this, args); + } + else + { + Error error(interfaceIndex, errorCode, BonjourResponderImpl::describeError(errorCode)); + ErrorEventArgs args(BrowseHandle(sdRef), 0, error); + hostResolveError(this, args); + } +} + + +void BonjourBrowserImpl::parseTXTRecord(Poco::UInt16 length, const void* data, Service::Properties& properties) +{ + Poco::UInt16 n = TXTRecordGetCount(length, data); + char key[256]; + std::string strKey; + for (Poco::UInt16 i = 0; i < n; ++i) + { + Poco::UInt8 valueLength = 0; + const void* value; + TXTRecordGetItemAtIndex(length, data, i, sizeof(key), key, &valueLength, &value); + strKey.assign(key); + if (!strKey.empty()) // An empty TXT record will contain one key with an empty name. + { + properties.add(strKey, std::string(value ? reinterpret_cast(value) : "", valueLength)); + } + } +} + + +} } } // namespace Poco::DNSSD::Bonjour diff --git a/DNSSD/Bonjour/src/BonjourResponderImpl.cpp b/DNSSD/Bonjour/src/BonjourResponderImpl.cpp new file mode 100644 index 000000000..96cd5ddf8 --- /dev/null +++ b/DNSSD/Bonjour/src/BonjourResponderImpl.cpp @@ -0,0 +1,341 @@ +// +// BonjourResponderImpl.cpp +// +// $Id: //poco/1.7/DNSSD/Bonjour/src/BonjourResponderImpl.cpp#1 $ +// +// Library: DNSSD/Bonjour +// Package: Implementation +// Module: BonjourResponderImpl +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Bonjour/BonjourResponderImpl.h" +#include "Poco/DNSSD/DNSSDException.h" +#include "Poco/ByteOrder.h" +#include "Poco/Buffer.h" +#include + + +namespace Poco { +namespace DNSSD { +namespace Bonjour { + + +extern "C" void DNSSD_API onRegisterServiceReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char* name, + const char* regtype, + const char* domain, + void *context) +{ + try + { + BonjourResponderImpl* pResponder = reinterpret_cast(context); + pResponder->onRegisterServiceReply(sdRef, flags, errorCode, name, regtype, domain); + } + catch (...) + { + } +} + + +BonjourResponderImpl::BonjourResponderImpl(Poco::DNSSD::DNSSDResponder& owner): + _owner(owner), + _browser(_eventLoop), + _running(false) +{ +} + + +BonjourResponderImpl::~BonjourResponderImpl() +{ + try + { + stop(); + } + catch (...) + { + poco_unexpected(); + } +} + + +DNSSDBrowser& BonjourResponderImpl::browser() +{ + return _browser; +} + + +ServiceHandle BonjourResponderImpl::registerService(const Service& service, int options) +{ + DNSServiceRef sdRef(nullptr); + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceFlags flags(0); + uint32_t intf = (options & DNSSDResponder::REG_LOCAL_ONLY) ? kDNSServiceInterfaceIndexLocalOnly : service.networkInterface(); + if (options & DNSSDResponder::REG_NO_AUTORENAME) flags |= kDNSServiceFlagsNoAutoRename; +#if (_DNS_SD_H <10960002) + // kDNSServiceFlagsNonBrowsable was removed in 1096.0.2 + if (options & DNSSDResponder::REG_NON_BROWSABLE) flags |= kDNSServiceFlagsNonBrowsable; +#endif + std::string txtRecord = createTXTRecord(service.properties()); + DNSServiceErrorType err = DNSServiceRegister(&sdRef, flags, intf, service.name().empty() ? 0 : service.name().c_str(), service.type().c_str(), service.domain().empty() ? 0 : service.domain().c_str(), service.host().empty() ? 0 : service.host().c_str(), Poco::ByteOrder::toNetwork(service.port()), txtRecord.size(), txtRecord.empty() ? 0 : txtRecord.data(), Poco::DNSSD::Bonjour::onRegisterServiceReply, this); + if (err == kDNSServiceErr_NoError) + { + _eventLoop.add(sdRef); + return ServiceHandle(sdRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to register " + service.type(), describeError(err), err); +} + + +void BonjourResponderImpl::unregisterService(ServiceHandle& serviceHandle) +{ + DNSServiceRef sdRef = serviceHandle.cast(); + _eventLoop.remove(sdRef); + serviceHandle.reset(); +} + + +RecordHandle BonjourResponderImpl::addRecord(ServiceHandle serviceHandle, const Record& record) +{ + DNSRecordRef recRef(0); + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceAddRecord(serviceHandle.cast(), &recRef, 0, record.type(), record.length(), record.data(), record.ttl()); + if (err == kDNSServiceErr_NoError) + { + return RecordHandle(recRef); + } + else throw Poco::DNSSD::DNSSDException("Failed to add record " + record.name(), describeError(err), err); +} + + +void BonjourResponderImpl::updateRecord(ServiceHandle serviceHandle, RecordHandle recordHandle, const Record& record) +{ + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceUpdateRecord(serviceHandle.cast(), recordHandle.cast(), 0, record.length(), record.data(), record.ttl()); + if (err != kDNSServiceErr_NoError) + { + throw Poco::DNSSD::DNSSDException("Failed to update record " + record.name(), describeError(err), err); + } +} + + +void BonjourResponderImpl::removeRecord(ServiceHandle serviceHandle, RecordHandle& recordHandle) +{ + EventLoop::ScopedLock lock(_eventLoop); + DNSServiceErrorType err = DNSServiceRemoveRecord(serviceHandle.cast(), recordHandle.cast(), 0); + if (err == kDNSServiceErr_NoError) + { + recordHandle.reset(); + } + else throw Poco::DNSSD::DNSSDException("Failed to remove record", describeError(err), err); +} + + +void BonjourResponderImpl::start() +{ + poco_assert (!_running); + + _eventLoopThread.start(_eventLoop); + _running = true; +} + + +void BonjourResponderImpl::stop() +{ + if (_running) + { + _eventLoop.stop(); + _eventLoopThread.join(); + _eventLoop.shutdown(); + _running = false; + } +} + + +const char* BonjourResponderImpl::describeError(int code) +{ + switch (code) + { + case kDNSServiceErr_Unknown: + return "Unknown"; + case kDNSServiceErr_NoSuchName: + return "No such name"; + case kDNSServiceErr_NoMemory: + return "No memory"; + case kDNSServiceErr_BadParam: + return "Bad parameter"; + case kDNSServiceErr_BadReference: + return "Bad reference"; + case kDNSServiceErr_BadState: + return "Bad state"; + case kDNSServiceErr_BadFlags: + return "Bad flags"; + case kDNSServiceErr_Unsupported: + return "Unsupported"; + case kDNSServiceErr_NotInitialized: + return "Not initialized"; + case kDNSServiceErr_AlreadyRegistered: + return "Already registered"; + case kDNSServiceErr_NameConflict: + return "Name conflict"; + case kDNSServiceErr_Invalid: + return "Invalid"; + case kDNSServiceErr_Firewall: + return "Firewall"; + case kDNSServiceErr_Incompatible: + return "Client library incompatible with daemon"; + case kDNSServiceErr_BadInterfaceIndex: + return "Bad interface index"; + case kDNSServiceErr_Refused: + return "Refused"; + case kDNSServiceErr_NoSuchRecord: + return "No such record"; + case kDNSServiceErr_NoAuth: + return "No auth"; + case kDNSServiceErr_NoSuchKey: + return "No such key"; + case kDNSServiceErr_NATTraversal: + return "NAT traversal"; + case kDNSServiceErr_DoubleNAT: + return "Double NAT"; + case kDNSServiceErr_BadTime: + return "Bad time"; + case kDNSServiceErr_BadSig: + return "Bad signature"; + case kDNSServiceErr_BadKey: + return "Bad key"; + case kDNSServiceErr_Transient: + return "Transient error"; + case kDNSServiceErr_ServiceNotRunning: + return "Service not running"; + case kDNSServiceErr_NATPortMappingUnsupported: + return "NAT port mapping not supported"; + case kDNSServiceErr_NATPortMappingDisabled: + return "NAT port mapping disabled"; +#if _DNS_SD_H+0 >= 2580000 + case kDNSServiceErr_NoRouter: + return "No router"; + case kDNSServiceErr_PollingMode: + return "Polling mode"; +#endif + default: + return "Error"; + } +} + + +std::string BonjourResponderImpl::createTXTRecord(const Service::Properties& properties) +{ + if (properties.empty()) return std::string(1, '\0'); + + Service::Properties::ConstIterator it = properties.begin(); + Service::Properties::ConstIterator itEnd = properties.end(); + std::size_t requiredSize = 0; + for (; it != itEnd; ++it) + { + if (it->first.size() == 0) + throw Poco::InvalidArgumentException("Empty property name is not allowed"); + + std::size_t prevSize = requiredSize; + requiredSize += it->first.size() + 1; // add length byte + if (!it->second.empty()) + { + requiredSize += it->second.size() + 1; // add '=' character + } + if (requiredSize - prevSize > 256) + throw Poco::InvalidArgumentException("Property too large: size of key and value together must not exceed 254 bytes"); + } + + if (requiredSize > 65535) + throw Poco::InvalidArgumentException("Too many properties: maximum TXT record size of 65535 bytes exceeded"); + + Poco::UInt16 size = static_cast(requiredSize); + Poco::Buffer buffer(requiredSize); + + TXTRecordRef ref; + TXTRecordCreate(&ref, size, buffer.begin()); + + // if present, txtvers must be first key in TXT record + Service::Properties::ConstIterator itVers = properties.find("txtvers"); + if (itVers != itEnd) + { + Poco::UInt8 valueSize = static_cast(itVers->second.size()); + TXTRecordSetValue(&ref, itVers->first.c_str(), valueSize, valueSize == 0 ? 0 : itVers->second.c_str()); + } + + it = properties.begin(); + for (; it != itEnd; ++it) + { + if (it != itVers) + { + Poco::UInt8 valueSize = static_cast(it->second.size()); + TXTRecordSetValue(&ref, it->first.c_str(), valueSize, valueSize == 0 ? 0 : it->second.c_str()); + } + } + const void* txtRecord = TXTRecordGetBytesPtr(&ref); + Poco::UInt16 txtSize = TXTRecordGetLength(&ref); + std::string result(reinterpret_cast(txtRecord), txtSize); + TXTRecordDeallocate(&ref); + + return result; +} + + +void BonjourResponderImpl::onRegisterServiceReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char* name, + const char* regtype, + const char* domain) +{ + if (errorCode == kDNSServiceErr_NoError) + { + Service service(0, name, regtype, domain); + DNSSDResponder::ServiceEventArgs args(ServiceHandle(sdRef), service); + _owner.serviceRegistered(this, args); + } + else + { + Service service(0, name, regtype, domain); + Error error(0, errorCode, describeError(errorCode)); + DNSSDResponder::ErrorEventArgs args(ServiceHandle(sdRef), service, error); + _owner.serviceRegistrationFailed(this, args); + } +} + + +} } } // namespace Poco::DNSSD::Bonjour + + +namespace Poco { +namespace DNSSD { + + +namespace +{ + Poco::DNSSD::Bonjour::BonjourResponderImplFactory implFactory; +} + + +void initializeDNSSD() +{ + Poco::DNSSD::DNSSDResponder::registerImplFactory(implFactory); +} + + +void uninitializeDNSSD() +{ + Poco::DNSSD::DNSSDResponder::unregisterImplFactory(); +} + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/Bonjour/src/EventLoop.cpp b/DNSSD/Bonjour/src/EventLoop.cpp new file mode 100644 index 000000000..b74a5cfe7 --- /dev/null +++ b/DNSSD/Bonjour/src/EventLoop.cpp @@ -0,0 +1,157 @@ +// +// EventLoop.cpp +// +// $Id: //poco/1.7/DNSSD/Bonjour/src/EventLoop.cpp#1 $ +// +// Library: DNSSD/Bonjour +// Package: Implementation +// Module: EventLoop +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Bonjour/EventLoop.h" +#include "Poco/Net/StreamSocket.h" +#include "Poco/Net/StreamSocketImpl.h" +#include + + +namespace Poco { +namespace DNSSD { +namespace Bonjour { + + +EventLoop::EventLoop(): + _stop(false) +{ +} + + +EventLoop::~EventLoop() +{ + try + { + shutdown(); + } + catch (...) + { + poco_unexpected(); + } +} + + +void EventLoop::shutdown() +{ + RefToSock::iterator it = _refs.begin(); + RefToSock::iterator itEnd = _refs.end(); + for (; it != itEnd; ++it) + { + DNSServiceRefDeallocate(it->first); + } + _refs.clear(); + _sockets.clear(); + _invalidatedRefs.clear(); +} + + +void EventLoop::add(DNSServiceRef sdRef) +{ + int sockfd = DNSServiceRefSockFD(sdRef); + Poco::Net::StreamSocket sock(new Poco::Net::StreamSocketImpl(sockfd)); + + { + Poco::Mutex::ScopedLock lock(_mutex); + _sockets[sock] = sdRef; + _refs[sdRef] = sock; + } + + _refAdded.set(); +} + + +void EventLoop::remove(DNSServiceRef sdRef) +{ + Poco::Mutex::ScopedLock lock(_mutex); + + _invalidatedRefs.insert(sdRef); +} + + +void EventLoop::removeImpl(DNSServiceRef sdRef) +{ + RefToSock::iterator it = _refs.find(sdRef); + if (it != _refs.end()) + { + _sockets.erase(it->second); + _refs.erase(it); + } + DNSServiceRefDeallocate(sdRef); +} + + +void EventLoop::run() +{ + Poco::Net::Socket::SocketList readList; + Poco::Net::Socket::SocketList writeList; + Poco::Net::Socket::SocketList errList; + + while (!_stop) + { + readList.clear(); + if (!_refs.empty() || _refAdded.tryWait(EVENTLOOP_TIMEOUT)) + { + Poco::Mutex::ScopedLock lock(_mutex); + + RefToSock::const_iterator it = _refs.begin(); + RefToSock::const_iterator itEnd = _refs.end(); + for (; it != itEnd; ++it) + { + readList.push_back(it->second); + } + } + + if (!readList.empty()) + { + Poco::Timespan timeout(1000*EVENTLOOP_TIMEOUT); + int ready = Poco::Net::Socket::select(readList, writeList, errList, timeout); + if (ready > 0) + { + Poco::Net::Socket::SocketList::iterator it = readList.begin(); + Poco::Net::Socket::SocketList::iterator itEnd = readList.end(); + for (; it != itEnd; ++it) + { + Poco::Mutex::ScopedLock lock(_mutex); + + SockToRef::iterator itSock = _sockets.find(*it); + poco_assert_dbg (itSock != _sockets.end()); + RefSet::iterator itSet = _invalidatedRefs.find(itSock->second); + if (itSet != _invalidatedRefs.end()) + { + removeImpl(itSock->second); + _invalidatedRefs.erase(itSet); + } + else + { + DNSServiceProcessResult(itSock->second); + } + } + } + } + + Poco::Mutex::ScopedLock lock(_mutex); + RefSet::iterator itSet =_invalidatedRefs.begin(); + RefSet::iterator itSetEnd = _invalidatedRefs.end(); + for (; itSet != itSetEnd; ++itSet) + { + removeImpl(*itSet); + } + _invalidatedRefs.clear(); + } +} + + +} } } // namespace Poco::DNSSD::Bonjour diff --git a/DNSSD/CMakeLists.txt b/DNSSD/CMakeLists.txt new file mode 100644 index 000000000..833a2c6ec --- /dev/null +++ b/DNSSD/CMakeLists.txt @@ -0,0 +1,88 @@ +# ITNOA + +set(DNSSD_IMPLEMENTATION_LIBRARY "") + +macro(ADD_AVAHI) + find_package(Avahi REQUIRED) + if(AVAHI_FOUND) + include_directories("${AVAHI_INCLUDE_DIR}") + message(STATUS "Avahi Support Enabled") + add_subdirectory( Avahi ) + set(DNSSD_IMPLEMENTATION_LIBRARY "DNSSDAvahi") + else() + message(ERROR "Avahi does not found, please make install it") + endif() +endmacro() + +macro(ADD_BONJOUR) + find_package(Bonjour REQUIRED) + if(BONJOUR_FOUND) + if(NOT APPLE) + include_directories("${BONJOUR_INCLUDE_DIR}") + endif() + message(STATUS "Bonjour Support Enabled") + add_subdirectory( Bonjour ) + set(DNSSD_IMPLEMENTATION_LIBRARY "DNSSDBonjour") + else() + message(ERROR "Bonjour does not found, please make install sdk") + endif() +endmacro() + +set(LIBNAME "DNSSD") +set(POCO_LIBNAME "Poco${LIBNAME}") + +# Sources +file(GLOB SRCS_G "src/*.cpp") +POCO_SOURCES_AUTO( SRCS ${SRCS_G}) + +# Headers +file(GLOB_RECURSE HDRS_G "include/*.h" ) +POCO_HEADERS_AUTO( SRCS ${HDRS_G}) + +if (NOT POCO_STATIC) + add_definitions(-DTHREADSAFE) +endif (NOT POCO_STATIC) + +add_library( "${LIBNAME}" ${LIB_MODE} ${SRCS} ) +add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}") +set_target_properties( "${LIBNAME}" + PROPERTIES + VERSION ${SHARED_LIBRARY_VERSION} SOVERSION ${SHARED_LIBRARY_VERSION} + OUTPUT_NAME ${POCO_LIBNAME} + DEFINE_SYMBOL DNSSD_EXPORTS + ) + +target_link_libraries( "${LIBNAME}" Foundation Net) +target_include_directories( "${LIBNAME}" + PUBLIC + $ + $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src + ) +target_compile_definitions("${LIBNAME}" PUBLIC ${LIB_MODE_DEFINITIONS}) + +POCO_INSTALL("${LIBNAME}") +POCO_GENERATE_PACKAGE("${LIBNAME}") + +if(ENABLE_DNSSD_DEFAULT) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") # `UNIX AND NOT APPLE` it is not equal to Linux ;) + set(LINUX TRUE) + endif() + if(LINUX) + ADD_AVAHI() + else() + ADD_BONJOUR() + endif() +endif() + +if(ENABLE_DNSSD_AVHAI) + ADD_AVAHI() +endif() + +if(ENABLE_DNSSD_BONJOUR) + ADD_BONJOUR() +endif() + +if (ENABLE_SAMPLES) + add_subdirectory(samples) +endif () diff --git a/DNSSD/DNSSD.progen b/DNSSD/DNSSD.progen new file mode 100644 index 000000000..eb0c92b90 --- /dev/null +++ b/DNSSD/DNSSD.progen @@ -0,0 +1,18 @@ +vc.project.guid = D9257FF3-3A9A-41F6-B60E-D077EFF94186 +vc.project.name = DNSSD +vc.project.target = Poco${vc.project.name} +vc.project.type = library +vc.project.pocobase = .. +vc.project.outdir = ${vc.project.pocobase} +vc.project.platforms = Win32, x64, WinCE +vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md +vc.project.prototype = ${vc.project.name}_vs90.vcproj +vc.project.compiler.include = ..\\Foundation\\include;..\\Net\\include +vc.project.compiler.defines = +vc.project.compiler.defines.shared = ${vc.project.name}_EXPORTS +vc.project.compiler.defines.debug_shared = ${vc.project.compiler.defines.shared} +vc.project.compiler.defines.release_shared = ${vc.project.compiler.defines.shared} +vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.x64 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.WinCE = ws2.lib iphlpapi.lib +vc.solution.create = true diff --git a/DNSSD/DNSSD_vs160.sln b/DNSSD/DNSSD_vs160.sln new file mode 100644 index 000000000..060001943 --- /dev/null +++ b/DNSSD/DNSSD_vs160.sln @@ -0,0 +1,61 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSD", "DNSSD_vs160.vcxproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Build.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Build.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.ActiveCfg = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Build.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Deploy.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Build.0 = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/DNSSD_vs160.vcxproj b/DNSSD/DNSSD_vs160.vcxproj new file mode 100644 index 000000000..2cf9269d4 --- /dev/null +++ b/DNSSD/DNSSD_vs160.vcxproj @@ -0,0 +1,635 @@ + + + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + DNSSD + {D9257FF3-3A9A-41F6-B60E-D077EFF94186} + DNSSD + Win32Proj + + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + DynamicLibrary + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + PocoDNSSDd + PocoDNSSDmdd + PocoDNSSDmtd + PocoDNSSD + PocoDNSSDmd + PocoDNSSDmt + PocoDNSSD64d + PocoDNSSDmdd + PocoDNSSDmtd + PocoDNSSD64 + PocoDNSSDmd + PocoDNSSDmt + + + ..\bin\ + obj\DNSSD\$(Configuration)\ + true + + + ..\bin\ + obj\DNSSD\$(Configuration)\ + false + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\bin64\ + obj64\DNSSD\$(Configuration)\ + true + + + ..\bin64\ + obj64\DNSSD\$(Configuration)\ + false + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin\PocoDNSSDd.dll + true + true + $(OutDir)$(TargetName).pdb + ..\lib;%(AdditionalLibraryDirectories) + Console + ..\lib\PocoDNSSDd.lib + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin\PocoDNSSD.dll + true + false + ..\lib;%(AdditionalLibraryDirectories) + Console + true + true + ..\lib\PocoDNSSD.lib + MachineX86 + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib\PocoDNSSDmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\lib\PocoDNSSDmt.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib\PocoDNSSDmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + + Default + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\lib\PocoDNSSDmd.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin64\PocoDNSSD64d.dll + true + true + $(OutDir)$(TargetName).pdb + ..\lib64;%(AdditionalLibraryDirectories) + Console + ..\lib64\PocoDNSSDd.lib + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin64\PocoDNSSD64.dll + true + false + ..\lib64;%(AdditionalLibraryDirectories) + Console + true + true + ..\lib64\PocoDNSSD.lib + MachineX64 + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmt.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmd.lib + + + + + + + + + + + + + + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/DNSSD_vs160.vcxproj.filters b/DNSSD/DNSSD_vs160.vcxproj.filters new file mode 100644 index 000000000..b6ecb4e67 --- /dev/null +++ b/DNSSD/DNSSD_vs160.vcxproj.filters @@ -0,0 +1,69 @@ + + + + + {99303623-ebed-4008-92f1-ea9429ece898} + + + {018aa474-204b-4604-8dd1-8d1089d23bb6} + + + {ce1ab056-bb91-4f68-be21-d2cd905c33d3} + + + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + \ No newline at end of file diff --git a/DNSSD/DNSSD_vs170.sln b/DNSSD/DNSSD_vs170.sln new file mode 100644 index 000000000..444853056 --- /dev/null +++ b/DNSSD/DNSSD_vs170.sln @@ -0,0 +1,85 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSD", "DNSSD_vs170.vcxproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 + release_static_mt|ARM64 = release_static_mt|ARM64 + debug_static_md|ARM64 = debug_static_md|ARM64 + release_static_md|ARM64 = release_static_md|ARM64 + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Build.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Build.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.ActiveCfg = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Build.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Deploy.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Build.0 = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/DNSSD_vs170.vcxproj b/DNSSD/DNSSD_vs170.vcxproj new file mode 100644 index 000000000..cc7714344 --- /dev/null +++ b/DNSSD/DNSSD_vs170.vcxproj @@ -0,0 +1,915 @@ + + + + + debug_shared + ARM64 + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + ARM64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + ARM64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + ARM64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + ARM64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + ARM64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + DNSSD + {D9257FF3-3A9A-41F6-B60E-D077EFF94186} + DNSSD + Win32Proj + + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + PocoDNSSDA64d + PocoDNSSDmdd + PocoDNSSDmtd + PocoDNSSDA64 + PocoDNSSDmd + PocoDNSSDmt + PocoDNSSDd + PocoDNSSDmdd + PocoDNSSDmtd + PocoDNSSD + PocoDNSSDmd + PocoDNSSDmt + PocoDNSSD64d + PocoDNSSDmdd + PocoDNSSDmtd + PocoDNSSD64 + PocoDNSSDmd + PocoDNSSDmt + + + ..\binA64\ + objA64\DNSSD\$(Configuration)\ + true + + + ..\binA64\ + objA64\DNSSD\$(Configuration)\ + false + + + ..\libA64\ + objA64\DNSSD\$(Configuration)\ + + + ..\libA64\ + objA64\DNSSD\$(Configuration)\ + + + ..\libA64\ + objA64\DNSSD\$(Configuration)\ + + + ..\libA64\ + objA64\DNSSD\$(Configuration)\ + + + ..\bin\ + obj\DNSSD\$(Configuration)\ + true + + + ..\bin\ + obj\DNSSD\$(Configuration)\ + false + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\lib\ + obj\DNSSD\$(Configuration)\ + + + ..\bin64\ + obj64\DNSSD\$(Configuration)\ + true + + + ..\bin64\ + obj64\DNSSD\$(Configuration)\ + false + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + ..\lib64\ + obj64\DNSSD\$(Configuration)\ + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\binA64\PocoDNSSDA64d.dll + true + true + $(OutDir)$(TargetName).pdb + ..\libA64;%(AdditionalLibraryDirectories) + Console + ..\libA64\PocoDNSSDd.lib + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\binA64\PocoDNSSDA64.dll + true + false + ..\libA64;%(AdditionalLibraryDirectories) + Console + true + true + ..\libA64\PocoDNSSD.lib + MachineARM64 + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\libA64\PocoDNSSDmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\libA64\PocoDNSSDmt.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\libA64\PocoDNSSDmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\libA64\PocoDNSSDmd.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin\PocoDNSSDd.dll + true + true + $(OutDir)$(TargetName).pdb + ..\lib;%(AdditionalLibraryDirectories) + Console + ..\lib\PocoDNSSDd.lib + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin\PocoDNSSD.dll + true + false + ..\lib;%(AdditionalLibraryDirectories) + Console + true + true + ..\lib\PocoDNSSD.lib + MachineX86 + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib\PocoDNSSDmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\lib\PocoDNSSDmt.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib\PocoDNSSDmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + + Default + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\lib\PocoDNSSDmd.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin64\PocoDNSSD64d.dll + true + true + $(OutDir)$(TargetName).pdb + ..\lib64;%(AdditionalLibraryDirectories) + Console + ..\lib64\PocoDNSSDd.lib + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;DNSSD_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ..\bin64\PocoDNSSD64.dll + true + false + ..\lib64;%(AdditionalLibraryDirectories) + Console + true + true + ..\lib64\PocoDNSSD.lib + MachineX64 + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmt.lib + + + + + Disabled + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + $(OutDir)$(TargetName).pdb + Level3 + ProgramDatabase + Default + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + ..\lib64\PocoDNSSDmd.lib + + + + + + + + + + + + + + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/DNSSD_vs170.vcxproj.filters b/DNSSD/DNSSD_vs170.vcxproj.filters new file mode 100644 index 000000000..e0af9e4c9 --- /dev/null +++ b/DNSSD/DNSSD_vs170.vcxproj.filters @@ -0,0 +1,69 @@ + + + + + {e8bdfc7b-57e4-484b-8d16-a3b65bd75b59} + + + {7dda570e-7773-45fd-8646-6f1d9c0a1fc3} + + + {084794a0-8344-4ddf-8fb3-937553fd8d9f} + + + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + Core\Header Files + + + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + Core\Source Files + + + \ No newline at end of file diff --git a/DNSSD/DNSSD_vs90.sln b/DNSSD/DNSSD_vs90.sln new file mode 100644 index 000000000..a2a04a19d --- /dev/null +++ b/DNSSD/DNSSD_vs90.sln @@ -0,0 +1,37 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSD", "DNSSD_vs90.vcproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Build.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/DNSSD_vs90.vcproj b/DNSSD/DNSSD_vs90.vcproj new file mode 100644 index 000000000..c91131f9f --- /dev/null +++ b/DNSSD/DNSSD_vs90.vcproj @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DNSSD/DNSSD_x64_vs90.sln b/DNSSD/DNSSD_x64_vs90.sln new file mode 100644 index 000000000..146f0f93e --- /dev/null +++ b/DNSSD/DNSSD_x64_vs90.sln @@ -0,0 +1,37 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSD", "DNSSD_x64_vs90.vcproj", "{D9257FF3-3A9A-41F6-B60E-D077EFF94186}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Build.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.ActiveCfg = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Build.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_shared|x64.Deploy.0 = release_shared|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Build.0 = release_static_md|x64 + {D9257FF3-3A9A-41F6-B60E-D077EFF94186}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/Default/Makefile b/DNSSD/Default/Makefile new file mode 100644 index 000000000..c5f4755c9 --- /dev/null +++ b/DNSSD/Default/Makefile @@ -0,0 +1,21 @@ +# +# Makefile +# +# $Id: //poco/1.7/DNSSD/Default/Makefile#1 $ +# +# Makefile for DNSSD Default Implementation. +# Use Avahi on Linux, otherwise Bonjour +# + +include $(POCO_BASE)/build/rules/global + +ifeq ($(OSNAME),Linux) +DNSSDLibrary = Avahi +else +DNSSDLibrary = Bonjour +endif + +.PHONY: projects +clean all: projects +projects: + $(MAKE) -C $(POCO_BASE)/DNSSD/$(DNSSDLibrary) $(MAKECMDGOALS) diff --git a/DNSSD/Default/dependencies b/DNSSD/Default/dependencies new file mode 100644 index 000000000..5ab5fc352 --- /dev/null +++ b/DNSSD/Default/dependencies @@ -0,0 +1,3 @@ +Foundation +Net +DNSSD diff --git a/DNSSD/LICENSE b/DNSSD/LICENSE new file mode 100644 index 000000000..2f2f957ce --- /dev/null +++ b/DNSSD/LICENSE @@ -0,0 +1,32 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- +Note: +Individual files contain the following tag instead of the full license text. + + SPDX-License-Identifier: BSL-1.0 + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ diff --git a/DNSSD/Makefile b/DNSSD/Makefile new file mode 100644 index 000000000..9506c395b --- /dev/null +++ b/DNSSD/Makefile @@ -0,0 +1,20 @@ +# +# Makefile +# +# $Id: //poco/1.7/DNSSD/Makefile#1 $ +# +# Makefile for Poco DNSSD +# + +include $(POCO_BASE)/build/rules/global + +objects = \ + Domain Error Record Service \ + DNSSDBrowser DNSSDResponder DNSSDResponderImpl \ + DNSSDException + +target = PocoDNSSD +target_version = 1 +target_libs = PocoNet PocoFoundation + +include $(POCO_BASE)/build/rules/lib diff --git a/DNSSD/README.md b/DNSSD/README.md new file mode 100644 index 000000000..2af727108 --- /dev/null +++ b/DNSSD/README.md @@ -0,0 +1,49 @@ +POCO DNS-SD (Zeroconf) Wrapper Library for Bonjour and Avahi +============================================================ + +This is a POCO-based wrapper library providing an easy-to-use and +unified programming interface to Apple Bonjour and Avahi libraries +implementing DNS Service Discovery (DNS-SD, also known as Zeroconf). + +Prerequisites +------------- + +The [Apple Bonjour SDK](https://developer.apple.com/bonjour/) is needed on Windows (and OS X, of course). The Avahi client libraries are needed on Linux. + +Getting Started +--------------- + +Clone into the root of an existing POCO source tree. + + + $ git clone https://github.com/pocoproject/poco-dnssd.git DNSSD + +On Linux, build with cmake like below. + + $ git apply DNSSD/CMakeLists.diff + $ sudo ./build_cmake.sh + +On Windows or OS X, build with cmake like below. + + $ git apply DNSSD/CMakeLists.diff + $ mkdir build + $ cd build + $ cmake .. + $ make -j8 + +For build without using cmake on Windows, build the included Visual C++ solution. On Linux/OS X, build with POCO_BASE environment variable set to the root of +the POCO source tree. + + $ export POCO_BASE=`pwd` + $ cd DNSSD + $ make -s -j8 + $ make -s -j8 -C Default + +See the [doc](https://github.com/pocoproject/poco-dnssd/tree/master/doc) directory for documentation and the samples directory for sample +applications. + + +License +------- + +Boost Software License 1.0 diff --git a/DNSSD/cmake/PocoDNSSDConfig.cmake b/DNSSD/cmake/PocoDNSSDConfig.cmake new file mode 100644 index 000000000..c603d8c63 --- /dev/null +++ b/DNSSD/cmake/PocoDNSSDConfig.cmake @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(PocoFoundation) +find_dependency(PocoNet) +include("${CMAKE_CURRENT_LIST_DIR}/PocoDNSSDTargets.cmake") diff --git a/DNSSD/dependencies b/DNSSD/dependencies new file mode 100644 index 000000000..f6d54af82 --- /dev/null +++ b/DNSSD/dependencies @@ -0,0 +1,2 @@ +Foundation +Net diff --git a/DNSSD/doc/00100-DNSSDOverview.page b/DNSSD/doc/00100-DNSSDOverview.page new file mode 100644 index 000000000..1da4ed3df --- /dev/null +++ b/DNSSD/doc/00100-DNSSDOverview.page @@ -0,0 +1,208 @@ +DNS Service Discovery and Zero Configuration Networking Overview +DNS-SD + +!!!Introduction + +A growing number of embedded devices are connected to TCP/IP networks. +And many of these devices are no longer passive network nodes, waiting +for someone else to control them. They are full-blown network citizens, +actively communicating with their peers and often relying on the network +services provided by other devices to do their job. For this to work, +all these devices must be configured properly. Configuring the network +parameters (e.g., IP address, netmask, etc.) of a device is a tedious task, +as many devices do not have an appropriate user interface to do this comfortably. +This is especially an issue with consumer devices, where the user might not even have the +necessary technical knowledge to configure such a device. And as the +number of devices in a network grows, configuring each device separately +is no longer practical. There from comes the need for the automatic +configuration of network devices and the automatic discovery of network +services. In recent years, the industry has come up with a variety of +different technologies and specifications to address this. + + +!!!Fundamental Issues + +Generally, there are three fundamental issues that must be dealt with +for the automatic discovery of network devices and services, and three +more issues that must be dealt with for the actual invocation or use of +the discovered services. + + +!!Address Assignment + +Every device must be assigned a unique network address. In case of +TCP/IP networks this can be done with the help of a DHCP (Dynamic Host +Configuration Protocol) server. Should, however, no DHCP server be +available (for example, in typical home user networks), another way of +assigning an IP addresses must be found. Apart from manual +configuration, which is often undesirable, a method called APIPA +(Automatic Private IP Addressing, or AutoIP for short) is used. In this +case, a device's TCP/IP stack randomly chooses an IP address in the +private (link-local) IP address range 169.254.0.0 to 169.254.255.255. To +prevent two or more devices from accidentally selecting the same address, +each device must probe, using the ARP (Address Resolution Protocol), +whether the chosen address is available. + + +!!Name Resolution + +Whenever a user (or device) wants to access another device over the +network, he usually wants to refer to the device by its name, not by its +IP address. In a typical TCP/IP network, a DNS (Domain Name System) +server is used to map domain names to IP addresses. Again, if no DNS +server is available, such as in a typical home network, another way of +resolving names to IP addresses is required. Multicast DNS (mDNS), as +used by Zeroconf, is such an alternative technology. + + +!!Service Discovery + +A user or device must be able to find a service provided by one or more +devices in the network. The important part here is that the user (or +device) usually does not care which device implements the service, as +long as the service with specific properties is available and +accessible. A typical example for service discovery is: <*I need to print +a document in color. Give me an IP address and port number where I can +send the print job to, using the Internet Printing Protocol (IPP), so +that the document will be printed in color.*> + +What all technologies for service discovery have in common is, that they +make use of IP multicasting. IP multicasting uses addresses in a special +address range (224.0.0.0 to 239.255.255.255). A packet (typically, a UDP +packet) sent to a multicast address is received by all hosts listening +to that specific address. + +Service discovery is implemented in the following way: + + - An application or device that needs a certain service sends a request + describing the required properties of the service to a specific multicast + address (and port number). + - Other applications or devices on the same network receive the request, + and if they provide the requested service themselves (or know another device + that implements the service), respond with a message describing where the + service can be found. + - The application or device searching for the service collects all responses, + and from the responses chooses the one service provider it is going to use. + +In addition, devices that join or leave a network can send announcements to other +devices describing the availability of the services they provide. + + +!!Service Description + +Once a certain service has been discovered, it may be necessary to +obtain more information about the service. For example, if a service +consists of multiple operations, it is necessary to find out exactly +what operations are supported, and what arguments must be passed to +them. This is the purpose of service description. + +In case only well-defined service protocols are used (e.g., HTTP, +Internet Printing, or media streaming), service description is not +necessary, because the only information needed to access the service is +the network address (IP address and port number, or URI), and this +information can be obtained by service discovery. In other cases, the +information obtained via service discovery is insufficient to +successfully access the service. In such a case, service discovery only +returns the address of a network resource that provides detailed +information about the capabilities of the service, and how to access +them. + + +!!Service Invocation + +After an application has obtained enough information about the services +it wants to access -- either via service discovery alone, or together +with service description, the application will access or invoke them. +This is usually beyond the scope of most service discovery technologies, +and the domain of specialized technologies and protocols. Examples for +such technologies are HTTP (HyperText Transfer Protocol), SOAP, +Java RMI (Remote Method Invocation), CORBA (Common Object Request Broker +Architecture), or media streaming protocols such as RTSP +(Real Time Streaming Protocol). + + +!!Service Presentation + +Some technologies (UPnP and Jini) provide facilities to present a device +specific user interface to the user, via another device (e.g., a central +management workstation, the user's PC or TV set). Such a user interface +can be used to allow the user to directly interact with a device, in +order to configure it, or to use some of its functions not available +otherwise. + +This requires that the user interface is implemented in a device +independent way. One way to do this is to implement the user interface +in HTML (HyperText Markup Language), served by an embedded web server +built into the device. Another way is to implement the user interface in +Java, so that it can be run everywhere a Java Virtual Machine is +available. The user interface code than talks to the device over a +network connection, using a possibly proprietary protocol. + + +!!!Zero Configuration Networking (Zeroconf) + +Zero Configuration Networking (Zeroconf) is a technology originally developed +by Apple and promoted under the trademark name Bonjour. Zeroconf is +built upon technologies known as multicast DNS (mDNS) and DNS +Service Discovery (DNS-SD), which themselves are based on the proven +DNS protocol. Its most popular uses are in network printers, network +cameras and for sharing music using Apple's iTunes music jukebox +software. Open source implementations are available from Apple and +others for all important platforms. + +Zeroconf uses DHCP and AutoIP for address assignment if no DHCP server +is available. A special variant of the well-known DNS protocol, +multicast DNS, is used for name resolution in case no DNS server is +available. In mDNS, a name resolution query is sent not directly to a +DNS server, as with traditional DNS, but to a multicast address. All +network devices supporting Zeroconf and listening to this multicast +address respond to name resolution queries, if they have the requested +information. + +Finally, for service discovery, an extension of the DNS protocol called +DNS Service Discovery is used. DNS-SD can be used both with multicast +DNS (the usual way), or with traditional unicast queries to a DNS +server. With the additional support for DNS Update and DNS Long Lived +Queries, two extensions of the DNS protocol, Zeroconf can be used to +announce services across the global internet. In this case, an ordinary +DNS server is used to make the service information available. Periodic +automatic updates of the DNS server's database ensure that its service +information is up to date. + +A major advantage of Zeroconf is that it is based on proven technology. +Also, it can be implemented in a very resource efficient way, making it +a good choice for resource constrained embedded devices. + +Beside heavy use by Apple in many of its applications for Mac OS X and +Windows (iTunes), Zeroconf is popular among manufacturers of printers +and network cameras. + + +!!Zeroconf Implementations + +Two implementations of Zeroconf are currently in widespread use. + +Apple's Bonjour was the first implementation of Zeroconf. The +implementation is available under an open source license and +can be used on different platforms like Mac OS X, Windows, Linux or +VxWorks. Bonjour is an integrated part of Mac OS X and iOS. +A Windows installer (and SDK) is available as well. + +Avahi is another open source implementation of Zeroconf, targeted +mostly at Linux, although it can also be used on other POSIX platforms +like FreeBSD or Solaris. Avahi has been integrated into many +Linux distributions such as Debian, Ubuntu, SuSE and others. + + +!!The POCO DNS-SD Library + +The POCO DNS-SD library provides an easy-to-use +and unified programming interface for integrating Zeroconf features +(service discovery and host name resolution) into a C++ application. +The library does not implement its own mDNS and DNS-SD protocol stacks, +but rather uses an existing Zeroconf implementation for that purpose. +Apple's Bonjour and Avahi can be used as backend for the DNS-SD library. + +A great advantage of the library is that it provides a unified +programming interface. For the programmer, it's completely +transparent whether Avahi or Bonjour is used as backend. diff --git a/DNSSD/doc/00200-DNSSDTutorialAndUserGuide.page b/DNSSD/doc/00200-DNSSDTutorialAndUserGuide.page new file mode 100644 index 000000000..038ec101f --- /dev/null +++ b/DNSSD/doc/00200-DNSSDTutorialAndUserGuide.page @@ -0,0 +1,406 @@ +DNS-SD Tuturial And User Guide +DNS-SD + +!!!Introduction + +The POCO DNS-SD POCO library provides an easy-to-use and +unified programming interface for integrating Zeroconf features +(service discovery and host name resolution) into a C++ application. +The Applied Informatics DNS-SD library does not +implement its own mDNS and DNS-SD protocol stacks, but rather uses +an existing Zeroconf implementation for that purpose. Apple's Bonjour +and Avahi can be used as backend for the DNS-SD library. + +A great advantage of the library is that it provides a unified +programming interface. For the programmer, it's completely +transparent whether Avahi or Bonjour is used as backend. + + +!!!Programming Basics + +The DNS-SD library provides an asynchronous programming interface. +This means that the application starts a browse or resolve operation +by calling a member function of the Poco::DNSSD::DNSSDBrowser class, +and this function returns immediately. The actual browse or resolve +operation (which involves sending queries over the network and +receiving responses from other hosts) is carried out in a separate +thread, and as soon as results become available, these are reported +to the application via events. + + +!!Event Handlers + +The event handlers registered by the application should +complete their work and return as quick as possible, otherwise they may +interfere with DNS-SD processing. Event handlers should never +wait for other events to happen. Specifically, they must never +wait for an other DNSSDBrowser event to happen, as this will +result in a deadlock. + + +!!Service Types + +Service types (or registration types) are the most important concept when +handling with DNS Service Discovery. A service type consists of a +short name (maximum of 15 characters) specifying the protocol implemented +by the service (prepended by an underscore), followed by a dot, followed +by a name identifying the primary transport protocol, which is either +"_tcp" or "_udp". Service types should be registered at <[dns-sd.org]>. +A list of currently registered service types, as well as information on how +to register a new service type can be found at the +[[http://www.dns-sd.org/ServiceTypes.html DNS-SD website]]. + +Examples for service types are "_daap._tcp" (Digital Audio Access Protocol, +the protocol used by iTunes music sharing), "_http._tcp" (web server) +or "_printer._tcp" for a printing service. + +Service names are not case sensitive. + + +!!!Programming Tasks + +In the following sections, the basic programming Tasks +that need to be performed when working with the DNS-SD library +are described. + + +!!Initializing the DNS-SD Library + +The DNS-SD core library only defines the classes that are part +of the programming interfaces, it does not provide an actual +implementation of these interfaces. So, in addition to the DNS-SD +core library, a backend library must be linked with the application +as well. Depending on which backend library is used, either Apple's +Bonjour or Avahi will be used. + +Before the DNS-SD library can be used it must be initialized. +This is done by calling the Poco::DNSSD::initializeDNSSD() function. +This function is actually defined implemented in a backend library, +so the backend libraries's header file must be included. + +It is good practice to control which backend header is being +included via the preprocessor. For a cross-platform application, +one would use Avahi on Linux platforms and Bonjour on Mac OS X and +Windows platforms. + +Typically, the <[#include]> statements for the DNS-SD library +would be as follows: + + #include "Poco/DNSSD/DNSSDResponder.h" + #include "Poco/DNSSD/DNSSDBrowser.h" + #if POCO_OS == POCO_OS_LINUX && !defined(POCO_DNSSD_USE_BONJOUR) + #include "Poco/DNSSD/Avahi/Avahi.h" + #else + #include "Poco/DNSSD/Bonjour/Bonjour.h" + #endif +---- + +These statements will include the header files for the Poco::DNSSD::DNSSDResponder +and Poco::DNSSD::DNSSDBrowser classes, as well as the core header +file for a backend. Note that an application that only registers a service, +but does not browse for services, does not need to include the +<*Poco/DNSSD/DNSSDBrowser.h*> header file. + +The Poco::DNSSD::initializeDNSSD() function must be called before an +instance of the Poco::DNSSD::DNSSDResponder class is created. If the +application uses the Poco::Util::Application class (or its server +counterpart), this can happen in the constructor of the application +subclass. It is also good practice to uninitialize the DNS-SD library +when the application exits by calling Poco::DNSSD::uninitializeDNSSD(), +which can be done in the application class destructor. + +After initializing the DNS-SD library, the application should +create an instance of the Poco::DNSSD::DNSSDResponder class. +This class provides the main entry point into the DNS-SD library. +Although it is possible to create more than one instance of +the Poco::DNSSD::DNSSDResponder class, application programmers +should refrain from doing so. The Poco::DNSSD::DNSSDResponder +object should be kept alive during the entire lifetime of +the application, or at least as long as DNS-SD services +are required. + +After the responder object has been created, its <[start()]> method +must be called. This will start a thread that handles all +DNS-SD related network activity for the application. + +Similarly, when the application terminates, or when DNS-SD +services are no longer required, the <[stop()]> method should +be called to orderly shut-down the background thread. + + +!!Registering A Service + +Registering a service, and thus making it discoverable to other +DNS-SD capable applications, is a two step process. +First, an instance of Poco::DNSSD::Service must be created +and properly initialized. At least the following information +must be specified: + + - the service type (e.g., "_http._tcp"), and + - the port number of the service. + +Other information can be specified, but defaults will be +used if not. This includes: + + - The service name, which defaults to the local hosts's machine name. + - The network interface (by its interface index), on which the + service shall be announced. The default is to announce the + service on all interfaces (interface index is zero). + - The domain, on which the service will be announced. + - The domain name of the host providing the service. + - Service properties, which will be announced in the TXT + record of the service. + +The service properties (basically, a list of key-value pairs) +can be used to provide additional information +necessary for invoking the service. These will be announced along +with the basic service information (host name, port number, etc.). +The content of the service properties is specific to the application +or network protocol the application uses. +When specifying service properties, a few restrictions must be +considered: + + - The total length of a key-value pair must not exceed 254 bytes. + - The total length of all key-value pairs, including two additional + bytes for each pair, must not exceed 65535 bytes. + - The length of the key should not exceed nine bytes. + - Values can contain text strings or arbitrary binary values, and + can also be empty. + + +The following code shows how to register and publish a HTTP server +(running on port 8080) on a Zeroconf network: + + Poco::DNSSD::DNSSDResponder dnssdResponder; + dnssdResponder.start(); + + Poco::DNSSD::Service service("_http._tcp", 8080); + Poco::DNSSD::ServiceHandle serviceHandle = dnssdResponder.registerService(service); +---- + +Another example, the following code shows how to register +and publish a network postscript-capable printer on a Zeroconf network. + + Poco::DNSSD::DNSSDResponder dnssdResponder; + dnssdResponder.start(); + + Poco::DNSSD::Service::Properties props; + props.add("txtvers", "1"); + props.add("pdl", "application/postscript"); + props.add("qtotal", "1"); + props.add("rp", "ThePrinter"); + props.add("ty", "A Postscript Printer"); + Poco::DNSSD::Service service(0, "The Printer", "", "_printer._tcp", "", "", 515, props); + Poco::DNSSD::ServiceHandle serviceHandle = dnssdResponder.registerService(service); +---- + +!Unregistering A Service + +The <[registerService()]> method returns a Poco::DNSSD::ServiceHandle object. +This object is used to unregister the service when it's no longer available, +by passing it as argument to the <[unregisterService()]> method. + + dnssdResponder.unregisterService(serviceHandle); +---- + + +!Handling Registration Errors + +The above code examples don't do a very good job of error handling. +Registration on the network may fail for various reasons. +The Poco::DNSSD::DNSSDResponder class provides two events that can be +used to check the status of a service registration. +If the registration was successful, the <[serviceRegistered]> event +will be fired. If registration failed, the <[serviceRegistrationFailed]> +event will be fired. Please see the class documentation for a +description of the available event arguments. + +Usually, there's not much an application can do when service registration +fails. This is especially true for embedded devices, which often don't +even have a way to communicate this error to the user. However, an application +should at least log a registration error in a log file, to help with +error diagnostics. + +Handling the <[serviceRegistered]> event is only necessary if the application +needs to know the actual service name used to announce the service. +In case of a name conflict (duplicate service names on the network), the +name specified when registering the service may have been changed by +the Bonjour or Avahi backend. + +The following example shows an event handler (delegate) function for handling +registration errors. + + void onError(const void* sender, const Poco::DNSSD::DNSSDResponder::ErrorEventArgs& args) + { + std::cerr + << "Service registration failed: " + << args.error.message() + << " (" << args.error.code() << ")" + << std::endl; + } +---- + +To register this function as delegate for the <[serviceRegistrationFailed]> event: + + dnssdResponder.serviceRegistrationFailed += Poco::delegate(onError); +---- + + +!!Browsing For Services + +To discover available services of a specific type on the network, a browse operation +for a specific service type must be initiated. For this purpose, the +Poco::DNSSD::DNSSDBrowser class is used. An instance of this class can be obtained +from the Poco::DNSSD::DNSSDResponder object, by calling the <[browswer()]> method. + +After a browse operation for a service type has been started, services becoming +available or unavailable will be reported via events. A service that has been +discovered will be reported via the <[serviceFound]> event. +If a service is no longer available, it will be reported via the <[serviceRemoved]> +event. The name, type and domain of the discovered service can be obtained from the +Poco::DNSSD::Service object passed as event argument. + +The following sample shows how to write a delegate function for +the <[serviceFound]> event. + + void onServiceFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args) + { + std::cout << "Service Found: \n" + << " Name: " << args.service.name() << "\n" + << " Domain: " << args.service.domain() << "\n" + << " Type: " << args.service.type() << "\n" + << " Interface: " << args.service.networkInterface() << "\n" << std::endl; + } +---- + +The next sample shows how to start a browse operation: + + Poco::DNSSD::DNSSDResponder dnssdResponder; + dnssdResponder.start(); + + dnssdResponder.browser().serviceFound += Poco::delegate(onServiceFound); + Poco::DNSSD::BrowseHandle bh = dnssdResponder.browser().browse("_printer._tcp", ""); +---- + +Poco::DNSSD::DNSSDBrowser::browse() returns a Poco::DNSSD::BrowseHandle object, which can +later be used to cancel a browse operation, by passing it to the <[cancel()]> method, as +shown in the following example: + + dnssdResponder.browser().cancel(bh); +---- + +After a service has been discovered, the next step is resolving the service, to obtain +its host name, port number and properties, so that the service can be invoked. + + +!!Resolving A Service + +Like browsing for services, resolving a service is an asynchronous operation. +A resolve operation is started with a call to <[resolve()]>, passing the +Poco::DNSSD::Service object obtained from the <[serviceFound]> event as +argument. Once the service has been resolved, the result is reported via +the <[serviceResolved]> event. The resolve operation can be started +directly from the <[serviceFound]> event handler, as shown in the +following sample: + + void onServiceFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args) + { + std::cout << "Service Found: \n" + << " Name: " << args.service.name() << "\n" + << " Domain: " << args.service.domain() << "\n" + << " Type: " << args.service.type() << "\n" + << " Interface: " << args.service.networkInterface() << "\n" << std::endl; + + reinterpret_cast(const_cast(sender))->resolve(args.service); + } +---- + +After a successful resolve, the service host name, port number and properties +are available through the Poco::DNSSD::Service object passed to the event handler, +as shown in the sample below: + + void onServiceResolved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args) + { + std::cout << "Service Resolved: \n" + << " Name: " << args.service.name() << "\n" + << " Full Name: " << args.service.fullName() << "\n" + << " Domain: " << args.service.domain() << "\n" + << " Type: " << args.service.type() << "\n" + << " Interface: " << args.service.networkInterface() << "\n" + << " Host: " << args.service.host() << "\n" + << " Port: " << args.service.port() << "\n" + << " Properties: \n"; + + for (Poco::DNSSD::Service::Properties::ConstIterator it = args.service.properties().begin(); it != args.service.properties().end(); ++it) + { + std::cout << " " << it->first << ": " << it->second << "\n"; + } + std::cout << std::endl; + } +---- + +Of course, the event delegate for the <[serviceResolved]> event must be registered: + + dnssdResponder.browser().serviceResolved += Poco::delegate(onServiceResolved); +---- + + +!!Resolving A Service's Host Name + +The last step necessary before invoking a service is to resolve the service's host name +into an IP address. On systems where mDNS is integrated into the DNS resolver (e.g., +Mac OS X, Windows with Bonjour or most Linux distributions with Avahi), this +can simply be done by creating a Poco::Net::SocketAddress instance from the service's +host name and port number. However if the systems's DNS resolver cannot handle +Multicast DNS queries, the host name must be resolved through the +Poco::DNSSD::DNSSDBrowser::resolveHost() method. Like resolving a service, resolving +a host name is an asynchronous operation, and the result will be reported via +an event -- the <[hostResolved]> event. + +The following sample shows how to implement the delegate function for the +<[hostResolved]> event: + + void onHostResolved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ResolveHostEventArgs& args) + { + std::cout << "Host Resolved: \n" + << " Host: " << args.host << "\n" + << " Interface: " << args.networkInterface << "\n" + << " Address: " << args.address.toString() << "\n" + << " TTL: " << args.ttl << "\n" << std::endl; + } +---- + +Like with resolving a service, it is possible to initiate resolving a host name directly +from within the event delegate for the <[serviceResolved]> event. + + +!!!Advanced Programming Tasks + +!!Enumerating Domains + +Available domains for browsing and registration can be enumerated by calling the +Poco::DNSSD::DNSSDBrowser::enumerateBrowseDomains() and +Poco::DNSSD::DNSSDBrowser::enumerateRegistrationDomains() methods. As usual, +results are reported via events. + + +!!Registering And Browsing For Records + +Additional DNS records for a specific service can be published on a Zeroconf network +by invoking the Poco::DNSSD::DNSSDResponder::addRecord() method. It is also possible +to alter a published record, or remove it. Records can be queried by invoking +Poco::DNSSD::DNSSDBrowser::queryRecord(). Results are reported via +events. + + +!!Enumerating Available Service Types + +It is possible to enumerate all available services types on a domain by +browsing for the special service type "_services._dns-sd._udp". + +Results will be reported via the <[serviceDiscovered]> event. +The service type (without the primary transport protocol part, +as in "_http") can be obtained from the service name stored +in the Poco::DNSSD::Service object passed as event argument. +The primary transport protocol and the domain can be obtained +from the service type. diff --git a/DNSSD/include/Poco/DNSSD/DNSSD.h b/DNSSD/include/Poco/DNSSD/DNSSD.h new file mode 100644 index 000000000..3d352373a --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/DNSSD.h @@ -0,0 +1,194 @@ +// +// DNSSD.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/DNSSD.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSSD +// +// Basic definitions for the Poco DNSSD library. +// This file must be the first file included by every other DNSSD +// header file. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_DNSSD_INCLUDED +#define DNSSD_DNSSD_INCLUDED + + +#include "Poco/Poco.h" + + +// +// The following block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the DNSSD_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// DNSSD_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. +// +#if defined(_WIN32) && defined(POCO_DLL) + #if defined(DNSSD_EXPORTS) + #define DNSSD_API __declspec(dllexport) + #else + #define DNSSD_API __declspec(dllimport) + #endif +#endif + + +#if !defined(DNSSD_API) + #define DNSSD_API +#endif + + +#if defined(_MSC_VER) && !defined(POCO_LIB_SUFFIX) + #if defined(POCO_DLL) + #if defined(_DEBUG) + #define POCO_LIB_SUFFIX "d.lib" + #else + #define POCO_LIB_SUFFIX ".lib" + #endif + #elif defined(_DLL) + #if defined(_DEBUG) + #define POCO_LIB_SUFFIX "mdd.lib" + #else + #define POCO_LIB_SUFFIX "md.lib" + #endif + #else + #if defined(_DEBUG) + #define POCO_LIB_SUFFIX "mtd.lib" + #else + #define POCO_LIB_SUFFIX "mt.lib" + #endif + #endif +#endif + + +#if defined(_MSC_VER) + #if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(DNSSD_EXPORTS) + #pragma comment(lib, "PocoDNSSD" POCO_LIB_SUFFIX) + #endif +#endif + + +namespace Poco { +namespace DNSSD { + + +enum HandleType +{ + SD_SERVICE_HANDLE = 1, + SD_RECORD_HANDLE = 2, + SD_BROWSE_HANDLE = 3 +}; + + +template +class OpaqueHandle +{ +public: + enum + { + TYPE = Type + }; + + OpaqueHandle(): + _h(Invalid), + _subtype(0) + { + } + + OpaqueHandle(Base h, int subtype = 0): + _h(h), + _subtype(subtype) + { + } + + template + OpaqueHandle(T h, int subtype = 0): + _h(reinterpret_cast(h)), + _subtype(subtype) + { + } + + ~OpaqueHandle() + { + } + + int subtype() const + { + return _subtype; + } + + template + T cast() const + { + return reinterpret_cast(_h); + } + + bool operator == (const OpaqueHandle& other) const + { + return _h == other._h; + } + + bool operator != (const OpaqueHandle& other) const + { + return _h != other._h; + } + + bool operator <= (const OpaqueHandle& other) const + { + return _h <= other._h; + } + + bool operator < (const OpaqueHandle& other) const + { + return _h < other._h; + } + + bool operator >= (const OpaqueHandle& other) const + { + return _h >= other._h; + } + + bool operator > (const OpaqueHandle& other) const + { + return _h > other._h; + } + + void reset() + { + _h = Invalid; + } + + bool isValid() const + { + return _h != Invalid; + } + + bool isNull() const + { + return _h == Invalid; + } + +private: + Base _h; + int _subtype; +}; + + +typedef OpaqueHandle ServiceHandle; +typedef OpaqueHandle RecordHandle; +typedef OpaqueHandle BrowseHandle; + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_DNSSD_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/DNSSDBrowser.h b/DNSSD/include/Poco/DNSSD/DNSSDBrowser.h new file mode 100644 index 000000000..deaa42419 --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/DNSSDBrowser.h @@ -0,0 +1,346 @@ +// +// DNSSDBrowser.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/DNSSDBrowser.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSSDBrowser +// +// Definition of the DNSSDBrowser class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_DNSSDBrowser_INCLUDED +#define DNSSD_DNSSDBrowser_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" +#include "Poco/DNSSD/Service.h" +#include "Poco/DNSSD/Domain.h" +#include "Poco/DNSSD/Record.h" +#include "Poco/DNSSD/Error.h" +#include "Poco/Net/IPAddress.h" +#include "Poco/BasicEvent.h" + + +namespace Poco { +namespace DNSSD { + + +class DNSSD_API DNSSDBrowser + /// The DNSSDBrowser class allows browsing for services, domains and records, + /// resolving services and error handling. Browse and resolve operations + /// are asynchronous. Discovered services, records and domains, as well as + /// error conditions are reported via events. + /// + /// A DNSSDBrowser object is never created directly. It can be obtained + /// from the DNSSDResponder by calling the DNSSDResponder::serviceBrowser() + /// method. + /// + /// A note on implementing event handlers: An event handler should + /// complete its work and return as quick as possible, otherwise it may + /// interfere with DNS-SD processing. An event handler should never + /// wait for other events to happen. Specifically, it must never + /// wait for an other DNSSDBrowser event to happen, as this will + /// result in a deadlock. +{ +public: + enum Options + /// Options for browsing, resolving and DNS queries. + { + RESOLVE_ON_DISCOVERED_INTERFACE = 0x01, + /// Attempt to resolve the service on the interface it was discovered on only. + + RESOLVE_ON_ALL_INTERFACES = 0x02, + /// Attempt to resolve the service on all interfaces. + + BROWSE_FORCE_MULTICAST = 0x04, + /// Force query to be performed with a link-local mDNS query, + /// even if the name is an apparently non-local name (i.e. a + /// name not ending in ".local."). + + BROWSE_LONG_LIVED_QUERY = 0x08 + /// Create a "long-lived" unicast query in a non-local domain. + /// Without enabling this option, unicast queries will be one-shot -- + /// that is, only answers available at the time of the call + /// will be returned. By setting this flag, answers that become available + /// after the initial call is made will generate + /// events. This flag has no effect on link-local multicast queries. + }; + + enum BrowseFlags + /// Flags reported in event arguments. + { + BROWSE_MORE_COMING = 0x01 + /// This flag signals that more events will follow + /// immediately. For the application this means for + /// example that updates to the user interface can be + /// delayed until an event is fired that does not have + /// this flag set. + }; + + struct CommonEventArgs + { + CommonEventArgs(BrowseHandle h, int f): + browseHandle(h), + flags(f) + { + } + + BrowseHandle browseHandle; + int flags; + }; + + struct ServiceEventArgs: public CommonEventArgs + { + ServiceEventArgs(BrowseHandle h, int f, const Service& s): + CommonEventArgs(h, f), + service(s) + { + } + + const Service& service; + }; + + struct DomainEventArgs: public CommonEventArgs + { + DomainEventArgs(BrowseHandle h, int f, const Domain& d): + CommonEventArgs(h, f), + domain(d) + { + } + + const Domain& domain; + }; + + struct RecordEventArgs: public CommonEventArgs + { + RecordEventArgs(BrowseHandle h, int f, const Record& r): + CommonEventArgs(h, f), + record(r) + { + } + + const Record& record; + }; + + struct ResolveHostEventArgs: public CommonEventArgs + { + ResolveHostEventArgs(BrowseHandle h, int f, const std::string& n, const Poco::Net::IPAddress& a, Poco::Int32 i, Poco::UInt32 t): + CommonEventArgs(h, f), + host(n), + address(a), + networkInterface(i), + ttl(t) + { + } + + std::string host; + Poco::Net::IPAddress address; + Poco::Int32 networkInterface; + Poco::UInt32 ttl; + }; + + struct ErrorEventArgs: public CommonEventArgs + { + ErrorEventArgs(BrowseHandle h, int f, const Error& e): + CommonEventArgs(h, f), + error(e) + { + } + + const Error& error; + }; + + Poco::BasicEvent browseError; + /// Fired when an error occures while browsing for services. + /// + /// The specific error condition can be found by looking at the + /// Error object in the argument. + + Poco::BasicEvent serviceFound; + /// Fired when a service has been found. + /// + /// The Service object given in the argument can be passed to resolve() + /// to resolve the service, and to obtain the service's host and port + /// number. + + Poco::BasicEvent serviceRemoved; + /// Fired when a service has been removed and is no longer available. + /// + /// The Service object given in the argument can be passed to resolve() + /// to resolve the service, and to obtain the service's host and port + /// number. + + Poco::BasicEvent resolveError; + /// Fired when an error occures while resolving a service. + /// + /// The specific error condition can be found by looking at the + /// ServiceError object in the argument. + + Poco::BasicEvent serviceResolved; + /// Fired when a service has been successfully resolved. + + Poco::BasicEvent browseDomainFound; + /// Fired when a browse domain has been found. + + Poco::BasicEvent browseDomainRemoved; + /// Fired when a browse domain has been removed and is no longer available. + + Poco::BasicEvent browseDomainError; + /// Fired when an error occures while browsing for browse domains. + /// + /// The specific error condition can be found by looking at the + /// Error object in the argument. + + Poco::BasicEvent registrationDomainFound; + /// Fired when a registration domain has been found. + + Poco::BasicEvent registrationDomainRemoved; + /// Fired when a registration domain has been removed and is no longer available. + + Poco::BasicEvent registrationDomainError; + /// Fired when an error occures while browsing for registration domains. + /// + /// The specific error condition can be found by looking at the + /// Error object in the argument. + + Poco::BasicEvent recordFound; + /// Fired when a record has been found. + + Poco::BasicEvent recordRemoved; + /// Fired when a record has been removed and is no longer available. + + Poco::BasicEvent recordError; + /// Fired when an error occures while browsing for a record type. + /// + /// The specific error condition can be found by looking at the + /// Error object in the argument. + + Poco::BasicEvent hostResolved; + /// Fired when a host name has been resolved. + + Poco::BasicEvent hostResolveError; + /// Fired when an error occurs while resolving a host name. + /// + /// The specific error condition can be found by looking at the + /// Error object in the argument. + + virtual BrowseHandle browse(const std::string& regType, const std::string& domain, int options = 0, Poco::Int32 networkInterface = 0) = 0; + /// Browse for a service type on a specific network interface, given by its index in networkInterface. + /// An interface with index 0 can be specified to search on all interfaces. + /// + /// - regType specifies the service type and protocol, separated by a dot + /// (e.g., "_ftp._tcp"). The transport protocol must be either "_tcp" or "_udp". + /// Optionally, a single subtype may be specified to perform filtered browsing: + /// e.g. browsing for "_primarytype._tcp,_subtype" will discover only those + /// instances of "_primarytype._tcp" that were registered specifying "_subtype" + /// in their list of registered subtypes. + /// - domain specifies the domain on which to browse for services. + /// If an empty string is specified, the default domain(s) will be browsed. + /// - options should be 0, as no browse options are currently supported. + /// + /// Results will be reported asynchronously via the serviceFound, serviceRemoved and serviceError events. + /// + /// The returned BrowseHandle can be passed to cancel() to cancel browsing. + /// + /// Note: It is possible to enumerate all service types registered on the local network + /// by browsing for the special regType "_services._dns-sd._udp". Available service types will + /// be reported with the Service object's name containing the service type (e.g., "_ftp") + /// and the Service's type containing the protocol and domain (e.g., "_tcp.local."). + + virtual BrowseHandle resolve(const Service& service, int options = RESOLVE_ON_DISCOVERED_INTERFACE) = 0; + /// Resolves the service specified by the given Service object. The given + /// Service object must be one obtained via the serviceFound event. + /// + /// Results will be sent asnychronously via the serviceResolved and resolveError events. + /// + /// If RESOLVE_ON_ALL_INTERFACES is specified in options, resolving will be attempted + /// on all network interfaces. Otherwise, if RESOLVE_ON_DISCOVERED_INTERFACE is specified, + /// resolving will only be attempted on the interfaces on which the service has + /// been discovered. + /// + /// The returned BrowseHandle can be passed to cancel() to cancel resolving. + /// However, this should be done before either the serviceResolved or resolveError event + /// has been fired. In practice, this has high potential for a race condition, + /// so calling cancel() with a BrowseHandle returned from this function is + /// not recommended. + /// After either the serviceResolved or resolveError event has been + /// fired, the returned BrowseHandle is no longer valid. + + virtual BrowseHandle enumerateBrowseDomains(Poco::Int32 networkInterface = 0) = 0; + /// Discovers domains for browse operations on the given interface, given by its index. + /// An interface with index 0 can be specified to search on all interfaces. + /// + /// Results will be sent asnychronously via the browseDomainFound, browseDomainRemoved and browseDomainError events. + + virtual BrowseHandle enumerateRegistrationDomains(Poco::Int32 networkInterface = 0) = 0; + /// Discovers domains for service registration on the given interface, given by its index. + /// An interface with index 0 can be specified to search on all interfaces. + /// + /// Results will be sent asnychronously via the registrationDomainFound, registrationDomainRemoved and registrationDomainError events. + /// + /// The returned BrowseHandle can be passed to cancel() to cancel resolving. + + virtual BrowseHandle queryRecord(const std::string& name, Poco::UInt16 type, Poco::UInt16 clazz = Record::RC_IN, int options = 0, Poco::Int32 networkInterface = 0) = 0; + /// Starts a query for a DNS record, specified by name, type and clazz, on the specified interface, given by its index. + /// An interface with index 0 can be specified to search on all interfaces. + /// + /// - name specifies the full domain name of the record. + /// - type specifies the record's type (e.g., RT_PTR). + /// Suitable values can be found in the RecordType enumeration. + /// - clazz specifies the record's class (usually RC_IN). + /// - options can be 0, BROWSE_FORCE_MULTICAST or BROWSE_LONG_LIVED_QUERY. + /// + /// Results will be sent asnychronously via the recordFound, recordRemoved and recordError events. + /// + /// The returned BrowseHandle can be passed to cancel() to cancel the query. + + virtual BrowseHandle resolveHost(const std::string& host, int options = 0, Poco::Int32 networkInterface = 0) = 0; + /// Resolves the given host name. The given host name should have + /// been obtained by resolving a service. + /// An interface with index 0 can be specified to search on all interfaces. + /// + /// - host specifies the hostname to resolve. It should be a hostname + /// obtained by resolving a service. + /// - options can be 0 or BROWSE_FORCE_MULTICAST. + /// + /// This should be used instead of Poco::Net::DNS to resolve host names + /// via Multicast DNS, if the system's domain name resolver does not + /// support Multicast DNS. + /// + /// Results will be sent asnychronously via the hostResolved and hostResolveError events. + /// + /// The returned BrowseHandle can be passed to cancel() to cancel resolving. + /// However, this should be done before either the hostResolved or hostResolveError event + /// has been fired. In practice, this has high potential for a race condition, + /// so calling cancel() with a BrowseHandle returned from this function is + /// not recommended. + /// After either the hostResolved or hostResolveError event has been + /// fired, the returned BrowseHandle is no longer valid. + + virtual void cancel(BrowseHandle& browseHandle) = 0; + /// Cancels the browse or resolve activity associated with the given BrowseHandle. + /// + /// The BrowseHandle is invalidated. + +protected: + DNSSDBrowser(); + virtual ~DNSSDBrowser(); + +private: + DNSSDBrowser(const DNSSDBrowser&); + DNSSDBrowser& operator = (const DNSSDBrowser&); +}; + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_DNSSDBrowser_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/DNSSDException.h b/DNSSD/include/Poco/DNSSD/DNSSDException.h new file mode 100644 index 000000000..e659c9239 --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/DNSSDException.h @@ -0,0 +1,37 @@ +// +// DNSSDException.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/DNSSDException.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSSDException +// +// Definition of the DNSSDException class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_DNSSDException_INCLUDED +#define DNSSD_DNSSDException_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" +#include "Poco/Exception.h" + + +namespace Poco { +namespace DNSSD { + + +POCO_DECLARE_EXCEPTION(DNSSD_API, DNSSDException, Poco::RuntimeException) + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_DNSSDException_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/DNSSDResponder.h b/DNSSD/include/Poco/DNSSD/DNSSDResponder.h new file mode 100644 index 000000000..1c25023c1 --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/DNSSDResponder.h @@ -0,0 +1,193 @@ +// +// DNSSDResponder.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/DNSSDResponder.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSSDResponder +// +// Definition of the DNSSDResponder class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_DNSSDResponder_INCLUDED +#define DNSSD_DNSSDResponder_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" +#include "Poco/DNSSD/Service.h" +#include "Poco/DNSSD/Record.h" +#include "Poco/DNSSD/Error.h" +#include "Poco/BasicEvent.h" + + +namespace Poco { +namespace DNSSD { + + +class DNSSDBrowser; +class DNSSDResponderImpl; +class DNSSDResponderImplFactory; + + +class DNSSD_API DNSSDResponder + /// DNSSDResponder provides a unified interface to the underlying + /// DNS Service Discovery implementation, which can be Apple's Bonjour + /// or Avahi. + /// + /// An application should not create more than one instance of + /// the DNSSDResponder class. + /// + /// To register a service with the DNSSDResponder, and thus to + /// announce a service on the network, create an instance + /// of Service with appropriate values. Then pass this object + /// to registerService(). Example: + /// + /// DNSSDResponder dnssdResponder; + /// dnssdResponder.start(): + /// ... + /// Service::Properties props; + /// Service myService(0, "My Service", "_mysvc._tcp", "", "", 1234, props); + /// ServiceHandle myServiceHandle = dnssdResponder.registerService(myService); + /// + /// Note that service registration is asynchronous, so the serviceRegistered + /// and serviceRegistrationFailed events must be observed to ensure the + /// service has actually been registered. + /// + /// A registered service can be unregistered, by passing its ServiceHandle + /// to unregisterService(). + /// + /// Before a DNSSDResponder instance can be created, registerImplFactory() must + /// be called to register a DNSSDResponderImplFactory. This is done by + /// calling the initializeDNSSD() function provided by an implementation library + /// (e.g., Bonjour or Avahi). +{ +public: + enum RegistrationOptions + /// Options for service registration. + { + REG_LOCAL_ONLY = 0x01, /// Service is visible on local host only. + REG_NO_AUTORENAME = 0x02, /// Do not allow automatic renaming in case another service with the same name exists. + REG_NON_BROWSABLE = 0x04 /// Service is not visible when browsing, but can be resolved (only for DNSSD version < 1096.0.2). + }; + + struct ServiceEventArgs + { + ServiceEventArgs(ServiceHandle h, const Service& s): + serviceHandle(h), + service(s) + { + } + + ServiceHandle serviceHandle; + const Service& service; + }; + + struct ErrorEventArgs + { + ErrorEventArgs(ServiceHandle h, const Service& s, const Error& e): + serviceHandle(h), + service(s), + error(e) + { + } + + ServiceHandle serviceHandle; + const Service& service; + const Error& error; + }; + + Poco::BasicEvent serviceRegistered; + /// Fired after the service has been registered successfully. + /// + /// If auto-rename has been enabled, the service name may be different from the + /// name originally specified. + + Poco::BasicEvent serviceRegistrationFailed; + /// Fired when service registration fails. + + DNSSDResponder(); + /// Creates a DNSSDResponder. + + ~DNSSDResponder(); + /// Destroys the DNSSDResponder. + + DNSSDBrowser& browser(); + /// Returns the DNSServiceBrowser, which is used to + /// discover and resolve services and domains. + + ServiceHandle registerService(const Service& service, int options = 0); + /// Registers a service, specified by the given Service object. + /// + /// Valid option values are defined in the RegistrationOptions enumeration. + /// + /// Service registration will be asynchronously. When the service + /// has been registered successfully, a serviceRegistered event + /// will be fired. Otherwise, a ServiceRegistrationFailed event + /// will be fired. + /// + /// Returns a ServiceHandle that can later be used to unregister + /// the service, or to add DNS records to the service. + + void unregisterService(ServiceHandle& serviceHandle); + /// Unregisters the service specified by serviceHandle. + /// + /// The ServiceHandle is invalidated. + + RecordHandle addRecord(ServiceHandle serviceHandle, const Record& record); + /// Add a record to a registered service. The name of the record will be the same as the + /// registered service's name. + /// + /// The record can later be updated or deregistered by passing the RecordHandle returned + /// by this function to updateRecord() or removeRecord(). + + void updateRecord(ServiceHandle serviceHandle, RecordHandle recordHandle, const Record& record); + /// Update a registered resource record. The record must either be: + /// - the primary txt record of a service registered via registerService() + /// (if recordHandle is a null handle), or + /// - a record added to a registered service via addRecord(). + + void removeRecord(ServiceHandle serviceHandle, RecordHandle& recordHandle); + /// Remove a registered resource record. The record must be + /// a record added to a registered service via addRecord(). + /// + /// The RecordHandle is invalidated. + + void start(); + /// Starts the responder. + /// + /// Must be called before services can be registered + /// or before browsing for domains and services. + + void stop(); + /// Stops the responder. + + static void registerImplFactory(DNSSDResponderImplFactory& factory); + /// Registers the factory for creating DNSSDResponderImpl objects. + /// + /// A factory must be registered before the first instance of + /// DNSSDResponder is created. + + static void unregisterImplFactory(); + /// Unregisters the currently registered DNSSDResponderImplFactory. + +private: + DNSSDResponder(const DNSSDResponder&); + DNSSDResponder& operator = (const DNSSDResponder&); + + DNSSDResponderImpl* _pImpl; + + static DNSSDResponderImplFactory* _pImplFactory; +}; + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_DNSSDResponder_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/DNSSDResponderImpl.h b/DNSSD/include/Poco/DNSSD/DNSSDResponderImpl.h new file mode 100644 index 000000000..982f2cd7f --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/DNSSDResponderImpl.h @@ -0,0 +1,119 @@ +// +// DNSSDResponderImpl.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/DNSSDResponderImpl.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSSDResponderImpl +// +// Definition of the DNSSDResponderImpl class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_DNSSDResponderImpl_INCLUDED +#define DNSSD_DNSSDResponderImpl_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" + + +namespace Poco { +namespace DNSSD { + + +class DNSSDBrowser; +class DNSSDResponder; +class Service; +class Record; + + +class DNSSD_API DNSSDResponderImpl + /// DNSSDResponderImpl subclasses implement the actual binding + /// to the underlying DNSSD engine (e.g., Bonjour or Avahi). +{ +public: + virtual ~DNSSDResponderImpl(); + /// Destroys the DNSSDResponderImpl. + + virtual DNSSDBrowser& browser() = 0; + /// Returns the DNSSDBrowser, which is used to + /// discover and resolve services and domains. + + virtual ServiceHandle registerService(const Service& service, int options) = 0; + /// Registers a service. + /// + /// Service registration will be asynchronously. When the service + /// has been registered successfully, a serviceRegistered event + /// will be fired. Otherwise, a ServiceRegistrationFailed event + /// will be fired. + /// + /// Returns a ServiceHandle that can later be used to unregister + /// the service, or to add DNS records to the service. + + virtual void unregisterService(ServiceHandle& serviceHandle) = 0; + /// Unregisters the service specified by serviceHandle. + /// + /// The ServiceHandle is invalidated. + + virtual RecordHandle addRecord(ServiceHandle serviceHandle, const Record& record) = 0; + /// Add a record to a registered service. The name of the record will be the same as the + /// registered service's name. + /// + /// The record can later be updated or deregistered by passing the RecordHandle returned + /// by this function to updateRecord() or removeRecord(). + + virtual void updateRecord(ServiceHandle serviceHandle, RecordHandle recordHandle, const Record& record) = 0; + /// Update a registered resource record. The record must either be: + /// - the primary txt record of a service registered via registerService() + /// (if recordHandle is a null handle), or + /// - a record added to a registered service via addRecord(). + + virtual void removeRecord(ServiceHandle serviceHandle, RecordHandle& recordHandle) = 0; + /// Remove a registered resource record. The record must either be: + /// a record added to a registered service via addRecord(). + /// + /// The RecordHandle is invalidated. + + virtual void start() = 0; + /// Starts the responder. + /// + /// Must be called before services can be registered + /// or before browsing for domains and services. + + virtual void stop() = 0; + /// Stops the responder. + +protected: + DNSSDResponderImpl(); + +private: + DNSSDResponderImpl(const DNSSDResponderImpl&); + DNSSDResponderImpl& operator = (const DNSSDResponderImpl&); +}; + + +class DNSSD_API DNSSDResponderImplFactory + /// A factory for DNSSDResponderImpl objects. + /// + /// A subclass of this class must be provided by DNSSD + /// implementations and registered with the DNSSDResponder class. +{ +public: + virtual DNSSDResponderImpl* createResponderImpl(DNSSDResponder& owner) = 0; + /// Creates a new DNSSDResponderImpl. + +protected: + virtual ~DNSSDResponderImplFactory(); +}; + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_DNSSDResponderImpl_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/Domain.h b/DNSSD/include/Poco/DNSSD/Domain.h new file mode 100644 index 000000000..5087c290d --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/Domain.h @@ -0,0 +1,87 @@ +// +// Domain.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/Domain.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: Domain +// +// Definition of the Domain class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Domain_INCLUDED +#define DNSSD_Domain_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" + + +namespace Poco { +namespace DNSSD { + + +class DNSSD_API Domain + /// Domain stores information about a browse domain. +{ +public: + Domain(); + /// Creates an empty Domain. + + Domain(Poco::Int32 networkInterface, const std::string& name, bool isDefault); + /// Creates a Domain using the given information. + /// + /// - networkInterface specifies the index of the interface the domain was discovered on. + /// - name specifies the name of the domain. + /// - isDefault specifies whether the domain is the default domain. + + ~Domain(); + /// Destroys the Domain. + + Poco::Int32 networkInterface() const; + /// Returns the index of the network interface the domain was discovered on. + + const std::string& name() const; + /// Returns the name of the domain. + + bool isDefault() const; + /// Returns true if the domain is the default domain. + +private: + Poco::Int32 _networkInterface; + std::string _name; + bool _isDefault; +}; + + +// +// inlines +// +inline Poco::Int32 Domain::networkInterface() const +{ + return _networkInterface; +} + + +inline const std::string& Domain::name() const +{ + return _name; +} + + +inline bool Domain::isDefault() const +{ + return _isDefault; +} + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_Domain_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/Error.h b/DNSSD/include/Poco/DNSSD/Error.h new file mode 100644 index 000000000..0033877be --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/Error.h @@ -0,0 +1,89 @@ +// +// Error.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/Error.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: Error +// +// Definition of the Error class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Error_INCLUDED +#define DNSSD_Error_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" + + +namespace Poco { +namespace DNSSD { + + +class DNSSD_API Error + /// Error stores information about an error + /// that occured during browsing or service + /// registration. +{ +public: + Error(); + /// Creates an uninitialized ServiceError. + + Error(Poco::Int32 networkInterface, Poco::Int32 code, const std::string& message); + /// Creates the ServiceError using the given information. + /// + /// - networkInterface specifies the index of the interface the error occured on. + /// - code contains the implementation-specific error code. + /// - message contains a human-readable error message. + + ~Error(); + /// Destroys the ServiceError. + + Poco::Int32 networkInterface() const; + /// Returns the network interface on which the error occurred. + + Poco::Int32 code() const; + /// Returns the implementation-specific error code. + + const std::string& message() const; + /// Returns the human-readable error message. + +private: + Poco::Int32 _networkInterface; + Poco::Int32 _code; + std::string _message; +}; + + +// +// inlines +// +inline Poco::Int32 Error::networkInterface() const +{ + return _networkInterface; +} + + +inline Poco::Int32 Error::code() const +{ + return _code; +} + + +inline const std::string& Error::message() const +{ + return _message; +} + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_Error_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/Record.h b/DNSSD/include/Poco/DNSSD/Record.h new file mode 100644 index 000000000..ede194c5e --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/Record.h @@ -0,0 +1,223 @@ +// +// Record.h +// +// $Id: //poco/1.7/DNSSD/include/Poco/DNSSD/Record.h#1 $ +// +// Library: DNSSD +// Package: Core +// Module: Record +// +// Definition of the Record class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Record_INCLUDED +#define DNSSD_Record_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" + + +namespace Poco { +namespace DNSSD { + + +class DNSSD_API Record + /// Service stores the information found in a DNSSD record. +{ +public: + enum RecordType + { + RT_A = 1, /// Host address. + RT_NS = 2, /// Authoritative server. + RT_MD = 3, /// Mail destination. + RT_MF = 4, /// Mail forwarder. + RT_CNAME = 5, /// Canonical name. + RT_SOA = 6, /// Start of authority zone. + RT_MB = 7, /// Mailbox domain name. + RT_MG = 8, /// Mail group member. + RT_MR = 9, /// Mail rename name. + RT_NULL = 10, /// Null resource record. + RT_WKS = 11, /// Well known service. + RT_PTR = 12, /// Domain name pointer. + RT_HINFO = 13, /// Host information. + RT_MINFO = 14, /// Mailbox information. + RT_MX = 15, /// Mail routing information. + RT_TXT = 16, /// One or more text strings (NOT "zero or more..."). + RT_RP = 17, /// Responsible person. + RT_AFSDB = 18, /// AFS cell database. + RT_X25 = 19, /// X_25 calling address. + RT_ISDN = 20, /// ISDN calling address. + RT_RT = 21, /// Router. + RT_NSAP = 22, /// NSAP address. + RT_NSAP_PTR = 23, /// Reverse NSAP lookup (deprecated). + RT_SIG = 24, /// Security signature. + RT_KEY = 25, /// Security key. + RT_PX = 26, /// X.400 mail mapping. + RT_GPOS = 27, /// Geographical position (withdrawn). + RT_AAAA = 28, /// IPv6 Address. + RT_LOC = 29, /// Location Information. + RT_NXT = 30, /// Next domain (security). + RT_EID = 31, /// Endpoint identifier. + RT_NIMLOC = 32, /// Nimrod Locator. + RT_SRV = 33, /// Server Selection. + RT_ATMA = 34, /// ATM Address + RT_NAPTR = 35, /// Naming Authority PoinTeR + RT_KX = 36, /// Key Exchange + RT_CERT = 37, /// Certification record + RT_A6 = 38, /// IPv6 Address (deprecated) + RT_DNAME = 39, /// Non-terminal DNAME (for IPv6) + RT_SINK = 40, /// Kitchen sink (experimental) + RT_OPT = 41, /// EDNS0 option (meta-RR) + RT_APL = 42, /// Address Prefix List + RT_DS = 43, /// Delegation Signer + RT_SSHFP = 44, /// SSH Key Fingerprint + RT_IPSECKEY = 45, /// IPSECKEY + RT_RRSIG = 46, /// RRSIG + RT_NSEC = 47, /// Denial of Existence + RT_DNSKEY = 48, /// DNSKEY + RT_DHCID = 49, /// DHCP Client Identifier + RT_NSEC3 = 50, /// Hashed Authenticated Denial of Existence + RT_NSEC3PARAM= 51, /// Hashed Authenticated Denial of Existence + RT_HIP = 55, /// Host Identity Protocol + + RT_SPF = 99, /// Sender Policy Framework for E-Mail + RT_UINFO = 100, /// IANA-Reserved + RT_UID = 101, /// IANA-Reserved + RT_GID = 102, /// IANA-Reserved + RT_UNSPEC = 103, /// IANA-Reserved + + RT_TKEY = 249, /// Transaction key + RT_TSIG = 250, /// Transaction signature. + RT_IXFR = 251, /// Incremental zone transfer. + RT_AXFR = 252, /// Transfer zone of authority. + RT_MAILB = 253, /// Transfer mailbox records. + RT_MAILA = 254, /// Transfer mail agent records. + RT_ANY = 255 /// Wildcard match. + }; + + enum RecordClass + { + RC_IN = 1 /// Internet + }; + + Record(); + /// Creates an empty Record. + + Record(Poco::Int32 networkInterface, const std::string& name, Poco::UInt16 type, Poco::UInt16 clazz, Poco::UInt16 length, const void* data, Poco::UInt32 ttl); + /// Creates the Record using the given information. + /// + /// - networkInterface specifies the index of the interface the record was discovered on. + /// - name specifies the full domain name of the record. + /// - type specifies the record's type (e.g., RT_PTR). + /// Suitable values can be found in the RecordType enumeration. + /// - clazz specifies the record's class (usually RC_IN). + /// - length specifies the length in bytes of the record's data. + /// - data points to the actual data. This pointer must be valid for the entire + /// lifetime of the Record object, as it's content is not copied. + /// - ttl specifies the time-to-live of the record in seconds. + + Record(const std::string& name, Poco::UInt16 type, Poco::UInt16 length, const void* data, Poco::UInt32 ttl = 0); + /// Creates the Record using the given information. + /// + /// - name specifies the full domain name of the record. + /// - type specifies the record's type (e.g., RT_PTR). + /// Suitable values can be found in the RecordType enumeration. + /// - length specifies the length in bytes of the record's data. + /// - data points to the actual data. This pointer must be valid for the entire + /// lifetime of the Record object, as it's content is not copied. + /// - ttl specifies the time-to-live of the record in seconds. + /// If ttl is 0, the system will chose an appropriate value. + /// + /// The record class is set to RT_IN. + + ~Record(); + /// Destroys the Service. + + Poco::Int32 networkInterface() const; + /// The id of the interface on which the remote service is running, or zero + /// if no interface has been specified. + + const std::string& name() const; + /// The full domain name of the record. + + Poco::UInt16 type() const; + /// The record's type (e.g., RT_PTR). + + Poco::UInt16 clazz() const; + /// The record's class, which is usually RC_IN. + + Poco::UInt16 length() const; + /// The length of the record. + + const void* data() const; + /// The actual data. + + Poco::UInt32 ttl() const; + /// The time-to-live for the record in seconds. + +private: + Poco::Int32 _networkInterface; + std::string _name; + Poco::UInt16 _type; + Poco::UInt16 _clazz; + Poco::UInt16 _length; + const void* _data; + Poco::UInt32 _ttl; +}; + + +// +// inlines +// +inline Poco::Int32 Record::networkInterface() const +{ + return _networkInterface; +} + + +inline const std::string& Record::name() const +{ + return _name; +} + + +inline Poco::UInt16 Record::type() const +{ + return _type; +} + + +inline Poco::UInt16 Record::clazz() const +{ + return _clazz; +} + + +inline Poco::UInt16 Record::length() const +{ + return _length; +} + + +inline const void* Record::data() const +{ + return _data; +} + + +inline Poco::UInt32 Record::ttl() const +{ + return _ttl; +} + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_Service_INCLUDED diff --git a/DNSSD/include/Poco/DNSSD/Service.h b/DNSSD/include/Poco/DNSSD/Service.h new file mode 100644 index 000000000..61435348b --- /dev/null +++ b/DNSSD/include/Poco/DNSSD/Service.h @@ -0,0 +1,247 @@ +// +// Service.h +// +// $Id$ +// +// Library: DNSSD +// Package: Core +// Module: Service +// +// Definition of the Service class. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef DNSSD_Service_INCLUDED +#define DNSSD_Service_INCLUDED + + +#include "Poco/DNSSD/DNSSD.h" +#include "Poco/Net/NameValueCollection.h" + + +namespace Poco { +namespace DNSSD { + + +class DNSSD_API Service + /// Service holds information for a registered or resolved service. +{ +public: + typedef Poco::Net::NameValueCollection Properties; + /// The Properties of a resolved service contains the + /// contents of the associated TXT record. + /// + /// The TXT record contains key-value pairs in + /// the form =. Each pair is preceded + /// by a length byte giving the total length + /// of the pair. Thus the total length of key + /// plus value must not exceed 254 bytes. + /// Keys are case insensitive and must consists + /// entirely of printable US-ASCII characters. + /// The length of a key should not exceed nine bytes, + /// to keep packet sizes small. Values can contain + /// arbitrary bytes. A value can also be empty; in + /// this case the '=' character can be omitted in + /// the record. + + Service(); + /// Creates an empty Service. + + Service(Poco::Int32 networkInterface, const std::string& name, const std::string& type, const std::string& domain); + /// Creates the Service using the given information. + /// + /// - networkInterface specifies the index of the interface the service was discovered on. + /// When registering a service, can be set to 0 to register the service on all + /// available interfaces. + /// - name specifies the human-readable service name. + /// When registering a service, can be left empty. In this case + /// the computer's name is used. Must be 1 - 63 bytes of UTF-8 text. + /// - type specifies the registration type of the service, consisting of service type + /// and network protocol (delimited by a dot, as in "_ftp._tcp"), + /// and an optional subtype (e.g., "_primarytype._tcp,_subtype"). + /// The protocol is always either "_tcp" or "_udp". + /// - domain specifies the name of the domain the service is registered on. + /// When registering a service, can be left empty to register in the default domain. + + Service(const std::string& type, Poco::UInt16 port, const Properties& properties = Properties()); + /// Creates the Service using the given information. This is the easiest way + /// to create a Service instance for registration. + /// + /// The service will be registered on all available network interfaces. The computer's name + /// will be used as the service name. The default domain is used, and the computer's host name + /// is used as host name for registering. + /// + /// - type specifies the registration type of the service, consisting of service type + /// and network protocol (delimited by a dot, as in "_ftp._tcp"), + /// and an optional subtype (e.g., "_primarytype._tcp,_subtype"). + /// The protocol is always either "_tcp" or "_udp". + /// - properties contains the contents of the service's TXT record. + + Service(Poco::Int32 networkInterface, const std::string& name, const std::string& fullName, const std::string& type, const std::string& domain, const std::string& host, Poco::UInt16 port); + /// Creates the Service using the given information. + /// + /// - networkInterface specifies the index of the interface the service was discovered on. + /// When registering a service, can be set to 0 to register the service on all + /// available interfaces. + /// - name specifies the human-readable service name. + /// When registering a service, can be left empty. In this case + /// the computer's name is used. Must be 1 - 63 bytes of UTF-8 text. + /// - fullName specifies the full service name in the form "...". + /// When registering a service, this should be left empty. + /// - type specifies the registration type of the service, consisting of service type + /// and network protocol (delimited by a dot, as in "_ftp._tcp"), + /// and an optional subtype (e.g., "_primarytype._tcp,_subtype"). + /// The protocol is always either "_tcp" or "_udp". + /// - domain specifies the name of the domain the service is registered on. + /// When registering a service, can be left empty to register in the default domain. + /// - host specifies the name of the host providing the service. + /// When registering a service, can be left empty to use the machine's default host name. + /// - port specifies the port number on which the service is available. + + Service(Poco::Int32 networkInterface, const std::string& name, const std::string& fullName, const std::string& type, const std::string& domain, const std::string& host, Poco::UInt16 port, const Properties& properties); + /// Creates the Service using the given information. + /// + /// - networkInterface specifies the index of the interface the service was discovered on. + /// When registering a service, can be set to 0 to register the service on all + /// available interfaces. + /// - name specifies the human-readable service name. + /// When registering a service, can be left empty. In this case + /// the computer's name is used. Must be 1 - 63 bytes of UTF-8 text. + /// - fullName specifies the full service name in the form "...". + /// When registering a service, this should be left empty. + /// - type specifies the registration type of the service, consisting of service type + /// and network protocol (delimited by a dot, as in "_ftp._tcp"), + /// and an optional subtype (e.g., "_primarytype._tcp,_subtype"). + /// The protocol is always either "_tcp" or "_udp". + /// - domain specifies the name of the domain the service is registered on. + /// When registering a service, can be left empty to register in the default domain. + /// - host specifies the name of the host providing the service. + /// When registering a service, can be left empty to use the machine's default host name. + /// - port specifies the port number on which the service is available. + /// - properties contains the contents of the service's TXT record. + + ~Service(); + /// Destroys the Service. + + Poco::Int32 networkInterface() const; + /// The id of the interface on which the remote service is running, or zero + /// if the service is available on all interfaces. + + const std::string& name() const; + /// The name of the service. + + const std::string& fullName() const; + /// Returns the full name of the service. + /// + /// The format of the full name is "...". + /// This name is escaped following standard DNS rules. + /// The full name will be empty for an unresolved service. + + const std::string& type() const; + /// The registration type of the service, consisting of service type + /// and network protocol (delimited by a dot, as in "_ftp._tcp"), + /// and an optional subtype (e.g., "_primarytype._tcp,_subtype"). + /// + /// The protocol is always either "_tcp" or "_udp". + + const std::string& domain() const; + /// The domain the service is registered on. + + const std::string& host() const; + /// Returns the host name of the host providing the service. + /// + /// Will be empty for an unresolved service. + + Poco::UInt16 port() const; + /// Returns the port number on which the service is available. + /// + /// Will be 0 for an unresolved service. + + const Properties& properties() const; + /// Returns the contents of the TXT record associated with the service. + /// + /// Will be empty for an unresolved service. + + Properties& properties(); + /// Returns the contents of the TXT record associated with the service. + /// + /// Will be empty for an unresolved service. + +private: + Poco::Int32 _networkInterface; + std::string _name; + std::string _fullName; + std::string _type; + std::string _domain; + std::string _host; + Poco::UInt16 _port; + Properties _properties; +}; + + +// +// inlines +// +inline Poco::Int32 Service::networkInterface() const +{ + return _networkInterface; +} + + +inline const std::string& Service::name() const +{ + return _name; +} + + +inline const std::string& Service::fullName() const +{ + return _fullName; +} + + +inline const std::string& Service::type() const +{ + return _type; +} + + +inline const std::string& Service::domain() const +{ + return _domain; +} + + +inline const std::string& Service::host() const +{ + return _host; +} + + +inline Poco::UInt16 Service::port() const +{ + return _port; +} + + +inline const Service::Properties& Service::properties() const +{ + return _properties; +} + + +inline Service::Properties& Service::properties() +{ + return _properties; +} + + +} } // namespace Poco::DNSSD + + +#endif // DNSSD_Service_INCLUDED diff --git a/DNSSD/samples/CMakeLists.txt b/DNSSD/samples/CMakeLists.txt new file mode 100644 index 000000000..790d90078 --- /dev/null +++ b/DNSSD/samples/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(DNSSDBrowser) +add_subdirectory(HTTPTimeServer) diff --git a/DNSSD/samples/DNSSDBrowser/CMakeLists.txt b/DNSSD/samples/DNSSDBrowser/CMakeLists.txt new file mode 100644 index 000000000..0970f51ae --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/CMakeLists.txt @@ -0,0 +1,7 @@ +set(SAMPLE_NAME "DNSSDBrowser") + +set(LOCAL_SRCS "") +aux_source_directory(src LOCAL_SRCS) + +add_executable( ${SAMPLE_NAME} ${LOCAL_SRCS} ) +target_link_libraries( ${SAMPLE_NAME} Foundation Net Util XML DNSSD ${DNSSD_IMPLEMENTATION_LIBRARY} ) diff --git a/DNSSD/samples/DNSSDBrowser/DNSSDBrowser.progen b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser.progen new file mode 100644 index 000000000..1375cd8e3 --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser.progen @@ -0,0 +1,13 @@ +vc.project.guid = ${vc.project.guidFromName} +vc.project.name = ${vc.project.baseName} +vc.project.target = ${vc.project.name} +vc.project.type = executable +vc.project.pocobase = ..\\..\\.. +vc.project.platforms = Win32, x64, WinCE +vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md +vc.project.prototype = ${vc.project.name}_vs90.vcproj +vc.project.compiler.include = ..\\..\\..\\Foundation\\include;..\\..\\..\\XML\\include;..\\..\\..\\Util\\include;..\\..\\..\\Net\\include;..\\..\\..\\DNSSD\\include;..\\..\\..\\DNSSD\\Bonjour\\include +vc.project.linker.dependencies = dnssd.lib +vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.x64 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.WinCE = ws2.lib iphlpapi.lib diff --git a/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj new file mode 100644 index 000000000..76ab8cce0 --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj @@ -0,0 +1,646 @@ + + + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + DNSSDBrowser + {36D5972E-D503-3863-AFC5-8740752A3A8F} + DNSSDBrowser + Win32Proj + + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowser + DNSSDBrowser + DNSSDBrowser + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowser + DNSSDBrowser + DNSSDBrowser + + + bin\ + obj\DNSSDBrowser\$(Configuration)\ + true + + + bin\ + obj\DNSSDBrowser\$(Configuration)\ + false + + + bin\static_mt\ + obj\DNSSDBrowser\$(Configuration)\ + true + + + bin\static_mt\ + obj\DNSSDBrowser\$(Configuration)\ + false + + + bin\static_md\ + obj\DNSSDBrowser\$(Configuration)\ + true + + + bin\static_md\ + obj\DNSSDBrowser\$(Configuration)\ + false + + + bin64\ + obj64\DNSSDBrowser\$(Configuration)\ + true + + + bin64\ + obj64\DNSSDBrowser\$(Configuration)\ + false + + + bin64\static_mt\ + obj64\DNSSDBrowser\$(Configuration)\ + true + + + bin64\static_mt\ + obj64\DNSSDBrowser\$(Configuration)\ + false + + + bin64\static_md\ + obj64\DNSSDBrowser\$(Configuration)\ + true + + + bin64\static_md\ + obj64\DNSSDBrowser\$(Configuration)\ + false + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\DNSSDBrowserd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\DNSSDBrowser.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\DNSSDBrowserd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\DNSSDBrowser.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\DNSSDBrowserd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\DNSSDBrowser.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\DNSSDBrowserd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\DNSSDBrowser.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\DNSSDBrowserd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\DNSSDBrowser.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\DNSSDBrowserd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\DNSSDBrowser.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj.filters b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj.filters new file mode 100644 index 000000000..712d84321 --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs160.vcxproj.filters @@ -0,0 +1,13 @@ + + + + + {9c9e8a3d-2ef3-43c9-8fd2-96e940dea679} + + + + + Source Files + + + \ No newline at end of file diff --git a/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj new file mode 100644 index 000000000..b0b0c4287 --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj @@ -0,0 +1,955 @@ + + + + + debug_shared + ARM64 + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + ARM64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + ARM64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + ARM64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + ARM64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + ARM64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + DNSSDBrowser + {36D5972E-D503-3863-AFC5-8740752A3A8F} + DNSSDBrowser + Win32Proj + + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowser + DNSSDBrowser + DNSSDBrowser + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowser + DNSSDBrowser + DNSSDBrowser + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowserd + DNSSDBrowser + DNSSDBrowser + DNSSDBrowser + + + binA64\ + objA64\DNSSDBrowser\$(Configuration)\ + true + + + binA64\ + objA64\DNSSDBrowser\$(Configuration)\ + false + + + binA64\static_mt\ + objA64\DNSSDBrowser\$(Configuration)\ + true + + + binA64\static_mt\ + objA64\DNSSDBrowser\$(Configuration)\ + false + + + binA64\static_md\ + objA64\DNSSDBrowser\$(Configuration)\ + true + + + binA64\static_md\ + objA64\DNSSDBrowser\$(Configuration)\ + false + + + bin\ + obj\DNSSDBrowser\$(Configuration)\ + true + + + bin\ + obj\DNSSDBrowser\$(Configuration)\ + false + + + bin\static_mt\ + obj\DNSSDBrowser\$(Configuration)\ + true + + + bin\static_mt\ + obj\DNSSDBrowser\$(Configuration)\ + false + + + bin\static_md\ + obj\DNSSDBrowser\$(Configuration)\ + true + + + bin\static_md\ + obj\DNSSDBrowser\$(Configuration)\ + false + + + bin64\ + obj64\DNSSDBrowser\$(Configuration)\ + true + + + bin64\ + obj64\DNSSDBrowser\$(Configuration)\ + false + + + bin64\static_mt\ + obj64\DNSSDBrowser\$(Configuration)\ + true + + + bin64\static_mt\ + obj64\DNSSDBrowser\$(Configuration)\ + false + + + bin64\static_md\ + obj64\DNSSDBrowser\$(Configuration)\ + true + + + bin64\static_md\ + obj64\DNSSDBrowser\$(Configuration)\ + false + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\DNSSDBrowser.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\DNSSDBrowserd.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\DNSSDBrowser.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_md\DNSSDBrowserd.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\DNSSDBrowserd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\DNSSDBrowser.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\DNSSDBrowserd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\DNSSDBrowser.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\DNSSDBrowserd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\DNSSDBrowser.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\DNSSDBrowserd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\DNSSDBrowser.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\DNSSDBrowserd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\DNSSDBrowser.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\DNSSDBrowserd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\DNSSDBrowser.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj.filters b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj.filters new file mode 100644 index 000000000..89378db0a --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs170.vcxproj.filters @@ -0,0 +1,13 @@ + + + + + {2bbee48a-22d9-405c-9f0d-cb65b4fa8c5e} + + + + + Source Files + + + \ No newline at end of file diff --git a/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs90.vcproj b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs90.vcproj new file mode 100644 index 000000000..2615db21d --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/DNSSDBrowser_vs90.vcproj @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DNSSD/samples/DNSSDBrowser/Makefile b/DNSSD/samples/DNSSDBrowser/Makefile new file mode 100644 index 000000000..a5d2fc882 --- /dev/null +++ b/DNSSD/samples/DNSSDBrowser/Makefile @@ -0,0 +1,23 @@ +# +# Makefile +# +# $Id: //poco/1.7/DNSSD/samples/DNSSDBrowser/Makefile#1 $ +# +# Makefile for DNSSDBrowser sample +# + +include $(POCO_BASE)/build/rules/global + +ifeq ($(OSNAME),Linux) +DNSSDLibrary = PocoDNSSDAvahi +else +DNSSDLibrary = PocoDNSSDBonjour +endif + +objects = DNSSDBrowser + +target = DNSSDBrowser +target_version = 1 +target_libs = $(DNSSDLibrary) PocoDNSSD PocoNet PocoUtil PocoXML PocoFoundation + +include $(POCO_BASE)/build/rules/exec diff --git a/DNSSD/samples/DNSSDBrowser/bin/Darwin/x86_64/DNSSDBrowser b/DNSSD/samples/DNSSDBrowser/bin/Darwin/x86_64/DNSSDBrowser new file mode 100755 index 0000000000000000000000000000000000000000..24c52135e5f45356aa75e6dce9be1dc676f9f827 GIT binary patch literal 85712 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 +#include + + +using Poco::Util::Application; +using Poco::Util::ServerApplication; +using Poco::Util::Option; +using Poco::Util::OptionSet; +using Poco::Util::OptionCallback; +using Poco::Util::HelpFormatter; +using Poco::DNSSD::DNSSDResponder; +using Poco::DNSSD::Service; +using Poco::DNSSD::BrowseHandle; +using Poco::DNSSD::ServiceHandle; + + +class DNSSDBrowserApp: public ServerApplication +{ +public: + DNSSDBrowserApp(): + _helpRequested(false), + _autoResolve(false), + _enumerateDomains(false), + _port(0), + _interface(0) + { + Poco::DNSSD::initializeDNSSD(); + } + + ~DNSSDBrowserApp() + { + Poco::DNSSD::uninitializeDNSSD(); + } + +protected: + void initialize(Application& self) + { + loadConfiguration(); // load default configuration files, if present + ServerApplication::initialize(self); + } + + void uninitialize() + { + ServerApplication::uninitialize(); + } + + void defineOptions(OptionSet& options) + { + ServerApplication::defineOptions(options); + + options.addOption( + Option("help", "h", "Display help information on command line arguments.") + .required(false) + .repeatable(false) + .callback(OptionCallback(this, &DNSSDBrowserApp::handleHelp))); + + options.addOption( + Option("browse", "b", + "Browse for services with the type given in the argument (e.g., _ftp._tcp). " + "Can be specified multiple times to browse for different types of services.") + .required(false) + .repeatable(true) + .argument("") + .callback(OptionCallback(this, &DNSSDBrowserApp::handleBrowse))); + + options.addOption( + Option("resolve", "r", + "Automatically resolve all discovered services.") + .required(false) + .repeatable(false) + .callback(OptionCallback(this, &DNSSDBrowserApp::handleResolve))); + + options.addOption( + Option("domain", "d", + "Specify the domain to browse, or register a service in. " + "If not specified, the default domain will be used.") + .required(false) + .repeatable(false) + .argument("") + .callback(OptionCallback(this, &DNSSDBrowserApp::handleDomain))); + + options.addOption( + Option("enumerate-domains", "e", "Enumerate browse- and registration-domains.") + .required(false) + .repeatable(false) + .callback(OptionCallback(this, &DNSSDBrowserApp::handleEnumerate))); + + options.addOption( + Option("register", "R", + "Register a service with the given type (e.g., _ftp._tcp).") + .required(false) + .repeatable(false) + .argument("") + .callback(OptionCallback(this, &DNSSDBrowserApp::handleRegister))); + + options.addOption( + Option("name", "n", + "Specify the service name for the service to be registered. " + "If not specified, the name of the machine will be used.") + .required(false) + .repeatable(false) + .argument("") + .callback(OptionCallback(this, &DNSSDBrowserApp::handleName))); + + options.addOption( + Option("host", "H", + "Specify the host name for the service to be registered. " + "If not specified, the machine's host name will be used.") + .required(false) + .repeatable(false) + .argument("") + .callback(OptionCallback(this, &DNSSDBrowserApp::handleHost))); + + options.addOption( + Option("port", "p", + "Specify the port number for the service to be registered. " + "If not specified, the service will be registered with port 0.") + .required(false) + .repeatable(false) + .argument("") + .validator(new Poco::Util::IntValidator(0, 65535)) + .callback(OptionCallback(this, &DNSSDBrowserApp::handlePort))); + + options.addOption( + Option("txt", "t", + "Specify a key-value pair for a registered service's TXT record. " + "Can be given multiple times.") + .required(false) + .repeatable(true) + .argument("<[=value]>") + .callback(OptionCallback(this, &DNSSDBrowserApp::handleTXT))); + + options.addOption( + Option("interface", "i", + "Specify a specific network interface for browsing and registration, by its " + "interface index. Specify 0 to browse/register on all interfaces (default).") + .required(false) + .repeatable(false) + .argument("") + .validator(new Poco::Util::IntValidator(0, 16)) + .callback(OptionCallback(this, &DNSSDBrowserApp::handleInterface))); + } + + void handleHelp(const std::string& name, const std::string& value) + { + _helpRequested = true; + stopOptionsProcessing(); + } + + void handleBrowse(const std::string& name, const std::string& value) + { + _browseTypes.insert(value); + } + + void handleResolve(const std::string& name, const std::string& value) + { + _autoResolve = true; + } + + void handleDomain(const std::string& name, const std::string& value) + { + _domain = value; + } + + void handleEnumerate(const std::string& name, const std::string& value) + { + _enumerateDomains = true; + } + + void handleRegister(const std::string& name, const std::string& value) + { + _registeredService = value; + } + + void handleName(const std::string& name, const std::string& value) + { + _name = value; + } + + void handleHost(const std::string& name, const std::string& value) + { + _host = value; + } + + void handlePort(const std::string& name, const std::string& value) + { + _port = static_cast(Poco::NumberParser::parseUnsigned(value)); + } + + void handleTXT(const std::string& name, const std::string& value) + { + std::string::size_type pos = value.find('='); + if (pos != std::string::npos) + { + _properties.add(value.substr(0, pos), value.substr(pos + 1)); + } + else + { + _properties.add(value, ""); + } + } + + void handleInterface(const std::string& name, const std::string& value) + { + _interface = Poco::NumberParser::parse(value); + } + + void displayHelp() + { + HelpFormatter helpFormatter(options()); + helpFormatter.setCommand(commandName()); + helpFormatter.setUsage("OPTIONS"); + helpFormatter.setHeader( + "\n" + "A sample application demonstrating the use of the DNSSDBrowser and DNSSDResponder classes. " + "The following command line options are supported:"); + helpFormatter.setFooter( + "For more information, please see the Applied Informatics C++ Libraries " + "and Tools documentation at ." + ); + helpFormatter.setIndent(8); + helpFormatter.format(std::cout); + } + + void onError(const void* sender, const Poco::DNSSD::DNSSDBrowser::ErrorEventArgs& args) + { + std::cout << args.error.message() << " (" << args.error.code() << ")" << std::endl; + } + + void onServiceFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args) + { + std::cout << "Service Found: \n" + << " Name: " << args.service.name() << "\n" + << " Domain: " << args.service.domain() << "\n" + << " Type: " << args.service.type() << "\n" + << " Interface: " << args.service.networkInterface() << "\n" << std::endl; + + if (_autoResolve) + { + reinterpret_cast(const_cast(sender))->resolve(args.service); + } + } + + void onServiceRemoved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args) + { + std::cout << "Service Removed: \n" + << " Name: " << args.service.name() << "\n" + << " Domain: " << args.service.domain() << "\n" + << " Type: " << args.service.type() << "\n" + << " Interface: " << args.service.networkInterface() << "\n" << std::endl; + } + + void onServiceResolved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ServiceEventArgs& args) + { + std::cout << "Service Resolved: \n" + << " Name: " << args.service.name() << "\n" + << " Full Name: " << args.service.fullName() << "\n" + << " Domain: " << args.service.domain() << "\n" + << " Type: " << args.service.type() << "\n" + << " Interface: " << args.service.networkInterface() << "\n" + << " Host: " << args.service.host() << "\n" + << " Port: " << args.service.port() << "\n" + << " Properties: \n"; + + for (Poco::DNSSD::Service::Properties::ConstIterator it = args.service.properties().begin(); it != args.service.properties().end(); ++it) + { + std::cout << " " << it->first << ": " << it->second << "\n"; + } + std::cout << std::endl; + + reinterpret_cast(const_cast(sender))->resolveHost(args.service.host()); + } + + void onHostResolved(const void* sender, const Poco::DNSSD::DNSSDBrowser::ResolveHostEventArgs& args) + { + std::cout << "Host Resolved: \n" + << " Host: " << args.host << "\n" + << " Interface: " << args.networkInterface << "\n" + << " Address: " << args.address.toString() << "\n" + << " TTL: " << args.ttl << "\n" << std::endl; + } + + void onBrowseDomainFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args) + { + std::cout << "Browse Domain Found:\n" + << " Name: " << args.domain.name() << "\n" + << " Interface: " << args.domain.networkInterface() << "\n" + << " Default: " << args.domain.isDefault() << "\n" << std::endl; + } + + void onBrowseDomainRemoved(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args) + { + std::cout << "Browse Domain Removed:\n" + << " Name: " << args.domain.name() << "\n" + << " Interface: " << args.domain.networkInterface() << "\n" + << " Default: " << args.domain.isDefault() << "\n" << std::endl; + } + + void onRegistrationDomainFound(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args) + { + std::cout << "Registration Domain Found:\n" + << " Name: " << args.domain.name() << "\n" + << " Interface: " << args.domain.networkInterface() << "\n" + << " Default: " << args.domain.isDefault() << "\n" << std::endl; + } + + void onRegistrationDomainRemoved(const void* sender, const Poco::DNSSD::DNSSDBrowser::DomainEventArgs& args) + { + std::cout << "Registration Domain Removed:\n" + << " Name: " << args.domain.name() << "\n" + << " Interface: " << args.domain.networkInterface() << "\n" + << " Default: " << args.domain.isDefault() << "\n" << std::endl; + } + + int main(const std::vector& args) + { + if (_helpRequested || (_browseTypes.empty() && _registeredService.empty() && !_enumerateDomains)) + { + displayHelp(); + } + else + { + DNSSDResponder dnssdResponder; + + dnssdResponder.browser().browseError += Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().resolveError += Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().serviceFound += Poco::delegate(this, &DNSSDBrowserApp::onServiceFound); + dnssdResponder.browser().serviceRemoved += Poco::delegate(this, &DNSSDBrowserApp::onServiceRemoved); + dnssdResponder.browser().serviceResolved += Poco::delegate(this, &DNSSDBrowserApp::onServiceResolved); + dnssdResponder.browser().browseDomainError += Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().browseDomainFound += Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainFound); + dnssdResponder.browser().browseDomainRemoved += Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainRemoved); + dnssdResponder.browser().registrationDomainError += Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().registrationDomainFound += Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainFound); + dnssdResponder.browser().registrationDomainRemoved += Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainRemoved); + dnssdResponder.browser().hostResolveError += Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().hostResolved += Poco::delegate(this, &DNSSDBrowserApp::onHostResolved); + + std::vector browseHandles; + for (std::set::const_iterator it = _browseTypes.begin(); it != _browseTypes.end(); ++it) + { + browseHandles.push_back(dnssdResponder.browser().browse(*it, _domain, 0, _interface)); + } + + if (_enumerateDomains) + { + browseHandles.push_back(dnssdResponder.browser().enumerateBrowseDomains(_interface)); + browseHandles.push_back(dnssdResponder.browser().enumerateRegistrationDomains(_interface)); + } + + ServiceHandle serviceHandle; + if (!_registeredService.empty()) + { + Service service(_interface, _name, "", _registeredService, _domain, _host, _port, _properties); + serviceHandle = dnssdResponder.registerService(service); + } + + dnssdResponder.start(); + waitForTerminationRequest(); + + if (serviceHandle.isValid()) + { + dnssdResponder.unregisterService(serviceHandle); + Poco::Thread::sleep(2500); // allow time for delivery of remove event + } + + for (std::vector::iterator it = browseHandles.begin(); it != browseHandles.end(); ++it) + { + dnssdResponder.browser().cancel(*it); + } + + dnssdResponder.stop(); + + dnssdResponder.browser().browseError -= Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().resolveError -= Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().serviceFound -= Poco::delegate(this, &DNSSDBrowserApp::onServiceFound); + dnssdResponder.browser().serviceRemoved -= Poco::delegate(this, &DNSSDBrowserApp::onServiceRemoved); + dnssdResponder.browser().serviceResolved -= Poco::delegate(this, &DNSSDBrowserApp::onServiceResolved); + dnssdResponder.browser().browseDomainError -= Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().browseDomainFound -= Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainFound); + dnssdResponder.browser().browseDomainRemoved -= Poco::delegate(this, &DNSSDBrowserApp::onBrowseDomainRemoved); + dnssdResponder.browser().registrationDomainError -= Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().registrationDomainFound -= Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainFound); + dnssdResponder.browser().registrationDomainRemoved -= Poco::delegate(this, &DNSSDBrowserApp::onRegistrationDomainRemoved); + dnssdResponder.browser().hostResolveError -= Poco::delegate(this, &DNSSDBrowserApp::onError); + dnssdResponder.browser().hostResolved -= Poco::delegate(this, &DNSSDBrowserApp::onHostResolved); + } + + return Application::EXIT_OK; + } + +private: + bool _helpRequested; + bool _autoResolve; + bool _enumerateDomains; + std::set _browseTypes; + std::string _domain; + std::string _registeredService; + std::string _name; + std::string _host; + Service::Properties _properties; + Poco::UInt16 _port; + Poco::Int32 _interface; +}; + + +POCO_SERVER_MAIN(DNSSDBrowserApp) diff --git a/DNSSD/samples/HTTPTimeServer/CMakeLists.txt b/DNSSD/samples/HTTPTimeServer/CMakeLists.txt new file mode 100644 index 000000000..b9bd48e27 --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/CMakeLists.txt @@ -0,0 +1,7 @@ +set(SAMPLE_NAME "DNSSDHTTPTimeServer") + +set(LOCAL_SRCS "") +aux_source_directory(src LOCAL_SRCS) + +add_executable( ${SAMPLE_NAME} ${LOCAL_SRCS} ) +target_link_libraries( ${SAMPLE_NAME} Foundation Net Util XML DNSSD ${DNSSD_IMPLEMENTATION_LIBRARY} ) diff --git a/DNSSD/samples/HTTPTimeServer/HTTPTimeServer.progen b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer.progen new file mode 100644 index 000000000..1375cd8e3 --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer.progen @@ -0,0 +1,13 @@ +vc.project.guid = ${vc.project.guidFromName} +vc.project.name = ${vc.project.baseName} +vc.project.target = ${vc.project.name} +vc.project.type = executable +vc.project.pocobase = ..\\..\\.. +vc.project.platforms = Win32, x64, WinCE +vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md +vc.project.prototype = ${vc.project.name}_vs90.vcproj +vc.project.compiler.include = ..\\..\\..\\Foundation\\include;..\\..\\..\\XML\\include;..\\..\\..\\Util\\include;..\\..\\..\\Net\\include;..\\..\\..\\DNSSD\\include;..\\..\\..\\DNSSD\\Bonjour\\include +vc.project.linker.dependencies = dnssd.lib +vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.x64 = ws2_32.lib iphlpapi.lib +vc.project.linker.dependencies.WinCE = ws2.lib iphlpapi.lib diff --git a/DNSSD/samples/HTTPTimeServer/HTTPTimeServer.properties b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer.properties new file mode 100644 index 000000000..a86940311 --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer.properties @@ -0,0 +1,13 @@ +# This is a sample configuration file for HTTPTimeServer + +logging.loggers.root.channel.class = ConsoleChannel +logging.loggers.app.name = Application +logging.loggers.app.channel = c1 +logging.formatters.f1.class = PatternFormatter +logging.formatters.f1.pattern = [%p] %t +logging.channels.c1.class = ConsoleChannel +logging.channels.c1.formatter = f1 +HTTPTimeServer.format = %W, %e %b %y %H:%M:%S %Z +HTTPTimeServer.port = 9980 +#HTTPTimeServer.maxQueued = 200 +#HTTPTimeServer.maxThreads = 64 diff --git a/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj new file mode 100644 index 000000000..f31548726 --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj @@ -0,0 +1,649 @@ + + + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + HTTPTimeServer + {18A0143A-444A-38E3-838C-1ACFBE4EE18C} + HTTPTimeServer + Win32Proj + + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + Application + MultiByte + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServer + HTTPTimeServer + HTTPTimeServer + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServer + HTTPTimeServer + HTTPTimeServer + + + bin\ + obj\HTTPTimeServer\$(Configuration)\ + true + + + bin\ + obj\HTTPTimeServer\$(Configuration)\ + false + + + bin\static_mt\ + obj\HTTPTimeServer\$(Configuration)\ + true + + + bin\static_mt\ + obj\HTTPTimeServer\$(Configuration)\ + false + + + bin\static_md\ + obj\HTTPTimeServer\$(Configuration)\ + true + + + bin\static_md\ + obj\HTTPTimeServer\$(Configuration)\ + false + + + bin64\ + obj64\HTTPTimeServer\$(Configuration)\ + true + + + bin64\ + obj64\HTTPTimeServer\$(Configuration)\ + false + + + bin64\static_mt\ + obj64\HTTPTimeServer\$(Configuration)\ + true + + + bin64\static_mt\ + obj64\HTTPTimeServer\$(Configuration)\ + false + + + bin64\static_md\ + obj64\HTTPTimeServer\$(Configuration)\ + true + + + bin64\static_md\ + obj64\HTTPTimeServer\$(Configuration)\ + false + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj.filters b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj.filters new file mode 100644 index 000000000..a9e67427b --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs160.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {05ecd2d8-936d-4c90-9cf1-546f7a313acc} + + + {9f18ac45-b5e5-4f7f-af10-320feb933138} + + + + + Configuration Files + + + + + Source Files + + + \ No newline at end of file diff --git a/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj new file mode 100644 index 000000000..f4f7fc258 --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj @@ -0,0 +1,958 @@ + + + + + debug_shared + ARM64 + + + debug_shared + Win32 + + + debug_shared + x64 + + + debug_static_md + ARM64 + + + debug_static_md + Win32 + + + debug_static_md + x64 + + + debug_static_mt + ARM64 + + + debug_static_mt + Win32 + + + debug_static_mt + x64 + + + release_shared + ARM64 + + + release_shared + Win32 + + + release_shared + x64 + + + release_static_md + ARM64 + + + release_static_md + Win32 + + + release_static_md + x64 + + + release_static_mt + ARM64 + + + release_static_mt + Win32 + + + release_static_mt + x64 + + + + 17.0 + HTTPTimeServer + {18A0143A-444A-38E3-838C-1ACFBE4EE18C} + HTTPTimeServer + Win32Proj + + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.34511.75 + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServer + HTTPTimeServer + HTTPTimeServer + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServer + HTTPTimeServer + HTTPTimeServer + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServerd + HTTPTimeServer + HTTPTimeServer + HTTPTimeServer + + + binA64\ + objA64\HTTPTimeServer\$(Configuration)\ + true + + + binA64\ + objA64\HTTPTimeServer\$(Configuration)\ + false + + + binA64\static_mt\ + objA64\HTTPTimeServer\$(Configuration)\ + true + + + binA64\static_mt\ + objA64\HTTPTimeServer\$(Configuration)\ + false + + + binA64\static_md\ + objA64\HTTPTimeServer\$(Configuration)\ + true + + + binA64\static_md\ + objA64\HTTPTimeServer\$(Configuration)\ + false + + + bin\ + obj\HTTPTimeServer\$(Configuration)\ + true + + + bin\ + obj\HTTPTimeServer\$(Configuration)\ + false + + + bin\static_mt\ + obj\HTTPTimeServer\$(Configuration)\ + true + + + bin\static_mt\ + obj\HTTPTimeServer\$(Configuration)\ + false + + + bin\static_md\ + obj\HTTPTimeServer\$(Configuration)\ + true + + + bin\static_md\ + obj\HTTPTimeServer\$(Configuration)\ + false + + + bin64\ + obj64\HTTPTimeServer\$(Configuration)\ + true + + + bin64\ + obj64\HTTPTimeServer\$(Configuration)\ + false + + + bin64\static_mt\ + obj64\HTTPTimeServer\$(Configuration)\ + true + + + bin64\static_mt\ + obj64\HTTPTimeServer\$(Configuration)\ + false + + + bin64\static_md\ + obj64\HTTPTimeServer\$(Configuration)\ + true + + + bin64\static_md\ + obj64\HTTPTimeServer\$(Configuration)\ + false + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\HTTPTimeServer.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\HTTPTimeServerd.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\HTTPTimeServer.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_md\HTTPTimeServerd.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\HTTPTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_mt\HTTPTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPTimeServerd.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin\static_md\HTTPTimeServer.exe + ..\..\..\lib;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX86 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\HTTPTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_mt\HTTPTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + Disabled + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPTimeServerd.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + true + true + $(OutDir)$(TargetName).pdb + Console + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include;..\..\..\Net\include;..\..\..\DNSSD\include;..\..\..\DNSSD\Bonjour\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + $(OutDir)$(TargetName).pdb + true + stdcpp17 + stdc11 + + + iphlpapi.lib;winmm.lib;dnssd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + bin64\static_md\HTTPTimeServer.exe + ..\..\..\lib64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineX64 + + + + + + + + true + stdcpp17 + stdc11 + + + + + diff --git a/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj.filters b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj.filters new file mode 100644 index 000000000..6556ec16f --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs170.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {441c16c9-88da-4016-a905-429b26f51567} + + + {00fba94b-d0c4-47a2-a9e8-cf363dd59707} + + + + + Configuration Files + + + + + Source Files + + + \ No newline at end of file diff --git a/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs90.vcproj b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs90.vcproj new file mode 100644 index 000000000..0fbc2302c --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/HTTPTimeServer_vs90.vcproj @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DNSSD/samples/HTTPTimeServer/Makefile b/DNSSD/samples/HTTPTimeServer/Makefile new file mode 100644 index 000000000..d0d3323b4 --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/Makefile @@ -0,0 +1,23 @@ +# +# Makefile +# +# $Id: //poco/1.7/DNSSD/samples/HTTPTimeServer/Makefile#1 $ +# +# Makefile for HTTPTimeServer sample +# + +include $(POCO_BASE)/build/rules/global + +ifeq ($(OSNAME),Linux) +DNSSDLibrary = PocoDNSSDAvahi +else +DNSSDLibrary = PocoDNSSDBonjour +endif + +objects = HTTPTimeServer + +target = HTTPTimeServer +target_version = 1 +target_libs = $(DNSSDLibrary) PocoDNSSD PocoNet PocoUtil PocoXML PocoFoundation + +include $(POCO_BASE)/build/rules/exec diff --git a/DNSSD/samples/HTTPTimeServer/bin/Darwin/x86_64/HTTPTimeServer b/DNSSD/samples/HTTPTimeServer/bin/Darwin/x86_64/HTTPTimeServer new file mode 100755 index 0000000000000000000000000000000000000000..20da9f60fd1e6769d7ce73aca59e2cd0818296e4 GIT binary patch literal 37932 zcmeHw3w%`7wf7kUm?E0^to4CY3KkzgCNB~Nnvjgnlmr5aNUbnTCMU_@WM(=K2v&3u zu#7R5+S+R`Z7;p{!Dqeqa=pbzEEg~m7xqh}<<@%{T6l>Ggi}i4t(U_}=A}qZH!AS?THMQ9tSnr<#+s%{8oFr{5D3!c^Ck4| zgun%Dl{fTpGzJ;ppoZWgdb~hIJYGv>lRjTOk!+2tB)fih%o6fel5udEw4gMtP|BMq z6NEfpryh#xF{Ih$86`sA+b}p?L`%^kAxFQCK)|PW2lQydm+-gR<-J%gF`!*u|5ZYsE=v$?v7eG85Xg%sV!?2SOt;IMK3B+lMk+;g_GQ=A=Szmy z2E%Q>V7NU3M!USB`9j`gIp~PC%gB~b<8BLheZKnImfEbG8X-q3mT92*k~EDs>LRo4 zK3_QGi?8cyjf8yBL~KNPrZ}xelxLZUsC!JCQku`#5y|vIu71TeLO+^&bP+9w4AUgf zv^gdCd?Ej6`Yo>!@@7aOL}$yR_C^uR%jawJC;TRrt6!>4$U7=oh&FANDV4!8>qvul z(L#515MWj2&6}-=JD6||8(x6yZ@;@=hmBWR~i;z0E?O=-AhpuJR%*0Jo1 z>RFCJdDKSpn!PqYI~oZ@X1Zq0VIAuIG0dmg-Bp#o%5q9+LT>${=H~hZk?`tBGB(RK z3wj1yg#?mIb~ypL7J(-wZ;_suRbFxO^t(0@3|R%9n10I}8?55E|NruSxjK>zW8MWL zVVhW%Tb0!>j!Dm8x;Zjq4L#VrE}qc4W-YMWt0b$O=I91xEf=`_a@A*-AeYA<=8F^f zrIM!kGj@$xV9Wwz78tX@m<7fxFlK=<3yfJ{%mQN;7_-2b1;#A!Kf?modeU#yURS%U z*|XuT7ooB@eWW%$?CITIJUl#Xd>f}so}P<7j#DSk#y!QJ^tUMaY4<_RSb+m|$yT5K zs3H9a<3=#ork|Ef#)1rkaRajI(?gyOd#R4k*RHJft=QvDKYh3eky+r3tOA##KtuXn zDH;7Pw~l%J_-TXC`e&_4Zvr)NUs)1+rV^eiy;oWqQ$YsH~oK{8kL zs_{Hf68z2?npSjijbo2-=vlEv0 z3~Vj|pqf0r6-gXa!Y-82hr=JucuX;Cf|+_tGB*ll%IKqWQR6PfeDEWdJOm(_rwV4u z=qn>;KbTQf4T%dx^{K>NnD4F~Ng|CqcPjgaJbrmh_~bHewkTW0k=|5r8jGGQ2Jr{V=D+X&*yQ#dEIISW5J7e9)H0{u-II#EjtSFX!`zO)20K^9s z4mdGRVQHlFfuG0h%h0axL!8K=85mGTCFt7p01W}K883m%h#dNmMQRz5Jwha9^c6{w zX=-rKY3EL(N_Q86*^_>SCi9zTaSAaTw}I)2C`uSRsEYK{G=ctz37Dy^U(_}T06uEK zOeYJVj6Rgoj46mkYqtyLof+nH1T$s0o;ThRb-ze#z4x%_-d--0e#L0y%w3d8YFrOB zpgEDoFGV@xH1-Re3L8%W�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 literal 0 HcmV?d00001 diff --git a/DNSSD/samples/HTTPTimeServer/bin/Darwin/x86_64/HTTPTimeServerd b/DNSSD/samples/HTTPTimeServer/bin/Darwin/x86_64/HTTPTimeServerd new file mode 100755 index 0000000000000000000000000000000000000000..5de70786b28eb3db0f65c2ce82539edffafad8bb GIT binary patch literal 66260 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 literal 0 HcmV?d00001 diff --git a/DNSSD/samples/HTTPTimeServer/src/HTTPTimeServer.cpp b/DNSSD/samples/HTTPTimeServer/src/HTTPTimeServer.cpp new file mode 100644 index 000000000..f0e0b3697 --- /dev/null +++ b/DNSSD/samples/HTTPTimeServer/src/HTTPTimeServer.cpp @@ -0,0 +1,248 @@ +// +// HTTPTimeServer.cpp +// +// $Id: //poco/1.7/DNSSD/samples/HTTPTimeServer/src/HTTPTimeServer.cpp#1 $ +// +// This sample demonstrates how a web server can advertise itself +// on the network using DNS Service Discovery. +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Net/HTTPServer.h" +#include "Poco/Net/HTTPRequestHandler.h" +#include "Poco/Net/HTTPRequestHandlerFactory.h" +#include "Poco/Net/HTTPServerParams.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTTPServerParams.h" +#include "Poco/Net/ServerSocket.h" +#include "Poco/Net/IPAddress.h" +#include "Poco/Net/NetworkInterface.h" +#include "Poco/Net/MulticastSocket.h" +#include "Poco/Util/ServerApplication.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionSet.h" +#include "Poco/Util/HelpFormatter.h" +#include "Poco/DNSSD/DNSSDResponder.h" +#if POCO_OS == POCO_OS_LINUX && !defined(POCO_DNSSD_USE_BONJOUR) +#include "Poco/DNSSD/Avahi/Avahi.h" +#else +#include "Poco/DNSSD/Bonjour/Bonjour.h" +#endif +#include "Poco/DateTimeFormatter.h" +#include "Poco/DateTimeFormat.h" +#include "Poco/StreamCopier.h" +#include "Poco/Exception.h" +#include "Poco/ThreadPool.h" +#include +#include + + +using Poco::Net::ServerSocket; +using Poco::Net::SocketAddress; +using Poco::Net::HTTPRequestHandler; +using Poco::Net::HTTPRequestHandlerFactory; +using Poco::Net::HTTPServer; +using Poco::Net::HTTPServerRequest; +using Poco::Net::HTTPServerResponse; +using Poco::Net::HTTPServerParams; +using Poco::Timestamp; +using Poco::DateTimeFormatter; +using Poco::DateTimeFormat; +using Poco::ThreadPool; +using Poco::Util::ServerApplication; +using Poco::Util::Application; +using Poco::Util::Option; +using Poco::Util::OptionSet; +using Poco::Util::HelpFormatter; + + +class TimeRequestHandler: public HTTPRequestHandler + /// Return a HTML document with the current date and time. +{ +public: + TimeRequestHandler(const std::string& format): + _format(format) + { + } + + void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) + { + Application& app = Application::instance(); + app.logger().information("Request from " + request.clientAddress().toString()); + + Timestamp now; + std::string dt(DateTimeFormatter::format(now, _format)); + + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + + std::ostream& ostr = response.send(); + ostr << "HTTPTimeServer powered by POCO C++ Libraries"; + ostr << ""; + ostr << "

"; + ostr << dt; + ostr << "

"; + } + +private: + std::string _format; +}; + + +class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory +{ +public: + TimeRequestHandlerFactory(const std::string& format): + _format(format) + { + } + + HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) + { + if (request.getURI() == "/") + return new TimeRequestHandler(_format); + else + return 0; + } + +private: + std::string _format; +}; + + +class HTTPTimeServer: public Poco::Util::ServerApplication + /// The main application class. + /// + /// This class handles command-line arguments and + /// configuration files. + /// Start the HTTPTimeServer executable with the help + /// option (/help on Windows, --help on Unix) for + /// the available command line options. + /// + /// To use the sample configuration file (HTTPTimeServer.properties), + /// copy the file to the directory where the HTTPTimeServer executable + /// resides. If you start the debug version of the HTTPTimeServer + /// (HTTPTimeServerd[.exe]), you must also create a copy of the configuration + /// file named HTTPTimeServerd.properties. In the configuration file, you + /// can specify the port on which the server is listening (default + /// 9980) and the format of the date/time string sent back to the client. + /// + /// To test the TimeServer you can use any web browser (http://localhost:9980/). +{ +public: + HTTPTimeServer(): _helpRequested(false) + { + Poco::DNSSD::initializeDNSSD(); + } + + ~HTTPTimeServer() + { + Poco::DNSSD::uninitializeDNSSD(); + } + +protected: + void initialize(Application& self) + { + loadConfiguration(); // load default configuration files, if present + ServerApplication::initialize(self); + } + + void uninitialize() + { + ServerApplication::uninitialize(); + } + + void defineOptions(OptionSet& options) + { + ServerApplication::defineOptions(options); + + options.addOption( + Option("help", "h", "Display help information on command line arguments.") + .required(false) + .repeatable(false)); + } + + void handleOption(const std::string& name, const std::string& value) + { + ServerApplication::handleOption(name, value); + + if (name == "help") + _helpRequested = true; + } + + void displayHelp() + { + HelpFormatter helpFormatter(options()); + helpFormatter.setCommand(commandName()); + helpFormatter.setUsage("OPTIONS"); + helpFormatter.setHeader("A web server that serves the current date and time and announces itself via UPnP SSDP."); + helpFormatter.format(std::cout); + } + + int main(const std::vector& args) + { + if (_helpRequested) + { + displayHelp(); + } + else + { + // get parameters from configuration file + unsigned short httpPort = static_cast(config().getInt("http.port", 9980)); + std::string format(config().getString("datetime.format", DateTimeFormat::SORTABLE_FORMAT)); + + Poco::Net::HTTPServerParams::Ptr pHTTPParams = new Poco::Net::HTTPServerParams; + pHTTPParams->setSoftwareVersion(config().getString("http.softwareVersion", "")); + pHTTPParams->setMaxQueued(config().getInt("http.maxQueued", 4)); + pHTTPParams->setMaxThreads(config().getInt("http.maxThreads", 4)); + pHTTPParams->setTimeout(Poco::Timespan(config().getInt("http.timeout", 5), 0)); + pHTTPParams->setKeepAlive(config().getBool("http.keepAlive", false)); + pHTTPParams->setMaxKeepAliveRequests(config().getInt("http.maxKeepAliveRequests", 10)); + pHTTPParams->setKeepAliveTimeout(Poco::Timespan(config().getInt("http.keepAliveTimeout", 10), 0)); + + ThreadPool::defaultPool().addCapacity(pHTTPParams->getMaxThreads()); + + // set-up a server socket + SocketAddress httpSA(Poco::Net::IPAddress(), httpPort); + ServerSocket httpSocket(httpSA); + // set-up a HTTPServer instance + HTTPServer srv(new TimeRequestHandlerFactory(format), httpSocket, pHTTPParams); + // start the HTTPServer + srv.start(); + + // register with DNSSDResponder + Poco::DNSSD::DNSSDResponder dnssdResponder; + dnssdResponder.start(); + + Poco::DNSSD::Service service("_http._tcp", httpPort); + Poco::DNSSD::ServiceHandle serviceHandle = dnssdResponder.registerService(service); + + // wait for CTRL-C or kill + waitForTerminationRequest(); + + // shut down UPnP + dnssdResponder.unregisterService(serviceHandle); + dnssdResponder.stop(); + + // Stop the HTTPServer + srv.stop(); + } + return Application::EXIT_OK; + } + +private: + bool _helpRequested; +}; + + +int main(int argc, char** argv) +{ + HTTPTimeServer app; + return app.run(argc, argv); +} diff --git a/DNSSD/samples/Makefile b/DNSSD/samples/Makefile new file mode 100644 index 000000000..64436a993 --- /dev/null +++ b/DNSSD/samples/Makefile @@ -0,0 +1,13 @@ +# +# Makefile +# +# $Id: //poco/1.7/DNSSD/samples/Makefile#1 $ +# +# Makefile for DNSSD Samples +# + +.PHONY: projects +clean all: projects +projects: + $(MAKE) -C DNSSDBrowser $(MAKECMDGOALS) + $(MAKE) -C HTTPTimeServer $(MAKECMDGOALS) diff --git a/DNSSD/samples/dependencies b/DNSSD/samples/dependencies new file mode 100644 index 000000000..b2586077a --- /dev/null +++ b/DNSSD/samples/dependencies @@ -0,0 +1,6 @@ +Foundation +XML +Util +Net +DNSSD +DNSSD/Default diff --git a/DNSSD/samples/samples.progen b/DNSSD/samples/samples.progen new file mode 100644 index 000000000..5dd93f1ba --- /dev/null +++ b/DNSSD/samples/samples.progen @@ -0,0 +1,6 @@ +vc.project.platforms = Win32, x64, WinCE +vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md +vc.solution.create = true +vc.solution.include = \ + DNSSDBrowser\\DNSSDBrowser; \ + HTTPTimeServer\\HTTPTimeServer diff --git a/DNSSD/samples/samples_vs160.sln b/DNSSD/samples/samples_vs160.sln new file mode 100644 index 000000000..07516a19d --- /dev/null +++ b/DNSSD/samples/samples_vs160.sln @@ -0,0 +1,99 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSDBrowser", "DNSSDBrowser\DNSSDBrowser_vs160.vcxproj", "{36D5972E-D503-3863-AFC5-8740752A3A8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HTTPTimeServer", "HTTPTimeServer\HTTPTimeServer_vs160.vcxproj", "{18A0143A-444A-38E3-838C-1ACFBE4EE18C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.Build.0 = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.Build.0 = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.ActiveCfg = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.Build.0 = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.Deploy.0 = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.Build.0 = release_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.Deploy.0 = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.Build.0 = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.Build.0 = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.ActiveCfg = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.Build.0 = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.Deploy.0 = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.Build.0 = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/samples/samples_vs170.sln b/DNSSD/samples/samples_vs170.sln new file mode 100644 index 000000000..3427c3fc9 --- /dev/null +++ b/DNSSD/samples/samples_vs170.sln @@ -0,0 +1,141 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSDBrowser", "DNSSDBrowser\DNSSDBrowser_vs170.vcxproj", "{36D5972E-D503-3863-AFC5-8740752A3A8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HTTPTimeServer", "HTTPTimeServer\HTTPTimeServer_vs170.vcxproj", "{18A0143A-444A-38E3-838C-1ACFBE4EE18C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 + release_static_mt|ARM64 = release_static_mt|ARM64 + debug_static_md|ARM64 = debug_static_md|ARM64 + release_static_md|ARM64 = release_static_md|ARM64 + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.Build.0 = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.Build.0 = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.ActiveCfg = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.Build.0 = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.Deploy.0 = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.Build.0 = release_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.Deploy.0 = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.Build.0 = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.Build.0 = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.ActiveCfg = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.Build.0 = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.Deploy.0 = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.Build.0 = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/samples/samples_vs90.sln b/DNSSD/samples/samples_vs90.sln new file mode 100644 index 000000000..ab731ea56 --- /dev/null +++ b/DNSSD/samples/samples_vs90.sln @@ -0,0 +1,57 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSDBrowser", "DNSSDBrowser\DNSSDBrowser_vs90.vcproj", "{36D5972E-D503-3863-AFC5-8740752A3A8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HTTPTimeServer", "HTTPTimeServer\HTTPTimeServer_vs90.vcproj", "{18A0143A-444A-38E3-838C-1ACFBE4EE18C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + debug_static_mt|Win32 = debug_static_mt|Win32 + release_static_mt|Win32 = release_static_mt|Win32 + debug_static_md|Win32 = debug_static_md|Win32 + release_static_md|Win32 = release_static_md|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.Build.0 = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.Build.0 = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|Win32.Deploy.0 = release_shared|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.Build.0 = release_static_md|Win32 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/samples/samples_x64_vs90.sln b/DNSSD/samples/samples_x64_vs90.sln new file mode 100644 index 000000000..becd97156 --- /dev/null +++ b/DNSSD/samples/samples_x64_vs90.sln @@ -0,0 +1,57 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DNSSDBrowser", "DNSSDBrowser\DNSSDBrowser_x64_vs90.vcproj", "{36D5972E-D503-3863-AFC5-8740752A3A8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HTTPTimeServer", "HTTPTimeServer\HTTPTimeServer_x64_vs90.vcproj", "{18A0143A-444A-38E3-838C-1ACFBE4EE18C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|x64 = debug_shared|x64 + release_shared|x64 = release_shared|x64 + debug_static_mt|x64 = debug_static_mt|x64 + release_static_mt|x64 = release_static_mt|x64 + debug_static_md|x64 = debug_static_md|x64 + release_static_md|x64 = release_static_md|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.Build.0 = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.ActiveCfg = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.Build.0 = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_shared|x64.Deploy.0 = release_shared|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.Build.0 = release_static_md|x64 + {36D5972E-D503-3863-AFC5-8740752A3A8F}.release_static_md|x64.Deploy.0 = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.ActiveCfg = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.Build.0 = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_shared|x64.Deploy.0 = debug_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.ActiveCfg = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.Build.0 = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_shared|x64.Deploy.0 = release_shared|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_mt|x64.Deploy.0 = debug_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_mt|x64.Deploy.0 = release_static_mt|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.debug_static_md|x64.Deploy.0 = debug_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.ActiveCfg = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.Build.0 = release_static_md|x64 + {18A0143A-444A-38E3-838C-1ACFBE4EE18C}.release_static_md|x64.Deploy.0 = release_static_md|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DNSSD/src/DNSSDBrowser.cpp b/DNSSD/src/DNSSDBrowser.cpp new file mode 100644 index 000000000..33d623e4a --- /dev/null +++ b/DNSSD/src/DNSSDBrowser.cpp @@ -0,0 +1,34 @@ +// +// DNSServiceBrowser.cpp +// +// $Id: //poco/1.7/DNSSD/src/DNSSDBrowser.cpp#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSServiceBrowser +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/DNSSDBrowser.h" + + +namespace Poco { +namespace DNSSD { + + +DNSSDBrowser::DNSSDBrowser() +{ +} + + +DNSSDBrowser::~DNSSDBrowser() +{ +} + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/src/DNSSDException.cpp b/DNSSD/src/DNSSDException.cpp new file mode 100644 index 000000000..dcd71cfbd --- /dev/null +++ b/DNSSD/src/DNSSDException.cpp @@ -0,0 +1,28 @@ +// +// ZeroconfException.cpp +// +// $Id: //poco/1.7/DNSSD/src/DNSSDException.cpp#1 $ +// +// Library: Zeroconf +// Package: Core +// Module: ZeroconfException +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/DNSSDException.h" +#include + + +namespace Poco { +namespace DNSSD { + + +POCO_IMPLEMENT_EXCEPTION(DNSSDException, Poco::RuntimeException, "DNSSD Exception") + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/src/DNSSDResponder.cpp b/DNSSD/src/DNSSDResponder.cpp new file mode 100644 index 000000000..df0c1741c --- /dev/null +++ b/DNSSD/src/DNSSDResponder.cpp @@ -0,0 +1,109 @@ +// +// DNSSDResponder.cpp +// +// $Id: //poco/1.7/DNSSD/src/DNSSDResponder.cpp#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSSDResponder +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/DNSSDResponder.h" +#include "Poco/DNSSD/DNSSDResponderImpl.h" +#include "Poco/Exception.h" + + +namespace Poco { +namespace DNSSD { + + +DNSSDResponderImplFactory* DNSSDResponder::_pImplFactory(0); + + +DNSSDResponder::DNSSDResponder(): + _pImpl(0) +{ + if (_pImplFactory) + { + _pImpl = _pImplFactory->createResponderImpl(*this); + } + else + { + throw Poco::IllegalStateException("No DNSResponderImplFactory available."); + } +} + + +DNSSDResponder::~DNSSDResponder() +{ + delete _pImpl; +} + + +DNSSDBrowser& DNSSDResponder::browser() +{ + return _pImpl->browser(); +} + + +ServiceHandle DNSSDResponder::registerService(const Service& service, int options) +{ + return _pImpl->registerService(service, options); +} + + +void DNSSDResponder::unregisterService(ServiceHandle& serviceHandle) +{ + _pImpl->unregisterService(serviceHandle); +} + + +RecordHandle DNSSDResponder::addRecord(ServiceHandle serviceHandle, const Record& record) +{ + return _pImpl->addRecord(serviceHandle, record); +} + + +void DNSSDResponder::updateRecord(ServiceHandle serviceHandle, RecordHandle recordHandle, const Record& record) +{ + _pImpl->updateRecord(serviceHandle, recordHandle, record); +} + + +void DNSSDResponder::removeRecord(ServiceHandle serviceHandle, RecordHandle& recordHandle) +{ + _pImpl->removeRecord(serviceHandle, recordHandle); +} + + +void DNSSDResponder::start() +{ + _pImpl->start(); +} + + +void DNSSDResponder::stop() +{ + _pImpl->stop(); +} + + +void DNSSDResponder::registerImplFactory(DNSSDResponderImplFactory& factory) +{ + _pImplFactory = &factory; +} + + +void DNSSDResponder::unregisterImplFactory() +{ + _pImplFactory = 0; +} + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/src/DNSSDResponderImpl.cpp b/DNSSD/src/DNSSDResponderImpl.cpp new file mode 100644 index 000000000..26a765c45 --- /dev/null +++ b/DNSSD/src/DNSSDResponderImpl.cpp @@ -0,0 +1,39 @@ +// +// DNSSDResponderImpl.cpp +// +// $Id: //poco/1.7/DNSSD/src/DNSSDResponderImpl.cpp#1 $ +// +// Library: DNSSD +// Package: Core +// Module: DNSSDResponderImpl +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/DNSSDResponderImpl.h" + + +namespace Poco { +namespace DNSSD { + + +DNSSDResponderImpl::DNSSDResponderImpl() +{ +} + + +DNSSDResponderImpl::~DNSSDResponderImpl() +{ +} + + +DNSSDResponderImplFactory::~DNSSDResponderImplFactory() +{ +} + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/src/Domain.cpp b/DNSSD/src/Domain.cpp new file mode 100644 index 000000000..41b530df6 --- /dev/null +++ b/DNSSD/src/Domain.cpp @@ -0,0 +1,44 @@ +// +// Domain.cpp +// +// $Id: //poco/1.7/DNSSD/src/Domain.cpp#1 $ +// +// Library: DNSSD +// Package: Core +// Module: Domain +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Domain.h" + + +namespace Poco { +namespace DNSSD { + + +Domain::Domain(): + _networkInterface(0), + _isDefault(false) +{ +} + + +Domain::Domain(Poco::Int32 networkInterface, const std::string& name, bool isDefault): + _networkInterface(networkInterface), + _name(name), + _isDefault(isDefault) +{ +} + + +Domain::~Domain() +{ +} + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/src/Error.cpp b/DNSSD/src/Error.cpp new file mode 100644 index 000000000..a56d73b23 --- /dev/null +++ b/DNSSD/src/Error.cpp @@ -0,0 +1,44 @@ +// +// Error.cpp +// +// $Id: //poco/1.7/DNSSD/src/Error.cpp#1 $ +// +// Library: DNSSD +// Package: Core +// Module: Error +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Error.h" + + +namespace Poco { +namespace DNSSD { + + +Error::Error(): + _networkInterface(0), + _code(0) +{ +} + + +Error::Error(Poco::Int32 networkInterface, Poco::Int32 code, const std::string& message): + _networkInterface(networkInterface), + _code(code), + _message(message) +{ +} + + +Error::~Error() +{ +} + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/src/Record.cpp b/DNSSD/src/Record.cpp new file mode 100644 index 000000000..c09742bb8 --- /dev/null +++ b/DNSSD/src/Record.cpp @@ -0,0 +1,64 @@ +// +// Record.cpp +// +// $Id: //poco/1.7/DNSSD/src/Record.cpp#1 $ +// +// Library: DNSSD +// Package: Core +// Module: Record +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Record.h" + + +namespace Poco { +namespace DNSSD { + + +Record::Record(): + _networkInterface(0), + _type(0), + _clazz(0), + _length(0), + _data(0), + _ttl(0) +{ +} + + +Record::Record(Poco::Int32 networkInterface, const std::string& name, Poco::UInt16 type, Poco::UInt16 clazz, Poco::UInt16 length, const void* data, Poco::UInt32 ttl): + _networkInterface(networkInterface), + _name(name), + _type(type), + _clazz(clazz), + _length(length), + _data(data), + _ttl(ttl) +{ +} + + +Record::Record(const std::string& name, Poco::UInt16 type, Poco::UInt16 length, const void* data, Poco::UInt32 ttl): + _networkInterface(0), + _name(name), + _type(type), + _clazz(RC_IN), + _length(length), + _data(data), + _ttl(ttl) +{ +} + + +Record::~Record() +{ +} + + +} } // namespace Poco::DNSSD diff --git a/DNSSD/src/Service.cpp b/DNSSD/src/Service.cpp new file mode 100644 index 000000000..5b56655a7 --- /dev/null +++ b/DNSSD/src/Service.cpp @@ -0,0 +1,80 @@ +// +// Service.cpp +// +// $Id: //poco/1.7/DNSSD/src/Service.cpp#1 $ +// +// Library: DNSSD +// Package: Core +// Module: Service +// +// Copyright (c) 2006-2024, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/DNSSD/Service.h" + + +namespace Poco { +namespace DNSSD { + + +Service::Service(): + _networkInterface(0), + _port(0) +{ +} + + +Service::Service(Poco::Int32 networkInterface, const std::string& name, const std::string& type, const std::string& domain): + _networkInterface(networkInterface), + _name(name), + _type(type), + _domain(domain), + _port(0) +{ +} + + +Service::Service(const std::string& type, Poco::UInt16 port, const Properties& properties): + _networkInterface(0), + _type(type), + _port(port), + _properties(properties) +{ +} + + +Service::Service(Poco::Int32 networkInterface, const std::string& name, const std::string& fullName, const std::string& type, const std::string& domain, const std::string& host, Poco::UInt16 port): + _networkInterface(networkInterface), + _name(name), + _fullName(fullName), + _type(type), + _domain(domain), + _host(host), + _port(port) +{ +} + + +Service::Service(Poco::Int32 networkInterface, const std::string& name, const std::string& fullName, const std::string& type, const std::string& domain, const std::string& host, Poco::UInt16 port, const Properties& properties): + _networkInterface(networkInterface), + _name(name), + _fullName(fullName), + _type(type), + _domain(domain), + _host(host), + _port(port), + _properties(properties) +{ +} + + +Service::~Service() +{ +} + + +} } // namespace Poco::DNSSD diff --git a/cmake/FindAvahi.cmake b/cmake/FindAvahi.cmake new file mode 100644 index 000000000..09bfa3e46 --- /dev/null +++ b/cmake/FindAvahi.cmake @@ -0,0 +1,20 @@ +# +# - Find Avahi +# Find the native AVAHI includes and library +# +# AVAHI_INCLUDE_DIRS - where to find pcre.h, etc. +# AVAHI_LIBRARIES - List of libraries when using pcre. +# AVAHI_FOUND - True if pcre found. + +find_library(AVAHI_LIBRARY-COMMON NAMES avahi-common) +find_library(AVAHI_LIBRARY-CLIENT NAMES avahi-client) + +find_path(AVAHI_INCLUDE_DIR avahi-client/publish.h) +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(Avahi DEFAULT_MSG AVAHI_LIBRARY-COMMON AVAHI_LIBRARY-CLIENT AVAHI_INCLUDE_DIR) + +if(AVAHI_FOUND) + set(AVAHI_LIBRARIES ${AVAHI_LIBRARY-COMMON} ${AVAHI_LIBRARY-CLIENT}) + set(AVAHI_INCLUDE_DIRS ${AVAHI_INCLUDE_DIR}) +endif() diff --git a/cmake/FindBonjour.cmake b/cmake/FindBonjour.cmake new file mode 100644 index 000000000..8b53ce62d --- /dev/null +++ b/cmake/FindBonjour.cmake @@ -0,0 +1,49 @@ +# - Try to find Bonjour +# (See http://developer.apple.com/networking/bonjour/index.html) +# By default available on MacOS X. +# Check for libdns_sd +# +# BONJOUR_INCLUDE_DIR - where to find dns_sd.h, etc. +# BONJOUR_LIBRARIES - List of libraries when using .... +# BONJOUR_FOUND - True if Bonjour libraries found. + +set(BONJOUR_FOUND FALSE) +set(BONJOUR_LIBRARIES) + +message(STATUS "Checking whether Bonjour is supported") + +# Bonjour is built-in on MacOS X / iOS (i.e. available in libSystem) +if(NOT APPLE) + IF (WIN32) + FIND_PATH(BONJOUR_INCLUDE_DIR dns_sd.h + PATHS $ENV{PROGRAMW6432}/Bonjour\ SDK/Include + ) + FIND_LIBRARY(BONJOUR_LIBRARY + NAMES dnssd + PATHS $ENV{PROGRAMW6432}/Bonjour\ SDK/Lib/x64 + ) + ELSE(WIN32) + find_path(BONJOUR_INCLUDE_DIR dns_sd.h + PATHS /opt/dnssd/include /usr/include /usr/local/include + ) + find_library(BONJOUR_LIBRARY + NAMES dns_sd + PATHS /opt/dnssd/lib /usr/lib /usr/local/lib + ) + ENDIF(WIN32) + if(NOT BONJOUR_INCLUDE_DIR OR NOT BONJOUR_LIBRARY) + return() + else() + set(BONJOUR_LIBRARIES ${BONJOUR_LIBRARY} ) + set(BONJOUR_FOUND TRUE) + endif() +else() + find_library(BONJOUR_LIBRARY CoreServices) + set(BONJOUR_FOUND TRUE) +endif() + + +mark_as_advanced( FORCE + BONJOUR_INCLUDE_DIR + BONJOUR_LIBRARY + ) diff --git a/components b/components index 811018f99..dcf24697d 100644 --- a/components +++ b/components @@ -25,5 +25,8 @@ Redis Prometheus ActiveRecord ActiveRecord/Compiler +DNSSD +DNSSD/Avahi +DNSSD/Bonjour PocoDoc ProGen diff --git a/configure b/configure index 1ceeebeee..466ca3fdc 100755 --- a/configure +++ b/configure @@ -171,8 +171,8 @@ unbundled="" static="" shared="" nosqlparser= -omitMinimal="Crypto NetSSL_OpenSSL Zip Data Data/SQLite Data/ODBC Data/MySQL Data/PostgreSQL MongoDB Redis PDF CppParser PageCompiler" -omitTypical="Data/ODBC Data/MySQL Data/PostgreSQL MongoDB Redis PDF CppParser" +omitMinimal="Crypto NetSSL_OpenSSL Zip Data Data/SQLite Data/ODBC Data/MySQL Data/PostgreSQL MongoDB Redis PDF DNSSD DNSSD/Avahi DNSSD/Bonjour CppParser PageCompiler" +omitTypical="Data/ODBC Data/MySQL Data/PostgreSQL MongoDB Redis PDF DNSSD DNSSD/Avahi DNSSD/Bonjour CppParser" omit=$omitTypical # parse arguments while [ $# -ge 1 ]; do