commit 05d6d35: [Feature] Allow to skip DNS resolution for keep-alive connections
Vsevolod Stakhov
vsevolod at highsecure.ru
Thu Dec 9 14:07:04 UTC 2021
Author: Vsevolod Stakhov
Date: 2021-12-09 14:02:18 +0000
URL: https://github.com/rspamd/rspamd/commit/05d6d354ec99e800007828137315b42be332c719 (HEAD -> master)
[Feature] Allow to skip DNS resolution for keep-alive connections
---
src/libserver/http/http_context.c | 56 ++++++++++++++++++++++++++++++++-------
src/libserver/http/http_context.h | 20 +++++++++++---
src/libserver/http/http_private.h | 1 +
src/lua/lua_http.c | 42 ++++++++++++++++++-----------
4 files changed, 91 insertions(+), 28 deletions(-)
diff --git a/src/libserver/http/http_context.c b/src/libserver/http/http_context.c
index b56f1c4c0..2dbaff0a4 100644
--- a/src/libserver/http/http_context.c
+++ b/src/libserver/http/http_context.c
@@ -365,19 +365,18 @@ rspamd_http_context_default (void)
gint32
rspamd_keep_alive_key_hash (struct rspamd_keepalive_hash_key *k)
{
- guint32 h;
+ rspamd_cryptobox_fast_hash_state_t hst;
- h = rspamd_inet_address_port_hash (k->addr);
+ rspamd_cryptobox_fast_hash_init (&hst, 0);
if (k->host) {
- h ^= rspamd_cryptobox_fast_hash (k->host, strlen (k->host), h);
+ rspamd_cryptobox_fast_hash_update (&hst, k->host, strlen (k->host));
}
- if (k->is_ssl) {
- h = ~h;
- }
+ rspamd_cryptobox_fast_hash_update (&hst, &k->port, sizeof(k->port));
+ rspamd_cryptobox_fast_hash_update (&hst, &k->is_ssl, sizeof(k->is_ssl));
- return (gint32)h;
+ return rspamd_cryptobox_fast_hash_final (&hst);
}
bool
@@ -389,12 +388,12 @@ rspamd_keep_alive_key_equal (struct rspamd_keepalive_hash_key *k1,
}
if (k1->host && k2->host) {
- if (rspamd_inet_address_port_equal (k1->addr, k2->addr)) {
+ if (k1->port == k2->port) {
return strcmp (k1->host, k2->host) == 0;
}
}
else if (!k1->host && !k2->host) {
- return rspamd_inet_address_port_equal (k1->addr, k2->addr);
+ return (k1->port == k2->port);
}
/* One has host and another has no host */
@@ -410,8 +409,13 @@ rspamd_http_context_check_keepalive(struct rspamd_http_context *ctx,
struct rspamd_keepalive_hash_key hk, *phk;
khiter_t k;
+ if (ctx == NULL) {
+ ctx = rspamd_http_context_default ();
+ }
+
hk.addr = (rspamd_inet_addr_t *)addr;
hk.host = (gchar *)host;
+ hk.port = rspamd_inet_address_get_port (addr);
hk.is_ssl = is_ssl;
k = kh_get (rspamd_keep_alive_hash, ctx->keep_alive_hash, &hk);
@@ -471,6 +475,37 @@ rspamd_http_context_check_keepalive(struct rspamd_http_context *ctx,
return NULL;
}
+const rspamd_inet_addr_t *
+rspamd_http_context_has_keepalive(struct rspamd_http_context *ctx,
+ const gchar *host,
+ unsigned port,
+ bool is_ssl)
+{
+ struct rspamd_keepalive_hash_key hk, *phk;
+ khiter_t k;
+
+ if (ctx == NULL) {
+ ctx = rspamd_http_context_default ();
+ }
+
+ hk.host = (gchar *)host;
+ hk.port = port;
+ hk.is_ssl = is_ssl;
+
+ k = kh_get (rspamd_keep_alive_hash, ctx->keep_alive_hash, &hk);
+
+ if (k != kh_end (ctx->keep_alive_hash)) {
+ phk = kh_key (ctx->keep_alive_hash, k);
+ GQueue *conns = &phk->conns;
+
+ if (g_queue_get_length(conns) > 0) {
+ return phk->addr;
+ }
+ }
+
+ return NULL;
+}
+
void
rspamd_http_context_prepare_keepalive(struct rspamd_http_context *ctx,
struct rspamd_http_connection *conn,
@@ -484,6 +519,7 @@ rspamd_http_context_prepare_keepalive(struct rspamd_http_context *ctx,
hk.addr = (rspamd_inet_addr_t *)addr;
hk.host = (gchar *)host;
hk.is_ssl = is_ssl;
+ hk.port = rspamd_inet_address_get_port (addr);
k = kh_get (rspamd_keep_alive_hash, ctx->keep_alive_hash, &hk);
@@ -504,6 +540,8 @@ rspamd_http_context_prepare_keepalive(struct rspamd_http_context *ctx,
phk->host = g_strdup (host);
phk->is_ssl = is_ssl;
phk->addr = rspamd_inet_address_copy (addr);
+ phk->port = hk.port;
+
kh_put (rspamd_keep_alive_hash, ctx->keep_alive_hash, phk, &r);
conn->keepalive_hash_key = phk;
diff --git a/src/libserver/http/http_context.h b/src/libserver/http/http_context.h
index f42164dba..635da7ba5 100644
--- a/src/libserver/http/http_context.h
+++ b/src/libserver/http/http_context.h
@@ -74,9 +74,23 @@ struct rspamd_http_context *rspamd_http_context_default (void);
* @param host
* @return
*/
-struct rspamd_http_connection *
-rspamd_http_context_check_keepalive(struct rspamd_http_context *ctx, const rspamd_inet_addr_t *addr, const gchar *host,
- bool is_ssl);
+struct rspamd_http_connection * rspamd_http_context_check_keepalive(struct rspamd_http_context *ctx,
+ const rspamd_inet_addr_t *addr,
+ const gchar *host,
+ bool is_ssl);
+
+/**
+ * Checks if there is a valid keepalive connection
+ * @param ctx
+ * @param addr
+ * @param host
+ * @param is_ssl
+ * @return
+ */
+const rspamd_inet_addr_t *rspamd_http_context_has_keepalive(struct rspamd_http_context *ctx,
+ const gchar *host,
+ unsigned port,
+ bool is_ssl);
/**
* Prepares keepalive key for a connection by creating a new entry or by reusing existent
diff --git a/src/libserver/http/http_private.h b/src/libserver/http/http_private.h
index c6a5b497b..0e48d9f3c 100644
--- a/src/libserver/http/http_private.h
+++ b/src/libserver/http/http_private.h
@@ -87,6 +87,7 @@ struct rspamd_keepalive_hash_key {
rspamd_inet_addr_t *addr;
gchar *host;
gboolean is_ssl;
+ unsigned port;
GQueue conns;
};
diff --git a/src/lua/lua_http.c b/src/lua/lua_http.c
index 1fee9e313..85aa04e1f 100644
--- a/src/lua/lua_http.c
+++ b/src/lua/lua_http.c
@@ -389,6 +389,7 @@ lua_http_make_connection (struct lua_http_cbdata *cbd)
{
rspamd_inet_address_set_port (cbd->addr, cbd->msg->port);
unsigned http_opts = RSPAMD_HTTP_CLIENT_SIMPLE;
+ struct rspamd_http_message *msg = cbd->msg;
if (cbd->msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL) {
http_opts |= RSPAMD_HTTP_CLIENT_SSL;
@@ -1036,20 +1037,6 @@ lua_http_request (lua_State *L)
}
- const rspamd_ftok_t *host_header_tok = rspamd_http_message_find_header (msg, "Host");
- if (host_header_tok != NULL) {
- if (msg->host) {
- g_string_free (msg->host, true);
- }
- msg->host = g_string_new_len (host_header_tok->begin, host_header_tok->len);
- cbd->host = msg->host->str;
- }
- else {
- if (msg->host) {
- cbd->host = msg->host->str;
- }
- }
-
if (body) {
if (gzip) {
if (rspamd_fstring_gzip (&body)) {
@@ -1064,8 +1051,31 @@ lua_http_request (lua_State *L)
cbd->session = session;
}
- if (msg->host && rspamd_parse_inet_address (&cbd->addr,
- msg->host->str, msg->host->len, RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) {
+ bool numeric_ip = false;
+
+ /* Check if we can skip resolving */
+ if (msg->host) {
+ cbd->host = msg->host->str;
+
+ if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_KEEP_ALIVE) {
+ const rspamd_inet_addr_t *ka_addr = rspamd_http_context_has_keepalive(NULL,
+ msg->host->str, msg->port, msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL);
+
+ if (ka_addr) {
+ cbd->addr = rspamd_inet_address_copy(ka_addr);
+ numeric_ip = true;
+ }
+ }
+
+ if (!cbd->addr) {
+ if (rspamd_parse_inet_address (&cbd->addr,
+ msg->host->str, msg->host->len, RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) {
+ numeric_ip = true;
+ }
+ }
+ }
+
+ if (numeric_ip) {
/* Host is numeric IP, no need to resolve */
gboolean ret;
More information about the Commits
mailing list