use getaddrinfo instead of dns_lookup when testing for

kerberos.REALM.  this allows reusing that information when actually
contacting the server and thus avoids one DNS lookup


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@10149 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
2001-06-21 04:05:28 +00:00
parent de04c2dd41
commit 789f49bc82

View File

@@ -238,6 +238,26 @@ krb5_krbhst_format_string(krb5_context context, const krb5_krbhst_info *host,
return 0; return 0;
} }
/*
* create a getaddrinfo `hints' based on
*/
static void
make_hints(struct addrinfo *hints, int proto)
{
memset(hints, 0, sizeof(*hints));
hints->ai_family = AF_UNSPEC;
switch(proto) {
case KRB5_KRBHST_UDP :
hints->ai_socktype = SOCK_DGRAM;
break;
case KRB5_KRBHST_HTTP :
case KRB5_KRBHST_TCP :
hints->ai_socktype = SOCK_STREAM;
break;
}
}
/* /*
* return an `struct addrinfo *' in `ai' corresponding to the information * return an `struct addrinfo *' in `ai' corresponding to the information
* in `host'. free:ing is handled by krb5_krbhst_free. * in `host'. free:ing is handled by krb5_krbhst_free.
@@ -252,17 +272,7 @@ krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
int ret; int ret;
if (host->ai == NULL) { if (host->ai == NULL) {
memset (&hints, 0, sizeof(hints)); make_hints(&hints, host->proto);
hints.ai_family = AF_UNSPEC;
switch(host->proto) {
case KRB5_KRBHST_UDP :
hints.ai_socktype = SOCK_DGRAM;
break;
case KRB5_KRBHST_HTTP :
case KRB5_KRBHST_TCP :
hints.ai_socktype = SOCK_STREAM;
break;
}
snprintf (portstr, sizeof(portstr), "%d", host->port); snprintf (portstr, sizeof(portstr), "%d", host->port);
ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai); ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
if (ret) if (ret)
@@ -317,12 +327,22 @@ config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
krb5_config_free_strings(hostlist); krb5_config_free_strings(hostlist);
} }
static void /*
* as a fallback, look for `serv_string.kd->realm' (typically
* kerberos.REALM, kerberos-1.REALM, ...
* `def_port' is the default port for the service, and `proto' the
* protocol
*/
static krb5_error_code
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
const char *serv_string, int def_port) const char *serv_string, int def_port, int proto)
{ {
char *host; char *host;
struct dns_reply *r; int ret;
struct addrinfo *ai;
struct addrinfo hints;
char portstr[NI_MAXSERV];
if(kd->fallback_count == 0) if(kd->fallback_count == 0)
asprintf(&host, "%s.%s.", serv_string, kd->realm); asprintf(&host, "%s.%s.", serv_string, kd->realm);
@@ -330,18 +350,34 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
asprintf(&host, "%s-%d.%s.", asprintf(&host, "%s-%d.%s.",
serv_string, kd->fallback_count, kd->realm); serv_string, kd->fallback_count, kd->realm);
r = dns_lookup(host, "A"); if (host == NULL)
if(r == NULL) return ENOMEM;
r = dns_lookup(host, "CNAME");
if(r == NULL) { make_hints(&hints, proto);
snprintf(portstr, sizeof(portstr), "%d", def_port);
ret = getaddrinfo(host, portstr, &hints, &ai);
if (ret) {
/* no more hosts, so we're done here */ /* no more hosts, so we're done here */
free(host); free(host);
kd->flags |= KD_FALLBACK; kd->flags |= KD_FALLBACK;
} else { } else {
host[strlen(host) - 1] = '\0'; struct krb5_krbhst_info *hi;
append_host_string(context, kd, host, def_port);
hi = calloc(1, sizeof(*hi) + strlen(host));
if(hi == NULL) {
free(host);
return ENOMEM;
}
hi->proto = proto;
hi->port = hi->def_port = def_port;
hi->ai = ai;
strcpy(hi->hostname, host);
free(host);
append_host_hostinfo(kd, hi);
kd->fallback_count++; kd->fallback_count++;
} }
return 0;
} }
static krb5_error_code static krb5_error_code
@@ -349,6 +385,7 @@ kdc_get_next(krb5_context context,
struct krb5_krbhst_data *kd, struct krb5_krbhst_data *kd,
krb5_krbhst_info **host) krb5_krbhst_info **host)
{ {
krb5_error_code ret;
int port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88)); int port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
if((kd->flags & KD_CONFIG) == 0) { if((kd->flags & KD_CONFIG) == 0) {
@@ -384,7 +421,10 @@ kdc_get_next(krb5_context context,
} }
while((kd->flags & KD_FALLBACK) == 0) { while((kd->flags & KD_FALLBACK) == 0) {
fallback_get_hosts(context, kd, "kerberos", port); ret = fallback_get_hosts(context, kd, "kerberos",
port, KRB5_KRBHST_UDP);
if(ret)
return ret;
if(get_next(kd, host)) if(get_next(kd, host))
return 0; return 0;
} }
@@ -397,6 +437,7 @@ admin_get_next(krb5_context context,
struct krb5_krbhst_data *kd, struct krb5_krbhst_data *kd,
krb5_krbhst_info **host) krb5_krbhst_info **host)
{ {
krb5_error_code ret;
int port = ntohs(krb5_getportbyname (context, "kerberos-adm", "tcp", 749)); int port = ntohs(krb5_getportbyname (context, "kerberos-adm", "tcp", 749));
if((kd->flags & KD_CONFIG) == 0) { if((kd->flags & KD_CONFIG) == 0) {
@@ -420,7 +461,10 @@ admin_get_next(krb5_context context,
if (krbhst_empty(kd) if (krbhst_empty(kd)
&& (kd->flags & KD_FALLBACK) == 0) { && (kd->flags & KD_FALLBACK) == 0) {
fallback_get_hosts(context, kd, "kerberos", port); ret = fallback_get_hosts(context, kd, "kerberos",
port, KRB5_KRBHST_UDP);
if(ret)
return ret;
kd->flags |= KD_FALLBACK; kd->flags |= KD_FALLBACK;
if(get_next(kd, host)) if(get_next(kd, host))
return 0; return 0;