diff --git a/CMakeLists.txt b/CMakeLists.txt
index a797a7ce152adf1b42f34d3d40b306642e41c0ad..d6394f99dcee7122cfef89b7475e053988037523 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,6 +33,8 @@ if (NODE_NPM)
 	message(STATUS "Found NPM: ${NODE_NPM}")
 endif()
 
+include_directories(${GLOG_INCLUDE_DIRS})
+
 # Why is this problematic on some machines?
 check_language(CUDA)
 if (CUDA_TOOLKIT_ROOT_DIR)
@@ -71,6 +73,9 @@ check_include_file("uuid/uuid.h" UUID_FOUND)
 if (NOT UUID_FOUND)
 	message(ERROR "UUID library is required")
 endif()
+find_library(UUID_LIBRARIES NAME uuid libuuid)
+else()
+
 endif()
 
 find_program(CPPCHECK_FOUND cppcheck)
diff --git a/cmake/Findglog.cmake b/cmake/Findglog.cmake
deleted file mode 100644
index 8b5883975bf0328aec24a14fe001aa975a1222ec..0000000000000000000000000000000000000000
--- a/cmake/Findglog.cmake
+++ /dev/null
@@ -1,37 +0,0 @@
-###############################################################################
-# Find glog
-#
-
-if(WIN32)
-find_path(glog_DIR NAMES include/glog/logging.h PATHS "C:/Program Files/glog" "C:/Program Files/google-glog" "C:/Program Files (x86)/google-glog")
-set(glog_DIR ${glog_DIR})
-else()
-set(glog_DIR "")
-endif()
-
-# Find lib
-set(GLOG_FOUND FALSE CACHE BOOL "" FORCE)
-find_library(GLOG_LIBRARY
-    NAMES glog libglog
-    PATHS ${glog_DIR}
-    PATH_SUFFIXES lib/
-)
-
-# Find include
-find_path(GLOG_INCLUDE_DIRS
-    NAMES glog/logging.h
-    PATHS ${glog_DIR}
-    PATH_SUFFIXES include
-)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(glog DEFAULT_MSG GLOG_LIBRARY GLOG_INCLUDE_DIRS)
-
-mark_as_advanced(GLOG_FOUND)
-
-if(GLOG_FOUND)
-	include_directories(${GLOG_INCLUDE_DIRS})
-    set(GLOG_FOUND TRUE CACHE BOOL "" FORCE)
-    set(GLOG_LIBRARIES ${GLOG_LIBRARY})
-    message(STATUS "Found glog")
-endif()
diff --git a/cv-node/CMakeLists.txt b/cv-node/CMakeLists.txt
index 8a77cce2b78b2466d63f05c7345f93d2446284df..53cfce7ab88eac15f6fbbd36f9657c70c7ad8d6b 100644
--- a/cv-node/CMakeLists.txt
+++ b/cv-node/CMakeLists.txt
@@ -47,6 +47,6 @@ set_property(TARGET cv-node PROPERTY CUDA_SEPARABLE_COMPILATION ON)
 endif()
 
 #target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(cv-node net Threads::Threads ${OpenCV_LIBS} ${LIBSGM_LIBRARIES} ${CUDA_LIBRARIES} ${GLOG_LIBRARIES})
+target_link_libraries(cv-node Threads::Threads ${OpenCV_LIBS} ${LIBSGM_LIBRARIES} ${CUDA_LIBRARIES} glog::glog ${PROJECT_BINARY_DIR}/net/cpp/Release/net.lib)
 
 
diff --git a/cv-node/include/ftl/algorithms/rtcensus.hpp b/cv-node/include/ftl/algorithms/rtcensus.hpp
index 0a7d382b6531e113c37d86e5d0920b2851579d45..2623e18bd7b72a1bbdd537696d3b004348ae789a 100644
--- a/cv-node/include/ftl/algorithms/rtcensus.hpp
+++ b/cv-node/include/ftl/algorithms/rtcensus.hpp
@@ -10,6 +10,8 @@
 #include <ftl/disparity.hpp>
 #include <nlohmann/json.hpp>
 
