+2002-06-04 Ken Raeburn <raeburn@mit.edu>
+
+ * k5-int.h (struct addrlist): Field "addrs" now points to
+ addrinfo instead of sockaddr.
+
2002-05-31 Ken Raeburn <raeburn@mit.edu>
* socket-utils.h (socklen) [! HAVE_SA_LEN]: Return a socklen_t
krb5_error_code krb5_os_hostaddr
(krb5_context, const char *, krb5_address ***);
+/* N.B.: You need to include fake-addrinfo.h *before* k5-int.h if you're
+ going to use this structure. */
struct addrlist {
- struct sockaddr **addrs;
+ struct addrinfo **addrs;
int naddrs;
int space;
};
+2002-06-04 Ken Raeburn <raeburn@mit.edu>
+
+ * sendmsg.c: Include fake-addrinfo.h.
+ (krb524_sendto_kdc): Update for addrlist changes.
+
2002-04-10 Danilo Almeida <dalmeida@mit.edu>
* encode.c, cnv_tkt_skey.c: Need port-sockets.h for Win32 (now
/* Grab socket stuff. This might want to go away later. */
#define NEED_SOCKETS
#define NEED_LOWLEVEL_IO
+#include "fake-addrinfo.h" /* for custom addrinfo if needed */
#include "k5-int.h"
#ifndef _WIN32
*/
if (retval == 0)
for (i = 0; i < al.naddrs; i++) {
- if (al.addrs[i]->sa_family == AF_INET)
- sa2sin (al.addrs[i])->sin_port = port;
+ if (al.addrs[i]->ai_family == AF_INET)
+ sa2sin (al.addrs[i]->ai_addr)->sin_port = port;
}
}
if (retval)
* protocol exists to support a particular socket type
* within a given protocol family.
*/
- socklist[host] = socket(al.addrs[host]->sa_family, SOCK_DGRAM,
+ socklist[host] = socket(al.addrs[host]->ai_family, SOCK_DGRAM,
0);
if (socklist[host] == INVALID_SOCKET)
continue; /* try other hosts */
socket will time out, so use connect, send, recv instead of
sendto, recvfrom. The connect here may return an error if
the destination host is known to be unreachable. */
- if (connect(socklist[host], al.addrs[host],
- socklen(al.addrs[host])) == SOCKET_ERROR)
+ if (connect(socklist[host], al.addrs[host]->ai_addr,
+ al.addrs[host]->ai_addrlen) == SOCKET_ERROR)
continue;
}
if (send(socklist[host], message->data, (int) message->length, 0)
+2002-06-04 Ken Raeburn <raeburn@mit.edu>
+
+ * locate_kdc.c: Include fake-addrinfo.h before k5-int.h.
+ (grow_list, krb5int_free_addrlist)
+ (add_addrinfo_to_list): Incorporate list-updating code from
+ add_sockaddr_to_list. Store an addrinfo pointer, and set the
+ ai_next field to null.
+ (add_host_to_list): New arg SOCKTYPE. Write port numbers into
+ buffers and let getaddrinfo fill in the sin*_port fields. Call
+ getaddrinfo twice, and use two loops to add entries to the
+ addrlist structure.
+ (add_sockaddr_to_list, set_port_num): Deleted.
+ (krb5_locate_srv_conf_1, krb5_locate_srv_dns_1): Pass extra arg
+ to add_host_to_list.
+ (krb5int_locate_server): New value 2 for is_stream arg means
+ accept both UDP and TCP.
+ * changepw.c: Include fake-addrinfo.h.
+ (krb5_locate_passwd, krb5_change_password): Update for addrlist
+ changes.
+ * sendto_kdc.c: Include fake-addrinfo.h.
+ (krb5_sendto_kdc): Update for addrlist changes. Skip any
+ addresses that are not SOCK_DGRAM.
+ * t_locate_kdc.c (stypename): New function.
+ (print_addrs): Update for addrlist changes. Print socket type
+ with address and port.
+
2002-04-12 Ken Raeburn <raeburn@mit.edu>
* lock_file.c (krb5_lock_file) [POSIX_FILE_LOCKS]: Make static
*/
#define NEED_SOCKETS
+#include "fake-addrinfo.h"
#include "k5-int.h"
#include "os-proto.h"
#include "adm_err.h"
port number to use DEFAULT_KPASSWD_PORT. */
int i;
for ( i=0;i<addrlist->naddrs;i++ ) {
- struct sockaddr *a = addrlist->addrs[i];
- if (a->sa_family == AF_INET)
- sa2sin (a)->sin_port = htons(DEFAULT_KPASSWD_PORT);
+ struct addrinfo *a = addrlist->addrs[i];
+ if (a->ai_family == AF_INET)
+ sa2sin (a->ai_addr)->sin_port = htons(DEFAULT_KPASSWD_PORT);
}
}
}
struct timeval timeout;
/* XXX Now the locate_ functions can return IPv6 addresses. */
- if (al.addrs[i]->sa_family != AF_INET)
+ if (al.addrs[i]->ai_family != AF_INET)
continue;
tried_one = 1;
- if (connect(s2, al.addrs[i], socklen(al.addrs[i])) == SOCKET_ERROR) {
+ if (connect(s2, al.addrs[i]->ai_addr, al.addrs[i]->ai_addrlen) == SOCKET_ERROR) {
if (SOCKET_ERRNO == ECONNREFUSED || SOCKET_ERRNO == EHOSTUNREACH)
continue; /* try the next addr */
if ((cc = sendto(s1, chpw_req.data,
(GETSOCKNAME_ARG3_TYPE) chpw_req.length, 0,
- al.addrs[i], socklen(al.addrs[i]))) != chpw_req.length)
+ al.addrs[i]->ai_addr, al.addrs[i]->ai_addrlen)) != chpw_req.length)
{
if ((cc < 0) && ((SOCKET_ERRNO == ECONNREFUSED) ||
(SOCKET_ERRNO == EHOSTUNREACH)))
*/
#define NEED_SOCKETS
+#include "fake-addrinfo.h"
#include "k5-int.h"
#include "os-proto.h"
#include <stdio.h>
#define T_SRV 33
#endif /* T_SRV */
-#include "fake-addrinfo.h"
-
/* for old Unixes and friends ... */
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
int i;
int newspace = lp->space + nmore;
size_t newsize = newspace * sizeof (struct addrlist);
- struct sockaddr **newaddrs;
+ struct addrinfo **newaddrs;
/* NULL check a concession to SunOS4 compatibility for now; not
required for pure ANSI support. */
{
int i;
for (i = 0; i < lp->naddrs; i++)
- free (lp->addrs[i]);
+ freeaddrinfo (lp->addrs[i]);
free (lp->addrs);
lp->addrs = NULL;
lp->naddrs = lp->space = 0;
}
#define free_list krb5int_free_addrlist
-static int
-add_sockaddr_to_list (struct addrlist *lp, const struct sockaddr *addr,
- size_t len)
-{
- struct sockaddr *copy;
- int err;
-
-#ifdef TEST
- char name[NI_MAXHOST];
-
- fprintf (stderr, "\tadding sockaddr family %2d, len %d", addr->sa_family,
- len);
-
- err = getnameinfo (addr, len, name, sizeof (name), NULL, 0,
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (err == 0)
- fprintf (stderr, "\t%s", name);
- fprintf (stderr, "\n");
-#endif
-
- if (lp->naddrs == lp->space) {
- err = grow_list (lp, 1);
- if (err) {
-#ifdef TEST
- fprintf (stderr, "grow_list failed %d\n", err);
-#endif
- return err;
- }
- }
- copy = malloc (len);
- if (copy == NULL) {
-#ifdef TEST
- perror ("malloc");
-#endif
- return errno;
- }
- memcpy (copy, addr, len);
- lp->addrs[lp->naddrs++] = copy;
-#ifdef TEST
- fprintf (stderr, "count is now %d\n", lp->naddrs);
-#endif
- return 0;
-}
-
static int translate_ai_error (int err)
{
switch (err) {
static int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a)
{
- int r;
- r = add_sockaddr_to_list (lp, a->ai_addr, a->ai_addrlen);
+ int err;
+
#ifdef TEST
switch (a->ai_socktype) {
case SOCK_DGRAM:
break;
}
#endif
- return r;
-}
-static void set_port_num (struct sockaddr *addr, int num)
-{
- switch (addr->sa_family) {
- case AF_INET:
- ((struct sockaddr_in *)addr)->sin_port = num;
- break;
-#ifdef KRB5_USE_INET6
- case AF_INET6:
- ((struct sockaddr_in6 *)addr)->sin6_port = num;
- break;
+ if (lp->naddrs == lp->space) {
+ err = grow_list (lp, 1);
+ if (err) {
+#ifdef TEST
+ fprintf (stderr, "grow_list failed %d\n", err);
#endif
+ return err;
+ }
}
+ lp->addrs[lp->naddrs++] = a;
+ a->ai_next = 0;
+#ifdef TEST
+ fprintf (stderr, "count is now %d\n", lp->naddrs);
+#endif
+ return 0;
}
static int
add_host_to_list (struct addrlist *lp, const char *hostname,
- int port, int secport)
+ int port, int secport, int socktype)
{
- struct addrinfo *addrs, *a, hint;
+ struct addrinfo *addrs, *a, *anext, hint;
int err;
+ char portbuf[10], secportbuf[10];
#ifdef TEST
fprintf (stderr, "adding hostname %s, ports %d,%d\n", hostname,
#endif
memset(&hint, 0, sizeof(hint));
- hint.ai_socktype = SOCK_DGRAM;
- err = getaddrinfo (hostname, NULL, &hint, &addrs);
+ hint.ai_socktype = socktype;
+ sprintf(portbuf, "%d", ntohs(port));
+ sprintf(secportbuf, "%d", ntohs(secport));
+ err = getaddrinfo (hostname, portbuf, &hint, &addrs);
if (err)
return translate_ai_error (err);
- for (a = addrs; a; a = a->ai_next) {
- set_port_num (a->ai_addr, port);
+ anext = 0;
+ for (a = addrs; a != 0 && err == 0; a = anext) {
+ anext = a->ai_next;
err = add_addrinfo_to_list (lp, a);
- if (err)
- break;
-
- if (secport == 0)
- continue;
-
- set_port_num (a->ai_addr, secport);
+ }
+ if (err || secport == 0)
+ goto egress;
+ err = getaddrinfo (hostname, secportbuf, &hint, &addrs);
+ if (err)
+ return translate_ai_error (err);
+ for (a = addrs; a != 0 && err == 0; a = anext) {
+ anext = a->ai_next;
err = add_addrinfo_to_list (lp, a);
- if (err)
- break;
}
- freeaddrinfo (addrs);
+egress:
+ if (anext)
+ freeaddrinfo (anext);
return err;
}
p2 = sec_udpport;
}
- code = add_host_to_list (addrlist, hostlist[i], p1, p2);
+ code = add_host_to_list (addrlist, hostlist[i], p1, p2, SOCK_DGRAM);
if (code) {
#ifdef TEST
fprintf (stderr, "error %d returned from add_host_to_list\n", code);
#ifdef TEST
fprintf (stderr, "\tport=%d host=%s\n", entry->port, entry->host);
#endif
- code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0);
+ code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0,
+ (strcmp("_tcp", protocol)
+ ? SOCK_DGRAM
+ : SOCK_STREAM));
if (code)
break;
}
#ifdef KRB5_DNS_LOOKUP
if (code && dnsname != 0) {
int use_dns = _krb5_use_dns_kdc(context);
- if (use_dns)
- code = krb5_locate_srv_dns_1(realm, dnsname,
- is_stream ? "_tcp" : "_udp", &al);
+ if (use_dns) {
+ /* Values of is_stream:
+ 0: udp only
+ 1: tcp only
+ 2: udp or tcp
+ No other values currently allowed. */
+ code = 0;
+#ifdef TEST
+ fprintf(stderr, "is_stream = %d\n", is_stream);
+#endif
+ if (is_stream != 1) {
+ code = krb5_locate_srv_dns_1(realm, dnsname, "_udp", &al);
+#ifdef TEST
+ if (code)
+ fprintf(stderr, "dns lookup returned error %d\n", code);
+#endif
+ }
+ if (is_stream != 0 && code == 0) {
+ code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp", &al);
+#ifdef TEST
+ if (code)
+ fprintf(stderr, "dns lookup returned error %d\n", code);
+#endif
+ }
+ }
}
#endif /* KRB5_DNS_LOOKUP */
#ifdef TEST
#define NEED_SOCKETS
#define NEED_LOWLEVEL_IO
+#include "fake-addrinfo.h"
#include "k5-int.h"
#ifdef HAVE_SYS_TIME_H
timeout <<= krb5_skdc_timeout_shift) {
sent = 0;
for (host = 0; host < addrs.naddrs; host++) {
- /* send to the host, wait timeout seconds for a response,
+ if (addrs.addrs[host]->ai_socktype != SOCK_DGRAM)
+ continue;
+ /* Send to the host, wait timeout seconds for a response,
then move on. */
- /* cache some sockets for each host */
+ /* Cache some sockets for each host. */
if (socklist[host] == INVALID_SOCKET) {
/* XXX 4.2/4.3BSD has PF_xxx = AF_xxx, so the socket
creation here will work properly... */
*/
#ifdef DEBUG
fprintf (stderr, "getting dgram socket in family %d...",
- addrs.addrs[host]->sa_family);
+ addrs.addrs[host]->ai_family);
#endif
- socklist[host] = socket(addrs.addrs[host]->sa_family,
+ socklist[host] = socket(addrs.addrs[host]->ai_family,
SOCK_DGRAM, 0);
if (socklist[host] == INVALID_SOCKET) {
#ifdef DEBUG
perror ("socket");
- fprintf (stderr, "af was %d\n", addrs.addrs[host]->sa_family);
+ fprintf (stderr, "af was %d\n", addrs.addrs[host]->ai_family);
#endif
continue; /* try other hosts */
}
#ifdef DEBUG
{
char addrbuf[NI_MAXHOST], portbuf[NI_MAXSERV];
- if (0 != getnameinfo (addrs.addrs[host],
- socklen (addrs.addrs[host]),
+ if (0 != getnameinfo (addrs.addrs[host]->ai_addr,
+ addrs.addrs[host]->ai_addrlen,
addrbuf, sizeof (addrbuf),
portbuf, sizeof (portbuf),
NI_NUMERICHOST | NI_NUMERICSERV))
sendto, recvfrom. The connect here may return an error if
the destination host is known to be unreachable. */
if (connect(socklist[host],
- addrs.addrs[host], socklen(addrs.addrs[host])) == SOCKET_ERROR) {
+ addrs.addrs[host]->ai_addr, addrs.addrs[host]->ai_addrlen) == SOCKET_ERROR) {
#ifdef DEBUG
perror ("connect");
#endif
exit (1);
}
+const char *stypename (int stype)
+{
+ static char buf[20];
+ switch (stype) {
+ case SOCK_STREAM:
+ return "stream";
+ case SOCK_DGRAM:
+ return "dgram";
+ case SOCK_RAW:
+ return "raw";
+ default:
+ sprintf(buf, "?%d", stype);
+ return buf;
+ }
+}
+
void print_addrs ()
{
int i;
- struct sockaddr **addrs = al.addrs;
+ struct addrinfo **addrs = al.addrs;
int naddrs = al.naddrs;
printf ("%d addresses:\n", naddrs);
for (i = 0; i < naddrs; i++) {
int err;
char hostbuf[NI_MAXHOST], srvbuf[NI_MAXSERV];
- err = getnameinfo (addrs[i], socklen(addrs[i]),
+ err = getnameinfo (addrs[i]->ai_addr, addrs[i]->ai_addrlen,
hostbuf, sizeof (hostbuf),
srvbuf, sizeof (srvbuf),
NI_NUMERICHOST | NI_NUMERICSERV);
printf ("%2d: getnameinfo returns error %d=%s\n",
i, err, gai_strerror (err));
else
- printf ("%2d: address %s\tport %s\n", i, hostbuf, srvbuf);
+ printf ("%2d: address %s\t%s\tport %s\n", i, hostbuf,
+ stypename (addrs[i]->ai_socktype), srvbuf);
}
}