Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Modules/getaddrinfo.c

    r2 r388  
    22 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    33 * All rights reserved.
    4  * 
     4 *
    55 * Redistribution and use in source and binary forms, with or without
    66 * modification, are permitted provided that the following conditions
     
    1414 *    may be used to endorse or promote products derived from this software
    1515 *    without specific prior written permission.
    16  * 
     16 *
    1717 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
    1818 * GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     
    7474static const char in_addrany[] = { 0, 0, 0, 0 };
    7575static const char in6_addrany[] = {
    76         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     76    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    7777};
    78 static const char in_loopback[] = { 127, 0, 0, 1 }; 
     78static const char in_loopback[] = { 127, 0, 0, 1 };
    7979static const char in6_loopback[] = {
    80         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
     80    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
    8181};
    8282
    8383struct sockinet {
    84         u_char  si_len;
    85         u_char  si_family;
    86         u_short si_port;
     84    u_char      si_len;
     85    u_char      si_family;
     86    u_short     si_port;
    8787};
    8888
    8989static struct gai_afd {
    90         int a_af;
    91         int a_addrlen;
    92         int a_socklen;
    93         int a_off;
    94         const char *a_addrany;
    95         const char *a_loopback;
     90    int a_af;
     91    int a_addrlen;
     92    int a_socklen;
     93    int a_off;
     94    const char *a_addrany;
     95    const char *a_loopback;
    9696} gai_afdl [] = {
    9797#ifdef ENABLE_IPV6
    9898#define N_INET6 0
    99         {PF_INET6, sizeof(struct in6_addr),
    100         sizeof(struct sockaddr_in6),
    101         offsetof(struct sockaddr_in6, sin6_addr),
    102         in6_addrany, in6_loopback},
     99    {PF_INET6, sizeof(struct in6_addr),
     100    sizeof(struct sockaddr_in6),
     101    offsetof(struct sockaddr_in6, sin6_addr),
     102    in6_addrany, in6_loopback},
    103103#define N_INET  1
    104104#else
    105105#define N_INET  0
    106106#endif
    107         {PF_INET, sizeof(struct in_addr),
    108         sizeof(struct sockaddr_in),
    109         offsetof(struct sockaddr_in, sin_addr),
    110         in_addrany, in_loopback},
    111         {0, 0, 0, 0, NULL, NULL},
     107    {PF_INET, sizeof(struct in_addr),
     108    sizeof(struct sockaddr_in),
     109    offsetof(struct sockaddr_in, sin_addr),
     110    in_addrany, in_loopback},
     111    {0, 0, 0, 0, NULL, NULL},
    112112};
    113113
    114114#ifdef ENABLE_IPV6
    115 #define PTON_MAX        16
     115#define PTON_MAX        16
    116116#else
    117 #define PTON_MAX        4
     117#define PTON_MAX        4
    118118#endif
    119119
    120120#ifndef IN_MULTICAST
    121 #define IN_MULTICAST(i)     (((i) & 0xf0000000U) == 0xe0000000U)
     121#define IN_MULTICAST(i)     (((i) & 0xf0000000U) == 0xe0000000U)
    122122#endif
    123123
     
    127127
    128128#ifndef IN_LOOPBACKNET
    129 #define IN_LOOPBACKNET      127
     129#define IN_LOOPBACKNET      127
    130130#endif
    131131
    132132static int get_name Py_PROTO((const char *, struct gai_afd *,
    133                           struct addrinfo **, char *, struct addrinfo *,
    134                           int));
     133                          struct addrinfo **, char *, struct addrinfo *,
     134                          int));
    135135static int get_addr Py_PROTO((const char *, int, struct addrinfo **,
    136                         struct addrinfo *, int));
     136                        struct addrinfo *, int));
    137137static int str_isnumber Py_PROTO((const char *));
    138        
     138
    139139static char *ai_errlist[] = {
    140         "success.",
    141         "address family for hostname not supported.",   /* EAI_ADDRFAMILY */
    142         "temporary failure in name resolution.",        /* EAI_AGAIN      */
    143         "invalid value for ai_flags.",                  /* EAI_BADFLAGS   */
    144         "non-recoverable failure in name resolution.",  /* EAI_FAIL       */
    145         "ai_family not supported.",                     /* EAI_FAMILY     */
    146         "memory allocation failure.",                   /* EAI_MEMORY     */
    147         "no address associated with hostname.",         /* EAI_NODATA     */
    148         "hostname nor servname provided, or not known.",/* EAI_NONAME     */
    149         "servname not supported for ai_socktype.",      /* EAI_SERVICE    */
    150         "ai_socktype not supported.",                   /* EAI_SOCKTYPE   */
    151         "system error returned in errno.",              /* EAI_SYSTEM     */
    152         "invalid value for hints.",                     /* EAI_BADHINTS   */
    153         "resolved protocol is unknown.",                /* EAI_PROTOCOL   */
    154         "unknown error.",                               /* EAI_MAX        */
     140    "success.",
     141    "address family for hostname not supported.",       /* EAI_ADDRFAMILY */
     142    "temporary failure in name resolution.",            /* EAI_AGAIN      */
     143    "invalid value for ai_flags.",                      /* EAI_BADFLAGS   */
     144    "non-recoverable failure in name resolution.",      /* EAI_FAIL       */
     145    "ai_family not supported.",                         /* EAI_FAMILY     */
     146    "memory allocation failure.",                       /* EAI_MEMORY     */
     147    "no address associated with hostname.",             /* EAI_NODATA     */
     148    "hostname nor servname provided, or not known.",/* EAI_NONAME     */
     149    "servname not supported for ai_socktype.",          /* EAI_SERVICE    */
     150    "ai_socktype not supported.",                       /* EAI_SOCKTYPE   */
     151    "system error returned in errno.",                  /* EAI_SYSTEM     */
     152    "invalid value for hints.",                         /* EAI_BADHINTS   */
     153    "resolved protocol is unknown.",                    /* EAI_PROTOCOL   */
     154    "unknown error.",                                   /* EAI_MAX        */
    155155};
    156156
    157157#define GET_CANONNAME(ai, str) \
    158158if (pai->ai_flags & AI_CANONNAME) {\
    159         if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
    160                 strcpy((ai)->ai_canonname, (str));\
    161         } else {\
    162                 error = EAI_MEMORY;\
    163                 goto free;\
    164         }\
     159    if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
     160        strcpy((ai)->ai_canonname, (str));\
     161    } else {\
     162        error = EAI_MEMORY;\
     163        goto free;\
     164    }\
    165165}
    166166
    167167#ifdef HAVE_SOCKADDR_SA_LEN
    168168#define GET_AI(ai, gai_afd, addr, port) {\
    169         char *p;\
    170         if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
    171                                               ((gai_afd)->a_socklen)))\
    172             == NULL) goto free;\
    173         memcpy(ai, pai, sizeof(struct addrinfo));\
    174         (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
    175         memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
    176         (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\
    177         (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
    178         ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
    179         p = (char *)((ai)->ai_addr);\
    180         memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
     169    char *p;\
     170    if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
     171                                          ((gai_afd)->a_socklen)))\
     172        == NULL) goto free;\
     173    memcpy(ai, pai, sizeof(struct addrinfo));\
     174    (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
     175    memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
     176    (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\
     177    (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
     178    ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
     179    p = (char *)((ai)->ai_addr);\
     180    memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
    181181}
    182182#else
    183183#define GET_AI(ai, gai_afd, addr, port) {\
    184         char *p;\
    185         if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
    186                                               ((gai_afd)->a_socklen)))\
    187             == NULL) goto free;\
    188         memcpy(ai, pai, sizeof(struct addrinfo));\
    189         (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
    190         memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
    191         (ai)->ai_addrlen = (gai_afd)->a_socklen;\
    192         (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
    193         ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
    194         p = (char *)((ai)->ai_addr);\
    195         memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
     184    char *p;\
     185    if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
     186                                          ((gai_afd)->a_socklen)))\
     187        == NULL) goto free;\
     188    memcpy(ai, pai, sizeof(struct addrinfo));\
     189    (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
     190    memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\
     191    (ai)->ai_addrlen = (gai_afd)->a_socklen;\
     192    (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\
     193    ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
     194    p = (char *)((ai)->ai_addr);\
     195    memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\
    196196}
    197197#endif
     
    202202gai_strerror(int ecode)
    203203{
    204         if (ecode < 0 || ecode > EAI_MAX)
    205                 ecode = EAI_MAX;
    206         return ai_errlist[ecode];
     204    if (ecode < 0 || ecode > EAI_MAX)
     205        ecode = EAI_MAX;
     206    return ai_errlist[ecode];
    207207}
    208208
     
    210210freeaddrinfo(struct addrinfo *ai)
    211211{
    212         struct addrinfo *next;
    213 
    214         do {
    215                 next = ai->ai_next;
    216                 if (ai->ai_canonname)
    217                         free(ai->ai_canonname);
    218                 /* no need to free(ai->ai_addr) */
    219                 free(ai);
    220         } while ((ai = next) != NULL);
     212    struct addrinfo *next;
     213
     214    do {
     215        next = ai->ai_next;
     216        if (ai->ai_canonname)
     217            free(ai->ai_canonname);
     218        /* no need to free(ai->ai_addr) */
     219        free(ai);
     220    } while ((ai = next) != NULL);
    221221}
    222222
     
    224224str_isnumber(const char *p)
    225225{
    226         unsigned char *q = (unsigned char *)p;
    227         while (*q) {
    228                 if (! isdigit(*q))
    229                         return NO;
    230                 q++;
    231         }
    232         return YES;
     226    unsigned char *q = (unsigned char *)p;
     227    while (*q) {
     228        if (! isdigit(*q))
     229            return NO;
     230        q++;
     231    }
     232    return YES;
    233233}
    234234
     
    237237            const struct addrinfo *hints, struct addrinfo **res)
    238238{
    239         struct addrinfo sentinel;
    240         struct addrinfo *top = NULL;
    241         struct addrinfo *cur;
    242         int i, error = 0;
    243         char pton[PTON_MAX];
    244         struct addrinfo ai;
    245         struct addrinfo *pai;
    246         u_short port;
     239    struct addrinfo sentinel;
     240    struct addrinfo *top = NULL;
     241    struct addrinfo *cur;
     242    int i, error = 0;
     243    char pton[PTON_MAX];
     244    struct addrinfo ai;
     245    struct addrinfo *pai;
     246    u_short port;
    247247
    248248#ifdef FAITH
    249         static int firsttime = 1;
    250 
    251         if (firsttime) {
    252                 /* translator hack */
    253                 {
    254                         char *q = getenv("GAI");
    255                         if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
    256                                 translate = YES;
    257                 }
    258                 firsttime = 0;
    259         }
    260 #endif
    261 
    262         /* initialize file static vars */
    263         sentinel.ai_next = NULL;
    264         cur = &sentinel;
    265         pai = &ai;
    266         pai->ai_flags = 0;
    267         pai->ai_family = PF_UNSPEC;
    268         pai->ai_socktype = GAI_ANY;
    269         pai->ai_protocol = GAI_ANY;
    270         pai->ai_addrlen = 0;
    271         pai->ai_canonname = NULL;
    272         pai->ai_addr = NULL;
    273         pai->ai_next = NULL;
    274         port = GAI_ANY;
    275        
    276         if (hostname == NULL && servname == NULL)
    277                 return EAI_NONAME;
    278         if (hints) {
    279                 /* error check for hints */
    280                 if (hints->ai_addrlen || hints->ai_canonname ||
    281                     hints->ai_addr || hints->ai_next)
    282                         ERR(EAI_BADHINTS); /* xxx */
    283                 if (hints->ai_flags & ~AI_MASK)
    284                         ERR(EAI_BADFLAGS);
    285                 switch (hints->ai_family) {
    286                 case PF_UNSPEC:
    287                 case PF_INET:
    288 #ifdef ENABLE_IPV6
    289                 case PF_INET6:
    290 #endif
    291                         break;
    292                 default:
    293                         ERR(EAI_FAMILY);
    294                 }
    295                 memcpy(pai, hints, sizeof(*pai));
    296                 switch (pai->ai_socktype) {
    297                 case GAI_ANY:
    298                         switch (pai->ai_protocol) {
    299                         case GAI_ANY:
    300                                 break;
    301                         case IPPROTO_UDP:
    302                                 pai->ai_socktype = SOCK_DGRAM;
    303                                 break;
    304                         case IPPROTO_TCP:
    305                                 pai->ai_socktype = SOCK_STREAM;
    306                                 break;
    307                         default:
    308                                 pai->ai_socktype = SOCK_RAW;
    309                                 break;
    310                         }
    311                         break;
    312                 case SOCK_RAW:
    313                         break;
    314                 case SOCK_DGRAM:
    315                         if (pai->ai_protocol != IPPROTO_UDP &&
    316                             pai->ai_protocol != GAI_ANY)
    317                                 ERR(EAI_BADHINTS);      /*xxx*/
    318                         pai->ai_protocol = IPPROTO_UDP;
    319                         break;
    320                 case SOCK_STREAM:
    321                         if (pai->ai_protocol != IPPROTO_TCP &&
    322                             pai->ai_protocol != GAI_ANY)
    323                                 ERR(EAI_BADHINTS);      /*xxx*/
    324                         pai->ai_protocol = IPPROTO_TCP;
    325                         break;
    326                 default:
    327                         ERR(EAI_SOCKTYPE);
    328                         /* unreachable */
    329                 }
    330         }
    331 
    332         /*
    333         * service port
    334         */
    335         if (servname) {
    336                 if (str_isnumber(servname)) {
    337                         if (pai->ai_socktype == GAI_ANY) {
    338                                 /* caller accept *GAI_ANY* socktype */
    339                                 pai->ai_socktype = SOCK_DGRAM;
    340                                 pai->ai_protocol = IPPROTO_UDP;
    341                         }
    342                         port = htons((u_short)atoi(servname));
    343                 } else {
    344                         struct servent *sp;
    345                         char *proto;
    346 
    347                         proto = NULL;
    348                         switch (pai->ai_socktype) {
    349                         case GAI_ANY:
    350                                 proto = NULL;
    351                                 break;
    352                         case SOCK_DGRAM:
    353                                 proto = "udp";
    354                                 break;
    355                         case SOCK_STREAM:
    356                                 proto = "tcp";
    357                                 break;
    358                         default:
    359                                 fprintf(stderr, "panic!\n");
    360                                 break;
    361                         }
    362                         if ((sp = getservbyname(servname, proto)) == NULL)
    363                                 ERR(EAI_SERVICE);
    364                         port = sp->s_port;
    365                         if (pai->ai_socktype == GAI_ANY) {
    366                                 if (strcmp(sp->s_proto, "udp") == 0) {
    367                                         pai->ai_socktype = SOCK_DGRAM;
    368                                         pai->ai_protocol = IPPROTO_UDP;
    369                                 } else if (strcmp(sp->s_proto, "tcp") == 0) {
    370                                         pai->ai_socktype = SOCK_STREAM;
    371                                         pai->ai_protocol = IPPROTO_TCP;
    372                                 } else
    373                                         ERR(EAI_PROTOCOL);      /*xxx*/
    374                         }
    375                 }
    376         }
    377        
    378         /*
    379         * hostname == NULL.
    380         * passive socket -> anyaddr (0.0.0.0 or ::)
    381         * non-passive socket -> localhost (127.0.0.1 or ::1)
    382         */
    383         if (hostname == NULL) {
    384                 struct gai_afd *gai_afd;
    385 
    386                 for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) {
    387                         if (!(pai->ai_family == PF_UNSPEC
    388                            || pai->ai_family == gai_afd->a_af)) {
    389                                 continue;
    390                         }
    391 
    392                         if (pai->ai_flags & AI_PASSIVE) {
    393                                 GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port);
    394                                 /* xxx meaningless?
    395                                 * GET_CANONNAME(cur->ai_next, "anyaddr");
    396                                 */
    397                         } else {
    398                                 GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback,
    399                                         port);
    400                                 /* xxx meaningless?
    401                                 * GET_CANONNAME(cur->ai_next, "localhost");
    402                                 */
    403                         }
    404                         cur = cur->ai_next;
    405                 }
    406                 top = sentinel.ai_next;
    407                 if (top)
    408                         goto good;
    409                 else
    410                         ERR(EAI_FAMILY);
    411         }
    412        
    413         /* hostname as numeric name */
    414         for (i = 0; gai_afdl[i].a_af; i++) {
    415                 if (inet_pton(gai_afdl[i].a_af, hostname, pton)) {
    416                         u_long v4a;
    417 #ifdef ENABLE_IPV6
    418                         u_char pfx;
    419 #endif
    420 
    421                         switch (gai_afdl[i].a_af) {
    422                         case AF_INET:
    423                                 v4a = ((struct in_addr *)pton)->s_addr;
    424                                 v4a = ntohl(v4a);
    425                                 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
    426                                         pai->ai_flags &= ~AI_CANONNAME;
    427                                 v4a >>= IN_CLASSA_NSHIFT;
    428                                 if (v4a == 0 || v4a == IN_LOOPBACKNET)
    429                                         pai->ai_flags &= ~AI_CANONNAME;
    430                                 break;
    431 #ifdef ENABLE_IPV6
    432                         case AF_INET6:
    433                                 pfx = ((struct in6_addr *)pton)->s6_addr8[0];
    434                                 if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
    435                                         pai->ai_flags &= ~AI_CANONNAME;
    436                                 break;
    437 #endif
    438                         }
    439                        
    440                         if (pai->ai_family == gai_afdl[i].a_af ||
    441                             pai->ai_family == PF_UNSPEC) {
    442                                 if (! (pai->ai_flags & AI_CANONNAME)) {
    443                                         GET_AI(top, &gai_afdl[i], pton, port);
    444                                         goto good;
    445                                 }
    446                                 /*
    447                                 * if AI_CANONNAME and if reverse lookup
    448                                 * fail, return ai anyway to pacify
    449                                 * calling application.
    450                                 *
    451                                 * XXX getaddrinfo() is a name->address
    452                                 * translation function, and it looks strange
    453                                 * that we do addr->name translation here.
    454                                 */
    455                                 get_name(pton, &gai_afdl[i], &top, pton, pai, port);
    456                                 goto good;
    457                         } else
    458                                 ERR(EAI_FAMILY);        /*xxx*/
    459                 }
    460         }
    461 
    462         if (pai->ai_flags & AI_NUMERICHOST)
    463                 ERR(EAI_NONAME);
    464 
    465         /* hostname as alphabetical name */
    466         error = get_addr(hostname, pai->ai_family, &top, pai, port);
    467         if (error == 0) {
    468                 if (top) {
     249    static int firsttime = 1;
     250
     251    if (firsttime) {
     252        /* translator hack */
     253        {
     254            char *q = getenv("GAI");
     255            if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
     256                translate = YES;
     257        }
     258        firsttime = 0;
     259    }
     260#endif
     261
     262    /* initialize file static vars */
     263    sentinel.ai_next = NULL;
     264    cur = &sentinel;
     265    pai = &ai;
     266    pai->ai_flags = 0;
     267    pai->ai_family = PF_UNSPEC;
     268    pai->ai_socktype = GAI_ANY;
     269    pai->ai_protocol = GAI_ANY;
     270    pai->ai_addrlen = 0;
     271    pai->ai_canonname = NULL;
     272    pai->ai_addr = NULL;
     273    pai->ai_next = NULL;
     274    port = GAI_ANY;
     275
     276    if (hostname == NULL && servname == NULL)
     277        return EAI_NONAME;
     278    if (hints) {
     279        /* error check for hints */
     280        if (hints->ai_addrlen || hints->ai_canonname ||
     281            hints->ai_addr || hints->ai_next)
     282            ERR(EAI_BADHINTS); /* xxx */
     283        if (hints->ai_flags & ~AI_MASK)
     284            ERR(EAI_BADFLAGS);
     285        switch (hints->ai_family) {
     286        case PF_UNSPEC:
     287        case PF_INET:
     288#ifdef ENABLE_IPV6
     289        case PF_INET6:
     290#endif
     291            break;
     292        default:
     293            ERR(EAI_FAMILY);
     294        }
     295        memcpy(pai, hints, sizeof(*pai));
     296        switch (pai->ai_socktype) {
     297        case GAI_ANY:
     298            switch (pai->ai_protocol) {
     299            case GAI_ANY:
     300                break;
     301            case IPPROTO_UDP:
     302                pai->ai_socktype = SOCK_DGRAM;
     303                break;
     304            case IPPROTO_TCP:
     305                pai->ai_socktype = SOCK_STREAM;
     306                break;
     307            default:
     308                pai->ai_socktype = SOCK_RAW;
     309                break;
     310            }
     311            break;
     312        case SOCK_RAW:
     313            break;
     314        case SOCK_DGRAM:
     315            if (pai->ai_protocol != IPPROTO_UDP &&
     316                pai->ai_protocol != GAI_ANY)
     317                ERR(EAI_BADHINTS);                      /*xxx*/
     318            pai->ai_protocol = IPPROTO_UDP;
     319            break;
     320        case SOCK_STREAM:
     321            if (pai->ai_protocol != IPPROTO_TCP &&
     322                pai->ai_protocol != GAI_ANY)
     323                ERR(EAI_BADHINTS);                      /*xxx*/
     324            pai->ai_protocol = IPPROTO_TCP;
     325            break;
     326        default:
     327            ERR(EAI_SOCKTYPE);
     328            /* unreachable */
     329        }
     330    }
     331
     332    /*
     333    * service port
     334    */
     335    if (servname) {
     336        if (str_isnumber(servname)) {
     337            if (pai->ai_socktype == GAI_ANY) {
     338                /* caller accept *GAI_ANY* socktype */
     339                pai->ai_socktype = SOCK_DGRAM;
     340                pai->ai_protocol = IPPROTO_UDP;
     341            }
     342            port = htons((u_short)atoi(servname));
     343        } else {
     344            struct servent *sp;
     345            char *proto;
     346
     347            proto = NULL;
     348            switch (pai->ai_socktype) {
     349            case GAI_ANY:
     350                proto = NULL;
     351                break;
     352            case SOCK_DGRAM:
     353                proto = "udp";
     354                break;
     355            case SOCK_STREAM:
     356                proto = "tcp";
     357                break;
     358            default:
     359                fprintf(stderr, "panic!\n");
     360                break;
     361            }
     362            if ((sp = getservbyname(servname, proto)) == NULL)
     363                ERR(EAI_SERVICE);
     364            port = sp->s_port;
     365            if (pai->ai_socktype == GAI_ANY) {
     366                if (strcmp(sp->s_proto, "udp") == 0) {
     367                    pai->ai_socktype = SOCK_DGRAM;
     368                    pai->ai_protocol = IPPROTO_UDP;
     369                } else if (strcmp(sp->s_proto, "tcp") == 0) {
     370                    pai->ai_socktype = SOCK_STREAM;
     371                    pai->ai_protocol = IPPROTO_TCP;
     372                } else
     373                    ERR(EAI_PROTOCOL);                          /*xxx*/
     374            }
     375        }
     376    }
     377
     378    /*
     379    * hostname == NULL.
     380    * passive socket -> anyaddr (0.0.0.0 or ::)
     381    * non-passive socket -> localhost (127.0.0.1 or ::1)
     382    */
     383    if (hostname == NULL) {
     384        struct gai_afd *gai_afd;
     385
     386        for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) {
     387            if (!(pai->ai_family == PF_UNSPEC
     388               || pai->ai_family == gai_afd->a_af)) {
     389                continue;
     390            }
     391
     392            if (pai->ai_flags & AI_PASSIVE) {
     393                GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port);
     394                /* xxx meaningless?
     395                * GET_CANONNAME(cur->ai_next, "anyaddr");
     396                */
     397            } else {
     398                GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback,
     399                    port);
     400                /* xxx meaningless?
     401                * GET_CANONNAME(cur->ai_next, "localhost");
     402                */
     403            }
     404            cur = cur->ai_next;
     405        }
     406        top = sentinel.ai_next;
     407        if (top)
     408            goto good;
     409        else
     410            ERR(EAI_FAMILY);
     411    }
     412
     413    /* hostname as numeric name */
     414    for (i = 0; gai_afdl[i].a_af; i++) {
     415        if (inet_pton(gai_afdl[i].a_af, hostname, pton)) {
     416            u_long v4a;
     417#ifdef ENABLE_IPV6
     418            u_char pfx;
     419#endif
     420
     421            switch (gai_afdl[i].a_af) {
     422            case AF_INET:
     423                v4a = ((struct in_addr *)pton)->s_addr;
     424                v4a = ntohl(v4a);
     425                if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
     426                    pai->ai_flags &= ~AI_CANONNAME;
     427                v4a >>= IN_CLASSA_NSHIFT;
     428                if (v4a == 0 || v4a == IN_LOOPBACKNET)
     429                    pai->ai_flags &= ~AI_CANONNAME;
     430                break;
     431#ifdef ENABLE_IPV6
     432            case AF_INET6:
     433                pfx = ((struct in6_addr *)pton)->s6_addr[0];
     434                if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
     435                    pai->ai_flags &= ~AI_CANONNAME;
     436                break;
     437#endif
     438            }
     439
     440            if (pai->ai_family == gai_afdl[i].a_af ||
     441                pai->ai_family == PF_UNSPEC) {
     442                if (! (pai->ai_flags & AI_CANONNAME)) {
     443                    GET_AI(top, &gai_afdl[i], pton, port);
     444                    goto good;
     445                }
     446                /*
     447                * if AI_CANONNAME and if reverse lookup
     448                * fail, return ai anyway to pacify
     449                * calling application.
     450                *
     451                * XXX getaddrinfo() is a name->address
     452                * translation function, and it looks strange
     453                * that we do addr->name translation here.
     454                */
     455                get_name(pton, &gai_afdl[i], &top, pton, pai, port);
     456                goto good;
     457            } else
     458                ERR(EAI_FAMILY);                        /*xxx*/
     459        }
     460    }
     461
     462    if (pai->ai_flags & AI_NUMERICHOST)
     463        ERR(EAI_NONAME);
     464
     465    /* hostname as alphabetical name */
     466    error = get_addr(hostname, pai->ai_family, &top, pai, port);
     467    if (error == 0) {
     468        if (top) {
    469469 good:
    470                         *res = top;
    471                         return SUCCESS;
    472                 } else
    473                         error = EAI_FAIL;
    474         }
     470            *res = top;
     471            return SUCCESS;
     472        } else
     473            error = EAI_FAIL;
     474    }
    475475 free:
    476         if (top)
    477                 freeaddrinfo(top);
     476    if (top)
     477        freeaddrinfo(top);
    478478 bad:
    479         *res = NULL;
    480         return error;
     479    *res = NULL;
     480    return error;
    481481}
    482482
    483483static int
    484484get_name(addr, gai_afd, res, numaddr, pai, port0)
    485         const char *addr;
    486         struct gai_afd *gai_afd;
    487         struct addrinfo **res;
    488         char *numaddr;
    489         struct addrinfo *pai;
    490         int port0;
     485    const char *addr;
     486    struct gai_afd *gai_afd;
     487    struct addrinfo **res;
     488    char *numaddr;
     489    struct addrinfo *pai;
     490    int port0;
    491491{
    492         u_short port = port0 & 0xffff;
    493         struct hostent *hp;
    494         struct addrinfo *cur;
    495         int error = 0;
    496 #ifdef ENABLE_IPV6
    497         int h_error;
    498 #endif
    499        
    500 #ifdef ENABLE_IPV6
    501         hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error);
     492    u_short port = port0 & 0xffff;
     493    struct hostent *hp;
     494    struct addrinfo *cur;
     495    int error = 0;
     496#ifdef ENABLE_IPV6
     497    int h_error;
     498#endif
     499
     500#ifdef ENABLE_IPV6
     501    hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error);
    502502#else
    503         hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET);
    504 #endif
    505         if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
    506                 GET_AI(cur, gai_afd, hp->h_addr_list[0], port);
    507                 GET_CANONNAME(cur, hp->h_name);
    508         } else
    509                 GET_AI(cur, gai_afd, numaddr, port);
    510        
    511 #ifdef ENABLE_IPV6
    512         if (hp)
    513                 freehostent(hp);
    514 #endif
    515         *res = cur;
    516         return SUCCESS;
     503    hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET);
     504#endif
     505    if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
     506        GET_AI(cur, gai_afd, hp->h_addr_list[0], port);
     507        GET_CANONNAME(cur, hp->h_name);
     508    } else
     509        GET_AI(cur, gai_afd, numaddr, port);
     510
     511#ifdef ENABLE_IPV6
     512    if (hp)
     513        freehostent(hp);
     514#endif
     515    *res = cur;
     516    return SUCCESS;
    517517 free:
    518         if (cur)
    519                 freeaddrinfo(cur);
    520 #ifdef ENABLE_IPV6
    521         if (hp)
    522                 freehostent(hp);
     518    if (cur)
     519        freeaddrinfo(cur);
     520#ifdef ENABLE_IPV6
     521    if (hp)
     522        freehostent(hp);
    523523#endif
    524524 /* bad: */
    525         *res = NULL;
    526         return error;
     525    *res = NULL;
     526    return error;
    527527}
    528528
    529529static int
    530530get_addr(hostname, af, res, pai, port0)
    531         const char *hostname;
    532         int af;
    533         struct addrinfo **res;
    534         struct addrinfo *pai;
    535         int port0;
     531    const char *hostname;
     532    int af;
     533    struct addrinfo **res;
     534    struct addrinfo *pai;
     535    int port0;
    536536{
    537         u_short port = port0 & 0xffff;
    538         struct addrinfo sentinel;
    539         struct hostent *hp;
    540         struct addrinfo *top, *cur;
    541         struct gai_afd *gai_afd;
    542         int i, error = 0, h_error;
    543         char *ap;
    544 
    545         top = NULL;
    546         sentinel.ai_next = NULL;
    547         cur = &sentinel;
    548 #ifdef ENABLE_IPV6
    549         if (af == AF_UNSPEC) {
    550                 hp = getipnodebyname(hostname, AF_INET6,
    551                                 AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
    552         } else
    553                 hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
     537    u_short port = port0 & 0xffff;
     538    struct addrinfo sentinel;
     539    struct hostent *hp;
     540    struct addrinfo *top, *cur;
     541    struct gai_afd *gai_afd;
     542    int i, error = 0, h_error;
     543    char *ap;
     544
     545    top = NULL;
     546    sentinel.ai_next = NULL;
     547    cur = &sentinel;
     548#ifdef ENABLE_IPV6
     549    if (af == AF_UNSPEC) {
     550        hp = getipnodebyname(hostname, AF_INET6,
     551                        AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
     552    } else
     553        hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
    554554#else
    555         hp = gethostbyname(hostname);
    556         h_error = h_errno;
    557 #endif
    558         if (hp == NULL) {
    559                 switch (h_error) {
    560                 case HOST_NOT_FOUND:
    561                 case NO_DATA:
    562                         error = EAI_NODATA;
    563                         break;
    564                 case TRY_AGAIN:
    565                         error = EAI_AGAIN;
    566                         break;
    567                 case NO_RECOVERY:
    568                 default:
    569                         error = EAI_FAIL;
    570                         break;
    571                 }
    572                 goto free;
    573         }
    574 
    575         if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
    576             (hp->h_addr_list[0] == NULL)) {
    577                 error = EAI_FAIL;
    578                 goto free;
    579         }
    580        
    581         for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
    582                 switch (af) {
    583 #ifdef ENABLE_IPV6
    584                 case AF_INET6:
    585                         gai_afd = &gai_afdl[N_INET6];
    586                         break;
     555    hp = gethostbyname(hostname);
     556    h_error = h_errno;
     557#endif
     558    if (hp == NULL) {
     559        switch (h_error) {
     560        case HOST_NOT_FOUND:
     561        case NO_DATA:
     562            error = EAI_NODATA;
     563            break;
     564        case TRY_AGAIN:
     565            error = EAI_AGAIN;
     566            break;
     567        case NO_RECOVERY:
     568        default:
     569            error = EAI_FAIL;
     570            break;
     571        }
     572        goto free;
     573    }
     574
     575    if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
     576        (hp->h_addr_list[0] == NULL)) {
     577        error = EAI_FAIL;
     578        goto free;
     579    }
     580
     581    for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
     582        switch (af) {
     583#ifdef ENABLE_IPV6
     584        case AF_INET6:
     585            gai_afd = &gai_afdl[N_INET6];
     586            break;
    587587#endif
    588588#ifndef ENABLE_IPV6
    589                 default:        /* AF_UNSPEC */
    590 #endif
    591                 case AF_INET:
    592                         gai_afd = &gai_afdl[N_INET];
    593                         break;
    594 #ifdef ENABLE_IPV6
    595                 default:        /* AF_UNSPEC */
    596                         if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
    597                                 ap += sizeof(struct in6_addr) -
    598                                         sizeof(struct in_addr);
    599                                 gai_afd = &gai_afdl[N_INET];
    600                         } else
    601                                 gai_afd = &gai_afdl[N_INET6];
    602                         break;
    603 #endif
    604                 }
     589        default:                /* AF_UNSPEC */
     590#endif
     591        case AF_INET:
     592            gai_afd = &gai_afdl[N_INET];
     593            break;
     594#ifdef ENABLE_IPV6
     595        default:                /* AF_UNSPEC */
     596            if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
     597                ap += sizeof(struct in6_addr) -
     598                    sizeof(struct in_addr);
     599                gai_afd = &gai_afdl[N_INET];
     600            } else
     601                gai_afd = &gai_afdl[N_INET6];
     602            break;
     603#endif
     604        }
    605605#ifdef FAITH
    606                 if (translate && gai_afd->a_af == AF_INET) {
    607                         struct in6_addr *in6;
    608 
    609                         GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port);
    610                         in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
    611                         memcpy(&in6->s6_addr32[0], &faith_prefix,
    612                             sizeof(struct in6_addr) - sizeof(struct in_addr));
    613                         memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
    614                 } else
     606        if (translate && gai_afd->a_af == AF_INET) {
     607            struct in6_addr *in6;
     608
     609            GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port);
     610            in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
     611            memcpy(&in6->s6_addr32[0], &faith_prefix,
     612                sizeof(struct in6_addr) - sizeof(struct in_addr));
     613            memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
     614        } else
    615615#endif /* FAITH */
    616                 GET_AI(cur->ai_next, gai_afd, ap, port);
    617                 if (cur == &sentinel) {
    618                         top = cur->ai_next;
    619                         GET_CANONNAME(top, hp->h_name);
    620                 }
    621                 cur = cur->ai_next;
    622         }
    623 #ifdef ENABLE_IPV6
    624         freehostent(hp);
    625 #endif
    626         *res = top;
    627         return SUCCESS;
     616        GET_AI(cur->ai_next, gai_afd, ap, port);
     617        if (cur == &sentinel) {
     618            top = cur->ai_next;
     619            GET_CANONNAME(top, hp->h_name);
     620        }
     621        cur = cur->ai_next;
     622    }
     623#ifdef ENABLE_IPV6
     624    freehostent(hp);
     625#endif
     626    *res = top;
     627    return SUCCESS;
    628628 free:
    629         if (top)
    630                 freeaddrinfo(top);
    631 #ifdef ENABLE_IPV6
    632         if (hp)
    633                 freehostent(hp);
     629    if (top)
     630        freeaddrinfo(top);
     631#ifdef ENABLE_IPV6
     632    if (hp)
     633        freehostent(hp);
    634634#endif
    635635/* bad: */
    636         *res = NULL;
    637         return error;
    638 }
     636    *res = NULL;
     637    return error;
     638}
Note: See TracChangeset for help on using the changeset viewer.