getaddrinfo()返回几个相同的结果
在/ etc / hosts我有:
127.0.0.1 localhost.localdomain localhost ::1 localhost.localdomain localhost 测试程序: #include <string.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> const char* family_to_string(int family) { return family == AF_INET ? "AF_INET" : family == AF_INET6 ? "AF_INET6" : "<unknown>"; } const char* socktype_to_string(int socktype) { return socktype == SOCK_STREAM ? "SOCK_STREAM" : socktype == SOCK_DGRAM ? "SOCK_DGRAM" : "<unknown>"; } const char* protocol_to_string(int protocol) { return protocol == IPPROTO_TCP ? "IPPROTO_TCP" : protocol == IPPROTO_UDP ? "IPPROTO_UDP" : "<unknown>"; } void print_addrinfo(struct addrinfo *ai) { int r; char hbuf[NI_MAXHOST],sbuf[NI_MAXSERV]; r = getnameinfo(ai->ai_addr,ai->ai_addrlen,hbuf,sizeof(hbuf),sbuf,sizeof(sbuf),NI_NUMERICHOST | NI_NUMERICSERV); if (r) { fputs("getnameinfon",stderr); exit(EXIT_FAILURE); } const char *family = family_to_string(ai->ai_family); const char *socktype = socktype_to_string(ai->ai_socktype); const char *protocol = protocol_to_string(ai->ai_protocol); const char *family2 = family_to_string(ai->ai_addr->sa_family); printf("flags=%i,family=%s,socktype=%s,protocol=%s,host=%s,serv=%sn",ai->ai_flags,family,socktype,protocol,family2,sbuf); } int main(int argc,char *argv[]) { (void)argc; (void)argv; int r; struct addrinfo hints; struct addrinfo *result,*ai; memset(&hints,sizeof(struct addrinfo)); // hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; r = getaddrinfo("localhost","8000",&hints,&result); if (r) { fputs("getaddrinfon",stderr); exit(EXIT_FAILURE); } ai = result; while (ai) { print_addrinfo(ai); ai = ai->ai_next; } exit(EXIT_SUCCESS); } 当我没有设置hints.ai_family时,它就像预期的那样: $gcc -Wall -Wextra -Werror -pedantic -pedantic-errors -g -gdwarf-2 -g3 % && ./a.out flags=0,family=AF_INET6,socktype=SOCK_STREAM,protocol=IPPROTO_TCP,host=::1,serv=8000 flags=0,family=AF_INET,host=127.0.0.1,serv=8000 使用hints.ai_family,它返回两个相同的addrinfo结构: flags=0,serv=8000 你能解释一下发生了什么吗?我认为提示充当过滤器.也就是说,在这种情况下只返回一个结果. UPD /etc/nsswitch.conf # Begin /etc/nsswitch.conf passwd: compat mymachines systemd group: compat mymachines systemd shadow: compat publickey: files hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname networks: files protocols: files services: files ethers: files rpc: files netgroup: files # End /etc/nsswitch.conf 在/etc/resolv.conf: # Generated by resolvconf search Dlink nameserver 192.168.0.1 192.168.0.1是我的路由器.我的IP地址是192.168.0.39. 解决方法
从我所看到的:
sysdeps/posix/getaddrinfo.c:2206 int getaddrinfo (const char *name,const char *service,const struct addrinfo *hints,struct addrinfo **pai) sysdeps/posix/getaddrinfo.c:2304 last_i = gaih_inet (name,pservice,hints,end,&naddrs,&tmpbuf); sysdeps/posix/getaddrinfo.c:342 static int gaih_inet (const char *name,const struct gaih_service *service,const struct addrinfo *req,struct addrinfo **pai,unsigned int *naddrs,struct scratch_buffer *tmpbuf) sysdeps/posix/getaddrinfo.c:595 rc = __gethostbyname2_r (name,AF_INET,&th,tmpbuf->data,tmpbuf->length,&h,&h_errno); nss/getXXbyYY_r.c:189 int INTERNAL (REENTRANT_NAME) (ADD_PARAMS,LOOKUP_TYPE *resbuf,char *buffer,size_t buflen,LOOKUP_TYPE **result H_ERRNO_PARM EXTRA_PARAMS) nss/getXXbyYY_r.c:316 status = DL_CALL_FCT (fct.l,(ADD_VARIABLES,resbuf,buffer,buflen,&errno H_ERRNO_VAR EXTRA_VARIABLES)); nss/nss_files/files-hosts.c:385 enum nss_status _nss_files_gethostbyname2_r (const char *name,int af,struct hostent *result,int *errnop,int *herrnop) nss/nss_files/files-hosts.c:389 return _nss_files_gethostbyname3_r (name,af,result,errnop,herrnop,NULL,NULL); nss/nss_files/files-hosts.c:334 enum nss_status _nss_files_gethostbyname3_r (const char *name,int *herrnop,int32_t *ttlp,char **canonp) 这里我们得到第一个匹配,并且 – 如果在/etc/host.conf中打开了多个 – 其余部分: nss/nss_files/files-hosts.c:352 while ((status = internal_getent (stream,flags)) == NSS_STATUS_SUCCESS) { LOOKUP_NAME_CASE (h_name,h_aliases) } if (status == NSS_STATUS_SUCCESS && _res_hconf.flags & HCONF_FLAG_MULTI) status = gethostbyname3_multi (stream,name,flags); nss/nss_files/files-hosts.c:127 static enum nss_status gethostbyname3_multi (FILE * stream,const char *name,int flags) nss/nss_files/files-hosts.c:162 status = internal_getent (stream,&tmp_result_buf,tmp_buffer.data,tmp_buffer.length,flags); nss/nss_files/files-XXX.c:178 static enum nss_status internal_getent (FILE *stream,struct STRUCTURE *result,int *errnop H_ERRNO_PROTO EXTRA_ARGS_DECL) nss/nss_files/files-XXX.c:222 || ! (parse_result = parse_line (p,data,errnop EXTRA_ARGS))); 这里我们解析“:: 1 localhost.localdomain localhost”行.我们试图 nss/nss_files/files-hosts.c:51 LINE_PARSER nss/nss_files/files-hosts.c:59 if (inet_pton (af == AF_UNSPEC ? AF_INET : af,addr,entdata->host_addr) > 0) af = af == AF_UNSPEC ? AF_INET : af; else { if (...) ... else if (af == AF_INET && inet_pton (AF_INET6,entdata->host_addr) > 0) { if (...) ... else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr)) { in_addr_t localhost = htonl (INADDR_LOOPBACK); memcpy (entdata->host_addr,&localhost,sizeof (localhost)); } 也许有人会在mailing list回复,我们会学到更多. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |