commit bcf9f0c: [Project] Start keep alive connections cache implementation

Vsevolod Stakhov vsevolod at highsecure.ru
Mon Mar 4 18:14:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-03-04 14:15:05 +0000
URL: https://github.com/rspamd/rspamd/commit/bcf9f0c5710a010783edef75742beef1192c89fb

[Project] Start keep alive connections cache implementation

---
 src/libutil/http_connection.c | 48 +++++++++++++++++++++++++++++++++----------
 src/libutil/http_connection.h | 13 ++++++++----
 src/libutil/http_context.c    | 31 ++++++++++++++++++++++++++++
 src/libutil/http_private.h    | 14 +++++++++++++
 4 files changed, 91 insertions(+), 15 deletions(-)

diff --git a/src/libutil/http_connection.c b/src/libutil/http_connection.c
index b1df4e335..7bc92cb1f 100644
--- a/src/libutil/http_connection.c
+++ b/src/libutil/http_connection.c
@@ -1489,6 +1489,7 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
 {
 	gchar datebuf[64];
 	gint meth_len = 0;
+	const gchar *conn_type = "close";
 
 	if (conn->type == RSPAMD_HTTP_SERVER) {
 		/* Format reply */
@@ -1619,6 +1620,10 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
 		}
 	}
 	else {
+		if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
+			conn_type = "keep-alive";
+		}
+
 		/* Format request */
 		enclen += msg->url->len + strlen (http_method_str (msg->method)) + 1;
 
@@ -1629,14 +1634,20 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
 						"%s %s HTTP/1.0\r\n"
 						"Content-Length: %z\r\n"
 						"Content-Type: application/octet-stream\r\n",
+						"Connection: %s\r\n",
 						"POST",
