getaddrinfo.c

ソースコードを見る。


データ構造

struct  sockinet
struct  afd

関数

static int get_name (const char *, struct afd *, struct addrinfo **, char *, struct addrinfo *, int)
static int get_addr (const char *, int, struct addrinfo **, struct addrinfo *, int)
static int str_isnumber (const char *)
static int get_ai (struct addrinfo **to_ai, struct addrinfo const *pai, struct afd *afd, const char *addr, short port)
char * gai_strerror (int ecode)
void freeaddrinfo (struct addrinfo *ai)
static int str_isnumber (char *p) const
int getaddrinfo (char *hostname, char *servname, const struct addrinfo *hints, struct addrinfo **res) const
static int get_name (char *addr, struct afd *afd, struct addrinfo **res, char *numaddr, struct addrinfo *pai, int port0) const
static int get_addr (char *hostname, int af, struct addrinfo **res, struct addrinfo *pai, int port0) const

変数

static int translate = NO
static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT
static const char in_addrany [] = { 0, 0, 0, 0 }
static const char in6_addrany []
static const char in_loopback [] = { 127, 0, 0, 1 }
static const char in6_loopback []
static struct afd afdl []
static char * ai_errlist []

関数

static int get_name ( const char *  ,
struct afd ,
struct addrinfo **  ,
char *  ,
struct addrinfo ,
int   
) [static]

static int get_addr ( const char *  ,
int  ,
struct addrinfo **  ,
struct addrinfo ,
int   
) [static]

static int str_isnumber ( const char *   )  [static]

参照元 getaddrinfo().

static int get_ai ( struct addrinfo **  to_ai,
struct addrinfo const *  pai,
struct afd afd,
const char *  addr,
short  port 
) [static]

getaddrinfo.c149 行で定義されています。

参照元 get_addr()get_name()getaddrinfo().

00154 {
00155         char *p;
00156         if ((*to_ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
00157                                               ((afd)->a_socklen)))
00158             == NULL) 
00159                 return 0;
00160         memcpy(*to_ai, pai, sizeof(struct addrinfo));
00161         (*to_ai)->ai_addr = (struct sockaddr *)((*to_ai) + 1);
00162         memset((*to_ai)->ai_addr, 0, (afd)->a_socklen);
00163         (*to_ai)->ai_addrlen = (afd)->a_socklen;
00164 #ifdef HAVE_SOCKADDR_LEN
00165         (*to_ai)->ai_addr->sa_len = (afd)->a_socklen;
00166 #endif
00167         (*to_ai)->ai_addr->sa_family = (*to_ai)->ai_family = (afd)->a_af;
00168         ((struct sockinet *)(*to_ai)->ai_addr)->si_port = port;
00169         p = (char *)((*to_ai)->ai_addr);
00170         memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);
00171         return 1;
00172 }

char* gai_strerror ( int  ecode  ) 

getaddrinfo.c177 行で定義されています。

参照元 check_name()client_name()lookup_name()match_address()open_socket_in()open_socket_out()try_bind_local().

00179 {
00180         if (ecode < 0 || ecode > EAI_MAX)
00181                 ecode = EAI_MAX;
00182         return ai_errlist[ecode];
00183 }

void freeaddrinfo ( struct addrinfo ai  ) 

getaddrinfo.c186 行で定義されています。

参照先 addrinfo::ai_next.

参照元 check_name()client_name()get_name()match_address()open_socket_in()try_bind_local().

00188 {
00189         struct addrinfo *next;
00190 
00191         do {
00192                 next = ai->ai_next;
00193                 if (ai->ai_canonname)
00194                         free(ai->ai_canonname);
00195                 /* no need to free(ai->ai_addr) */
00196                 free(ai);
00197         } while ((ai = next) != NULL);
00198 }

static int str_isnumber ( char *  p  )  const [static]

getaddrinfo.c201 行で定義されています。

00203 {
00204         char *q = (char *)p;
00205         while (*q) {
00206                 if (! isdigit(*q))
00207                         return NO;
00208                 q++;
00209         }
00210         return YES;
00211 }

