From: ueno Date: Tue, 22 Jan 2002 12:40:30 +0000 (+0000) Subject: * addrinfo.h: Removed and gave up to emulate getaddrinfo(3). Thus X-Git-Tag: starttls-0_9~12 X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0ad35214d3c67926be72ad2e13b9c67ad2091bf;p=elisp%2Fstarttls.git * addrinfo.h: Removed and gave up to emulate getaddrinfo(3). Thus on systems where there is no such thing, we are now being unable to use IPv6. * bittypes.h: Ditto. * getaddrinfo.c: Ditto. * sockstorage.h: Ditto. * Makefile.am: Took off the above stuff from EXTRA_DIST. * configure.in: Don't touch $LIBOBJS even if there is no getaddrinfo working. * starttls.c (tls_connect) [!HAVE_ADDRINFO]: Don't use the fake getaddrinfo. --- diff --git a/Makefile.am b/Makefile.am index 78b2b04..c9eb5f7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ DEFS = -I$(srcdir) $(CFLAGS) @DEFS@ LIBOBJS = @LIBOBJS@ -EXTRA_DIST = starttls.el bittypes.h sockstorage.h addrinfo.h basename.c getaddrinfo.c getopt.c getopt.h getopt1.c +EXTRA_DIST = starttls.el basename.c getopt.c getopt.h getopt1.c bin_PROGRAMS= starttls lisp_LISP = starttls.el diff --git a/addrinfo.h b/addrinfo.h deleted file mode 100644 index 3cf2537..0000000 --- a/addrinfo.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* $Id: addrinfo.h,v 1.2 2002-01-22 08:33:28 ueno Exp $ */ - -#ifndef HAVE_ADDRINFO - -/* - * Error return codes from getaddrinfo() - */ -#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ -#define EAI_AGAIN 2 /* temporary failure in name resolution */ -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ -#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ -#define EAI_FAMILY 5 /* ai_family not supported */ -#define EAI_MEMORY 6 /* memory allocation failure */ -#define EAI_NODATA 7 /* no address associated with hostname */ -#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ -#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ -#define EAI_SYSTEM 11 /* system error returned in errno */ -#define EAI_BADHINTS 12 -#define EAI_PROTOCOL 13 -#define EAI_MAX 14 - -/* internal error */ -#define NETDB_INTERNAL -1 /* see errno */ - -/* - * Flag values for getaddrinfo() - */ -#define AI_PASSIVE 0x00000001 /* get address to use bind() */ -#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ -#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ -/* valid flags for addrinfo */ -#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) - -#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ -#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ -#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ -#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ -/* special recommended flags for getipnodebyname */ -#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) - -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; - -extern void freeaddrinfo (struct addrinfo *); -extern void freehostent (struct hostent *); -extern char *gai_strerror (int); -extern int getaddrinfo (const char *, const char *, - const struct addrinfo *, struct addrinfo **); -extern int getnameinfo (const struct sockaddr *, size_t, char *, - size_t, char *, size_t, int); -extern struct hostent *getipnodebyaddr (const void *, size_t, int, int *); -extern struct hostent *getipnodebyname (const char *, int, int, int *); -extern int inet_pton (int, const char *, void *); -extern const char *inet_ntop (int, const void *, char *, size_t); -#endif /* HAVE_ADDRINFO */ - -/* - * Constants for getnameinfo() - */ -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif -#ifndef NI_MAXSERV -#define NI_MAXSERV 32 -#endif - -/* - * Flag values for getnameinfo() - */ -#ifndef NI_NOFQDN -#define NI_NOFQDN 0x00000001 -#endif -#ifndef NI_NUMERICHOST -#define NI_NUMERICHOST 0x00000002 -#endif -#ifndef NI_NAMEREQD -#define NI_NAMEREQD 0x00000004 -#endif -#ifndef NI_NUMERICSERV -#define NI_NUMERICSERV 0x00000008 -#endif -#ifndef NI_DGRAM -#define NI_DGRAM 0x00000010 -#endif diff --git a/bittypes.h b/bittypes.h deleted file mode 100644 index 500f39f..0000000 --- a/bittypes.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#ifndef HAVE_U_INT8_T - -#if SIZEOF_CHAR == 1 -typedef unsigned char u_int8_t; -#elif SIZEOF_INT == 1 -typedef unsigned int u_int8_t; -#else /* XXX */ -#error "there's no appropriate type for u_int8_t" -#endif - -#endif /* HAVE_U_INT8_T */ - -#ifndef HAVE_U_INT16_T - -#if SIZEOF_SHORT == 2 -typedef unsigned short u_int16_t; -#elif SIZEOF_INT == 2 -typedef unsigned int u_int16_t; -#elif SIZEOF_CHAR == 2 -typedef unsigned char u_int16_t; -#else /* XXX */ -#error "there's no appropriate type for u_int16_t" -#endif - -#endif /* HAVE_U_INT16_T */ - -#ifndef HAVE_U_INT32_T - -#if SIZEOF_INT == 4 -typedef unsigned int u_int32_t; -#elif SIZEOF_LONG == 4 -typedef unsigned long u_int32_t; -#elif SIZEOF_SHORT == 4 -typedef unsigned short u_int32_t; -#else /* XXX */ -#error "there's no appropriate type for u_int32_t" -#endif - -#endif /* HAVE_U_INT32_T */ diff --git a/configure.in b/configure.in index 63df020..5fc0131 100644 --- a/configure.in +++ b/configure.in @@ -12,18 +12,14 @@ AC_PROG_RANLIB AC_CHECK_HEADERS(libgen.h sys/select.h sys/poll.h) -AC_CHECK_LIB(nsl, gethostbyname) -AC_CHECK_LIB(socket, socket) -AC_CHECK_TYPE(fd_set, int) -AC_CHECK_FUNC(getopt_long,,LIBOBJS="$LIBOBJS getopt.o getopt1.o") -AC_REPLACE_FUNCS(basename getaddrinfo) -AC_CHECK_FUNC(poll) - AC_STRUCT_ADDRINFO(ac_cv_struct_addrinfo) if test "$ac_cv_struct_addrinfo" = "no"; then - AC_CHECK_BITTYPES(ac_cv_bittypes) - AC_STRUCT_SA_STORAGE(ac_cv_sa_storage) + AC_CHECK_LIB(nsl, gethostbyname) fi +AC_CHECK_LIB(socket, socket) +AC_CHECK_FUNC(getopt_long,,LIBOBJS="$LIBOBJS getopt.o getopt1.o") +AC_REPLACE_FUNCS(basename) +AC_CHECK_FUNC(poll) AC_ARG_WITH(openssl,[ --with-openssl=PATH use OpenSSL from PATH]) diff --git a/getaddrinfo.c b/getaddrinfo.c deleted file mode 100644 index af8d114..0000000 --- a/getaddrinfo.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. - * - * Issues to be discussed: - * - Thread safe-ness must be checked. - * - Return values. There are nonstandard return values defined and used - * in the source code. This is because RFC2553 is silent about which error - * code must be returned for which situation. - * Note: - * - We use getipnodebyname() just for thread-safeness. There's no intent - * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to - * getipnodebyname(). - * - The code filters out AFs that are not supported by the kernel, - * when globbing NULL hostname (to loopback, or wildcard). Is it the right - * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG - * in ai_flags? - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifndef lint -static const char rcsid[] = - "@(#) $Header: /opt/backups/cvs.m17n.org/root/starttls/Attic/getaddrinfo.c,v 1.3 2002-01-22 08:33:28 ueno Exp $"; -#endif - -#include -#include -#if 0 -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef HAVE_U_INT32_T -#include "bittypes.h" -#endif - -#ifndef HAVE_SOCKADDR_STORAGE -#include "sockstorage.h" -#endif - -#ifdef NEED_ADDRINFO_H -#include "addrinfo.h" -#endif - -#if defined(__KAME__) && defined(INET6) -# define FAITH -#endif - -#define SUCCESS 0 -#define ANY 0 -#define YES 1 -#define NO 0 - -#ifdef FAITH -static int translate = NO; -static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT; -#endif - -static const char in_addrany[] = { 0, 0, 0, 0 }; -static const char in6_addrany[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -static const char in_loopback[] = { 127, 0, 0, 1 }; -static const char in6_loopback[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 -}; - -struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; - u_int32_t si_scope_id; -}; - -static const struct afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; - const char *a_addrany; - const char *a_loopback; - int a_scoped; -} afdl [] = { -#ifdef INET6 - {PF_INET6, sizeof(struct in6_addr), - sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr), - in6_addrany, in6_loopback, 1}, -#endif - {PF_INET, sizeof(struct in_addr), - sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr), - in_addrany, in_loopback, 0}, - {0, 0, 0, 0, NULL, NULL, 0}, -}; - -struct explore { - int e_af; - int e_socktype; - int e_protocol; - const char *e_protostr; - int e_wild; -#define WILD_AF(ex) ((ex)->e_wild & 0x01) -#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) -#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) -}; - -static const struct explore explore[] = { -#if 0 - { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, -#endif -#ifdef INET6 - { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, - { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, - { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, -#endif - { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, - { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, - { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, - { -1, 0, 0, NULL, 0 }, -}; - -#ifdef INET6 -#define PTON_MAX 16 -#else -#define PTON_MAX 4 -#endif - - -static int str_isnumber (const char *); -static int explore_fqdn (const struct addrinfo *, const char *, - const char *, struct addrinfo **); -static int explore_null (const struct addrinfo *, const char *, - const char *, struct addrinfo **); -static int explore_numeric (const struct addrinfo *, const char *, - const char *, struct addrinfo **); -static int explore_numeric_scope (const struct addrinfo *, const char *, - const char *, struct addrinfo **); -static int get_name (const char *, const struct afd *, struct addrinfo **, - char *, const struct addrinfo *, const char *); -static int get_canonname (const struct addrinfo *, - struct addrinfo *, const char *); -static struct addrinfo *get_ai (const struct addrinfo *, - const struct afd *, const char *); -static int get_portmatch (const struct addrinfo *, const char *); -static int get_port (struct addrinfo *, const char *, int); -static const struct afd *find_afd (int); - -static char *ai_errlist[] = { - "Success", - "Address family for hostname not supported", /* EAI_ADDRFAMILY */ - "Temporary failure in name resolution", /* EAI_AGAIN */ - "Invalid value for ai_flags", /* EAI_BADFLAGS */ - "Non-recoverable failure in name resolution", /* EAI_FAIL */ - "ai_family not supported", /* EAI_FAMILY */ - "Memory allocation failure", /* EAI_MEMORY */ - "No address associated with hostname", /* EAI_NODATA */ - "hostname nor servname provided, or not known", /* EAI_NONAME */ - "servname not supported for ai_socktype", /* EAI_SERVICE */ - "ai_socktype not supported", /* EAI_SOCKTYPE */ - "System error returned in errno", /* EAI_SYSTEM */ - "Invalid value for hints", /* EAI_BADHINTS */ - "Resolved protocol is unknown", /* EAI_PROTOCOL */ - "Unknown error", /* EAI_MAX */ -}; - -/* XXX macros that make external reference is BAD. */ - -#define GET_AI(ai, afd, addr) \ -do { \ - /* external reference: pai, error, and label free */ \ - (ai) = get_ai(pai, (afd), (addr)); \ - if ((ai) == NULL) { \ - error = EAI_MEMORY; \ - goto free; \ - } \ -} while (0) - -#define GET_PORT(ai, serv) \ -do { \ - /* external reference: error and label free */ \ - error = get_port((ai), (serv), 0); \ - if (error != 0) \ - goto free; \ -} while (0) - -#define GET_CANONNAME(ai, str) \ -do { \ - /* external reference: pai, error and label free */ \ - error = get_canonname(pai, (ai), (str)); \ - if (error != 0) \ - goto free; \ -} while (0) - -#define ERR(err) \ -do { \ - /* external reference: error, and label bad */ \ - error = (err); \ - goto bad; \ -} while (0) - -#define MATCH_FAMILY(x, y, w) \ - ((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) -#define MATCH(x, y, w) \ - ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY))) - -char * -gai_strerror(ecode) - int ecode; -{ - if (ecode < 0 || ecode > EAI_MAX) - ecode = EAI_MAX; - return ai_errlist[ecode]; -} - -void -freeaddrinfo(ai) - struct addrinfo *ai; -{ - struct addrinfo *next; - - do { - next = ai->ai_next; - if (ai->ai_canonname) - free(ai->ai_canonname); - /* no need to free(ai->ai_addr) */ - free(ai); - } while ((ai = next) != NULL); -} - -static int -str_isnumber(p) - const char *p; -{ - char *q = (char *)p; - while (*q) { - if (! isdigit(*q)) - return NO; - q++; - } - return YES; -} - -int -getaddrinfo(hostname, servname, hints, res) - const char *hostname, *servname; - const struct addrinfo *hints; - struct addrinfo **res; -{ - struct addrinfo sentinel; - struct addrinfo *cur; - int error = 0; - struct addrinfo ai; - struct addrinfo ai0; - struct addrinfo *pai; - const struct afd *afd; - const struct explore *ex; - -#ifdef FAITH - static int firsttime = 1; - - if (firsttime) { - /* translator hack */ - char *q = getenv("GAI"); - if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) - translate = YES; - firsttime = 0; - } -#endif - - sentinel.ai_next = NULL; - cur = &sentinel; - pai = &ai; - pai->ai_flags = 0; - pai->ai_family = PF_UNSPEC; - pai->ai_socktype = ANY; - pai->ai_protocol = ANY; - pai->ai_addrlen = 0; - pai->ai_canonname = NULL; - pai->ai_addr = NULL; - pai->ai_next = NULL; - - if (hostname == NULL && servname == NULL) - return EAI_NONAME; - if (hints) { - /* error check for hints */ - if (hints->ai_addrlen || hints->ai_canonname || - hints->ai_addr || hints->ai_next) - ERR(EAI_BADHINTS); /* xxx */ - if (hints->ai_flags & ~AI_MASK) - ERR(EAI_BADFLAGS); - switch (hints->ai_family) { - case PF_UNSPEC: - case PF_INET: -#ifdef INET6 - case PF_INET6: -#endif - break; - default: - ERR(EAI_FAMILY); - } - memcpy(pai, hints, sizeof(*pai)); - - /* - * if both socktype/protocol are specified, check if they - * are meaningful combination. - */ - if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { - for (ex = explore; ex->e_af >= 0; ex++) { - if (pai->ai_family != ex->e_af) - continue; - if (ex->e_socktype == ANY) - continue; - if (ex->e_protocol == ANY) - continue; - if (pai->ai_socktype == ex->e_socktype - && pai->ai_protocol != ex->e_protocol) { - ERR(EAI_BADHINTS); - } - } - } - } - - /* - * check for special cases. (1) numeric servname is disallowed if - * socktype/protocol are left unspecified. (2) servname is disallowed - * for raw and other inet{,6} sockets. - */ - if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) -#ifdef PF_INET6 - || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) -#endif - ) { - ai0 = *pai; - - if (pai->ai_family == PF_UNSPEC) { -#ifdef PF_INET6 - pai->ai_family = PF_INET6; -#else - pai->ai_family = PF_INET; -#endif - } - error = get_portmatch(pai, servname); - if (error) - ERR(error); - - *pai = ai0; - } - - ai0 = *pai; - - /* NULL hostname, or numeric hostname */ - for (ex = explore; ex->e_af >= 0; ex++) { - *pai = ai0; - - if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) - continue; - if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) - continue; - if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) - continue; - - if (pai->ai_family == PF_UNSPEC) - pai->ai_family = ex->e_af; - if (pai->ai_socktype == ANY && ex->e_socktype != ANY) - pai->ai_socktype = ex->e_socktype; - if (pai->ai_protocol == ANY && ex->e_protocol != ANY) - pai->ai_protocol = ex->e_protocol; - - if (hostname == NULL) - error = explore_null(pai, hostname, servname, &cur->ai_next); - else - error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next); - - if (error) - goto free; - - while (cur && cur->ai_next) - cur = cur->ai_next; - } - - /* - * XXX - * If numreic representation of AF1 can be interpreted as FQDN - * representation of AF2, we need to think again about the code below. - */ - if (sentinel.ai_next) - goto good; - - if (pai->ai_flags & AI_NUMERICHOST) - ERR(EAI_NONAME); - if (hostname == NULL) - ERR(EAI_NONAME); - - /* - * hostname as alphabetical name. - * we would like to prefer AF_INET6 than AF_INET, so we'll make a - * outer loop by AFs. - */ - for (afd = afdl; afd->a_af; afd++) { - *pai = ai0; - - if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1)) - continue; - - for (ex = explore; ex->e_af >= 0; ex++) { - *pai = ai0; - - if (pai->ai_family == PF_UNSPEC) - pai->ai_family = afd->a_af; - - if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) - continue; - if (!MATCH(pai->ai_socktype, ex->e_socktype, - WILD_SOCKTYPE(ex))) { - continue; - } - if (!MATCH(pai->ai_protocol, ex->e_protocol, - WILD_PROTOCOL(ex))) { - continue; - } - - if (pai->ai_family == PF_UNSPEC) - pai->ai_family = ex->e_af; - if (pai->ai_socktype == ANY && ex->e_socktype != ANY) - pai->ai_socktype = ex->e_socktype; - if (pai->ai_protocol == ANY && ex->e_protocol != ANY) - pai->ai_protocol = ex->e_protocol; - - error = explore_fqdn(pai, hostname, servname, - &cur->ai_next); - - while (cur && cur->ai_next) - cur = cur->ai_next; - } - } - - /* XXX */ - if (sentinel.ai_next) - error = 0; - - if (error) - goto free; - if (error == 0) { - if (sentinel.ai_next) { - good: - *res = sentinel.ai_next; - return SUCCESS; - } else - error = EAI_FAIL; - } - free: - bad: - if (sentinel.ai_next) - freeaddrinfo(sentinel.ai_next); - *res = NULL; - return error; -} - -/* - * FQDN hostname, DNS lookup - */ -static int -explore_fqdn(pai, hostname, servname, res) - const struct addrinfo *pai; - const char *hostname; - const char *servname; - struct addrinfo **res; -{ - struct hostent *hp; - int h_error; - int af; - char **aplist = NULL, *apbuf = NULL; - char *ap; - struct addrinfo sentinel, *cur; - int i; -#ifndef USE_GETIPNODEBY - int naddrs; -#endif - const struct afd *afd; - int error; - - *res = NULL; - sentinel.ai_next = NULL; - cur = &sentinel; - - /* - * Do not filter unsupported AFs here. We need to honor content of - * databases (/etc/hosts, DNS and others). Otherwise we cannot - * replace gethostbyname() by getaddrinfo(). - */ - - /* - * if the servname does not match socktype/protocol, ignore it. - */ - if (get_portmatch(pai, servname) != 0) - return 0; - - afd = find_afd(pai->ai_family); - - /* - * post-RFC2553: should look at (pai->ai_flags & AI_ADDRCONFIG) - * rather than hardcoding it. we may need to add AI_ADDRCONFIG - * handling code by ourselves in case we don't have getipnodebyname(). - */ -#ifdef USE_GETIPNODEBY - hp = getipnodebyname(hostname, pai->ai_family, AI_ADDRCONFIG, &h_error); -#else -#ifdef HAVE_GETHOSTBYNAME2 - hp = gethostbyname2(hostname, pai->ai_family); -#else - if (pai->ai_family != AF_INET) - return 0; - hp = gethostbyname(hostname); -#ifdef HAVE_H_ERRNO - h_error = h_errno; -#else - h_error = EINVAL; -#endif -#endif /*HAVE_GETHOSTBYNAME2*/ -#endif /*USE_GETIPNODEBY*/ - - if (hp == NULL) { - switch (h_error) { - case HOST_NOT_FOUND: - case NO_DATA: - error = EAI_NODATA; - break; - case TRY_AGAIN: - error = EAI_AGAIN; - break; - case NO_RECOVERY: - case NETDB_INTERNAL: - default: - error = EAI_FAIL; - break; - } - } else if ((hp->h_name == NULL) || (hp->h_name[0] == 0) - || (hp->h_addr_list[0] == NULL)) { -#ifdef USE_GETIPNODEBY - freehostent(hp); -#endif - hp = NULL; - error = EAI_FAIL; - } - - if (hp == NULL) - goto free; - -#ifdef USE_GETIPNODEBY - aplist = hp->h_addr_list; -#else - /* - * hp will be overwritten if we use gethostbyname2(). - * always deep copy for simplification. - */ - for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++) - ; - naddrs++; - aplist = (char **)malloc(sizeof(aplist[0]) * naddrs); - apbuf = (char *)malloc(hp->h_length * naddrs); - if (aplist == NULL || apbuf == NULL) { - error = EAI_MEMORY; - goto free; - } - memset(aplist, 0, sizeof(aplist[0]) * naddrs); - for (i = 0; i < naddrs; i++) { - if (hp->h_addr_list[i] == NULL) { - aplist[i] = NULL; - continue; - } - memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i], - hp->h_length); - aplist[i] = &apbuf[i * hp->h_length]; - } -#endif - - for (i = 0; aplist[i] != NULL; i++) { - af = hp->h_addrtype; - ap = aplist[i]; -#ifdef AF_INET6 - if (af == AF_INET6 - && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { - af = AF_INET; - ap = ap + sizeof(struct in6_addr) - - sizeof(struct in_addr); - } -#endif - - if (af != pai->ai_family) - continue; - - if ((pai->ai_flags & AI_CANONNAME) == 0) { - GET_AI(cur->ai_next, afd, ap); - GET_PORT(cur->ai_next, servname); - } else { - /* - * if AI_CANONNAME and if reverse lookup - * fail, return ai anyway to pacify - * calling application. - * - * XXX getaddrinfo() is a name->address - * translation function, and it looks - * strange that we do addr->name - * translation here. - */ - get_name(ap, afd, &cur->ai_next, - ap, pai, servname); - } - - while (cur && cur->ai_next) - cur = cur->ai_next; - } - - *res = sentinel.ai_next; - return 0; - -free: -#ifdef USE_GETIPNODEBY - if (hp) - freehostent(hp); -#endif - if (aplist) - free(aplist); - if (apbuf) - free(apbuf); - if (sentinel.ai_next) - freeaddrinfo(sentinel.ai_next); - return error; -} - -/* - * hostname == NULL. - * passive socket -> anyaddr (0.0.0.0 or ::) - * non-passive socket -> localhost (127.0.0.1 or ::1) - */ -static int -explore_null(pai, hostname, servname, res) - const struct addrinfo *pai; - const char *hostname; - const char *servname; - struct addrinfo **res; -{ - int s; - const struct afd *afd; - struct addrinfo *cur; - struct addrinfo sentinel; - int error; - - *res = NULL; - sentinel.ai_next = NULL; - cur = &sentinel; - - /* - * filter out AFs that are not supported by the kernel - * XXX errno? - */ - s = socket(pai->ai_family, SOCK_DGRAM, 0); - if (s < 0) { - if (errno != EMFILE) - return 0; - } else - close(s); - - /* - * if the servname does not match socktype/protocol, ignore it. - */ - if (get_portmatch(pai, servname) != 0) - return 0; - - afd = find_afd(pai->ai_family); - - if (pai->ai_flags & AI_PASSIVE) { - GET_AI(cur->ai_next, afd, afd->a_addrany); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "anyaddr"); - */ - GET_PORT(cur->ai_next, servname); - } else { - GET_AI(cur->ai_next, afd, afd->a_loopback); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "localhost"); - */ - GET_PORT(cur->ai_next, servname); - } - cur = cur->ai_next; - - *res = sentinel.ai_next; - return 0; - -free: - if (sentinel.ai_next) - freeaddrinfo(sentinel.ai_next); - return error; -} - -/* - * numeric hostname - */ -static int -explore_numeric(pai, hostname, servname, res) - const struct addrinfo *pai; - const char *hostname; - const char *servname; - struct addrinfo **res; -{ - const struct afd *afd; - struct addrinfo *cur; - struct addrinfo sentinel; - int error; - char pton[PTON_MAX]; - int flags; - - *res = NULL; - sentinel.ai_next = NULL; - cur = &sentinel; - - /* - * if the servname does not match socktype/protocol, ignore it. - */ - if (get_portmatch(pai, servname) != 0) - return 0; - - afd = find_afd(pai->ai_family); - flags = pai->ai_flags; - - if (inet_pton(afd->a_af, hostname, pton) == 1) { - u_int32_t v4a; -#ifdef INET6 - u_char pfx; -#endif - - switch (afd->a_af) { - case AF_INET: - v4a = (u_int32_t)ntohl(((struct in_addr *)pton)->s_addr); - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - flags &= ~AI_CANONNAME; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0 || v4a == IN_LOOPBACKNET) - flags &= ~AI_CANONNAME; - break; -#ifdef INET6 - case AF_INET6: - pfx = ((struct in6_addr *)pton)->s6_addr[0]; - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - flags &= ~AI_CANONNAME; - break; -#endif - } - - if (pai->ai_family == afd->a_af || - pai->ai_family == PF_UNSPEC /*?*/) { - if ((flags & AI_CANONNAME) == 0) { - GET_AI(cur->ai_next, afd, pton); - GET_PORT(cur->ai_next, servname); - } else { - /* - * if AI_CANONNAME and if reverse lookup - * fail, return ai anyway to pacify - * calling application. - * - * XXX getaddrinfo() is a name->address - * translation function, and it looks - * strange that we do addr->name - * translation here. - */ - get_name(pton, afd, &cur->ai_next, - pton, pai, servname); - } - while (cur && cur->ai_next) - cur = cur->ai_next; - } else - ERR(EAI_FAMILY); /*xxx*/ - } - - *res = sentinel.ai_next; - return 0; - -free: -bad: - if (sentinel.ai_next) - freeaddrinfo(sentinel.ai_next); - return error; -} - -/* - * numeric hostname with scope - */ -static int -explore_numeric_scope(pai, hostname, servname, res) - const struct addrinfo *pai; - const char *hostname; - const char *servname; - struct addrinfo **res; -{ -#ifndef SCOPE_DELIMITER - return explore_numeric(pai, hostname, servname, res); -#else - const struct afd *afd; - struct addrinfo *cur; - int error; - char *cp, *hostname2 = NULL; - int scope; - struct sockaddr_in6 *sin6; - - /* - * if the servname does not match socktype/protocol, ignore it. - */ - if (get_portmatch(pai, servname) != 0) - return 0; - - afd = find_afd(pai->ai_family); - if (!afd->a_scoped) - return explore_numeric(pai, hostname, servname, res); - - cp = strchr(hostname, SCOPE_DELIMITER); - if (cp == NULL) - return explore_numeric(pai, hostname, servname, res); - - /* - * Handle special case of - */ - hostname2 = strdup(hostname); - if (hostname2 == NULL) - return EAI_MEMORY; - /* terminate at the delimiter */ - hostname2[cp - hostname] = '\0'; - - cp++; - switch (pai->ai_family) { -#ifdef INET6 - case AF_INET6: - scope = if_nametoindex(cp); - if (scope == 0) { - free(hostname2); - return (EAI_NONAME); - } - break; -#endif - } - - error = explore_numeric(pai, hostname2, servname, res); - if (error == 0) { - for (cur = *res; cur; cur = cur->ai_next) { - if (cur->ai_family != AF_INET6) - continue; - sin6 = (struct sockaddr_in6 *)cur->ai_addr; - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || - IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) - sin6->sin6_scope_id = scope; - } - } - - free(hostname2); - - return error; -#endif -} - -static int -get_name(addr, afd, res, numaddr, pai, servname) - const char *addr; - const struct afd *afd; - struct addrinfo **res; - char *numaddr; - const struct addrinfo *pai; - const char *servname; -{ - struct hostent *hp = NULL; - struct addrinfo *cur = NULL; - int error = 0; - char *ap = NULL, *cn = NULL; -#ifdef USE_GETIPNODEBY - int h_error; - - hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); -#else - hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); -#endif - if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { -#ifdef USE_GETIPNODEBY - GET_AI(cur, afd, hp->h_addr_list[0]); - GET_PORT(cur, servname); - GET_CANONNAME(cur, hp->h_name); -#else - /* hp will be damaged if we use gethostbyaddr() */ - if ((ap = (char *)malloc(hp->h_length)) == NULL) { - error = EAI_MEMORY; - goto free; - } - memcpy(ap, hp->h_addr_list[0], hp->h_length); - if ((cn = strdup(hp->h_name)) == NULL) { - error = EAI_MEMORY; - goto free; - } - - GET_AI(cur, afd, ap); - GET_PORT(cur, servname); - GET_CANONNAME(cur, cn); - free(ap); ap = NULL; - free(cn); cn = NULL; -#endif - } else { - GET_AI(cur, afd, numaddr); - GET_PORT(cur, servname); - } - -#ifdef USE_GETIPNODEBY - if (hp) - freehostent(hp); -#endif - *res = cur; - return SUCCESS; - free: - if (cur) - freeaddrinfo(cur); - if (ap) - free(ap); - if (cn) - free(cn); -#ifdef USE_GETIPNODEBY - if (hp) - freehostent(hp); -#endif - *res = NULL; - return error; -} - -static int -get_canonname(pai, ai, str) - const struct addrinfo *pai; - struct addrinfo *ai; - const char *str; -{ - if ((pai->ai_flags & AI_CANONNAME) != 0) { - ai->ai_canonname = (char *)malloc(strlen(str) + 1); - if (ai->ai_canonname == NULL) - return EAI_MEMORY; - strcpy(ai->ai_canonname, str); - } - return 0; -} - -static struct addrinfo * -get_ai(pai, afd, addr) - const struct addrinfo *pai; - const struct afd *afd; - const char *addr; -{ - char *p; - struct addrinfo *ai; - - ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) - + (afd->a_socklen)); - if (ai == NULL) - return NULL; - - memcpy(ai, pai, sizeof(struct addrinfo)); - ai->ai_addr = (struct sockaddr *)(ai + 1); - memset(ai->ai_addr, 0, afd->a_socklen); -#ifdef HAVE_SOCKADDR_SA_LEN - ai->ai_addr->sa_len = afd->a_socklen; -#endif - ai->ai_addrlen = afd->a_socklen; - ai->ai_addr->sa_family = ai->ai_family = afd->a_af; - p = (char *)(ai->ai_addr); - memcpy(p + afd->a_off, addr, afd->a_addrlen); - return ai; -} - -static int -get_portmatch(ai, servname) - const struct addrinfo *ai; - const char *servname; -{ - - /* get_port does not touch first argument. when matchonly == 1. */ - return get_port((struct addrinfo *)ai, servname, 1); -} - -static int -get_port(ai, servname, matchonly) - struct addrinfo *ai; - const char *servname; - int matchonly; -{ - const char *proto; - struct servent *sp; - int port; - int allownumeric; - - if (servname == NULL) - return 0; - switch (ai->ai_family) { - case AF_INET: -#ifdef AF_INET6 - case AF_INET6: -#endif - break; - default: - return 0; - } - - switch (ai->ai_socktype) { - case SOCK_RAW: - return EAI_SERVICE; - case SOCK_DGRAM: - case SOCK_STREAM: - allownumeric = 1; - break; - case ANY: - allownumeric = 0; - break; - default: - return EAI_SOCKTYPE; - } - - if (str_isnumber(servname)) { - if (!allownumeric) - return EAI_SERVICE; - port = htons(atoi(servname)); - if (port < 0 || port > 65535) - return EAI_SERVICE; - } else { - switch (ai->ai_socktype) { - case SOCK_DGRAM: - proto = "udp"; - break; - case SOCK_STREAM: - proto = "tcp"; - break; - default: - proto = NULL; - break; - } - - if ((sp = getservbyname(servname, proto)) == NULL) - return EAI_SERVICE; - port = sp->s_port; - } - - if (!matchonly) { - switch (ai->ai_family) { - case AF_INET: - ((struct sockaddr_in *)ai->ai_addr)->sin_port = port; - break; -#ifdef INET6 - case AF_INET6: - ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port; - break; -#endif - } - } - - return 0; -} - -static const struct afd * -find_afd(af) - int af; -{ - const struct afd *afd; - - if (af == PF_UNSPEC) - return NULL; - for (afd = afdl; afd->a_af; afd++) { - if (afd->a_af == af) - return afd; - } - return NULL; -} diff --git a/sockstorage.h b/sockstorage.h deleted file mode 100644 index 557eb4d..0000000 --- a/sockstorage.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -struct sockaddr_storage { -#ifdef HAVE_SOCKADDR_SA_LEN - u_int8_t __ss_len; - u_int8_t __ss_family; - u_int8_t fill[126]; -#else - u_int8_t __ss_family; - u_int8_t fill[127]; -#endif /* HAVE_SOCKADDR_SA_LEN */ -}; diff --git a/starttls.c b/starttls.c index 99ba293..3666177 100644 --- a/starttls.c +++ b/starttls.c @@ -39,10 +39,6 @@ #include #include -#ifdef NEED_ADDRINFO_H -#include "addrinfo.h" -#endif - #include #include #include @@ -135,13 +131,22 @@ tls_connect (hostname, service) const char *hostname, *service; { struct protoent *proto; + int server, false = 0, family, socktype; + struct sockaddr *addr; + struct sockaddr_in sin; + socklen_t addrlen; +#ifdef HAVE_ADDRINFO struct addrinfo *in, hints; - int server, false = 0; +#else + struct hostent *host; + struct servent serv; +#endif proto = getprotobyname ("tcp"); if (!proto) return -1; +#ifdef HAVE_ADDRINFO memset (&hints, 0, sizeof (hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -150,15 +155,36 @@ tls_connect (hostname, service) if (getaddrinfo (hostname, service, &hints, &in) < 0) return -1; - server = socket (in->ai_family, in->ai_socktype, 0); - if (server < 0) + family = in->ai_family; + socktype = in->ai_socktype; + addr = in->ai_addr; + addrlen = in->ai_addrlen; + freeaddrinfo (in); +#else + memset (&sin, 0, sizeof (sin)); + host = gethostbyname (hostname); + if (!host) return -1; + memcpy (&sin.sin_addr, host->h_addr, host->h_length); + serv = getservbyname (service, proto->p_name); + if (serv) + sin.sin_port = htons (serv->s_port); + else if (isdigit (service[0])) + sin.sin_port = htons (atoi (service)); + family = sin.sin_family = AF_INET; + socktype = SOCK_STREAM; + addr = (struct sockaddr *)&sin; + addrlen = sizeof (sin); +#endif - if (setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, - (const char *) &false, sizeof (false))) + server = socket (family, socktype, 0); + if (server == -1) return -1; - if (connect (server, in->ai_addr, in->ai_addrlen) < 0) + setsockopt (server, SOL_SOCKET, SO_KEEPALIVE, (const char *) &false, + sizeof (false)); + + if (connect (server, addr, addrlen) < 0) { close (server); return -1;