-						"/post", enclen);
+						"/post",
+						enclen,
+						conn_type);
 			}
 			else {
 				rspamd_printf_fstring (buf,
 						"%s %V HTTP/1.0\r\n"
-						"Content-Length: %z\r\n",
-						http_method_str (msg->method), msg->url, bodylen);
+						"Content-Length: %z\r\n"
+						"Connection: %s\r\n",
+						http_method_str (msg->method), msg->url, bodylen,
+						conn_type);
+
 				if (bodylen > 0) {
 					if (mime_type == NULL) {
 						mime_type = "text/plain";
@@ -1653,38 +1664,53 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
 				if (host != NULL) {
 					rspamd_printf_fstring (buf,
 							"%s %s HTTP/1.1\r\n"
-							"Connection: close\r\n"
+							"Connection: %s\r\n"
 							"Host: %s\r\n"
 							"Content-Length: %z\r\n"
 							"Content-Type: application/octet-stream\r\n",
-							"POST", "/post", host, enclen);
+							"POST",
+							"/post",
+							conn_type,
+							host,
+							enclen);
 				}
 				else {
 					rspamd_printf_fstring (buf,
 							"%s %s HTTP/1.1\r\n"
-							"Connection: close\r\n"
+							"Connection: %s\r\n"
 							"Host: %V\r\n"
 							"Content-Length: %z\r\n"
 							"Content-Type: application/octet-stream\r\n",
-							"POST", "/post", msg->host, enclen);
+							"POST",
+							"/post",
+							conn_type,
+							msg->host,
+							enclen);
 				}
 			}
 			else {
 				if (host != NULL) {
 					rspamd_printf_fstring (buf,
-							"%s %V HTTP/1.1\r\nConnection: close\r\n"
+							"%s %V HTTP/1.1\r\n"
+							"Connection: %s\r\n"
 							"Host: %s\r\n"
 							"Content-Length: %z\r\n",
-							http_method_str (msg->method), msg->url, host,
+							http_method_str (msg->method),
+							msg->url,
+							conn_type,
+							host,
 							bodylen);
 				}
 				else {
 					rspamd_printf_fstring (buf,
 							"%s %V HTTP/1.1\r\n"
-							"Connection: close\r\n"
+							"Connection: %s\r\n"
 							"Host: %V\r\n"
 							"Content-Length: %z\r\n",
-							http_method_str (msg->method), msg->url, msg->host,
+							http_method_str (msg->method),
+							msg->url,
+							conn_type,
+							msg->host,
 							bodylen);
 				}
 
diff --git a/src/libutil/http_connection.h b/src/libutil/http_connection.h
index 5fadf4509..87159bdd0 100644
--- a/src/libutil/http_connection.h
+++ b/src/libutil/http_connection.h
@@ -29,6 +29,7 @@
 #include "ref.h"
 #include "http_message.h"
 #include "http_util.h"
+#include "addr.h"
 
 #include <event.h>
 
@@ -73,10 +74,6 @@ struct rspamd_storage_shmem {
  * Do not verify server's certificate
  */
 #define RSPAMD_HTTP_FLAG_SSL_NOVERIFY (1 << 6)
-/**
- * Do not verify server's certificate
- */
-#define RSPAMD_HTTP_FLAG_KEEPALIVE (1 << 7)
 /**
  * Options for HTTP connection
  */
@@ -132,6 +129,14 @@ struct rspamd_http_connection *rspamd_http_connection_new (
 		unsigned opts,
 		enum rspamd_http_connection_type type);
 
+struct rspamd_http_connection *rspamd_http_connection_new_keepalive (
+		struct rspamd_http_context *ctx,
+		rspamd_http_body_handler_t body_handler,
+		rspamd_http_error_handler_t error_handler,
+		rspamd_http_finish_handler_t finish_handler,
+		rspamd_inet_addr_t *addr,
+		const gchar *host);
+
 
 /**
  * Set key pointed by an opaque pointer
diff --git a/src/libutil/http_context.c b/src/libutil/http_context.c
index d5ab49450..6695e8032 100644
--- a/src/libutil/http_context.c
+++ b/src/libutil/http_context.c
@@ -207,4 +207,35 @@ rspamd_http_context_default (void)
 	g_assert (default_ctx != NULL);
 
 	return default_ctx;
+}
+
+gint32
+rspamd_keep_alive_key_hash (struct rspamd_keepalive_hash_key k)
+{
+	gint32 h;
+
+	h = rspamd_inet_address_port_hash (k.addr);
+
+	if (k.host) {
+		h = rspamd_cryptobox_fast_hash (k.host, strlen (k.host), h);
+	}
+
+	return h;
+}
+
+bool
+rspamd_keep_alive_key_equal (struct rspamd_keepalive_hash_key k1,
+								  struct rspamd_keepalive_hash_key k2)
+{
+	if (k1.host && k2.host) {
+		if (rspamd_inet_address_port_equal (k1.addr, k2.addr)) {
+			return strcmp (k1.host, k2.host);
+		}
+	}
+	else if (!k1.host && !k2.host) {
+		return rspamd_inet_address_port_equal (k1.addr, k2.addr);
+	}
+
+	/* One has host and another has no host */
+	return false;
 }
\ No newline at end of file
diff --git a/src/libutil/http_private.h b/src/libutil/http_private.h
index 0f8c847a2..29c6ea45f 100644
--- a/src/libutil/http_private.h
+++ b/src/libutil/http_private.h
@@ -22,6 +22,7 @@
 #include "keypair.h"
 #include "keypairs_cache.h"
 #include "ref.h"
+#include "khash.h"
 #define HASH_CASELESS
 #include "uthash_strcase.h"
 
@@ -76,6 +77,18 @@ struct rspamd_http_message {
 	ref_entry_t ref;
 };
 
+struct rspamd_keepalive_hash_key {
+	rspamd_inet_addr_t *addr;
+	gchar *host;
+};
+
+gint32 rspamd_keep_alive_key_hash (struct rspamd_keepalive_hash_key k);
+bool rspamd_keep_alive_key_equal (struct rspamd_keepalive_hash_key k1,
+								  struct rspamd_keepalive_hash_key k2);
+
+KHASH_INIT (rspamd_keep_alive_hash, struct rspamd_keepalive_hash_key,
+		GQueue, true, rspamd_keep_alive_key_hash, rspamd_keep_alive_key_equal);
+
 struct rspamd_http_context {
 	struct rspamd_http_context_cfg config;
 	struct rspamd_keypair_cache *client_kp_cache;
@@ -85,6 +98,7 @@ struct rspamd_http_context {
 	gpointer ssl_ctx_noverify;
 	struct event_base *ev_base;
 	struct event client_rotate_ev;
+	khash_t (rspamd_keep_alive_hash) *keep_alive_hash;
 };
 
 #define HTTP_ERROR http_error_quark ()


More information about the Commits mailing list