int getaddrinfo ( char *  hostname,
char *  servname,
const struct addrinfo hints,
struct addrinfo **  res 
) const

getaddrinfo.c214 行で定義されています。

参照先 afd::a_addranyafd::a_afafdladdrinfo::ai_addraddrinfo::ai_addrlenaddrinfo::ai_canonnameaddrinfo::ai_familyaddrinfo::ai_flagsaddrinfo::ai_nextaddrinfo::ai_protocoladdrinfo::ai_socktypefaith_prefixget_ai()inet_pton()str_isnumber()translate.

参照元 check_name()client_name()match_address()open_socket_in()open_socket_out()try_bind_local().

00218 {
00219         struct addrinfo sentinel;
00220         struct addrinfo *top = NULL;
00221         struct addrinfo *cur;
00222         int i, error = 0;
00223         char pton[PTON_MAX];
00224         struct addrinfo ai;
00225         struct addrinfo *pai;
00226         u_short port;
00227 
00228 #ifdef FAITH
00229         static int firsttime = 1;
00230 
00231         if (firsttime) {
00232                 /* translator hack */
00233                 {
00234                         char *q = getenv("GAI");
00235                         if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
00236                                 translate = YES;
00237                 }
00238                 firsttime = 0;
00239         }
00240 #endif
00241 
00242         /* initialize file static vars */
00243         sentinel.ai_next = NULL;
00244         cur = &sentinel;
00245         pai = &ai;
00246         pai->ai_flags = 0;
00247         pai->ai_family = PF_UNSPEC;
00248         pai->ai_socktype = ANY;
00249         pai->ai_protocol = ANY;
00250         pai->ai_addrlen = 0;
00251         pai->ai_canonname = NULL;
00252         pai->ai_addr = NULL;
00253         pai->ai_next = NULL;
00254         port = ANY;
00255         
00256         if (hostname == NULL && servname == NULL)
00257                 return EAI_NONAME;
00258         if (hints) {
00259                 /* error check for hints */
00260                 if (hints->ai_addrlen || hints->ai_canonname ||
00261                     hints->ai_addr || hints->ai_next)
00262                         ERR(EAI_BADHINTS); /* xxx */
00263                 if (hints->ai_flags & ~AI_MASK)
00264                         ERR(EAI_BADFLAGS);
00265                 switch (hints->ai_family) {
00266                 case PF_UNSPEC:
00267                 case PF_INET:
00268 #ifdef INET6
00269                 case PF_INET6:
00270 #endif
00271                         break;
00272                 default:
00273                         ERR(EAI_FAMILY);
00274                 }
00275                 memcpy(pai, hints, sizeof(*pai));
00276                 switch (pai->ai_socktype) {
00277                 case ANY:
00278                         switch (pai->ai_protocol) {
00279                         case ANY:
00280                                 break;
00281                         case IPPROTO_UDP:
00282                                 pai->ai_socktype = SOCK_DGRAM;
00283                                 break;
00284                         case IPPROTO_TCP:
00285                                 pai->ai_socktype = SOCK_STREAM;
00286                                 break;
00287                         default:
00288                                 pai->ai_socktype = SOCK_RAW;
00289                                 break;
00290                         }
00291                         break;
00292                 case SOCK_RAW:
00293                         break;
00294                 case SOCK_DGRAM:
00295                         if (pai->ai_protocol != IPPROTO_UDP &&
00296                             pai->ai_protocol != ANY)
00297                                 ERR(EAI_BADHINTS);      /*xxx*/
00298                         pai->ai_protocol = IPPROTO_UDP;
00299                         break;
00300                 case SOCK_STREAM:
00301                         if (pai->ai_protocol != IPPROTO_TCP &&
00302                             pai->ai_protocol != ANY)
00303                                 ERR(EAI_BADHINTS);      /*xxx*/
00304                         pai->ai_protocol = IPPROTO_TCP;
00305                         break;
00306                 default:
00307                         ERR(EAI_SOCKTYPE);
00308                         break;
00309                 }
00310         }
00311 
00312         /*
00313          * service port
00314          */
00315         if (servname) {
00316                 if (str_isnumber(servname)) {
00317                         if (pai->ai_socktype == ANY) {
00318                                 /* caller accept *ANY* socktype */
00319                                 pai->ai_socktype = SOCK_DGRAM;
00320                                 pai->ai_protocol = IPPROTO_UDP;
00321                         }
00322                         port = htons(atoi(servname));
00323                 } else {
00324                         struct servent *sp;
00325                         char *proto;
00326 
00327                         proto = NULL;
00328                         switch (pai->ai_socktype) {
00329                         case ANY:
00330                                 proto = NULL;
00331                                 break;
00332                         case SOCK_DGRAM:
00333                                 proto = "udp";
00334                                 break;
00335                         case SOCK_STREAM:
00336                                 proto = "tcp";
00337                                 break;
00338                         default:
00339                                 fprintf(stderr, "panic!\n");
00340                                 break;
00341                         }
00342                         if ((sp = getservbyname(servname, proto)) == NULL)
00343                                 ERR(EAI_SERVICE);
00344                         port = sp->s_port;
00345                         if (pai->ai_socktype == ANY) {
00346                                 if (strcmp(sp->s_proto, "udp") == 0) {
00347                                         pai->ai_socktype = SOCK_DGRAM;
00348                                         pai->ai_protocol = IPPROTO_UDP;
00349                                 } else if (strcmp(sp->s_proto, "tcp") == 0) {
00350                                         pai->ai_socktype = SOCK_STREAM;
00351                                         pai->ai_protocol = IPPROTO_TCP;
00352                                 } else
00353                                         ERR(EAI_PROTOCOL);      /*xxx*/
00354                         }
00355                 }
00356         }
00357         
00358         /*
00359          * hostname == NULL.
00360          * passive socket -> anyaddr (0.0.0.0 or ::)
00361          * non-passive socket -> localhost (127.0.0.1 or ::1)
00362          */
00363         if (hostname == NULL) {
00364                 struct afd *afd;
00365 
00366                 for (afd = &afdl[0]; afd->a_af; afd++) {
00367                         if (!(pai->ai_family == PF_UNSPEC
00368                            || pai->ai_family == afd->a_af)) {
00369                                 continue;
00370                         }
00371 
00372                         if (pai->ai_flags & AI_PASSIVE) {
00373                                 if (!get_ai(&cur->ai_next, pai, afd, afd->a_addrany, port))
00374                                         goto free;
00375                                 /* xxx meaningless?
00376                                  * GET_CANONNAME(cur->ai_next, "anyaddr");
00377                                  */
00378                         } else {
00379                                 if (!get_ai(&cur->ai_next, pai, afd, afd->a_loopback,
00380                                         port))
00381                                         goto free;
00382                                 /* xxx meaningless?
00383                                  * GET_CANONNAME(cur->ai_next, "localhost");
00384                                  */
00385                         }
00386                         cur = cur->ai_next;
00387                 }
00388                 top = sentinel.ai_next;
00389                 if (top)
00390                         goto good;
00391                 else
00392                         ERR(EAI_FAMILY);
00393         }
00394         
00395         /* hostname as numeric name */
00396         for (i = 0; afdl[i].a_af; i++) {
00397                 if (inet_pton(afdl[i].a_af, hostname, pton)) {
00398                         u_long v4a;
00399 
00400                         switch (afdl[i].a_af) {
00401                         case AF_INET:
00402                                 v4a = ((struct in_addr *)pton)->s_addr;
00403                                 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
00404                                         pai->ai_flags &= ~AI_CANONNAME;
00405                                 v4a >>= IN_CLASSA_NSHIFT;
00406                                 if (v4a == 0 || v4a == IN_LOOPBACKNET)
00407                                         pai->ai_flags &= ~AI_CANONNAME;
00408                                 break;
00409 #ifdef INET6
00410                         case AF_INET6:
00411                         {
00412                                 u_char pfx;
00413                                 pfx = ((struct in6_addr *)pton)->s6_addr[0];
00414                                 if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
00415                                         pai->ai_flags &= ~AI_CANONNAME;
00416                                 break;
00417                         }
00418 #endif
00419                         }
00420                         
00421                         if (pai->ai_family == afdl[i].a_af ||
00422                             pai->ai_family == PF_UNSPEC) {
00423                                 if (! (pai->ai_flags & AI_CANONNAME)) {
00424                                         if (get_ai(&top, pai, &afdl[i], pton, port))
00425                                                 goto good;
00426                                         else
00427                                                 goto free;
00428                                 }
00429                                 /*
00430                                  * if AI_CANONNAME and if reverse lookup
00431                                  * fail, return ai anyway to pacify
00432                                  * calling application.
00433                                  *
00434                                  * XXX getaddrinfo() is a name->address
00435                                  * translation function, and it looks strange
00436                                  * that we do addr->name translation here.
00437                                  */
00438                                 get_name(pton, &afdl[i], &top, pton, pai, port);
00439                                 goto good;
00440                         } else 
00441                                 ERR(EAI_FAMILY);        /*xxx*/
00442                 }
00443         }
00444 
00445         if (pai->ai_flags & AI_NUMERICHOST)
00446                 ERR(EAI_NONAME);
00447 
00448         /* hostname as alphabetical name */
00449         error = get_addr(hostname, pai->ai_family, &top, pai, port);
00450         if (error == 0) {
00451                 if (top) {
00452  good:
00453                         *res = top;
00454                         return SUCCESS;
00455                 } else
00456                         error = EAI_FAIL;
00457         }
00458  free:
00459         if (top)
00460                 freeaddrinfo(top);
00461  bad:
00462         *res = NULL;
00463         return error;
00464 }

