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).
p->realm = r;
cfg_server = cfg_getnsec (cfg_realm, "server", j);
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");
}
}
p->secret = cfg_getstr (cfg_server, "secret");
}
}
#if defined (RS_ENABLE_TLS)
#include "tls.h"
#endif
#if defined (RS_ENABLE_TLS)
#include "tls.h"
#endif
+#include "err.h"
+#include "radsec.h"
#include "event.h"
#include "packet.h"
#include "conn.h"
#include "event.h"
#include "packet.h"
#include "conn.h"
if (conn->fd != -1)
return RSE_OK;
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)",
if (conn->fd < 0)
return rs_err_conn_push_fl (conn, RSE_SOCKERR, __FILE__, __LINE__,
"socket: %d (%s)",
{
char host[80], serv[80];
{
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));
host, sizeof(host), serv, sizeof(serv),
0 /* NI_NUMERICHOST|NI_NUMERICSERV*/);
rs_debug (("%s: connecting to %s:%s\n", __func__, host, serv));
if (p->conn->bev) /* TCP */
{
conn_activate_timeout (conn); /* Connect timeout. */
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",
if (err < 0)
rs_err_conn_push_fl (p->conn, RSE_EVENT, __FILE__, __LINE__,
"bufferevent_socket_connect: %s",
- 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);
if (err < 0)
{
sockerr = evutil_socket_geterror (p->conn->fd);
struct rs_peer {
struct rs_connection *conn;
struct rs_realm *realm;
struct rs_peer {
struct rs_connection *conn;
struct rs_realm *realm;
- struct evutil_addrinfo *addr;
+ char *hostname;
+ char *service;
char *secret; /* RADIUS secret. */
char *secret; /* RADIUS secret. */
+ struct evutil_addrinfo *addr_cache;
struct rs_packet *next; /* Used for UDP output queue. */
};
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
#if defined (__cplusplus)
}
#endif
{
char host[80], serv[80];
{
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));
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));
-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;
{
int err;
struct evutil_addrinfo hints, *res = NULL;
for (p = r->peers; p; )
{
struct rs_peer *tmp = p;
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);
}
p = p->next;
rs_free (ctx, tmp);
}