Browse Source

Add DNS TXT resolver (need one for Windows)

Adam Ierymenko 6 years ago
parent
commit
846f03504e
3 changed files with 71 additions and 20 deletions
  1. 8 13
      CMakeLists.txt
  2. 58 0
      osdep/OSUtils.cpp
  3. 5 7
      osdep/OSUtils.hpp

+ 8 - 13
CMakeLists.txt

@@ -8,7 +8,6 @@ else()
     cmake_policy(VERSION 3.15)
 endif()
 
-
 if(WIN32)
 	# If building on Windows, set minimum target to Windows 7
 	set(CMAKE_SYSTEM_VERSION "7" CACHE STRING INTERNAL FORCE)
@@ -17,8 +16,8 @@ endif(WIN32)
 # ZeroTier One Version Config
 
 set(ZEROTIER_ONE_VERSION_MAJOR 1 CACHE INTERNAL "")
-set(ZEROTIER_ONE_VERSION_MINOR 4 CACHE INTERNAL "")
-set(ZEROTIER_ONE_VERSION_REVISION 2 CACHE INTERNAL "")
+set(ZEROTIER_ONE_VERSION_MINOR 9 CACHE INTERNAL "")
+set(ZEROTIER_ONE_VERSION_REVISION 0 CACHE INTERNAL "")
 set(ZEROTIER_ONE_VERSION_BUILD 0 CACHE INTERNAL "")
 
 # Set a default build type if none was specified
@@ -26,7 +25,7 @@ set(default_build_type "Release")
 if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
 	set(default_build_type "Debug")
 endif()
-   
+
 if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
 	message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
 	set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
@@ -42,7 +41,6 @@ option(ZT_DEBUG_TRACE "Debug Trace Messages" OFF)
 
 if (BUILD_CENTRAL_CONTROLLER)
 	find_package(PostgreSQL REQUIRED)
-
 	set(ENABLE_SSL_SUPPORT OFF)
 	set(BUILD_SHARED_LIBS OFF)
 	set(BUILD_EXAMPLES OFF)
@@ -62,7 +60,6 @@ project(zerotier-one
 	DESCRIPTION "ZeroTier One"
 	LANGUAGES CXX C)
 
-
 if(WIN32)
 	add_definitions(-DNOMINMAX)
 else(WIN32)
@@ -76,14 +73,13 @@ else(WIN32)
 			-msse
 			-msse2
 			-msse3
-			-msse4.1
 			$<$<CONFIG:Debug>:-g>
 			$<$<CONFIG:DEBUG>:-O0>
-			$<$<CONFIG:RELEASE>:-O3>
-			$<$<CONFIG:RELEASE>:-fstack-protector>
+			$<$<CONFIG:RELEASE>:-Ofast>
+			$<$<CONFIG:RELEASE>:-fstack-protector-strong>
 			$<$<CONFIG:RELEASE>:-fPIE>
-			$<$<CONFIG:RELWITHDEBINFO>:-O3>
-			$<$<CONFIG:RELWITHDEBINFO>:-fstack-protector>
+			$<$<CONFIG:RELWITHDEBINFO>:-Ofast>
+			$<$<CONFIG:RELWITHDEBINFO>:-fstack-protector-strong>
 			$<$<CONFIG:RELWITHDEBINFO>:-fPIE>
 			$<$<CONFIG:RELWITHDEBINFO>:-g>
 		)
@@ -97,7 +93,6 @@ else(WIN32)
 			-msse
 			-msse2
 			-msse3
-			-msse4.1
 			$<$<CONFIG:Debug>:-g>
 			$<$<CONFIG:DEBUG>:-O0>
 			$<$<CONFIG:RELEASE>:-O3>
@@ -165,7 +160,7 @@ if(WIN32)
 		"windows/ZeroTierOne/ZeroTierOneService.h"
 	)
 else(WIN32)
-	set(libs ${libs} pthread)
+	set(libs ${libs} pthread resolv)
 endif(WIN32)
 
 if(BUILD_CENTRAL_CONTROLLER)

+ 58 - 0
osdep/OSUtils.cpp

@@ -44,6 +44,14 @@
 #include <sys/uio.h>
 #include <dirent.h>
 #include <netdb.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#ifndef C_IN
+#define C_IN ns_c_in
+#endif
+#ifndef T_TXT
+#define T_TXT ns_t_txt
+#endif
 #endif
 
 #ifdef __WINDOWS__
@@ -54,6 +62,8 @@
 #include <iphlpapi.h>
 #endif
 
+#include <atomic>
+
 #include "OSUtils.hpp"
 
 namespace ZeroTier {
@@ -303,6 +313,54 @@ int64_t OSUtils::getFileSize(const char *path)
 	return -1;
 }
 
+std::vector<std::string> OSUtils::resolveTxt(const char *host)
+{
+	static std::atomic_bool libresolvInitialized(false);
+	if (!libresolvInitialized.exchange(true))
+		res_init();
+
+	std::vector<std::string> results;
+
+	uint8_t answer[32768];
+	char name[1024];
+	int alen = res_search(host,C_IN,T_TXT,answer,sizeof(answer));
+	if ((alen > 12)&&(alen < sizeof(answer))) {
+		uint8_t *pptr = answer + 12;
+		uint8_t *const end = answer + alen;
+		int explen = dn_expand(answer,end,pptr,name,sizeof(name));
+		if (explen > 0) {
+			pptr += explen;
+			if ((pptr + 2) >= end) return results;
+			unsigned int rtype = ((unsigned int)pptr[0] << 8) | (unsigned int)pptr[1];
+			if (rtype == T_TXT) {
+				pptr += 4;
+				if (pptr >= end) return results;
+				while (pptr < end) {
+					explen = dn_expand(answer,end,pptr,name,sizeof(name));
+					if (explen > 0) {
+						pptr += explen;
+						if ((pptr + 2) >= end) return results;
+						rtype = ((unsigned int)pptr[0] << 8) | (unsigned int)pptr[1];
+						pptr += 10;
+						if (pptr >= end) return results;
+						unsigned int elen = *(pptr++);
+						if (elen) {
+							if ((pptr + elen) > end) return results;
+							if (rtype == T_TXT)
+								results.push_back(std::string((const char *)pptr,elen));
+							pptr += elen;
+						}
+					} else {
+						return results;
+					}
+				}
+			}
+		}
+	}
+
+	return results;
+}
+
 bool OSUtils::readFile(const char *path,std::string &buf)
 {
 	char tmp[16384];

+ 5 - 7
osdep/OSUtils.hpp

@@ -199,14 +199,12 @@ public:
 	static int64_t getFileSize(const char *path);
 
 	/**
-	 * Get IP (v4 and/or v6) addresses for a given host
-	 *
-	 * This is a blocking resolver.
-	 *
-	 * @param name Host name
-	 * @return IP addresses in InetAddress sort order or empty vector if not found
+	 * Get full DNS TXT results
+	 * 
+	 * @param name DNS FQDN
+	 * @return TXT record result(s) or empty on error or not found
 	 */
-	static std::vector<InetAddress> resolve(const char *name);
+	static std::vector<std::string> resolveTxt(const char *name);
 
 	/**
 	 * @return Current time in milliseconds since epoch