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
}
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 */
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);
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,
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);
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;
* @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
{
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;
}
- 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)) {
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;