TcpSocket: Impliment TLSConnectionPosix Write

Impliment TLSConnectionPosix Write by first iteratively checking for
available write data on each connection then calling Write if any data
is available

Change-Id: I95be9c75aea2b618e7d7516eb9bb15ec72f5bedd
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/1819543
Reviewed-by: Jordan Bayles <jophba@chromium.org>
Reviewed-by: Yuri Wiitala <miu@chromium.org>
Commit-Queue: Ryan Keane <rwkeane@google.com>
diff --git a/platform/impl/tls_connection_factory_posix.cc b/platform/impl/tls_connection_factory_posix.cc
index 55aac74..cc370fc 100644
--- a/platform/impl/tls_connection_factory_posix.cc
+++ b/platform/impl/tls_connection_factory_posix.cc
@@ -113,6 +113,9 @@
   if (context == nullptr) {
     return;
   }
+
+  SSL_CTX_set_mode(context, SSL_MODE_ENABLE_PARTIAL_WRITE);
+
   ssl_context_.reset(context);
 }
 
diff --git a/platform/impl/tls_connection_posix.cc b/platform/impl/tls_connection_posix.cc
index 0e1c250..e11b85b 100644
--- a/platform/impl/tls_connection_posix.cc
+++ b/platform/impl/tls_connection_posix.cc
@@ -18,6 +18,7 @@
 #include <memory>
 
 #include "absl/types/optional.h"
+#include "absl/types/span.h"
 #include "platform/api/logging.h"
 #include "platform/base/error.h"
 #include "platform/impl/stream_socket.h"
@@ -76,5 +77,23 @@
   }
 }
 
+void TlsConnectionPosix::SendAvailableBytes() {
+  absl::Span<const uint8_t> sendable_bytes = buffer_.GetReadableRegion();
+  if (sendable_bytes.empty()) {
+    return;
+  }
+
+  const int result =
+      SSL_write(ssl_.get(), sendable_bytes.data(), sendable_bytes.size());
+  if (result <= 0) {
+    const Error result_error = GetSSLError(ssl_.get(), result);
+    if (!result_error.ok() && (result_error.code() != Error::Code::kAgain)) {
+      OnError(result_error);
+    }
+  } else {
+    buffer_.Consume(static_cast<size_t>(result));
+  }
+}
+
 }  // namespace platform
 }  // namespace openscreen
diff --git a/platform/impl/tls_connection_posix.h b/platform/impl/tls_connection_posix.h
index b98686b..dd58354 100644
--- a/platform/impl/tls_connection_posix.h
+++ b/platform/impl/tls_connection_posix.h
@@ -30,6 +30,9 @@
                      TaskRunner* task_runner);
   ~TlsConnectionPosix();
 
+  // Sends any available bytes from this connection's buffer_.
+  void SendAvailableBytes();
+
   // TlsConnection overrides.
   void Write(const void* data, size_t len) override;
   const IPEndpoint& local_address() const override;
diff --git a/platform/impl/tls_data_router_posix.cc b/platform/impl/tls_data_router_posix.cc
index c5a1b1d..b65210b 100644
--- a/platform/impl/tls_data_router_posix.cc
+++ b/platform/impl/tls_data_router_posix.cc
@@ -46,8 +46,10 @@
 }
 
 void TlsDataRouterPosix::WriteAll() {
-  // TODO(jophba, rwkeane): implement this method.
-  OSP_UNIMPLEMENTED();
+  std::lock_guard<std::mutex> lock(connections_mutex_);
+  for (TlsConnectionPosix* connection : connections_) {
+    connection->SendAvailableBytes();
+  }
 }
 
 void TlsDataRouterPosix::ProcessReadyHandle(