Unix Network Programming Episode 78

'getaddrinfo' Function

The gethostbyname and gethostbyaddr functions only support IPv4. The API for resolving IPv6 addresses went through several iterations, as will be described in Section 11.20(See 8.9.20); the final result is the getaddrinfo function.

The POSIX definition of this function comes from an earlier proposal by Keith Sklower for a function named getconninfo. This function was the result of discussions with Eric Allman, William Durst, Michael Karels, and Steven Wise, and from an early implementation written by Eric Allman. The observation that specifying a hostname and a service name would suffice for connecting to a service independent of protocol details was made by Marshall Rose in a proposal to X/Open.

复制代码
#include <netdb.h>
int getaddrinfo (const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result) ;

This function returns through the result pointer a pointer to a linked list of addrinfo structures, which is defined by including <netdb.h>.

复制代码
struct addrinfo {
	int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
	int ai_family; /* AF_xxx */
	int ai_socktype; /* SOCK_xxx */
	int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
	socklen_t ai_addrlen; /* length of ai_addr */
	char *ai_canonname; /* ptr to canonical name for host */
	struct sockaddr *ai_addr; /* ptr to socket address structure */
	struct addrinfo *ai_next; /* ptr to next structure in linked list */
};

The members of the hints structure that can be set by the caller are:

  • ai_flags (zero or more AI_XXX values OR'ed together)
  • ai_family (an AF_xxx value)
  • ai_socktype (a SOCK_xxx value)
  • ai_protocol

If the function returns success (0), the variable pointed to by the result argument is filled in with a pointer to a linked list of addrinfo structures, linked through the ai_next pointer. There are two ways that multiple structures can be returned:

1.If there are multiple addresses associated with the hostname, one structure is returned for each address that is usable with the requested address family (the ai_family hint, if specified).

2.If the service is provided for multiple socket types, one structure can be returned for each socket type, depending on the ai_socktype hint. (Note that most getaddrinfo implementations consider a port number string to be implemented only by the socket type requested in ai_socktype; if ai_socktype is not specified, an error is returned instead.)

For example, if no hints are provided and if the domain service is looked up for a host with two IP addresses, four addrinfo structures are returned:

  • One for the first IP address and a socket type of SOCK_STREAM
  • One for the first IP address and a socket type of SOCK_DGRAM
  • One for the second IP address and a socket type of SOCK_STREAM
  • One for the second IP address and a socket type of SOCK_DGRAM

If we were to enumerate all 64 possible inputs to getaddrinfo (there are six input variables), many would be invalid and some would make little sense. Instead, we will look at the common cases.

  • Specify the hostname and service. This is normal for a TCP or UDP client. On return, a TCP client loops through all returned IP addresses, calling socket and connect for each one, until the connection succeeds or until all addresses have been tried. We will show an example of this with our tcp_connect function in Figure 11.10(See 8.9.12).
  • For a UDP client, the socket address structure filled in by getaddrinfo would be used in a call to sendto or connect. If the client can tell that the first address doesn't appear to work (either by receiving an error on a connected UDP socket or by experiencing a timeout on an unconnected socket), additional addresses can be tried.
  • If the client knows it handles only one type of socket (e.g., Telnet and FTP clients handle only TCP; TFTP clients handle only UDP), then the ai_socktype member of the hints structure should be specified as either SOCK_STREAM or SOCK_DGRAM.
  • A typical server specifies the service but not the hostname, and specifies the AI_PASSIVE flag in the hints structure. The socket address structures returned should contain an IP address of INADDR_ANY (for IPv4) or IN6ADDR_ANY_INIT (for IPv6). A TCP server then calls socket, bind, and listen. If the server wants to malloc another socket address structure to obtain the client's address from accept, the returned ai_addrlen value specifies this size.
  • A UDP server would call socket, bind, and then recvfrom. If the server wants to malloc another socket address structure to obtain the client's address from recvfrom, the returned ai_addrlen value specifies this size.
  • As with the typical client code, if the server knows it only handles one type of socket, the ai_socktype member of the hints structure should be set to either SOCK_STREAM or SOCK_DGRAM. This avoids having multiple structures returned, possibly with the wrong ai_socktype value.
  • The TCP servers that we have shown so far create one listening socket, and the UDP servers create one datagram socket. That is what we assume in the previous item. An alternate server design is for the server to handle multiple sockets using select or poll. In this scenario, the server would go through the entire list of structures returned by getaddrinfo, create one socket per structure, and use select or poll.
相关推荐
阳光是sunny1 分钟前
LangGraph实战教程:状态管理与`graph.invoke`入参深度解析
前端·人工智能·后端
老猿AI洞察4 分钟前
7月25日热点:马斯克说中国AI有望成为全球领导者,这次不是客套话
大数据·人工智能
AI_小站8 分钟前
Loop Engineering又是啥?一文讲清企业Agent落地的四层工程进化论
java·人工智能·架构·prompt·大模型开发·智能体·大模型应用
BEOL贝尔科技9 分钟前
还在担心样本的安全吗?如何制定有效的温湿度异常应急预案?
人工智能·安全
科技之门15 分钟前
百公里管网漏损分级定位实战方案2026
前端·人工智能·算法
火山引擎开发者社区16 分钟前
LLM Space 开源!任意组装 loop、tools、skills,顺手无痛“蒸馏” Kimi-K3
人工智能
zhishidi19 分钟前
深度学习中的优化器
人工智能·深度学习
糖果店的幽灵21 分钟前
2026 年最强Obsidian保姆级教程,10分钟打造你的第二大脑
人工智能·langgraph
巫山老妖38 分钟前
AI驱动的Flutter工程:如何让AI生成代码不跑偏
人工智能