static int get_name ( char *  addr,
struct afd afd,
struct addrinfo **  res,
char *  numaddr,
struct addrinfo pai,
int  port0 
) const [static]

getaddrinfo.c467 行で定義されています。

参照先 afd::a_addrlenafd::a_affreeaddrinfo()freehostent()get_ai().

00474 {
00475         u_short port = port0 & 0xffff;
00476         struct hostent *hp;
00477         struct addrinfo *cur;
00478         int error = 0;
00479         
00480 #ifdef INET6
00481         {
00482                 int h_error;
00483                 hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
00484         }
00485 #else
00486         hp = gethostbyaddr(addr, afd->a_addrlen, AF_INET);
00487 #endif
00488         if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
00489                 if (!get_ai(&cur, pai, afd, hp->h_addr_list[0], port))
00490                         goto free;
00491                 GET_CANONNAME(cur, hp->h_name);
00492         } else {
00493                 if (!get_ai(&cur, pai, afd, numaddr, port))
00494                         goto free;
00495         }
00496         
00497 #ifdef INET6
00498         if (hp)
00499                 freehostent(hp);
00500 #endif
00501         *res = cur;
00502         return SUCCESS;
00503  free:
00504         if (cur)
00505                 freeaddrinfo(cur);
00506 #ifdef INET6
00507         if (hp)
00508                 freehostent(hp);
00509 #endif
00510  /* bad: */
00511         *res = NULL;
00512         return error;
00513 }

