summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordu.net>2012-04-25 17:41:27 +0200
committerLinus Nordberg <linus@nordu.net>2012-04-25 17:41:27 +0200
commit19b5ce7ac3f838e689ae6e6b1e4a0c114b44ce67 (patch)
tree8b1cf80d30846833111d1e6733a8031408fb2321
parent41ca60fee8c14f74af22bbeeda56574e883c21a9 (diff)
Postpone resolving of DNS names of server.
We used to resolve DNS names when reading configuration. We now do it in event_init_socket() and cache the result in the connection object. The imminent need for changing this is to keep host names around for X509 certificate verification (CNAME and subjectAltName). This will also help later when we implement server failover (and later, when people want to do more dynamic configuration, f.ex. NAPTR).
-rw-r--r--lib/conf.c6
-rw-r--r--lib/event.c27
-rw-r--r--lib/include/radsec/radsec-impl.h9
-rw-r--r--lib/packet.c4
-rw-r--r--lib/radsec.c15
5 files changed, 35 insertions, 26 deletions
diff --git a/lib/conf.c b/lib/conf.c
index 71bd169..ad1a5f8 100644
--- a/lib/conf.c
+++ b/lib/conf.c
@@ -226,10 +226,8 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)
p->realm = r;
cfg_server = cfg_getnsec (cfg_realm, "server", j);
- /* FIXME: Handle resolve errors, possibly by postponing name
- resolution. */
- rs_resolv (&p->addr, r->type, cfg_getstr (cfg_server, "hostname"),
- cfg_getstr (cfg_server, "service"));
+ p->hostname = cfg_getstr (cfg_server, "hostname");
+ p->service = cfg_getstr (cfg_server, "service");
p->secret = cfg_getstr (cfg_server, "secret");
}
}
diff --git a/lib/event.c b/lib/event.c
index ff05012..2229689 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -19,6 +19,8 @@
#if defined (RS_ENABLE_TLS)
#include "tls.h"
#endif
+#include "err.h"
+#include "radsec.h"
#include "event.h"
#include "packet.h"
#include "conn.h"
@@ -97,9 +99,16 @@ event_init_socket (struct rs_connection *conn, struct rs_peer *p)
if (conn->fd != -1)
return RSE_OK;
- assert (p->addr);
- conn->fd = socket (p->addr->ai_family, p->addr->ai_socktype,
- p->addr->ai_protocol);
+ if (p->addr_cache == NULL)
+ {
+ struct rs_error *err =
+ rs_resolve (&p->addr_cache, p->realm->type, p->hostname, p->service);
+ if (err != NULL)
+ return err_conn_push_err (conn, err);
+ }
+
+ conn->fd = socket (p->addr_cache->ai_family, p->addr_cache->ai_socktype,
+ p->addr_cache->ai_protocol);
if (conn->fd < 0)
return rs_err_conn_push_fl (conn, RSE_SOCKERR, __FILE__, __LINE__,
"socket: %d (%s)",
@@ -168,8 +177,8 @@ event_do_connect (struct rs_connection *conn)
{
char host[80], serv[80];
- getnameinfo (p->addr->ai_addr,
- p->addr->ai_addrlen,
+ getnameinfo (p->addr_cache->ai_addr,
+ p->addr_cache->ai_addrlen,
host, sizeof(host), serv, sizeof(serv),
0 /* NI_NUMERICHOST|NI_NUMERICSERV*/);
rs_debug (("%s: connecting to %s:%s\n", __func__, host, serv));
@@ -179,8 +188,8 @@ event_do_connect (struct rs_connection *conn)
if (p->conn->bev) /* TCP */
{
conn_activate_timeout (conn); /* Connect timeout. */
- err = bufferevent_socket_connect (p->conn->bev, p->addr->ai_addr,
- p->addr->ai_addrlen);
+ err = bufferevent_socket_connect (p->conn->bev, p->addr_cache->ai_addr,
+ p->addr_cache->ai_addrlen);
if (err < 0)
rs_err_conn_push_fl (p->conn, RSE_EVENT, __FILE__, __LINE__,
"bufferevent_socket_connect: %s",
@@ -190,7 +199,9 @@ event_do_connect (struct rs_connection *conn)
}
else /* UDP */
{
- err = connect (p->conn->fd, p->addr->ai_addr, p->addr->ai_addrlen);
+ err = connect (p->conn->fd,
+ p->addr_cache->ai_addr,
+ p->addr_cache->ai_addrlen);
if (err < 0)
{
sockerr = evutil_socket_geterror (p->conn->fd);
diff --git a/lib/include/radsec/radsec-impl.h b/lib/include/radsec/radsec-impl.h
index 59cb8bf..752ea71 100644
--- a/lib/include/radsec/radsec-impl.h
+++ b/lib/include/radsec/radsec-impl.h
@@ -50,8 +50,10 @@ struct rs_error {
struct rs_peer {
struct rs_connection *conn;
struct rs_realm *realm;
- struct evutil_addrinfo *addr;
+ char *hostname;
+ char *service;
char *secret; /* RADIUS secret. */
+ struct evutil_addrinfo *addr_cache;
struct rs_peer *next;
};
@@ -127,11 +129,6 @@ struct rs_packet {
struct rs_packet *next; /* Used for UDP output queue. */
};
-/* Nonpublic functions (in radsec.c -- FIXME: move?). */
-struct rs_error *rs_resolv (struct evutil_addrinfo **addr,
- rs_conn_type_t type,
- const char *hostname,
- const char *service);
#if defined (__cplusplus)
}
#endif
diff --git a/lib/packet.c b/lib/packet.c
index a7e09f6..8e6f22d 100644
--- a/lib/packet.c
+++ b/lib/packet.c
@@ -85,8 +85,8 @@ packet_do_send (struct rs_packet *pkt)
{
char host[80], serv[80];
- getnameinfo (pkt->conn->active_peer->addr->ai_addr,
- pkt->conn->active_peer->addr->ai_addrlen,
+ getnameinfo (pkt->conn->active_peer->addr_cache->ai_addr,
+ pkt->conn->active_peer->addr_cache->ai_addrlen,
host, sizeof(host), serv, sizeof(serv),
0 /* NI_NUMERICHOST|NI_NUMERICSERV*/);
rs_debug (("%s: about to send this to %s:%s:\n", __func__, host, serv));
diff --git a/lib/radsec.c b/lib/radsec.c
index 53b5942..e176b6d 100644
--- a/lib/radsec.c
+++ b/lib/radsec.c
@@ -97,10 +97,10 @@ rs_context_init_freeradius_dict (struct rs_context *ctx, const char *dict)
}
struct rs_error *
-rs_resolv (struct evutil_addrinfo **addr,
- rs_conn_type_t type,
- const char *hostname,
- const char *service)
+rs_resolve (struct evutil_addrinfo **addr,
+ rs_conn_type_t type,
+ const char *hostname,
+ const char *service)
{
int err;
struct evutil_addrinfo hints, *res = NULL;
@@ -150,8 +150,11 @@ rs_context_destroy (struct rs_context *ctx)
for (p = r->peers; p; )
{
struct rs_peer *tmp = p;
- if (p->addr)
- evutil_freeaddrinfo (p->addr);
+ if (p->addr_cache)
+ {
+ evutil_freeaddrinfo (p->addr_cache);
+ p->addr_cache = NULL;
+ }
p = p->next;
rs_free (ctx, tmp);
}