From 30a6a5cdd1cc40de923226953bb887a80f004c47 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 27 Aug 2020 08:17:55 -0700 Subject: [PATCH 1/2] Add support for TRACY_ONLY_IPV4 macro to exclude listening on IPv6 --- common/TracySocket.cpp | 28 ++++++++++++++++------------ manual/tracy.tex | 2 ++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/common/TracySocket.cpp b/common/TracySocket.cpp index ade450fe..6a0fc446 100644 --- a/common/TracySocket.cpp +++ b/common/TracySocket.cpp @@ -386,33 +386,37 @@ ListenSocket::~ListenSocket() if( m_sock != -1 ) Close(); } -bool ListenSocket::Listen( int port, int backlog ) +static int addrinfo_and_socket_for_family(int port, int ai_family, struct addrinfo** res) { - assert( m_sock == -1 ); - - struct addrinfo* res; struct addrinfo hints; - memset( &hints, 0, sizeof( hints ) ); - hints.ai_family = AF_INET6; + hints.ai_family = ai_family; hints.ai_socktype = SOCK_STREAM; #ifndef TRACY_ONLY_LOCALHOST hints.ai_flags = AI_PASSIVE; #endif - char portbuf[32]; sprintf( portbuf, "%i", port ); + if( getaddrinfo( nullptr, portbuf, &hints, res ) != 0 ) return -1; + int sock = socket( (*res)->ai_family, (*res)->ai_socktype, (*res)->ai_protocol ); + if (sock == -1) freeaddrinfo( *res ); + return sock; +} - if( getaddrinfo( nullptr, portbuf, &hints, &res ) != 0 ) return false; +bool ListenSocket::Listen( int port, int backlog ) +{ + assert( m_sock == -1 ); - m_sock = socket( res->ai_family, res->ai_socktype, res->ai_protocol ); + struct addrinfo* res = nullptr; + +#ifndef TRACY_ONLY_IPV4 + m_sock = addrinfo_and_socket_for_family(port, AF_INET6, &res); +#endif if (m_sock == -1) { // IPV6 protocol may not be available/is disabled. Try to create a socket // with the IPV4 protocol - hints.ai_family = AF_INET; - if( getaddrinfo( nullptr, portbuf, &hints, &res ) != 0 ) return false; - m_sock = socket( res->ai_family, res->ai_socktype, res->ai_protocol ); + m_sock = addrinfo_and_socket_for_family(port, AF_INET, &res); if( m_sock == -1 ) return false; } #if defined _WIN32 || defined __CYGWIN__ diff --git a/manual/tracy.tex b/manual/tracy.tex index 57098426..e36528e1 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -427,6 +427,8 @@ By default Tracy client will announce its presence to the local network\footnote By default Tracy client will listen on all network interfaces. If you want to restrict it to only listening on the localhost interface, define the \texttt{TRACY\_ONLY\_LOCALHOST} macro. +By default Tracy client will listen on IPv6 interfaces, falling back to IPv4 only if IPv6 is not available. If you want to restrict it to only listening on IPv4 interfaces, define the \texttt{TRACY\_ONLY\_IPV4} macro. + \subsubsection{Setup for multi-DLL projects} In projects that consist of multiple DLLs/shared objects things are a bit different. Compiling \texttt{TracyClient.cpp} into every DLL is not an option because this would result in several instances of Tracy objects lying around in the process. We rather need to pass the instances of them to the different DLLs to be reused there. From 2ea81a3ef92e0d4b8921f36236b902cfc9079b32 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 27 Aug 2020 10:47:05 -0700 Subject: [PATCH 2/2] Make TRACY_ONLY_IPV4 and TRACY_ONLY_LOCALHOST also settable with runtime env vars. --- common/TracySocket.cpp | 12 ++++++++++-- manual/tracy.tex | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/common/TracySocket.cpp b/common/TracySocket.cpp index 6a0fc446..ed7737a3 100644 --- a/common/TracySocket.cpp +++ b/common/TracySocket.cpp @@ -393,7 +393,11 @@ static int addrinfo_and_socket_for_family(int port, int ai_family, struct addrin hints.ai_family = ai_family; hints.ai_socktype = SOCK_STREAM; #ifndef TRACY_ONLY_LOCALHOST - hints.ai_flags = AI_PASSIVE; + const char* onlyLocalhost = getenv( "TRACY_ONLY_LOCALHOST" ); + if( !onlyLocalhost || onlyLocalhost[0] != '1' ) + { + hints.ai_flags = AI_PASSIVE; + } #endif char portbuf[32]; sprintf( portbuf, "%i", port ); @@ -410,7 +414,11 @@ bool ListenSocket::Listen( int port, int backlog ) struct addrinfo* res = nullptr; #ifndef TRACY_ONLY_IPV4 - m_sock = addrinfo_and_socket_for_family(port, AF_INET6, &res); + const char* onlyIPv4 = getenv( "TRACY_ONLY_IPV4" ); + if( !onlyIPv4 || onlyIPv4[0] != '1' ) + { + m_sock = addrinfo_and_socket_for_family(port, AF_INET6, &res); + } #endif if (m_sock == -1) { diff --git a/manual/tracy.tex b/manual/tracy.tex index e36528e1..359a3aa1 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -425,9 +425,9 @@ By default Tracy client will announce its presence to the local network\footnote \subsubsection{Client network interface} -By default Tracy client will listen on all network interfaces. If you want to restrict it to only listening on the localhost interface, define the \texttt{TRACY\_ONLY\_LOCALHOST} macro. +By default Tracy client will listen on all network interfaces. If you want to restrict it to only listening on the localhost interface, define the \texttt{TRACY\_ONLY\_LOCALHOST} macro at compile time, or set the \texttt{TRACY\_ONLY\_LOCALHOST} environment variable to $1$ at runtime. -By default Tracy client will listen on IPv6 interfaces, falling back to IPv4 only if IPv6 is not available. If you want to restrict it to only listening on IPv4 interfaces, define the \texttt{TRACY\_ONLY\_IPV4} macro. +By default Tracy client will listen on IPv6 interfaces, falling back to IPv4 only if IPv6 is not available. If you want to restrict it to only listening on IPv4 interfaces, define the \texttt{TRACY\_ONLY\_IPV4} macro at compile time, or set the \texttt{TRACY\_ONLY\_IPV4} environment variable to $1$ at runtime. \subsubsection{Setup for multi-DLL projects}