static int get_addr ( char *  hostname,
int  af,
struct addrinfo **  res,
struct addrinfo pai,
int  port0 
) const [static]

getaddrinfo.c516 行で定義されています。

参照先 afd::a_afafdladdrinfo::ai_addraddrinfo::ai_nextfaith_prefixget_ai()translate.

00522 {
00523         u_short port = port0 & 0xffff;
00524         struct addrinfo sentinel;
00525         struct hostent *hp;
00526         struct addrinfo *top, *cur;
00527         struct afd *afd;
00528         int i, error = 0, h_error;
00529         char *ap;
00530 #ifndef INET6
00531         extern int h_errno;
00532 #endif
00533 
00534         top = NULL;
00535         sentinel.ai_next = NULL;
00536         cur = &sentinel;
00537 #ifdef INET6
00538         if (af == AF_UNSPEC) {
00539                 hp = getipnodebyname(hostname, AF_INET6,
00540                                 AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
00541         } else
00542                 hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
00543 #else
00544         hp = gethostbyname(hostname);
00545         h_error = h_errno;
00546 #endif
00547         if (hp == NULL) {
00548                 switch (h_error) {
00549                 case HOST_NOT_FOUND:
00550                 case NO_DATA:
00551                         error = EAI_NODATA;
00552                         break;
00553                 case TRY_AGAIN:
00554                         error = EAI_AGAIN;
00555                         break;
00556                 case NO_RECOVERY:
00557                 default:
00558                         error = EAI_FAIL;
00559                         break;
00560                 }
00561                 goto bad;
00562         }
00563 
00564         if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
00565             (hp->h_addr_list[0] == NULL))
00566                 ERR(EAI_FAIL);
00567         
00568         for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
00569                 switch (af) {
00570 #ifdef INET6
00571                 case AF_INET6:
00572                         afd = &afdl[N_INET6];
00573                         break;
00574 #endif
00575 #ifndef INET6
00576                 default:        /* AF_UNSPEC */
00577 #endif
00578                 case AF_INET:
00579                         afd = &afdl[N_INET];
00580                         break;
00581 #ifdef INET6
00582                 default:        /* AF_UNSPEC */
00583                         if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
00584                                 ap += sizeof(struct in6_addr) -
00585                                         sizeof(struct in_addr);
00586                                 afd = &afdl[N_INET];
00587                         } else
00588                                 afd = &afdl[N_INET6];
00589                         break;
00590 #endif
00591                 }
00592 #ifdef FAITH
00593                 if (translate && afd->a_af == AF_INET) {
00594                         struct in6_addr *in6;
00595 
00596                         if (!get_ai(&cur->ai_next, pai, &afdl[N_INET6], ap, port))
00597                                 goto free;
00598                         in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
00599                         memcpy(&in6->s6_addr32[0], &faith_prefix,
00600                             sizeof(struct in6_addr) - sizeof(struct in_addr));
00601                         memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
00602                 } else
00603 #endif /* FAITH */
00604                 if (!get_ai(&cur->ai_next, pai, afd, ap, port))
00605                         goto free;
00606                 if (cur == &sentinel) {
00607                         top = cur->ai_next;
00608                         GET_CANONNAME(top, hp->h_name);
00609                 }
00610                 cur = cur->ai_next;
00611         }
00612 #ifdef INET6
00613         freehostent(hp);
00614 #endif
00615         *res = top;
00616         return SUCCESS;
00617  free:
00618         if (top)
00619                 freeaddrinfo(top);
00620 #ifdef INET6
00621         if (hp)
00622                 freehostent(hp);
00623 #endif
00624  bad:
00625         *res = NULL;
00626         return error;
00627 }


