diff --git a/src/common.hpp b/src/common.hpp
index d3db0c62ea97313d46ada757839c2f454a5645ac..91077ccd9193134dc1d81dc42a1e3102d36c146e 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -16,7 +16,7 @@ constexpr size_t DGRAM_BUFFER_SIZE = 20480;
 //   to the real openvpn server.
 constexpr size_t SERVER_ENCRYPT_CONNECTION_TIMEOUT_SECONDS = 60;
 
-// MAGIC PORT NUMBER! Warning!
+// MAGIC PORT NUMBER! Warning! Used for Inbound - Outbound IPC talking. Windows wepoll doesn't support PIPE, so I have to use this. 
 constexpr uint16_t TCP_TMP_PORT_NUMBER = 50999;
 
 #endif
diff --git a/src/forwarder.hpp b/src/forwarder.hpp
index 6a0de5b62f3fe0b4d50630625c67468a782d67f0..851d87c8386b26af71697c0bb5fe3ca66c033c3b 100644
--- a/src/forwarder.hpp
+++ b/src/forwarder.hpp
@@ -30,6 +30,11 @@ public:
         if (ptrOutbound) delete ptrOutbound;
     }
 
+    [[noreturn]] void runForever() {
+        std::thread([this] {ptrInbound->listenForever(ptrOutbound);}).detach();
+        ptrOutbound->listenForever(ptrInbound); // Blocks
+    }
+
 
 private:
     Protocols::BaseInbound *ptrInbound;
diff --git a/src/lib/rlib/sys/sio.hpp b/src/lib/rlib/sys/sio.hpp
index 7919729f3f8280e0c3c66e6225e404a429546030..6a7da72705ba242ac76891351709186ef6310ee0 100644
--- a/src/lib/rlib/sys/sio.hpp
+++ b/src/lib/rlib/sys/sio.hpp
@@ -504,6 +504,11 @@ namespace rlib {
                 currvptr = (char *)vptr + current / 2;
             }
         }
+        static void close_ex(sockfd_t fd) {
+            if (closesocket(fd) == SOCKET_ERROR) {
+                throw std::runtime_error("closeSocket failed. error code: " + std::to_string(WSAGetLastError()));
+            }
+        }
 #else 
     // POSIX sockIO
     public:
@@ -589,6 +594,11 @@ namespace rlib {
                 currvptr = (char *)vptr + current / 2;
             }
         }
+        static void close_ex(sockfd_t fd) {
+            if (close(fd) == -1) {
+                throw std::runtime_error("close failed. error code: " + std::to_string(errno));
+            }
+        }
 #endif
 
 #ifndef MSG_NOSIGNAL
diff --git a/src/main.cc b/src/main.cc
index f088caa075206e7a158acfbc5fc230bcc36a47ec..37da970ddd84c953423b828bd779cdd82a793841 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -11,6 +11,9 @@ using namespace std::chrono_literals;
 
 #if RLIB_OS_ID == OS_WINDOWS
     #define windows_main main
+    #ifdef ERROR
+    #undef ERROR
+    #endif
 #else
     #define real_main main
 #endif
@@ -39,7 +42,7 @@ int real_main(int argc, char **argv) {
     else
         throw std::runtime_error("Unknown log level: " + log_level);
 
-    Forwarder(inboundConfig, outboundConfig).run_forever();
+    Forwarder(inboundConfig, outboundConfig).runForever();
 
     return 0;
 }
diff --git a/src/protocols/base.hpp b/src/protocols/base.hpp
index ddf3af3adc674b4a400e3488b4cbe0e6ea4dbc5c..09a9bed7b74bb88b59247349292d69b03ec29136 100644
--- a/src/protocols/base.hpp
+++ b/src/protocols/base.hpp
@@ -16,6 +16,8 @@ User
 */
 
 namespace Protocols {
+	struct BaseInbound;
+
 	// Outbound holds the senderId=>nextHopFd mapping.
 	// senderId is "$ip@$port", for example, `fe80:8100::1@1080`. 
 	// Note: this interface works for both TCP and UDP.
diff --git a/src/protocols/plain.hpp b/src/protocols/plain.hpp
index 69aea0063715898bb4fbac0809549179645c0e51..2bcc7bc97104eb7d193d3d88c448166478ec515d 100644
--- a/src/protocols/plain.hpp
+++ b/src/protocols/plain.hpp
@@ -20,14 +20,14 @@ namespace Protocols {
 		}
 		virtual void forwardMessageToOutbound(string binaryMessage, string senderId) override {
 			// Outbound calls this function, to alert the inbound listener thread, for the new msg.
-
-
+			rlib::sockIO::send_msg(ipcPipe, senderId);
+			rlib::sockIO::send_msg(ipcPipe, binaryMessage);
 		}
 		virtual void listenForever(BaseOutbound* nextHop) override {
 			std::tie(this->ipcPipe, nextHop->ipcPipe) = mk_tcp_pipe();
 
 			auto listenFd = rlib::quick_listen(listenAddr, listenPort, true);
-			rlib_defer([&] {close(listenFd);});
+			rlib_defer([&] {rlib::sockIO::close_ex(listenFd);});
 
 			auto epollFd = epoll_create1(0);
 			dynamic_assert((int)epollFd != -1, "epoll_create1 failed");
diff --git a/src/utils.hpp b/src/utils.hpp
index 3019e2a2bf3c2cd64328e34f3d90a905c954577f..f124673152491ce572e0aea9458169e63171931c 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -13,6 +13,9 @@
 #include <wepoll.h>
 #endif
 
+#include <string>
+using std::string;
+
 struct SockAddr {
     union {
         sockaddr_storage addr_storage;
@@ -20,7 +23,7 @@ struct SockAddr {
         sockaddr_in in4;
         sockaddr_in6 in6;
     };
-    int len;
+    socklen_t len;
 };
 
 struct ConnectionMapping {