dovecot-2.2: lib-http: Prepare for TLS SNI support.
dovecot at dovecot.org
dovecot at dovecot.org
Thu Apr 4 17:39:29 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/52efc1740e15
changeset: 16158:52efc1740e15
user: Timo Sirainen <tss at iki.fi>
date: Thu Apr 04 17:34:23 2013 +0300
description:
lib-http: Prepare for TLS SNI support.
diffstat:
src/lib-http/http-client-connection.c | 15 +++++----------
src/lib-http/http-client-host.c | 31 ++++++++++++++++++-------------
src/lib-http/http-client-peer.c | 24 ++++++------------------
src/lib-http/http-client-private.h | 6 ++----
4 files changed, 31 insertions(+), 45 deletions(-)
diffs (253 lines):
diff -r c040fa0fcfdf -r 52efc1740e15 src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c Thu Apr 04 16:53:08 2013 +0300
+++ b/src/lib-http/http-client-connection.c Thu Apr 04 17:34:23 2013 +0300
@@ -640,6 +640,7 @@
http_client_connection_ssl_handshaked(const char **error_r, void *context)
{
struct http_client_connection *conn = context;
+ const char *host = conn->peer->addr.https_name;
if (conn->client->set.ssl_allow_invalid_cert) {
/* skip certificate checks */
@@ -651,16 +652,10 @@
else
*error_r = "Received invalid SSL certificate";
return -1;
+ } else if (ssl_iostream_cert_match_name(conn->ssl_iostream, host) == 0) {
+ http_client_connection_debug(conn, "SSL handshake successful");
+ return 0;
} else {
- const char *host = http_client_peer_get_hostname(conn->peer);
-
- i_assert(host != NULL);
-
- if (ssl_iostream_cert_match_name(conn->ssl_iostream, host) == 0) {
- http_client_connection_debug(conn, "SSL handshake successful");
- return 0;
- }
-
*error_r = t_strdup_printf(
"SSL certificate doesn't match expected host name %s", host);
return -1;
@@ -720,7 +715,7 @@
"connect(%s) failed: %m", _conn->name));
} else {
http_client_connection_debug(conn, "Connected");
- if (conn->peer->addr.ssl) {
+ if (conn->peer->addr.https_name != NULL) {
if (http_client_connection_ssl_init(conn, &error) < 0) {
http_client_peer_connection_failure(conn->peer, error);
http_client_connection_unref(&conn);
diff -r c040fa0fcfdf -r 52efc1740e15 src/lib-http/http-client-host.c
--- a/src/lib-http/http-client-host.c Thu Apr 04 16:53:08 2013 +0300
+++ b/src/lib-http/http-client-host.c Thu Apr 04 17:34:23 2013 +0300
@@ -43,12 +43,13 @@
static struct http_client_host_port *
http_client_host_port_find(struct http_client_host *host,
- unsigned int port, bool ssl)
+ unsigned int port, const char *https_name)
{
struct http_client_host_port *hport;
array_foreach_modifiable(&host->ports, hport) {
- if (hport->port == port && hport->ssl == ssl)
+ if (hport->port == port &&
+ null_strcmp(hport->https_name, https_name) == 0)
return hport;
}
@@ -57,15 +58,15 @@
static struct http_client_host_port *
http_client_host_port_init(struct http_client_host *host,
- unsigned int port, bool ssl)
+ unsigned int port, const char *https_name)
{
struct http_client_host_port *hport;
- hport = http_client_host_port_find(host, port, ssl);
+ hport = http_client_host_port_find(host, port, https_name);
if (hport == NULL) {
hport = array_append_space(&host->ports);
hport->port = port;
- hport->ssl = ssl;
+ hport->https_name = i_strdup(https_name);
hport->ips_connect_idx = 0;
i_array_init(&hport->request_queue, 16);
}
@@ -89,6 +90,7 @@
{
http_client_host_port_error
(hport, HTTP_CLIENT_REQUEST_ERROR_ABORTED, "Aborted");
+ i_free(hport->https_name);
array_free(&hport->request_queue);
}
@@ -121,10 +123,11 @@
addr.ip = host->ips[hport->ips_connect_idx];
addr.port = hport->port;
- addr.ssl = hport->ssl;
+ addr.https_name = hport->https_name;
- http_client_host_debug(host, "Setting up connection to %s:%u (ssl=%s)",
- net_ip2addr(&addr.ip), addr.port, (addr.ssl ? "yes" : "no"));
+ http_client_host_debug(host, "Setting up connection to %s:%u%s",
+ net_ip2addr(&addr.ip), addr.port, addr.https_name == NULL ? "" :
+ t_strdup_printf(" (SSL=%s)", addr.https_name));
peer = http_client_peer_get(host->client, &addr);
http_client_peer_add_host(peer, host);
@@ -138,7 +141,7 @@
http_client_host_debug(host, "Failed to connect to %s:%u: %s",
net_ip2addr(&addr->ip), addr->port, reason);
- hport = http_client_host_port_find(host, addr->port, addr->ssl);
+ hport = http_client_host_port_find(host, addr->port, addr->https_name);
if (hport == NULL)
return;
@@ -275,6 +278,7 @@
struct http_client_request *req)
{
struct http_client_host_port *hport;
+ const char *https_name = req->ssl ? req->hostname : NULL;
const char *error;
req->host = host;
@@ -288,7 +292,7 @@
}
/* add request to host (grouped by tcp port) */
- hport = http_client_host_port_init(host, req->port, req->ssl);
+ hport = http_client_host_port_init(host, req->port, https_name);
if (req->urgent)
array_insert(&hport->request_queue, 0, &req, 1);
else
@@ -314,7 +318,7 @@
struct http_client_request *req;
unsigned int i, count;
- hport = http_client_host_port_find(host, addr->port, addr->ssl);
+ hport = http_client_host_port_find(host, addr->port, addr->https_name);
if (hport == NULL)
return NULL;
@@ -348,7 +352,7 @@
*num_urgent_r = 0;
- hport = http_client_host_port_find(host, addr->port, addr->ssl);
+ hport = http_client_host_port_find(host, addr->port, addr->https_name);
if (hport == NULL)
return 0;
@@ -362,8 +366,9 @@
struct http_client_request *req)
{
struct http_client_host_port *hport;
+ const char *https_name = req->ssl ? req->hostname : NULL;
- hport = http_client_host_port_find(host, req->port, req->ssl);
+ hport = http_client_host_port_find(host, req->port, https_name);
if (hport == NULL)
return;
diff -r c040fa0fcfdf -r 52efc1740e15 src/lib-http/http-client-peer.c
--- a/src/lib-http/http-client-peer.c Thu Apr 04 16:53:08 2013 +0300
+++ b/src/lib-http/http-client-peer.c Thu Apr 04 17:34:23 2013 +0300
@@ -43,7 +43,8 @@
unsigned int http_client_peer_addr_hash
(const struct http_client_peer_addr *peer)
{
- return net_ip_hash(&peer->ip) + peer->port + peer->ssl;
+ return net_ip_hash(&peer->ip) + peer->port +
+ str_hash(peer->https_name);
}
int http_client_peer_addr_cmp
@@ -56,28 +57,13 @@
return ret;
if (peer1->port != peer2->port)
return (peer1->port > peer2->port ? 1 : -1);
- if (peer1->ssl != peer2->ssl)
- return (peer1->ssl > peer2->ssl ? 1 : -1);
- return 0;
+ return null_strcmp(peer1->https_name, peer2->https_name);
}
/*
* Peer
*/
-const char *
-http_client_peer_get_hostname(struct http_client_peer *peer)
-{
- struct http_client_host *const *host;
-
- if (array_count(&peer->hosts) == 0)
- return NULL;
-
- /* just return name of initial host */
- host = array_idx(&peer->hosts, 1);
- return (*host)->name;
-}
-
static void
http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
{
@@ -182,11 +168,12 @@
{
struct http_client_peer *peer;
- i_assert(!addr->ssl || client->ssl_ctx != NULL);
+ i_assert(addr->https_name == NULL || client->ssl_ctx != NULL);
peer = i_new(struct http_client_peer, 1);
peer->client = client;
peer->addr = *addr;
+ peer->addr.https_name = i_strdup(addr->https_name);
i_array_init(&peer->hosts, 16);
i_array_init(&peer->conns, 16);
@@ -227,6 +214,7 @@
(peer->client->peers, (const struct http_client_peer_addr *)&peer->addr);
DLLIST_REMOVE(&peer->client->peers_list, peer);
+ i_free(peer->addr.https_name);
i_free(peer);
*_peer = NULL;
}
diff -r c040fa0fcfdf -r 52efc1740e15 src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h Thu Apr 04 16:53:08 2013 +0300
+++ b/src/lib-http/http-client-private.h Thu Apr 04 17:34:23 2013 +0300
@@ -79,7 +79,7 @@
/* requests pending in queue to be picked up by connections */
ARRAY_TYPE(http_client_request) request_queue;
- unsigned int ssl:1;
+ char *https_name;
};
struct http_client_host {
@@ -103,9 +103,9 @@
};
struct http_client_peer_addr {
+ char *https_name; /* TLS SNI */
struct ip_addr ip;
unsigned int port;
- unsigned int ssl:1; /* https */
};
struct http_client_peer {
@@ -220,8 +220,6 @@
(const struct http_client_peer_addr *peer1,
const struct http_client_peer_addr *peer2) ATTR_PURE;
-const char *
- http_client_peer_get_hostname(struct http_client_peer *peer);
struct http_client_peer *
http_client_peer_get(struct http_client *client,
const struct http_client_peer_addr *addr);
More information about the dovecot-cvs
mailing list