変数

int translate = NO [static]

getaddrinfo.c54 行で定義されています。

参照元 get_addr()getaddrinfo().

struct in6_addr faith_prefix = IN6ADDR_ANY_INIT [static]

getaddrinfo.c55 行で定義されています。

参照元 get_addr()getaddrinfo().

const char in_addrany[] = { 0, 0, 0, 0 } [static]

getaddrinfo.c66 行で定義されています。

const char in6_addrany[] [static]

初期値:

 {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}

getaddrinfo.c67 行で定義されています。

const char in_loopback[] = { 127, 0, 0, 1 } [static]

getaddrinfo.c70 行で定義されています。

const char in6_loopback[] [static]

初期値:

 {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
}

getaddrinfo.c71 行で定義されています。

struct afd afdl[] [static]

参照元 get_addr()getaddrinfo()getnameinfo().

char* ai_errlist[] [static]

初期値:

 {
        "success.",
        "address family for hostname not supported.",   
        "temporary failure in name resolution.",        
        "invalid value for ai_flags.",                  
        "non-recoverable failure in name resolution.",  
        "ai_family not supported.",                     
        "memory allocation failure.",                   
        "no address associated with hostname.",         
        "hostname nor servname provided, or not known.",
        "servname not supported for ai_socktype.",      
        "ai_socktype not supported.",                   
        "system error returned in errno.",              
        "invalid value for hints.",                     
        "resolved protocol is unknown.",                
        "unknown error.",                               
}

getaddrinfo.c120 行で定義されています。


rsyncに対してSat Dec 5 19:45:44 2009に生成されました。  doxygen 1.4.7