+#include <ftl/config.h>
+
 #if defined HAVE_CUDA
 #include <opencv2/core/cuda.hpp>
 #endif
diff --git a/cv-node/src/main.cpp b/cv-node/src/main.cpp
index d336bcae82e7e3932250e0c6321aaae1f6fb989b..0b664073ca0a7b56dfcab79390b23e3135057c3d 100644
--- a/cv-node/src/main.cpp
+++ b/cv-node/src/main.cpp
@@ -8,6 +8,7 @@
 #include <string>
 #include <map>
 #include <vector>
+#include <fstream>
 
 #include <opencv2/opencv.hpp>
 #include <ftl/local.hpp>
@@ -42,9 +43,20 @@ static json config;
  * Find and load a JSON configuration file
  */
 static bool findConfiguration(const string &file) {
-	// TODO(nick) Check other locations
-	ifstream i((file != "") ? file : FTL_LOCAL_CONFIG_ROOT "/config.json");
-	if (!i.is_open()) return false;
+	ifstream i;
+	
+	if (file != "") {
+		i.open(file);
+	}
+	if (!i.is_open()) {
+		i.open("./config.json");
+	}
+	if (!i.is_open()) {
+		i.open(FTL_LOCAL_CONFIG_ROOT "/config.json");
+	}
+	if (!i.is_open()) {
+		i.open(FTL_GLOBAL_CONFIG_ROOT "/config.json");
+	}
 	i >> config;
 	return true;
 }
diff --git a/net/cpp/CMakeLists.txt b/net/cpp/CMakeLists.txt
index 1f80ac61414b9d0ed3aea51e77e04e6c5c9aec72..0031ab45fd9bdcc26d9918b4a57984fbe1259da2 100644
--- a/net/cpp/CMakeLists.txt
+++ b/net/cpp/CMakeLists.txt
@@ -20,10 +20,10 @@ set(NETSOURCE
 check_function_exists(uriParseSingleUriA HAVE_URIPARSESINGLE)
 
 add_library(net ${NETSOURCE})
-target_link_libraries(net pthread)
+target_link_libraries(net Threads::Threads glog::glog)
 
 add_executable(net-cli src/main.cpp)
-target_link_libraries(net-cli "${PROJECT_BINARY_DIR}/net/cpp/libnet.a" ${GLOG_LIBRARIES} ${URIPARSER_LIBRARIES} pthread readline uuid)
+target_link_libraries(net-cli "${PROJECT_BINARY_DIR}/net/cpp/libnet.a" glog::glog ${URIPARSER_LIBRARIES} Threads::Threads ${READLINE_LIBRARIES} ${UUID_LIBRARIES})
 add_dependencies(net-cli net)
 
 ADD_SUBDIRECTORY(test)
diff --git a/net/cpp/include/ftl/net/dispatcher.hpp b/net/cpp/include/ftl/net/dispatcher.hpp
index 3d94659911a08806df269e44c3e4ea3cc9c03250..c80849e7d8b90a73a242779810fefd2609b60601 100644
--- a/net/cpp/include/ftl/net/dispatcher.hpp
+++ b/net/cpp/include/ftl/net/dispatcher.hpp
@@ -2,6 +2,11 @@
 #define _FTL_NET_DISPATCHER_HPP_
 
 #include <ftl/net/func_traits.hpp>
+
+#ifdef _MSC_VER
+#include <msgpack_optional.hpp>
+#endif
+
 #include <msgpack.hpp>
 #include <memory>
 #include <tuple>
diff --git a/net/cpp/include/ftl/net/p2p.hpp b/net/cpp/include/ftl/net/p2p.hpp
index f9547dbde9a9645348c7a4239e676bbbd9cbe34d..8c956fd2685b1512872c40b837268cd97c16810b 100644
--- a/net/cpp/include/ftl/net/p2p.hpp
+++ b/net/cpp/include/ftl/net/p2p.hpp
@@ -1,6 +1,8 @@
 #ifndef _FTL_NET_P2P_HPP_
 #define _FTL_NET_P2P_HPP_
 
+#include <ftl/net/protocol.hpp>
+#include <ftl/net/socket.hpp>
 #include <ftl/uuid.hpp>
 #include <optional>
 #include <string>
@@ -8,8 +10,6 @@
 #include <chrono>
 #include <vector>
 #include <memory>
-#include <ftl/net/protocol.hpp>
-#include <ftl/net/socket.hpp>
 
 namespace ftl {
 namespace net {
diff --git a/net/cpp/include/ftl/uuid.hpp b/net/cpp/include/ftl/uuid.hpp
index 4a042c9cdf474e728e9ec7dee8fe61680d356f37..76fae762977e12d69904c21f710a7a6e5dea3e34 100644
--- a/net/cpp/include/ftl/uuid.hpp
+++ b/net/cpp/include/ftl/uuid.hpp
@@ -20,7 +20,7 @@ namespace ftl {
 		public:
 		UUID() {
 #ifdef WIN32
-			::UuidCreate(&uuid_);
+			::UuidCreate(&guid_);
 #else
 			uuid_generate(uuid_);
 #endif
@@ -50,7 +50,7 @@ namespace ftl {
 		std::string to_string() const {
 			char b[37];
 #ifdef WIN32
-			UuidToString(&uuid_, (RPC_CSTR*)b);
+			UuidToString(&guid_, (RPC_CSTR*)b);
 #else
 			uuid_unparse(uuid_, b);
 #endif
@@ -62,7 +62,10 @@ namespace ftl {
 		
 		private:
 #ifdef WIN32
-		_GUID uuid_;
+		union {
+			_GUID guid_;
+			unsigned char uuid_[16];
+		};
 #else
 		unsigned char uuid_[16];
 #endif
diff --git a/net/cpp/include/msgpack_optional.hpp b/net/cpp/include/msgpack_optional.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..440c2146cd15023fc2be4c08cac9a2ea4fcc3927
--- /dev/null
+++ b/net/cpp/include/msgpack_optional.hpp
@@ -0,0 +1,91 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// Copyright (C) 2017 KONDO Takatoshi
+//
+//    Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//    http://www.boost.org/LICENSE_1_0.txt)
+//
+#ifndef MSGPACK_V1_TYPE_OPTIONAL_HPP
+#define MSGPACK_V1_TYPE_OPTIONAL_HPP
+
+// #if __cplusplus >= 201703
+
+#include "msgpack/versioning.hpp"
+#include "msgpack/adaptor/adaptor_base.hpp"
+#include "msgpack/adaptor/check_container_size.hpp"
+
+#include <optional>
+
+namespace msgpack {
+
+/// @cond
+MSGPACK_API_VERSION_NAMESPACE(v1) {
+/// @endcond
+
+namespace adaptor {
+
+#if !defined (MSGPACK_USE_CPP03)
+
+template <typename T>
+struct as<std::optional<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
+    std::optional<T> operator()(msgpack::object const& o) const {
+        if(o.is_nil()) return std::nullopt;
+        return o.as<T>();
+    }
+};
+
+#endif // !defined (MSGPACK_USE_CPP03)
+
+template <typename T>
+struct convert<std::optional<T> > {
+    msgpack::object const& operator()(msgpack::object const& o, std::optional<T>& v) const {
+        if(o.is_nil()) v = std::nullopt;
+        else {
+            T t;
+            msgpack::adaptor::convert<T>()(o, t);
+            v = t;
+        }
+        return o;
+    }
+};
+
+template <typename T>
+struct pack<std::optional<T> > {
+    template <typename Stream>
+    msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::optional<T>& v) const {
+        if (v) o.pack(*v);
+        else o.pack_nil();
+        return o;
+    }
+};
+
+template <typename T>
+struct object<std::optional<T> > {
+    void operator()(msgpack::object& o, const std::optional<T>& v) const {
+        if (v) msgpack::adaptor::object<T>()(o, *v);
+        else o.type = msgpack::type::NIL;
+    }
+};
+
+template <typename T>
+struct object_with_zone<std::optional<T> > {
+    void operator()(msgpack::object::with_zone& o, const std::optional<T>& v) const {
+        if (v) msgpack::adaptor::object_with_zone<T>()(o, *v);
+        else o.type = msgpack::type::NIL;
+    }
+};
+
+} // namespace adaptor
+
+/// @cond
+} // MSGPACK_API_VERSION_NAMESPACE(v1)
+/// @endcond
+
+} // namespace msgpack
+
+// #endif // __cplusplus >= 201703
+
+#endif // MSGPACK_V1_TYPE_OPTIONAL_HPP
+
diff --git a/net/cpp/src/listener.cpp b/net/cpp/src/listener.cpp
index dcfe31bf0ca3d4687be5b112041aedbff1fc066b..4a9deb08590409f4ba9fe140adb7d2735710f26e 100644
--- a/net/cpp/src/listener.cpp
+++ b/net/cpp/src/listener.cpp
@@ -19,10 +19,9 @@
 #endif
 
 #ifdef WIN32
+#include <winsock2.h>
 #include <windows.h>
-#include <winsock.h>
 typedef int socklen_t;
-#define MSG_WAITALL 0
 #endif
 
 using namespace ftl;
diff --git a/net/cpp/src/main.cpp b/net/cpp/src/main.cpp
index 34c1a1d73e313094f3226a05fa2ba29ac7556094..74730cbddcb4fca7ccc291e24a7c81c3e30691fd 100644
--- a/net/cpp/src/main.cpp
+++ b/net/cpp/src/main.cpp
@@ -5,7 +5,14 @@
 #include <ftl/net/socket.hpp>
 #include <memory>
 #include <thread>
+
+#ifndef WIN32
 #include <readline/readline.h>
+#endif
+
+#ifdef WIN32
+#pragma comment(lib, "Ws2_32.lib")
+#endif
 
 using std::string;
 using std::shared_ptr;
diff --git a/net/cpp/src/net.cpp b/net/cpp/src/net.cpp
index 9aae938f816f9072e50089245ce47d1657d4e9b8..3ea57c1c483bc4db84012ebd79cfc6d5c82182d6 100644
--- a/net/cpp/src/net.cpp
+++ b/net/cpp/src/net.cpp
@@ -10,10 +10,6 @@
 #include <iostream>
 #include <chrono>
 
-#ifdef WIN32
-#pragma comment(lib, "Ws2_32.lib")
-#endif
-
 using namespace std;
 using namespace std::chrono;
 using ftl::net::Listener;
diff --git a/net/cpp/src/socket.cpp b/net/cpp/src/socket.cpp
index 1f2f13641e983f7fb74663bb75c128cd0717dbbc..914806b66010c69d9cdf9f08d3f9e39461897c4a 100644
--- a/net/cpp/src/socket.cpp
+++ b/net/cpp/src/socket.cpp
@@ -19,9 +19,9 @@
 #endif
 
 #ifdef WIN32
-#include <windows.h>
 #include <winsock2.h>
 #include <Ws2tcpip.h>
+#include <windows.h>
 #endif
 
 #include <iostream>
@@ -35,6 +35,26 @@ using ftl::URI;
 using ftl::net::ws_connect;
 using namespace std;
 
+namespace ftl { namespace net { namespace internal {
+#ifdef TEST_MOCKS
+#ifdef WIN32
+	extern int recv(SOCKET sd, char *buf, int n, int f);
+	extern int send(SOCKET sd, const char *v, int cnt, int flags);
+#else
+	extern ssize_t recv(int sd, void *buf, size_t n, int f);
+	extern ssize_t writev(int sd, const struct iovec *v, int cnt);
+#endif
+#else
+#ifdef WIN32
+	inline int recv(SOCKET sd, char *buf, int n, int f) { return ::recv(sd,buf,n,f); }
+	inline int send(SOCKET sd, const char *v, int cnt, int flags) { return ::send(sd,v,cnt,flags); }
+#else
+	inline ssize_t recv(int sd, void *buf, size_t n, int f) { return ::recv(sd,buf,n,f); }
+	inline ssize_t writev(int sd, const struct iovec *v, int cnt) { return ::writev(sd,v,cnt); }
+#endif
+#endif
+}}}
+
 /*static std::string hexStr(const std::string &s)
 {
 	const char *data = s.data();
diff --git a/net/cpp/src/ws_internal.cpp b/net/cpp/src/ws_internal.cpp
index 5b1aece52126a854425a099701fdb939f7d90d7c..1b8038d5277bdcaabc89510c2cab1bc5fa2c1926 100644
--- a/net/cpp/src/ws_internal.cpp
+++ b/net/cpp/src/ws_internal.cpp
@@ -21,9 +21,9 @@
 #endif
 
 #ifdef WIN32
-#include <windows.h>
 #include <winsock2.h>
 #include <Ws2tcpip.h>
+#include <windows.h>
 #endif
 
 #include <string>
diff --git a/net/cpp/test/CMakeLists.txt b/net/cpp/test/CMakeLists.txt
index 89a38738afc52792d51c125490a9c1c3cee74035..391ad05e3d2688a8738c4ee282d1508293588000 100644
--- a/net/cpp/test/CMakeLists.txt
+++ b/net/cpp/test/CMakeLists.txt
@@ -2,8 +2,7 @@ add_executable(protocol_unit
 	./tests.cpp
 	./protocol_unit.cpp
 )
-target_include_directories(protocol_unit PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(protocol_unit ${GLOG_LIBRARIES})
+target_link_libraries(protocol_unit glog::glog)
 
 add_executable(socket_unit
 	./tests.cpp
@@ -11,13 +10,13 @@ add_executable(socket_unit
 	./socket_unit.cpp
 )
 target_include_directories(socket_unit PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(socket_unit ${URIPARSER_LIBRARIES} ${GLOG_LIBRARIES})
+target_link_libraries(socket_unit ${URIPARSER_LIBRARIES} glog::glog)
 
 add_executable(uri_unit
 	./tests.cpp
 	./uri_unit.cpp
 )
-target_include_directories(uri_unit PUBLIC ${PROJECT_SOURCE_DIR}/include)
+
 target_link_libraries(uri_unit ${URIPARSER_LIBRARIES})
 
 add_executable(p2p_base_unit
@@ -31,8 +30,8 @@ add_executable(p2p_base_unit
 	../src/listener.cpp
 	../src/ws_internal.cpp
 )
-target_include_directories(p2p_base_unit PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(p2p_base_unit ${URIPARSER_LIBRARIES} gflags ${GLOG_LIBRARIES} uuid)
+
+target_link_libraries(p2p_base_unit ${URIPARSER_LIBRARIES} gflags glog::glog ${UUID_LIBRARIES})
 
 add_executable(net_integration
 	./tests.cpp
@@ -44,8 +43,7 @@ add_executable(net_integration
 	../src/net.cpp
 	../src/ws_internal.cpp
 )
-target_include_directories(net_integration PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(net_integration ${URIPARSER_LIBRARIES} ${GLOG_LIBRARIES})
+target_link_libraries(net_integration ${URIPARSER_LIBRARIES} glog::glog)
 
 add_test(URIUnitTest uri_unit)
 add_test(ProtocolUnitTest protocol_unit)
diff --git a/net/cpp/test/net_integration.cpp b/net/cpp/test/net_integration.cpp
index ea915da0b82a7351d66e74f3d3b9d990f534380d..38712c5c0e169b4ab393f553709979fda04930dd 100644
--- a/net/cpp/test/net_integration.cpp
+++ b/net/cpp/test/net_integration.cpp
@@ -24,9 +24,11 @@ using std::shared_ptr;
 #endif
 
 #ifdef WIN32
-#include <windows.h>
 #include <winsock2.h>
 #include <Ws2tcpip.h>
+#include <windows.h>
+
+#pragma comment(lib, "Ws2_32.lib")
 #endif
 
 static int ssock = INVALID_SOCKET;
diff --git a/net/cpp/test/p2p_base_unit.cpp b/net/cpp/test/p2p_base_unit.cpp
index 656f8ddc7a4573f83f837d4289f0b0bc48763c88..ee360c5539813becbf63492bfcc1afc664136348 100644
--- a/net/cpp/test/p2p_base_unit.cpp
+++ b/net/cpp/test/p2p_base_unit.cpp
@@ -7,6 +7,8 @@
 
 #ifndef WIN32
 #include <sys/select.h>
+#else
+typedef int ssize_t;
 #endif
 
 using ftl::net::Dispatcher;