From 37aa8032e1efb094ef0aee32946568b6e6538d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Wed, 9 May 2018 13:33:12 +0200 Subject: [PATCH 01/24] Added check code for attempting rendezvous to self --- srtcore/api.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++ srtcore/netinet_any.h | 19 ++++++++++ 2 files changed, 103 insertions(+) diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 2d4dcdc72..4c70cc74c 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -65,6 +65,9 @@ modified by #ifdef WIN32 #include + #include // getting local interfaces +#else + #include // getting local interfaces #endif using namespace std; @@ -824,6 +827,87 @@ int CUDTUnited::connect(const SRTSOCKET u, const sockaddr* name, int namelen, in else if (s->m_Status != SRTS_OPENED) throw CUDTException(MJ_NOTSUP, MN_ISCONNECTED, 0); + if (s->m_pUDT->m_bRendezvous) + { + sockaddr_any bound = s->m_pSelfAddr; + sockaddr_any target = name; + + if (!bound.isany()) + { + // Bound to a specific local address, so only check if + // this isn't the same address as 'target'. + if (target.equal_address(bound)) + { + LOGC(mglog.Error, log << "connect: Rendezvous attempt to self on addr: " + << SockaddrToString(&target.sa) << " - rejected"); + throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); + + } + } + else + { + // Bound to INADDR_ANY, so matching with any local IP address is invalid. + vector locals; +#ifdef WIN32 + ULONG family = s->m_pSeflAddr->sa_family; + ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; + ULONG outBufLen = 0; + + // This function doesn't allocate memory by itself, you have to do it + // yourself, worst case when it's too small, the size will be corrected + // and the function will do nothing. So, simply, call the function with + // always too little 0 size and make it show the correct one. + GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen); + // Ignore errors. Check errors on the real call. + + // Good, now we can allocate memory + PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)::operator new(outBufLen); + ULONG st = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); + if (st == ERROR_SUCCESS) + { + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; + while (pUnicast) + { + locals.push_back(pUnicast->Address.lpSockaddr); + pUnicast = pUnicast->Next; + } + } + + ::operator delete(pAddresses); + +#else + // Use POSIX method: getifaddrs + struct ifaddrs* pif, * pifa; + int st = getifaddrs(&pifa); + if (st == 0) + { + for (pif = pifa; pif; pif = pif->ifa_next) + { + locals.push_back(pif->ifa_addr); + } + } + + freeifaddrs(pifa); +#endif + + // If any of the above function fails, it will collect + // no local interfaces, so it's impossible to check anything. + // OTOH it should also mean that the network isn't working, + // so it's unlikely, as well as no address should match the + // local address anyway. + for (size_t i = 0; i < locals.size(); ++i) + { + if (locals[i].equal_address(target)) + { + LOGC(mglog.Error, log << "connect: Rendezvous bound to any, but target (" + << SockaddrToString(&target.sa) << ") matches one of local interfaces"); + throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); + } + } + + } + } + // connect_complete() may be called before connect() returns. // So we need to update the status before connect() is called, // otherwise the status may be overwritten with wrong value diff --git a/srtcore/netinet_any.h b/srtcore/netinet_any.h index 0418a1a84..ec6435a4c 100644 --- a/srtcore/netinet_any.h +++ b/srtcore/netinet_any.h @@ -42,6 +42,17 @@ struct sockaddr_any len = size(); } + sockaddr_any(const sockaddr* src) + { + // It's not safe to copy it directly, so check. + if (src->sa_family == AF_INET) + memcpy(&sin, src, sizeof sin); + + // Note: this isn't too safe, may crash for stupid values + // in the source structure, so make sure it's correct first. + memcpy(&sin6, src, sizeof sin6); + } + socklen_t size() const { switch (sa.sa_family) @@ -120,6 +131,14 @@ struct sockaddr_any return memcmp(&c1, &c2, sizeof(c1)) < 0; } }; + + // Tests if the current address is the "any" wildcard. + bool isany() + { + if (sa.sa_family == AF_INET) + return sin.sin_addr.s_addr == INADDR_ANY; + return 0 == memcmp(&sin6.sin6_addr, &in6addr_any, sizeof in6addr_any); + } }; template<> struct sockaddr_any::TypeMap { typedef sockaddr_in type; }; From 7aaeeb34f98e16a6f153034e531cd1dbe97a9a2c Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Wed, 9 May 2018 16:05:16 +0200 Subject: [PATCH 02/24] Fixed build breaks on MICROSOFT --- CMakeLists.txt | 21 ++++++++++----------- srtcore/api.cpp | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56b9f2548..a804fdb3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -434,16 +434,20 @@ endif() set (VIRTUAL_srt $ $) set (HEADERS_srt ${HEADERS_srt} ${HEADERS_srt_win32}) +macro(srt_update_library_deps target) + list (APPEND INSTALL_TARGETS ${target}) + target_link_libraries(${target} PRIVATE ${SSL_LIBRARIES}) + if (MICROSOFT) + target_link_libraries(${target} PRIVATE ws2_32.lib Iphlpapi.lib) + endif() +endmacro() + if (srt_libspec_shared) add_library(${TARGET_srt}_shared SHARED ${VIRTUAL_srt}) # shared libraries need PIC set_property(TARGET ${TARGET_srt}_shared PROPERTY OUTPUT_NAME ${TARGET_srt}) set_target_properties (${TARGET_srt}_shared PROPERTIES VERSION ${SRT_VERSION} SOVERSION ${SRT_VERSION_MAJOR}) - list (APPEND INSTALL_TARGETS ${TARGET_srt}_shared) - target_link_libraries(${TARGET_srt}_shared PRIVATE ${SSL_LIBRARIES}) - if (MICROSOFT) - target_link_libraries(${TARGET_srt}_shared PRIVATE ws2_32.lib) - endif() + srt_update_library_deps(${TARGET_srt}_shared) endif() if (srt_libspec_static) @@ -462,12 +466,7 @@ if (srt_libspec_static) else() set_property(TARGET ${TARGET_srt}_static PROPERTY OUTPUT_NAME ${TARGET_srt}) endif() - - list (APPEND INSTALL_TARGETS ${TARGET_srt}_static) - target_link_libraries(${TARGET_srt}_static PRIVATE ${SSL_LIBRARIES}) - if (MICROSOFT) - target_link_libraries(${TARGET_srt}_static PRIVATE ws2_32.lib) - endif() + srt_update_library_deps(${TARGET_srt}_static) endif() diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 4c70cc74c..3d938ab4b 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -849,7 +849,7 @@ int CUDTUnited::connect(const SRTSOCKET u, const sockaddr* name, int namelen, in // Bound to INADDR_ANY, so matching with any local IP address is invalid. vector locals; #ifdef WIN32 - ULONG family = s->m_pSeflAddr->sa_family; + ULONG family = s->m_pSelfAddr->sa_family; ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; ULONG outBufLen = 0; From e39d94da11e67305593dd401b5a915555da5ba32 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Wed, 16 May 2018 11:33:06 +0200 Subject: [PATCH 03/24] Fixed copying by type recognition condition --- srtcore/netinet_any.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/srtcore/netinet_any.h b/srtcore/netinet_any.h index ec6435a4c..648c0b022 100644 --- a/srtcore/netinet_any.h +++ b/srtcore/netinet_any.h @@ -46,11 +46,16 @@ struct sockaddr_any { // It's not safe to copy it directly, so check. if (src->sa_family == AF_INET) + { memcpy(&sin, src, sizeof sin); - - // Note: this isn't too safe, may crash for stupid values - // in the source structure, so make sure it's correct first. - memcpy(&sin6, src, sizeof sin6); + } + else // assume AF_INET6 + { + // Note: this isn't too safe, may crash for stupid values + // of src->sa_family or any other data + // in the source structure, so make sure it's correct first. + memcpy(&sin6, src, sizeof sin6); + } } socklen_t size() const From d798b01a7cc27c641b9acd229a4e5820ddcab0d5 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Wed, 16 May 2018 11:38:17 +0200 Subject: [PATCH 04/24] Changed style --- srtcore/netinet_any.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srtcore/netinet_any.h b/srtcore/netinet_any.h index 648c0b022..1b1e96be5 100644 --- a/srtcore/netinet_any.h +++ b/srtcore/netinet_any.h @@ -142,7 +142,7 @@ struct sockaddr_any { if (sa.sa_family == AF_INET) return sin.sin_addr.s_addr == INADDR_ANY; - return 0 == memcmp(&sin6.sin6_addr, &in6addr_any, sizeof in6addr_any); + return memcmp(&sin6.sin6_addr, &in6addr_any, sizeof in6addr_any) == 0; } }; From 2f5a50548f0f58e20ce7eb5055b74c81dd23a439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Thu, 17 May 2018 12:28:40 +0200 Subject: [PATCH 05/24] Split out apputil.cpp file --- apps/apputil.cpp | 185 +++++++++++++++++++++++++++++++++++++ apps/apputil.hpp | 185 ++----------------------------------- apps/support.maf | 1 + testing/srt-test-file.maf | 1 + testing/srt-test-live.maf | 1 + testing/srt-test-relay.maf | 1 + 6 files changed, 198 insertions(+), 176 deletions(-) create mode 100644 apps/apputil.cpp diff --git a/apps/apputil.cpp b/apps/apputil.cpp new file mode 100644 index 000000000..71e234606 --- /dev/null +++ b/apps/apputil.cpp @@ -0,0 +1,185 @@ +/* + * SRT - Secure, Reliable, Transport + * Copyright (c) 2018 Haivision Systems Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include +// For Options +#include +#include + +#include "apputil.hpp" + +// NOTE: MINGW currently does not include support for inet_pton(). See +// http://mingw.5.n7.nabble.com/Win32API-request-for-new-functions-td22029.html +// Even if it did support inet_pton(), it is only available on Windows Vista +// and later. Since we need to support WindowsXP and later in ORTHRUS. Many +// customers still use it, we will need to implement using something like +// WSAStringToAddress() which is available on Windows95 and later. +// Support for IPv6 was added on WindowsXP SP1. +// Header: winsock2.h +// Implementation: ws2_32.dll +// See: +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms742214(v=vs.85).aspx +// http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedInternet3b.html +#ifdef __MINGW32__ +static int inet_pton(int af, const char * src, void * dst) +{ + struct sockaddr_storage ss; + int ssSize = sizeof(ss); + char srcCopy[INET6_ADDRSTRLEN + 1]; + + ZeroMemory(&ss, sizeof(ss)); + + // work around non-const API + strncpy(srcCopy, src, INET6_ADDRSTRLEN + 1); + srcCopy[INET6_ADDRSTRLEN] = '\0'; + + if (WSAStringToAddress( + srcCopy, af, NULL, (struct sockaddr *)&ss, &ssSize) != 0) + { + return 0; + } + + switch (af) + { + case AF_INET : + { + *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; + return 1; + } + case AF_INET6 : + { + *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; + return 1; + } + default : + { + // No-Op + } + } + + return 0; +} +#endif // __MINGW__ + +sockaddr_in CreateAddrInet(const std::string& name, unsigned short port) +{ + sockaddr_in sa; + memset(&sa, 0, sizeof sa); + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + + if ( name != "" ) + { + if ( inet_pton(AF_INET, name.c_str(), &sa.sin_addr) == 1 ) + return sa; + + // XXX RACY!!! Use getaddrinfo() instead. Check portability. + // Windows/Linux declare it. + // See: + // http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedInternet3b.html + hostent* he = gethostbyname(name.c_str()); + if ( !he || he->h_addrtype != AF_INET ) + throw std::invalid_argument("SrtSource: host not found: " + name); + + sa.sin_addr = *(in_addr*)he->h_addr_list[0]; + } + + return sa; +} + +std::string Join(const std::vector& in, std::string sep) +{ + if ( in.empty() ) + return ""; + + std::ostringstream os; + + os << in[0]; + for (auto i = in.begin()+1; i != in.end(); ++i) + os << sep << *i; + return os.str(); +} + + +options_t ProcessOptions(char* const* argv, int argc, std::vector scheme) +{ + using namespace std; + + string current_key = ""; + size_t vals = 0; + OptionScheme::Args type = OptionScheme::ARG_VAR; // This is for no-option-yet or consumed + map> params; + bool moreoptions = true; + + for (char* const* p = argv+1; p != argv+argc; ++p) + { + const char* a = *p; + // cout << "*D ARG: '" << a << "'\n"; + if ( moreoptions && a[0] == '-' ) + { + current_key = a+1; + if ( current_key == "-" ) + { + // The -- argument terminates the options. + // The default key is restored to empty so that + // it collects now all arguments under the empty key + // (not-option-assigned argument). + moreoptions = false; + goto EndOfArgs; + } + params[current_key].clear(); + vals = 0; + + // Find the key in the scheme. If not found, treat it as ARG_NONE. + for (auto s: scheme) + { + if (s.names.count(current_key)) + { + // cout << "*D found '" << current_key << "' in scheme type=" << int(s.type) << endl; + if ( s.type == OptionScheme::ARG_NONE ) + { + // Anyway, consider it already processed. + break; + } + type = s.type; + goto Found; + } + + } + // Not found: set ARG_NONE. + // cout << "*D KEY '" << current_key << "' assumed type NONE\n"; +EndOfArgs: + type = OptionScheme::ARG_VAR; + current_key = ""; +Found: + continue; + } + + // Collected a value - check if full + // cout << "*D COLLECTING '" << a << "' for key '" << current_key << "' (" << vals << " so far)\n"; + params[current_key].push_back(a); + ++vals; + if ( vals == 1 && type == OptionScheme::ARG_ONE ) + { + // cout << "*D KEY TYPE ONE - resetting to empty key\n"; + // Reset the key to "default one". + current_key = ""; + vals = 0; + type = OptionScheme::ARG_VAR; + } + else + { + // cout << "*D KEY type VAR - still collecting until the end of options or next option.\n"; + } + } + + return params; +} + diff --git a/apps/apputil.hpp b/apps/apputil.hpp index acded0b5a..be2549643 100644 --- a/apps/apputil.hpp +++ b/apps/apputil.hpp @@ -11,7 +11,12 @@ #ifndef INC__APPCOMMON_H #define INC__APPCOMMON_H - + +#include +#include +#include +#include + #if WIN32 // Keep this below commented out. @@ -55,112 +60,14 @@ inline void SysCleanupNetwork() {} #endif -#include -#include -// For Options -#include -#include -#include -#include -#include - -// NOTE: MINGW currently does not include support for inet_pton(). See -// http://mingw.5.n7.nabble.com/Win32API-request-for-new-functions-td22029.html -// Even if it did support inet_pton(), it is only available on Windows Vista -// and later. Since we need to support WindowsXP and later in ORTHRUS. Many -// customers still use it, we will need to implement using something like -// WSAStringToAddress() which is available on Windows95 and later. -// Support for IPv6 was added on WindowsXP SP1. -// Header: winsock2.h -// Implementation: ws2_32.dll -// See: -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms742214(v=vs.85).aspx -// http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedInternet3b.html -#ifdef __MINGW32__ -static inline int inet_pton(int af, const char * src, void * dst) -{ - struct sockaddr_storage ss; - int ssSize = sizeof(ss); - char srcCopy[INET6_ADDRSTRLEN + 1]; - - ZeroMemory(&ss, sizeof(ss)); - - // work around non-const API - strncpy(srcCopy, src, INET6_ADDRSTRLEN + 1); - srcCopy[INET6_ADDRSTRLEN] = '\0'; - - if (WSAStringToAddress( - srcCopy, af, NULL, (struct sockaddr *)&ss, &ssSize) != 0) - { - return 0; - } - - switch (af) - { - case AF_INET : - { - *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; - return 1; - } - case AF_INET6 : - { - *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; - return 1; - } - default : - { - // No-Op - } - } - - return 0; -} -#endif // __MINGW__ - #ifdef WIN32 inline int SysError() { return ::GetLastError(); } #else inline int SysError() { return errno; } #endif -inline sockaddr_in CreateAddrInet(const std::string& name, unsigned short port) -{ - sockaddr_in sa; - memset(&sa, 0, sizeof sa); - sa.sin_family = AF_INET; - sa.sin_port = htons(port); - - if ( name != "" ) - { - if ( inet_pton(AF_INET, name.c_str(), &sa.sin_addr) == 1 ) - return sa; - - // XXX RACY!!! Use getaddrinfo() instead. Check portability. - // Windows/Linux declare it. - // See: - // http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedInternet3b.html - hostent* he = gethostbyname(name.c_str()); - if ( !he || he->h_addrtype != AF_INET ) - throw std::invalid_argument("SrtSource: host not found: " + name); - - sa.sin_addr = *(in_addr*)he->h_addr_list[0]; - } - - return sa; -} - -inline std::string Join(const std::vector& in, std::string sep) -{ - if ( in.empty() ) - return ""; - - std::ostringstream os; - - os << in[0]; - for (auto i = in.begin()+1; i != in.end(); ++i) - os << sep << *i; - return os.str(); -} +sockaddr_in CreateAddrInet(const std::string& name, unsigned short port); +std::string Join(const std::vector& in, std::string sep); typedef std::map> options_t; @@ -176,7 +83,6 @@ struct OutString static type process(const options_t::mapped_type& i) { return Join(i, " "); } }; - template inline typename OutType::type Option(const options_t&, OutValue deflt=OutValue()) { return deflt; } @@ -207,80 +113,7 @@ struct OptionScheme enum Args { ARG_NONE, ARG_ONE, ARG_VAR } type; }; -inline options_t ProcessOptions(char* const* argv, int argc, std::vector scheme) -{ - using namespace std; - - string current_key = ""; - size_t vals = 0; - OptionScheme::Args type = OptionScheme::ARG_VAR; // This is for no-option-yet or consumed - map> params; - bool moreoptions = true; - - for (char* const* p = argv+1; p != argv+argc; ++p) - { - const char* a = *p; - // cout << "*D ARG: '" << a << "'\n"; - if ( moreoptions && a[0] == '-' ) - { - current_key = a+1; - if ( current_key == "-" ) - { - // The -- argument terminates the options. - // The default key is restored to empty so that - // it collects now all arguments under the empty key - // (not-option-assigned argument). - moreoptions = false; - goto EndOfArgs; - } - params[current_key].clear(); - vals = 0; - - // Find the key in the scheme. If not found, treat it as ARG_NONE. - for (auto s: scheme) - { - if (s.names.count(current_key)) - { - // cout << "*D found '" << current_key << "' in scheme type=" << int(s.type) << endl; - if ( s.type == OptionScheme::ARG_NONE ) - { - // Anyway, consider it already processed. - break; - } - type = s.type; - goto Found; - } - - } - // Not found: set ARG_NONE. - // cout << "*D KEY '" << current_key << "' assumed type NONE\n"; -EndOfArgs: - type = OptionScheme::ARG_VAR; - current_key = ""; -Found: - continue; - } - - // Collected a value - check if full - // cout << "*D COLLECTING '" << a << "' for key '" << current_key << "' (" << vals << " so far)\n"; - params[current_key].push_back(a); - ++vals; - if ( vals == 1 && type == OptionScheme::ARG_ONE ) - { - // cout << "*D KEY TYPE ONE - resetting to empty key\n"; - // Reset the key to "default one". - current_key = ""; - vals = 0; - type = OptionScheme::ARG_VAR; - } - else - { - // cout << "*D KEY type VAR - still collecting until the end of options or next option.\n"; - } - } - - return params; -} +options_t ProcessOptions(char* const* argv, int argc, std::vector scheme); #endif // INC__APPCOMMON_H diff --git a/apps/support.maf b/apps/support.maf index e0fc9eef9..5c1d6dfcc 100644 --- a/apps/support.maf +++ b/apps/support.maf @@ -8,6 +8,7 @@ # take selectively whichever parts they need. SOURCES +apputil.cpp logsupport.cpp socketoptions.cpp transmitmedia.cpp diff --git a/testing/srt-test-file.maf b/testing/srt-test-file.maf index 3e5e3c076..36a8582b7 100644 --- a/testing/srt-test-file.maf +++ b/testing/srt-test-file.maf @@ -2,6 +2,7 @@ SOURCES srt-test-file.cpp testmedia.cpp +../apps/apputil.cpp ../apps/verbose.cpp ../apps/socketoptions.cpp ../apps/uriparser.cpp diff --git a/testing/srt-test-live.maf b/testing/srt-test-live.maf index f1c3341f0..f609b77b7 100644 --- a/testing/srt-test-live.maf +++ b/testing/srt-test-live.maf @@ -3,6 +3,7 @@ SOURCES srt-test-live.cpp testmedia.cpp +../apps/apputil.cpp ../apps/verbose.cpp ../apps/socketoptions.cpp ../apps/uriparser.cpp diff --git a/testing/srt-test-relay.maf b/testing/srt-test-relay.maf index 07b4e1ef4..594a650af 100644 --- a/testing/srt-test-relay.maf +++ b/testing/srt-test-relay.maf @@ -3,6 +3,7 @@ SOURCES srt-test-relay.cpp testmedia.cpp +../apps/apputil.cpp ../apps/verbose.cpp ../apps/socketoptions.cpp ../apps/uriparser.cpp From c9200e131cb73630bc6ba713446eb2c1f0cf2d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Thu, 17 May 2018 12:59:18 +0200 Subject: [PATCH 06/24] Added prevention of self-connecting to testing applications --- CMakeLists.txt | 6 ++- apps/apputil.cpp | 103 ++++++++++++++++++++++++++++++++++++++++-- apps/apputil.hpp | 1 + srtcore/api.cpp | 84 ---------------------------------- testing/testmedia.cpp | 16 +++++++ 5 files changed, 120 insertions(+), 90 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a804fdb3a..0ebbb5b89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -438,7 +438,7 @@ macro(srt_update_library_deps target) list (APPEND INSTALL_TARGETS ${target}) target_link_libraries(${target} PRIVATE ${SSL_LIBRARIES}) if (MICROSOFT) - target_link_libraries(${target} PRIVATE ws2_32.lib Iphlpapi.lib) + target_link_libraries(${target} PRIVATE ws2_32.lib) endif() endmacro() @@ -642,6 +642,10 @@ macro(srt_make_application name) set_target_properties(${name} PROPERTIES COMPILE_FLAGS "${CFLAGS_CXX_STANDARD} ${EXTRA_stransmit}" ${FORCE_RPATH}) target_link_libraries(${name} ${srt_link_library}) + + if (MICROSOFT) + target_link_libraries(${target} PRIVATE Iphlpapi.lib) + endif() endmacro() macro(srt_add_application name sources) diff --git a/apps/apputil.cpp b/apps/apputil.cpp index 71e234606..b9823fee4 100644 --- a/apps/apputil.cpp +++ b/apps/apputil.cpp @@ -14,6 +14,16 @@ #include #include "apputil.hpp" +#include "netinet_any.h" + +#ifdef WIN32 + #include // getting local interfaces +#else + #include // getting local interfaces +#endif + +using namespace std; + // NOTE: MINGW currently does not include support for inet_pton(). See // http://mingw.5.n7.nabble.com/Win32API-request-for-new-functions-td22029.html @@ -68,7 +78,7 @@ static int inet_pton(int af, const char * src, void * dst) } #endif // __MINGW__ -sockaddr_in CreateAddrInet(const std::string& name, unsigned short port) +sockaddr_in CreateAddrInet(const string& name, unsigned short port) { sockaddr_in sa; memset(&sa, 0, sizeof sa); @@ -86,7 +96,7 @@ sockaddr_in CreateAddrInet(const std::string& name, unsigned short port) // http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedInternet3b.html hostent* he = gethostbyname(name.c_str()); if ( !he || he->h_addrtype != AF_INET ) - throw std::invalid_argument("SrtSource: host not found: " + name); + throw invalid_argument("SrtSource: host not found: " + name); sa.sin_addr = *(in_addr*)he->h_addr_list[0]; } @@ -94,12 +104,12 @@ sockaddr_in CreateAddrInet(const std::string& name, unsigned short port) return sa; } -std::string Join(const std::vector& in, std::string sep) +string Join(const vector& in, string sep) { if ( in.empty() ) return ""; - std::ostringstream os; + ostringstream os; os << in[0]; for (auto i = in.begin()+1; i != in.end(); ++i) @@ -108,7 +118,7 @@ std::string Join(const std::vector& in, std::string sep) } -options_t ProcessOptions(char* const* argv, int argc, std::vector scheme) +options_t ProcessOptions(char* const* argv, int argc, vector scheme) { using namespace std; @@ -183,3 +193,86 @@ options_t ProcessOptions(char* const* argv, int argc, std::vector return params; } +static vector GetLocalInterfaces() +{ + vector locals; +#ifdef WIN32 + ULONG family = s->m_pSelfAddr->sa_family; + ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; + ULONG outBufLen = 0; + + // This function doesn't allocate memory by itself, you have to do it + // yourself, worst case when it's too small, the size will be corrected + // and the function will do nothing. So, simply, call the function with + // always too little 0 size and make it show the correct one. + GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen); + // Ignore errors. Check errors on the real call. + + // Good, now we can allocate memory + PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)::operator new(outBufLen); + ULONG st = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); + if (st == ERROR_SUCCESS) + { + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; + while (pUnicast) + { + locals.push_back(pUnicast->Address.lpSockaddr); + pUnicast = pUnicast->Next; + } + } + + ::operator delete(pAddresses); + +#else + // Use POSIX method: getifaddrs + struct ifaddrs* pif, * pifa; + int st = getifaddrs(&pifa); + if (st == 0) + { + for (pif = pifa; pif; pif = pif->ifa_next) + { + locals.push_back(pif->ifa_addr); + } + } + + freeifaddrs(pifa); +#endif + return locals; +} + +bool IsTargetAddrSelf(const sockaddr* boundaddr, const sockaddr* targetaddr) +{ + sockaddr_any bound = boundaddr; + sockaddr_any target = targetaddr; + + if (!bound.isany()) + { + // Bound to a specific local address, so only check if + // this isn't the same address as 'target'. + if (target.equal_address(bound)) + { + return true; + } + } + else + { + // Bound to INADDR_ANY, so check matching with any local IP address + vector locals = GetLocalInterfaces(); + + // If any of the above function fails, it will collect + // no local interfaces, so it's impossible to check anything. + // OTOH it should also mean that the network isn't working, + // so it's unlikely, as well as no address should match the + // local address anyway. + for (size_t i = 0; i < locals.size(); ++i) + { + if (locals[i].equal_address(target)) + { + return true; + } + } + } + + return false; +} + diff --git a/apps/apputil.hpp b/apps/apputil.hpp index be2549643..746c7f71c 100644 --- a/apps/apputil.hpp +++ b/apps/apputil.hpp @@ -115,5 +115,6 @@ struct OptionScheme options_t ProcessOptions(char* const* argv, int argc, std::vector scheme); +bool IsTargetAddrSelf(const sockaddr* boundaddr, const sockaddr* targetaddr); #endif // INC__APPCOMMON_H diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 3d938ab4b..2d4dcdc72 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -65,9 +65,6 @@ modified by #ifdef WIN32 #include - #include // getting local interfaces -#else - #include // getting local interfaces #endif using namespace std; @@ -827,87 +824,6 @@ int CUDTUnited::connect(const SRTSOCKET u, const sockaddr* name, int namelen, in else if (s->m_Status != SRTS_OPENED) throw CUDTException(MJ_NOTSUP, MN_ISCONNECTED, 0); - if (s->m_pUDT->m_bRendezvous) - { - sockaddr_any bound = s->m_pSelfAddr; - sockaddr_any target = name; - - if (!bound.isany()) - { - // Bound to a specific local address, so only check if - // this isn't the same address as 'target'. - if (target.equal_address(bound)) - { - LOGC(mglog.Error, log << "connect: Rendezvous attempt to self on addr: " - << SockaddrToString(&target.sa) << " - rejected"); - throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); - - } - } - else - { - // Bound to INADDR_ANY, so matching with any local IP address is invalid. - vector locals; -#ifdef WIN32 - ULONG family = s->m_pSelfAddr->sa_family; - ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; - ULONG outBufLen = 0; - - // This function doesn't allocate memory by itself, you have to do it - // yourself, worst case when it's too small, the size will be corrected - // and the function will do nothing. So, simply, call the function with - // always too little 0 size and make it show the correct one. - GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen); - // Ignore errors. Check errors on the real call. - - // Good, now we can allocate memory - PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)::operator new(outBufLen); - ULONG st = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); - if (st == ERROR_SUCCESS) - { - PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; - while (pUnicast) - { - locals.push_back(pUnicast->Address.lpSockaddr); - pUnicast = pUnicast->Next; - } - } - - ::operator delete(pAddresses); - -#else - // Use POSIX method: getifaddrs - struct ifaddrs* pif, * pifa; - int st = getifaddrs(&pifa); - if (st == 0) - { - for (pif = pifa; pif; pif = pif->ifa_next) - { - locals.push_back(pif->ifa_addr); - } - } - - freeifaddrs(pifa); -#endif - - // If any of the above function fails, it will collect - // no local interfaces, so it's impossible to check anything. - // OTOH it should also mean that the network isn't working, - // so it's unlikely, as well as no address should match the - // local address anyway. - for (size_t i = 0; i < locals.size(); ++i) - { - if (locals[i].equal_address(target)) - { - LOGC(mglog.Error, log << "connect: Rendezvous bound to any, but target (" - << SockaddrToString(&target.sa) << ") matches one of local interfaces"); - throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); - } - } - - } - } - // connect_complete() may be called before connect() returns. // So we need to update the status before connect() is called, // otherwise the status may be overwritten with wrong value diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp index 435e628a8..44b3122d0 100644 --- a/testing/testmedia.cpp +++ b/testing/testmedia.cpp @@ -24,6 +24,7 @@ #endif #include "netinet_any.h" +#include "api.h" // SockaddrToString - XXX move to utils or some more suitable place #include "apputil.hpp" #include "socketoptions.hpp" #include "uriparser.hpp" @@ -579,6 +580,21 @@ void SrtCommon::ConnectClient(string host, int port) sockaddr_in sa = CreateAddrInet(host, port); sockaddr* psa = (sockaddr*)&sa; + { + // Check if trying to connect to self. + sockaddr_any lsa; + int size = lsa.size(); + srt_getsockname(m_sock, &lsa, &size); + + if (lsa.hport() == port && IsTargetAddrSelf(&lsa, psa)) + { + Verb() << "ERROR: Trying to connect to SELF address " << SockaddrToString(psa) + << " with socket bound to " << SockaddrToString(&lsa); + UDT::ERRORINFO inval(MJ_SETUP, MN_INVAL, 0); + Error(inval, "srt_connect"); + } + } + Verb() << "Connecting to " << host << ":" << port << " ... " << VerbNoEOL; int stat = srt_connect(m_sock, psa, sizeof sa); if ( stat == SRT_ERROR ) From 00e10c2f2828e11d6b5a7af0d5f945d4cefff0b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Thu, 17 May 2018 13:28:26 +0200 Subject: [PATCH 07/24] Fixed build break on Windows --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ebbb5b89..c7e0e20d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -644,7 +644,7 @@ macro(srt_make_application name) target_link_libraries(${name} ${srt_link_library}) if (MICROSOFT) - target_link_libraries(${target} PRIVATE Iphlpapi.lib) + target_link_libraries(${name} PRIVATE Iphlpapi.lib) endif() endmacro() From 1d5bd086bbd09f782130ada9f510950ad3db3836 Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Thu, 17 May 2018 16:15:33 +0200 Subject: [PATCH 08/24] Fixed incorrect implementation on Windows. Reading all families --- CMakeLists.txt | 11 +++++++---- apps/apputil.cpp | 24 +++++++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7e0e20d9..fe4102dd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -644,7 +644,7 @@ macro(srt_make_application name) target_link_libraries(${name} ${srt_link_library}) if (MICROSOFT) - target_link_libraries(${name} PRIVATE Iphlpapi.lib) + target_link_libraries(${name} Iphlpapi) endif() endmacro() @@ -724,9 +724,12 @@ if ( ENABLE_CXX11 ) endmacro() srt_add_testprogram(utility-test) - srt_add_testprogram(uriparser-test) - target_compile_options(uriparser-test PRIVATE -DTEST) - target_compile_options(uriparser-test PRIVATE ${CFLAGS_CXX_STANDARD}) + if (NOT WIN32) + # Block this for Windows because this causes weird GPF and symlink problems. + srt_add_testprogram(uriparser-test) + target_compile_options(uriparser-test PRIVATE -DTEST) + target_compile_options(uriparser-test PRIVATE ${CFLAGS_CXX_STANDARD}) + endif() srt_add_testprogram(srt-test-live) srt_make_application(srt-test-live) diff --git a/apps/apputil.cpp b/apps/apputil.cpp index b9823fee4..e96be70ea 100644 --- a/apps/apputil.cpp +++ b/apps/apputil.cpp @@ -9,9 +9,9 @@ */ #include -// For Options #include #include +#include #include "apputil.hpp" #include "netinet_any.h" @@ -197,20 +197,24 @@ static vector GetLocalInterfaces() { vector locals; #ifdef WIN32 - ULONG family = s->m_pSelfAddr->sa_family; ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; - ULONG outBufLen = 0; + ULONG outBufLen4 = 0, outBufLen6 = 0, outBufLen = 0; // This function doesn't allocate memory by itself, you have to do it // yourself, worst case when it's too small, the size will be corrected // and the function will do nothing. So, simply, call the function with // always too little 0 size and make it show the correct one. - GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen); + GetAdaptersAddresses(AF_INET, flags, NULL, NULL, &outBufLen4); + GetAdaptersAddresses(AF_INET, flags, NULL, NULL, &outBufLen6); // Ignore errors. Check errors on the real call. + // (Have doubts about this "max" here, as VC reports errors when + // using std::max, so it will likely resolve to a macro - hope this + // won't cause portability problems, this code is Windows only. + outBufLen = max(outBufLen4, outBufLen6); // Good, now we can allocate memory PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)::operator new(outBufLen); - ULONG st = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); + ULONG st = GetAdaptersAddresses(AF_INET, flags, NULL, pAddresses, &outBufLen); if (st == ERROR_SUCCESS) { PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; @@ -220,6 +224,16 @@ static vector GetLocalInterfaces() pUnicast = pUnicast->Next; } } + st = GetAdaptersAddresses(AF_INET6, flags, NULL, pAddresses, &outBufLen); + if (st == ERROR_SUCCESS) + { + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; + while (pUnicast) + { + locals.push_back(pUnicast->Address.lpSockaddr); + pUnicast = pUnicast->Next; + } + } ::operator delete(pAddresses); From 6356b7660adbf98624fcc2966125d1ddcd3f6519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Fri, 9 Aug 2019 08:52:20 +0200 Subject: [PATCH 09/24] Fixed after merge --- apps/apputil.cpp | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/apps/apputil.cpp b/apps/apputil.cpp index 52b2dc40a..0e4c9941b 100644 --- a/apps/apputil.cpp +++ b/apps/apputil.cpp @@ -121,7 +121,8 @@ options_t ProcessOptions(char* const* argv, int argc, std::vector { using namespace std; - string current_key = ""; + string current_key; + string extra_arg; size_t vals = 0; OptionScheme::Args type = OptionScheme::ARG_VAR; // This is for no-option-yet or consumed map> params; @@ -133,14 +134,8 @@ options_t ProcessOptions(char* const* argv, int argc, std::vector // cout << "*D ARG: '" << a << "'\n"; if (moreoptions && a[0] == '-') { - string key(a + 1); // omit '-' - size_t pos = key.find_first_of(":"); - if (pos == string::npos) - pos = key.find(' '); - string value = pos == string::npos ? "" : key.substr(pos + 1); - key = key.substr(0, pos); - - current_key = key; + size_t seppos; // (see goto, it would jump over initialization) + current_key = a+1; if ( current_key == "-" ) { // The -- argument terminates the options. @@ -150,28 +145,51 @@ options_t ProcessOptions(char* const* argv, int argc, std::vector moreoptions = false; goto EndOfArgs; } + + // Maintain the backward compatibility with argument specified after : + // or with one string separated by space inside. + seppos = current_key.find(':'); + if (seppos == string::npos) + seppos = current_key.find(' '); + if (seppos != string::npos) + { + // Old option specification. + extra_arg = current_key.substr(seppos + 1); + current_key = current_key.substr(0, 0 + seppos); + } + params[current_key].clear(); vals = 0; + if (extra_arg != "") + { + params[current_key].push_back(extra_arg); + ++vals; + extra_arg.clear(); + } + // Find the key in the scheme. If not found, treat it as ARG_NONE. for (auto s: scheme) { if (s.names.count(current_key)) { // cout << "*D found '" << current_key << "' in scheme type=" << int(s.type) << endl; - if (s.type == OptionScheme::ARG_NONE ) + if (s.type == OptionScheme::ARG_NONE) { // Anyway, consider it already processed. break; } - else if (s.type == OptionScheme::ARG_ONE) + type = s.type; + + if ( vals == 1 && type == OptionScheme::ARG_ONE ) { - if (!value.empty()) - params[current_key].push_back(value); + // Argument for one-arg option already consumed, + // so set to free args. + goto EndOfArgs; } - type = s.type; goto Found; } + } // Not found: set ARG_NONE. // cout << "*D KEY '" << current_key << "' assumed type NONE\n"; From 1c1b4f278cde08cecb1b24fd5e90b68a1faea6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Fri, 9 Aug 2019 09:41:09 +0200 Subject: [PATCH 10/24] Fixed external inet_pton for mingw --- apps/apputil.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/apputil.cpp b/apps/apputil.cpp index 0e4c9941b..085dd0a33 100644 --- a/apps/apputil.cpp +++ b/apps/apputil.cpp @@ -37,8 +37,10 @@ using namespace std; // See: // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742214(v=vs.85).aspx // http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedInternet3b.html -#ifdef __MINGW32__ -static int inet_pton(int af, const char * src, void * dst) +#if defined(__MINGW32__) && !defined(InetPton) +namespace // Prevent conflict in case when still defined +{ +int inet_pton(int af, const char * src, void * dst) { struct sockaddr_storage ss; int ssSize = sizeof(ss); @@ -76,6 +78,7 @@ static int inet_pton(int af, const char * src, void * dst) return 0; } +} #endif // __MINGW__ sockaddr_in CreateAddrInet(const string& name, unsigned short port) From 46208500d68b057e906cd9bc1236cd7a3179ac05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Wed, 14 Aug 2019 12:34:57 +0200 Subject: [PATCH 11/24] Moved Iphlpapi lib to test programs only --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 571962746..56c60b9c5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -763,10 +763,6 @@ macro(srt_make_application name) target_link_libraries(${name} PRIVATE ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS}) endif() - if (MICROSOFT AND ENABLE_CONSELF_CHECK_WIN32) - target_link_libraries(${name} Iphlpapi) - add_definitions(-DSRT_ENABLE_CONSELF_CHECK_WIN32) - endif() if (srt_libspec_static AND CMAKE_DL_LIBS) target_link_libraries(${name} ${CMAKE_DL_LIBS}) endif() @@ -834,6 +830,10 @@ if (ENABLE_APPS) # list of source files in its own Manifest file. MafReadDir(testing ${name}.maf SOURCES SOURCES_app) srt_add_program(${name} ${SOURCES_app}) + if (MICROSOFT AND ENABLE_CONSELF_CHECK_WIN32) + target_link_libraries(${name} Iphlpapi) + add_definitions(-DSRT_ENABLE_CONSELF_CHECK_WIN32) + endif() endmacro() srt_add_testprogram(utility-test) From 99399ffadd1e7e597a928074c957cfe76bce3b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Wed, 14 Aug 2019 13:22:26 +0200 Subject: [PATCH 12/24] Some fixes for Windows --- CMakeLists.txt | 9 +++++---- apps/apputil.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56c60b9c5..0aa707441 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,7 @@ endif() option(CYGWIN_USE_POSIX "Should the POSIX API be used for cygwin. Ignored if the system isn't cygwin." OFF) option(ENABLE_CXX11 "Should the c++11 parts (srt-live-transmit) be enabled" ON) option(ENABLE_APPS "Should the Support Applications be Built?" ON) +option(ENABLE_TESTING "Should the Developer Test Applications be Built?" OFF) option(ENABLE_PROFILE "Should instrument the code for profiling. Ignored for non-GNU compiler." $ENV{HAI_BUILD_PROFILE}) option(ENABLE_LOGGING "Should logging be enabled" ON) option(ENABLE_HEAVY_LOGGING "Should heavy debug logging be enabled" ${ENABLE_HEAVY_LOGGING_DEFAULT}) @@ -732,6 +733,10 @@ macro(srt_add_program name) target_include_directories(${name} PRIVATE apps) target_include_directories(${name} PRIVATE common) install(TARGETS ${name} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + if (MICROSOFT AND ENABLE_CONSELF_CHECK_WIN32) + target_link_libraries(${name} Iphlpapi) + add_definitions(-DSRT_ENABLE_CONSELF_CHECK_WIN32) + endif() endmacro() macro(srt_make_application name) @@ -830,10 +835,6 @@ if (ENABLE_APPS) # list of source files in its own Manifest file. MafReadDir(testing ${name}.maf SOURCES SOURCES_app) srt_add_program(${name} ${SOURCES_app}) - if (MICROSOFT AND ENABLE_CONSELF_CHECK_WIN32) - target_link_libraries(${name} Iphlpapi) - add_definitions(-DSRT_ENABLE_CONSELF_CHECK_WIN32) - endif() endmacro() srt_add_testprogram(utility-test) diff --git a/apps/apputil.cpp b/apps/apputil.cpp index e4536320d..51c5f9cfb 100644 --- a/apps/apputil.cpp +++ b/apps/apputil.cpp @@ -240,7 +240,7 @@ static vector GetLocalInterfaces() { vector locals; #ifdef _WIN32 - ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; + ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_INTERFACES; ULONG outBufLen4 = 0, outBufLen6 = 0, outBufLen = 0; // This function doesn't allocate memory by itself, you have to do it From bc3e2ed879405b7da1c4a54da2941e0932ff65ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Fri, 8 Nov 2019 12:25:22 +0100 Subject: [PATCH 13/24] Removed empty line to avoid unnecessary changes --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c53739cc0..d3d687010 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -844,7 +844,6 @@ macro(srt_make_application name) if (USE_GNUSTL) target_link_libraries(${name} PRIVATE ${GNUSTL_LIBRARIES} ${GNUSTL_LDFLAGS}) endif() - if (srt_libspec_static AND CMAKE_DL_LIBS) target_link_libraries(${name} ${CMAKE_DL_LIBS}) endif() From e27c268dbc8a83e55c58a69bc2f53994ada18de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Mon, 28 Nov 2022 12:58:24 +0100 Subject: [PATCH 14/24] Fixed compile errors after merge --- apps/apputil.cpp | 3 ++- testing/testmedia.cpp | 12 +++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/apps/apputil.cpp b/apps/apputil.cpp index 0cfa6875a..dc96c2245 100644 --- a/apps/apputil.cpp +++ b/apps/apputil.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "srt.h" // Required for SRT_SYNC_CLOCK_* definitions. #include "apputil.hpp" #include "netinet_any.h" @@ -503,4 +504,4 @@ bool IsTargetAddrSelf(const sockaddr* , const sockaddr* ) // prevention from connecting to self will not be in force. return false; } -#endif \ No newline at end of file +#endif diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp index 895173531..115537573 100755 --- a/testing/testmedia.cpp +++ b/testing/testmedia.cpp @@ -1283,15 +1283,13 @@ void SrtCommon::ConnectClient(string host, int port) { // Check if trying to connect to self. sockaddr_any lsa; - int size = lsa.size(); - srt_getsockname(m_sock, &lsa, &size); + srt_getsockname(m_sock, lsa.get(), &lsa.len); - if (lsa.hport() == port && IsTargetAddrSelf(&lsa, psa)) + if (lsa.hport() == port && IsTargetAddrSelf(lsa.get(), sa.get())) { - Verb() << "ERROR: Trying to connect to SELF address " << SockaddrToString(psa) - << " with socket bound to " << SockaddrToString(&lsa); - UDT::ERRORINFO inval(MJ_SETUP, MN_INVAL, 0); - Error(inval, "srt_connect"); + Verb() << "ERROR: Trying to connect to SELF address " << sa.str() + << " with socket bound to " << lsa.str(); + Error("srt_connect", 0, SRT_EINVPARAM); } } Verb() << "Connecting to " << host << ":" << port << " ... " << VerbNoEOL; From c1ed25365810133a45a76dd966e53f14c5b55e7f Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Fri, 26 Jul 2024 12:38:24 +0200 Subject: [PATCH 15/24] [core][API] Added srt_getsockdevname to obtain the device name from a connected socket --- CMakeLists.txt | 6 +-- apps/apputil.cpp | 87 ++----------------------------------------- apps/verbose.hpp | 2 +- srtcore/api.cpp | 51 +++++++++++++++++++++++++ srtcore/api.h | 1 + srtcore/common.cpp | 83 +++++++++++++++++++++++++++++++++++++++++ srtcore/common.h | 8 ++++ srtcore/core.h | 1 + srtcore/srt.h | 1 + srtcore/srt_c_api.cpp | 1 + testing/testmedia.cpp | 12 ++++++ 11 files changed, 165 insertions(+), 88 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97755da77..347703022 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,7 +175,7 @@ option(USE_OPENSSL_PC "Use pkg-config to find OpenSSL libraries" ON) option(OPENSSL_USE_STATIC_LIBS "Link OpenSSL libraries statically." OFF) option(USE_BUSY_WAITING "Enable more accurate sending times at a cost of potentially higher CPU load" OFF) option(USE_GNUSTL "Get c++ library/headers from the gnustl.pc" OFF) -option(ENABLE_CONSELF_CHECK_WIN32 "Enable rendezvous-connect-to-self prevention on Windows (adds Iphlpapi.lib dep)" OFF) +option(ENABLE_LOCALIF_WIN32 "Enable rendezvous-connect-to-self prevention on Windows (adds Iphlpapi.lib dep)" OFF) option(ENABLE_SOCK_CLOEXEC "Enable setting SOCK_CLOEXEC on a socket" ON) option(ENABLE_SHOW_PROJECT_CONFIG "Enable show Project Configuration" OFF) @@ -1293,9 +1293,9 @@ macro(srt_add_program name) else() message(WARNING "No location to install program ${name}") endif() - if (MICROSOFT AND ENABLE_CONSELF_CHECK_WIN32) + if (MICROSOFT AND ENABLE_LOCALIF_WIN32) target_link_libraries(${name} Iphlpapi) - add_definitions(-DSRT_ENABLE_CONSELF_CHECK_WIN32) + add_definitions(-DSRT_ENABLE_LOCALIF_WIN32) endif() endmacro() diff --git a/apps/apputil.cpp b/apps/apputil.cpp index ec1996b73..6b54b41f1 100644 --- a/apps/apputil.cpp +++ b/apps/apputil.cpp @@ -16,8 +16,8 @@ #include #include -#include #include "srt.h" // Required for SRT_SYNC_CLOCK_* definitions. +#include "common.h" #include "apputil.hpp" #include "netinet_any.h" #include "srt_compat.h" @@ -391,79 +391,6 @@ void PrintLibVersion() cerr << "SRT Library version: " << major << "." << minor << "." << patch << ", clock type: " << SRTClockTypeStr() << endl; } -#ifdef _WIN32 - #if SRT_ENABLE_CONSELF_CHECK_WIN32 - #define ENABLE_CONSELF_CHECK 1 - #endif -#else - -// For non-Windows platofm, enable always. -#define ENABLE_CONSELF_CHECK 1 -#endif - -#if ENABLE_CONSELF_CHECK - -static vector GetLocalInterfaces() -{ - vector locals; -#ifdef _WIN32 - ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_INTERFACES; - ULONG outBufLen4 = 0, outBufLen6 = 0, outBufLen = 0; - - // This function doesn't allocate memory by itself, you have to do it - // yourself, worst case when it's too small, the size will be corrected - // and the function will do nothing. So, simply, call the function with - // always too little 0 size and make it show the correct one. - GetAdaptersAddresses(AF_INET, flags, NULL, NULL, &outBufLen4); - GetAdaptersAddresses(AF_INET, flags, NULL, NULL, &outBufLen6); - // Ignore errors. Check errors on the real call. - // (Have doubts about this "max" here, as VC reports errors when - // using std::max, so it will likely resolve to a macro - hope this - // won't cause portability problems, this code is Windows only. - outBufLen = max(outBufLen4, outBufLen6); - - // Good, now we can allocate memory - PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)::operator new(outBufLen); - ULONG st = GetAdaptersAddresses(AF_INET, flags, NULL, pAddresses, &outBufLen); - if (st == ERROR_SUCCESS) - { - PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; - while (pUnicast) - { - locals.push_back(pUnicast->Address.lpSockaddr); - pUnicast = pUnicast->Next; - } - } - st = GetAdaptersAddresses(AF_INET6, flags, NULL, pAddresses, &outBufLen); - if (st == ERROR_SUCCESS) - { - PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; - while (pUnicast) - { - locals.push_back(pUnicast->Address.lpSockaddr); - pUnicast = pUnicast->Next; - } - } - - ::operator delete(pAddresses); - -#else - // Use POSIX method: getifaddrs - struct ifaddrs* pif, * pifa; - int st = getifaddrs(&pifa); - if (st == 0) - { - for (pif = pifa; pif; pif = pif->ifa_next) - { - locals.push_back(pif->ifa_addr); - } - } - - freeifaddrs(pifa); -#endif - return locals; -} - bool IsTargetAddrSelf(const sockaddr* boundaddr, const sockaddr* targetaddr) { sockaddr_any bound = boundaddr; @@ -481,7 +408,7 @@ bool IsTargetAddrSelf(const sockaddr* boundaddr, const sockaddr* targetaddr) else { // Bound to INADDR_ANY, so check matching with any local IP address - vector locals = GetLocalInterfaces(); + vector locals = srt::GetLocalInterfaces(); // If any of the above function fails, it will collect // no local interfaces, so it's impossible to check anything. @@ -490,7 +417,7 @@ bool IsTargetAddrSelf(const sockaddr* boundaddr, const sockaddr* targetaddr) // local address anyway. for (size_t i = 0; i < locals.size(); ++i) { - if (locals[i].equal_address(target)) + if (locals[i].addr.equal_address(target)) { return true; } @@ -500,11 +427,3 @@ bool IsTargetAddrSelf(const sockaddr* boundaddr, const sockaddr* targetaddr) return false; } -#else -bool IsTargetAddrSelf(const sockaddr* , const sockaddr* ) -{ - // State that the given address is never "self", so - // prevention from connecting to self will not be in force. - return false; -} -#endif diff --git a/apps/verbose.hpp b/apps/verbose.hpp index 879d54086..90aca74bd 100644 --- a/apps/verbose.hpp +++ b/apps/verbose.hpp @@ -80,7 +80,7 @@ inline void Print(Log& ) {} template inline void Print(Log& out, Arg1&& arg1, Args&&... args) { - out << std::forward(arg1); + out << std::forward(arg1); Print(out, args...); } diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 665593c39..76db04c21 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -2180,6 +2180,39 @@ void srt::CUDTUnited::getsockname(const SRTSOCKET u, sockaddr* pw_name, int* pw_ *pw_namelen = len; } +void srt::CUDTUnited::getsockdevname(const SRTSOCKET u, char* pw_name, size_t* pw_namelen) +{ + if (!pw_name || !pw_namelen) + throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); + + CUDTSocket* s = locateSocket(u); + + if (!s) + throw CUDTException(MJ_NOTSUP, MN_SIDINVAL, 0); + + if (s->core().m_bBroken) + throw CUDTException(MJ_NOTSUP, MN_SIDINVAL, 0); + + if (s->m_Status == SRTS_INIT) + throw CUDTException(MJ_CONNECTION, MN_NOCONN, 0); + + vector locals = GetLocalInterfaces(); + + for (vector::iterator i = locals.begin(); i != locals.end(); ++i) + { + if (i->addr.equal_address(s->m_SelfAddr)) + { + if (*pw_namelen < i->name.size() + 1) + throw CUDTException(MJ_NOTSUP, MN_INVAL); + memcpy((pw_name), i->name.c_str(), i->name.size()+1); + *pw_namelen = i->name.size(); + return; + } + } + + *pw_namelen = 0; // report empty one +} + int srt::CUDTUnited::select(UDT::UDSET* readfds, UDT::UDSET* writefds, UDT::UDSET* exceptfds, const timeval* timeout) { const steady_clock::time_point entertime = steady_clock::now(); @@ -3784,6 +3817,24 @@ int srt::CUDT::getsockname(SRTSOCKET u, sockaddr* name, int* namelen) } } +int srt::CUDT::getsockdevname(SRTSOCKET u, char* name, size_t* namelen) +{ + try + { + uglobal().getsockdevname(u, name, namelen); + return 0; + } + catch (const CUDTException& e) + { + return APIError(e); + } + catch (const std::exception& ee) + { + LOGC(aclog.Fatal, log << "getsockname: UNEXPECTED EXCEPTION: " << typeid(ee).name() << ": " << ee.what()); + return APIError(MJ_UNKNOWN, MN_NONE, 0); + } +} + int srt::CUDT::getsockopt(SRTSOCKET u, int, SRT_SOCKOPT optname, void* pw_optval, int* pw_optlen) { if (!pw_optval || !pw_optlen) diff --git a/srtcore/api.h b/srtcore/api.h index 6dbad6634..99f33642a 100644 --- a/srtcore/api.h +++ b/srtcore/api.h @@ -299,6 +299,7 @@ class CUDTUnited int close(CUDTSocket* s); void getpeername(const SRTSOCKET u, sockaddr* name, int* namelen); void getsockname(const SRTSOCKET u, sockaddr* name, int* namelen); + void getsockdevname(const SRTSOCKET u, char* name, size_t* namelen); int select(UDT::UDSET* readfds, UDT::UDSET* writefds, UDT::UDSET* exceptfds, const timeval* timeout); int selectEx(const std::vector& fds, std::vector* readfds, diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 6d747ecaa..6a18afcce 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -60,6 +60,15 @@ modified by #include #include #include + +#if _WIN32 + #if SRT_ENABLE_LOCALIF_WIN32 + #include + #endif +#else + #include +#endif + #include "udt.h" #include "md5.h" #include "common.h" @@ -461,6 +470,80 @@ bool SrtParseConfig(const string& s, SrtConfig& w_config) return true; } + +vector GetLocalInterfaces() +{ + vector locals; +#ifdef _WIN32 + // If not enabled, simply an empty local vector will be returned + #if SRT_ENABLE_LOCALIF_WIN32 + ULONG flags = GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_INTERFACES; + ULONG outBufLen = 0; + + // This function doesn't allocate memory by itself, you have to do it + // yourself, worst case when it's too small, the size will be corrected + // and the function will do nothing. So, simply, call the function with + // always too little 0 size and make it show the correct one. + GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &outBufLen); + // Ignore errors. Check errors on the real call. + // (Have doubts about this "max" here, as VC reports errors when + // using std::max, so it will likely resolve to a macro - hope this + // won't cause portability problems, this code is Windows only. + + // Good, now we can allocate memory + PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)::operator new(outBufLen); + ULONG st = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &outBufLen); + if (st == ERROR_SUCCESS) + { + for (PIP_ADAPTER_ADDRESSES* i = pAddresses; i; i = pAddresses->Next) + { + std::string name = i->AdapterName; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; + while (pUnicast) + { + LocalInterface a; + a.addr = pUnicast->Address.lpSockaddr; + if (a.addr.len > 0) + { + // DO NOT collect addresses that are not of + // AF_INET or AF_INET6 family. + a.name = name; + locals.push_back(a); + } + pUnicast = pUnicast->Next; + } + } + } + + ::operator delete(pAddresses); + #endif + +#else + // Use POSIX method: getifaddrs + struct ifaddrs* pif, * pifa; + int st = getifaddrs(&pifa); + if (st == 0) + { + for (pif = pifa; pif; pif = pif->ifa_next) + { + LocalInterface i; + i.addr = pif->ifa_addr; + if (i.addr.len > 0) + { + // DO NOT collect addresses that are not of + // AF_INET or AF_INET6 family. + i.name = pif->ifa_name ? pif->ifa_name : ""; + locals.push_back(i); + } + } + } + + freeifaddrs(pifa); +#endif + return locals; +} + + } // namespace srt namespace srt_logging diff --git a/srtcore/common.h b/srtcore/common.h index 6a8912118..017badb3b 100644 --- a/srtcore/common.h +++ b/srtcore/common.h @@ -1453,6 +1453,14 @@ inline std::string FormatLossArray(const std::vector< std::pair GetLocalInterfaces(); + } // namespace srt #endif diff --git a/srtcore/core.h b/srtcore/core.h index 3935b99d3..5614d554f 100644 --- a/srtcore/core.h +++ b/srtcore/core.h @@ -217,6 +217,7 @@ class CUDT static int close(SRTSOCKET u); static int getpeername(SRTSOCKET u, sockaddr* name, int* namelen); static int getsockname(SRTSOCKET u, sockaddr* name, int* namelen); + static int getsockdevname(SRTSOCKET u, char* name, size_t* namelen); static int getsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, void* optval, int* optlen); static int setsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, const void* optval, int optlen); static int send(SRTSOCKET u, const char* buf, int len, int flags); diff --git a/srtcore/srt.h b/srtcore/srt.h index 614a85aea..97945abc5 100644 --- a/srtcore/srt.h +++ b/srtcore/srt.h @@ -776,6 +776,7 @@ SRT_API int srt_rendezvous (SRTSOCKET u, const struct sockaddr* local_na SRT_API int srt_close (SRTSOCKET u); SRT_API int srt_getpeername (SRTSOCKET u, struct sockaddr* name, int* namelen); SRT_API int srt_getsockname (SRTSOCKET u, struct sockaddr* name, int* namelen); +SRT_API int srt_getsockdevname(SRTSOCKET u, char* name, size_t* namelen); SRT_API int srt_getsockopt (SRTSOCKET u, int level /*ignored*/, SRT_SOCKOPT optname, void* optval, int* optlen); SRT_API int srt_setsockopt (SRTSOCKET u, int level /*ignored*/, SRT_SOCKOPT optname, const void* optval, int optlen); SRT_API int srt_getsockflag (SRTSOCKET u, SRT_SOCKOPT opt, void* optval, int* optlen); diff --git a/srtcore/srt_c_api.cpp b/srtcore/srt_c_api.cpp index 031030cd7..2f2960bae 100644 --- a/srtcore/srt_c_api.cpp +++ b/srtcore/srt_c_api.cpp @@ -159,6 +159,7 @@ int srt_close(SRTSOCKET u) int srt_getpeername(SRTSOCKET u, struct sockaddr * name, int * namelen) { return CUDT::getpeername(u, name, namelen); } int srt_getsockname(SRTSOCKET u, struct sockaddr * name, int * namelen) { return CUDT::getsockname(u, name, namelen); } +int srt_getsockdevname(SRTSOCKET u, char* devname, size_t * devnamelen) { return CUDT::getsockdevname(u, devname, devnamelen); } int srt_getsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, void * optval, int * optlen) { return CUDT::getsockopt(u, level, optname, optval, optlen); } int srt_setsockopt(SRTSOCKET u, int level, SRT_SOCKOPT optname, const void * optval, int optlen) diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp index 101b2844d..55cadda8a 100755 --- a/testing/testmedia.cpp +++ b/testing/testmedia.cpp @@ -1419,6 +1419,18 @@ void SrtCommon::ConnectClient(string host, int port) } Verb() << " connected."; + + sockaddr_any agent; + string dev; + if (Verbose::on) + { + srt_getsockname(m_sock, agent.get(), &agent.len); + char name[256]; + size_t len = 255; + if (srt_getsockdevname(m_sock, name, &len) == SRT_SUCCESS) + dev.assign(name, len); + } + Verb("Connected AGENT:", agent.str(), "[", dev, "] PEER:", sa.str()); stat = ConfigurePost(m_sock); if (stat == SRT_ERROR) Error("ConfigurePost"); From e5aa2dc8725f86b849050b0c996831861fc8a378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Fri, 26 Jul 2024 12:43:05 +0200 Subject: [PATCH 16/24] Enabled LOCALIF flag on C++11-win workflow --- .github/workflows/cxx11-win.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cxx11-win.yaml b/.github/workflows/cxx11-win.yaml index 1a9e10a95..3beff7740 100644 --- a/.github/workflows/cxx11-win.yaml +++ b/.github/workflows/cxx11-win.yaml @@ -17,7 +17,7 @@ jobs: - name: configure run: | md _build && cd _build - cmake ../ -DENABLE_STDCXX_SYNC=ON -DENABLE_ENCRYPTION=OFF -DENABLE_UNITTESTS=ON -DENABLE_BONDING=ON + cmake ../ -DENABLE_STDCXX_SYNC=ON -DENABLE_ENCRYPTION=OFF -DENABLE_UNITTESTS=ON -DENABLE_BONDING=ON -DENABLE_LOCALIF_WIN32 - name: build run: cd _build && cmake --build ./ --config Release - name: test From b8fbbc56a742d74782d22eeb212213182a564193 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Fri, 26 Jul 2024 13:47:16 +0200 Subject: [PATCH 17/24] Fixed a case when the address is NULL (found on Cygwin) --- srtcore/common.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 6a18afcce..9b950c4f6 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -502,7 +502,8 @@ vector GetLocalInterfaces() while (pUnicast) { LocalInterface a; - a.addr = pUnicast->Address.lpSockaddr; + if (pUnicast->Address.lpSockaddr) + a.addr = pUnicast->Address.lpSockaddr; if (a.addr.len > 0) { // DO NOT collect addresses that are not of @@ -527,7 +528,8 @@ vector GetLocalInterfaces() for (pif = pifa; pif; pif = pif->ifa_next) { LocalInterface i; - i.addr = pif->ifa_addr; + if (pif->ifa_addr) + i.addr = pif->ifa_addr; if (i.addr.len > 0) { // DO NOT collect addresses that are not of From d51262ba82aa4f8db341ecf698589efe47a1d1cb Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Fri, 26 Jul 2024 13:49:17 +0200 Subject: [PATCH 18/24] Fixed mistake in workflofs/cxx11-win --- .github/workflows/cxx11-win.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cxx11-win.yaml b/.github/workflows/cxx11-win.yaml index 3beff7740..15d275aac 100644 --- a/.github/workflows/cxx11-win.yaml +++ b/.github/workflows/cxx11-win.yaml @@ -17,7 +17,7 @@ jobs: - name: configure run: | md _build && cd _build - cmake ../ -DENABLE_STDCXX_SYNC=ON -DENABLE_ENCRYPTION=OFF -DENABLE_UNITTESTS=ON -DENABLE_BONDING=ON -DENABLE_LOCALIF_WIN32 + cmake ../ -DENABLE_STDCXX_SYNC=ON -DENABLE_ENCRYPTION=OFF -DENABLE_UNITTESTS=ON -DENABLE_BONDING=ON -DENABLE_LOCALIF_WIN32=ON - name: build run: cd _build && cmake --build ./ --config Release - name: test From 7b53f6f17c488e7568e350a858c8070e2ef3539a Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Fri, 26 Jul 2024 13:58:26 +0200 Subject: [PATCH 19/24] Added printing device on listener in verbose mode --- testing/testmedia.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp index 55cadda8a..53c04669d 100755 --- a/testing/testmedia.cpp +++ b/testing/testmedia.cpp @@ -612,13 +612,17 @@ void SrtCommon::AcceptNewClient() } sockaddr_any agentaddr(AF_INET6); - string agent = ""; + string agent = "", dev; if (-1 != srt_getsockname(m_sock, (agentaddr.get()), (&agentaddr.len))) { agent = agentaddr.str(); + char name[256]; + size_t len = 255; + if (srt_getsockdevname(m_sock, name, &len) == SRT_SUCCESS) + dev.assign(name, len); } - Verb() << " connected [" << agent << "] <-- " << peer; + Verb() << " connected [" << agent << "] <-- " << peer << " [" << dev << "]"; } ::transmit_throw_on_interrupt = false; From 8fe7b3a3c47020e60c2c7783b70286dd7c7d1c7f Mon Sep 17 00:00:00 2001 From: Mikolaj Malecki Date: Fri, 26 Jul 2024 14:20:34 +0200 Subject: [PATCH 20/24] Fixed build break on Windows --- srtcore/common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 9b950c4f6..16397a719 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -495,7 +495,7 @@ vector GetLocalInterfaces() ULONG st = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &outBufLen); if (st == ERROR_SUCCESS) { - for (PIP_ADAPTER_ADDRESSES* i = pAddresses; i; i = pAddresses->Next) + for (PIP_ADAPTER_ADDRESSES i = pAddresses; i; i = pAddresses->Next) { std::string name = i->AdapterName; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; From 0488b2513012b3f1267b1ed031466686d752e48b Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Fri, 26 Jul 2024 15:08:16 +0200 Subject: [PATCH 21/24] Merged and fixed --- CMakeLists.txt | 19 +++++++++++++------ srtcore/common.cpp | 2 +- testing/testmedia.cpp | 8 ++------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 347703022..8e73832f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,7 @@ option(ENABLE_PKTINFO "Enable using IP_PKTINFO to allow the listener extracting option(ENABLE_RELATIVE_LIBPATH "Should application contain relative library paths, like ../lib" OFF) option(ENABLE_GETNAMEINFO "In-logs sockaddr-to-string should do rev-dns" OFF) option(ENABLE_UNITTESTS "Enable unit tests" OFF) +option(ENABLE_UNITTESTS_AUTO "Enable unit tests" OFF) option(ENABLE_ENCRYPTION "Enable encryption in SRT" ON) option(ENABLE_AEAD_API_PREVIEW "Enable AEAD API preview in SRT" Off) option(ENABLE_MAXREXMITBW "Enable SRTO_MAXREXMITBW (v1.6.0 API preview)" Off) @@ -175,7 +176,7 @@ option(USE_OPENSSL_PC "Use pkg-config to find OpenSSL libraries" ON) option(OPENSSL_USE_STATIC_LIBS "Link OpenSSL libraries statically." OFF) option(USE_BUSY_WAITING "Enable more accurate sending times at a cost of potentially higher CPU load" OFF) option(USE_GNUSTL "Get c++ library/headers from the gnustl.pc" OFF) -option(ENABLE_LOCALIF_WIN32 "Enable rendezvous-connect-to-self prevention on Windows (adds Iphlpapi.lib dep)" OFF) +option(ENABLE_LOCALIF_WIN32 "Enable local interface check ability on Windows (adds Iphlpapi.lib dep)" OFF) option(ENABLE_SOCK_CLOEXEC "Enable setting SOCK_CLOEXEC on a socket" ON) option(ENABLE_SHOW_PROJECT_CONFIG "Enable show Project Configuration" OFF) @@ -1282,6 +1283,10 @@ macro(srt_add_program_dont_install name) add_executable(${name} ${ARGN}) target_include_directories(${name} PRIVATE apps) target_include_directories(${name} PRIVATE common) + if (MICROSOFT AND ENABLE_LOCALIF_WIN32) + target_link_libraries(${name} Iphlpapi) + add_definitions(-DSRT_ENABLE_LOCALIF_WIN32) + endif() endmacro() macro(srt_add_program name) @@ -1293,10 +1298,6 @@ macro(srt_add_program name) else() message(WARNING "No location to install program ${name}") endif() - if (MICROSOFT AND ENABLE_LOCALIF_WIN32) - target_link_libraries(${name} Iphlpapi) - add_definitions(-DSRT_ENABLE_LOCALIF_WIN32) - endif() endmacro() macro(srt_make_application name) @@ -1479,6 +1480,10 @@ endif() srt_add_example(testcapi-connect.c) endif() +if (ENABLE_UNITTESTS_AUTO) + set (ENABLE_UNITTESTS ON) +endif() + if (ENABLE_UNITTESTS AND ENABLE_CXX11) @@ -1534,7 +1539,9 @@ if (ENABLE_UNITTESTS AND ENABLE_CXX11) #set_tests_properties(test-srt PROPERTIES RUN_SERIAL TRUE) else() set_tests_properties(${tests_srt} PROPERTIES RUN_SERIAL TRUE) - gtest_discover_tests(test-srt) + if (ENABLE_UNITTESTS_AUTO) + gtest_discover_tests(test-srt) + endif() endif() enable_testing() diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 16397a719..9b950c4f6 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -495,7 +495,7 @@ vector GetLocalInterfaces() ULONG st = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &outBufLen); if (st == ERROR_SUCCESS) { - for (PIP_ADAPTER_ADDRESSES i = pAddresses; i; i = pAddresses->Next) + for (PIP_ADAPTER_ADDRESSES* i = pAddresses; i; i = pAddresses->Next) { std::string name = i->AdapterName; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp index 53c04669d..55cadda8a 100755 --- a/testing/testmedia.cpp +++ b/testing/testmedia.cpp @@ -612,17 +612,13 @@ void SrtCommon::AcceptNewClient() } sockaddr_any agentaddr(AF_INET6); - string agent = "", dev; + string agent = ""; if (-1 != srt_getsockname(m_sock, (agentaddr.get()), (&agentaddr.len))) { agent = agentaddr.str(); - char name[256]; - size_t len = 255; - if (srt_getsockdevname(m_sock, name, &len) == SRT_SUCCESS) - dev.assign(name, len); } - Verb() << " connected [" << agent << "] <-- " << peer << " [" << dev << "]"; + Verb() << " connected [" << agent << "] <-- " << peer; } ::transmit_throw_on_interrupt = false; From 42666ca6506ce383a7bc365457f29626ea8c6208 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Fri, 26 Jul 2024 15:29:21 +0200 Subject: [PATCH 22/24] Fixing wrong withdrawn changes --- srtcore/common.cpp | 2 +- testing/testmedia.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/srtcore/common.cpp b/srtcore/common.cpp index 9b950c4f6..16397a719 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -495,7 +495,7 @@ vector GetLocalInterfaces() ULONG st = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &outBufLen); if (st == ERROR_SUCCESS) { - for (PIP_ADAPTER_ADDRESSES* i = pAddresses; i; i = pAddresses->Next) + for (PIP_ADAPTER_ADDRESSES i = pAddresses; i; i = pAddresses->Next) { std::string name = i->AdapterName; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAddresses->FirstUnicastAddress; diff --git a/testing/testmedia.cpp b/testing/testmedia.cpp index 55cadda8a..53c04669d 100755 --- a/testing/testmedia.cpp +++ b/testing/testmedia.cpp @@ -612,13 +612,17 @@ void SrtCommon::AcceptNewClient() } sockaddr_any agentaddr(AF_INET6); - string agent = ""; + string agent = "", dev; if (-1 != srt_getsockname(m_sock, (agentaddr.get()), (&agentaddr.len))) { agent = agentaddr.str(); + char name[256]; + size_t len = 255; + if (srt_getsockdevname(m_sock, name, &len) == SRT_SUCCESS) + dev.assign(name, len); } - Verb() << " connected [" << agent << "] <-- " << peer; + Verb() << " connected [" << agent << "] <-- " << peer << " [" << dev << "]"; } ::transmit_throw_on_interrupt = false; From eb6a84a2a61d5b97d26f7ad42f048110cb74cdd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Ma=C5=82ecki?= Date: Wed, 14 Aug 2024 12:15:57 +0200 Subject: [PATCH 23/24] Enabled LOCALIF always on windows, not only MICROSOFT --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f5781b9b..6d53f2f47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1283,7 +1283,7 @@ macro(srt_add_program_dont_install name) add_executable(${name} ${ARGN}) target_include_directories(${name} PRIVATE apps) target_include_directories(${name} PRIVATE common) - if (MICROSOFT AND ENABLE_LOCALIF_WIN32) + if (WIN32 AND ENABLE_LOCALIF_WIN32) target_link_libraries(${name} Iphlpapi) add_definitions(-DSRT_ENABLE_LOCALIF_WIN32) endif() From 22fc22bd92fcc7ae4e40af8f87e23cfd8850d697 Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Wed, 14 Aug 2024 16:40:50 +0200 Subject: [PATCH 24/24] Fixed Iphlpapi library depend declaration on Windows --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d53f2f47..3cdeb5c77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1063,6 +1063,10 @@ if (srt_libspec_shared) if (ENABLE_ENCRYPTION) target_link_libraries(${TARGET_srt}_shared PRIVATE ${SSL_LIBRARIES}) endif() + if (WIN32 AND ENABLE_LOCALIF_WIN32) + target_link_libraries(${TARGET_srt}_shared PRIVATE Iphlpapi) + add_definitions(-DSRT_ENABLE_LOCALIF_WIN32) + endif() if (MICROSOFT) target_link_libraries(${TARGET_srt}_shared PRIVATE ws2_32.lib) if (NOT (ENABLE_ENCRYPTION AND "${USE_ENCLIB}" STREQUAL "botan")) @@ -1084,6 +1088,10 @@ endif() if (srt_libspec_static) add_library(${TARGET_srt}_static STATIC ${OBJECT_LIB_SUPPORT} ${VIRTUAL_srt}) + if (WIN32 AND ENABLE_LOCALIF_WIN32) + target_link_libraries(${TARGET_srt}_static PRIVATE Iphlpapi) + add_definitions(-DSRT_ENABLE_LOCALIF_WIN32) + endif() # For Windows, leave the name to be "srt_static.lib". # Windows generates two different library files: