From c0ee8dc3a526fc3090a50e9559a3ceab938dbfb2 Mon Sep 17 00:00:00 2001
From: Fabian Keil <fk@fabiankeil.de>
Date: Sat, 30 May 2020 05:39:32 +0200
Subject: [PATCH] Add ssl_send_data_delayed()
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

... a SSL version of write_socket_delayed().

Based on a patch by Vašek Švec.
---
 ssl.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ssl.h |  2 ++
 2 files changed, 65 insertions(+)

diff --git a/ssl.c b/ssl.c
index 0bb549bf..852a9ce5 100644
--- a/ssl.c
+++ b/ssl.c
@@ -260,6 +260,69 @@ extern int ssl_send_data(mbedtls_ssl_context *ssl, const unsigned char *buf, siz
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  ssl_send_data_delayed
+ *
+ * Description :  Sends the contents of buf (for n bytes) to given SSL
+ *                connection, optionally delaying the operation.
+ *
+ * Parameters  :
+ *          1  :  ssl = SSL context to send data to
+ *          2  :  buf = Pointer to data to be sent
+ *          3  :  len = Length of data to be sent to the SSL context
+ *          4  :  delay = Delay in milliseconds.
+ *
+ * Returns     :  0 on success (entire buffer sent).
+ *                nonzero on error.
+ *
+ *********************************************************************/
+extern int ssl_send_data_delayed(mbedtls_ssl_context *ssl,
+                                 const unsigned char *buf, size_t len,
+                                 unsigned int delay)
+{
+   size_t i = 0;
+
+   if (delay == 0)
+   {
+      if (ssl_send_data(ssl, buf, len) < 0)
+      {
+         return -1;
+      }
+      else
+      {
+         return 0;
+      }
+   }
+
+   while (i < len)
+   {
+      size_t write_length;
+      enum { MAX_WRITE_LENGTH = 10 };
+
+      if ((i + MAX_WRITE_LENGTH) > len)
+      {
+         write_length = len - i;
+      }
+      else
+      {
+         write_length = MAX_WRITE_LENGTH;
+      }
+
+      privoxy_millisleep(delay);
+
+      if (ssl_send_data(ssl, buf + i, write_length) < 0)
+      {
+         return -1;
+      }
+      i += write_length;
+   }
+
+   return 0;
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  ssl_recv_data
diff --git a/ssl.h b/ssl.h
index 1c65182f..f62f9735 100644
--- a/ssl.h
+++ b/ssl.h
@@ -54,6 +54,8 @@ extern int tunnel_established_successfully(const char *response, unsigned int re
 
 /* Functions for sending and receiving data over TLS/SSL connections */
 extern int  ssl_send_data(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len);
+extern int ssl_send_data_delayed(mbedtls_ssl_context *ssl, const unsigned char *buf,
+                                 size_t len, unsigned int delay);
 extern int  ssl_recv_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t maxLen);
 extern long ssl_flush_socket(mbedtls_ssl_context *ssl, struct iob *iob);
 extern void ssl_send_certificate_error(struct client_state *csp);
-- 
2.49.0