getaddrinfo: in what way is AI_PASSIVE ignored if the nodename is specified?

时光怂恿深爱的人放手 提交于 2019-12-24 05:21:48

问题


Quoting from the specs of getaddrinfo:

If the AI_PASSIVE flag is specified, the returned address information shall be suitable for use in binding a socket for accepting incoming connections for the specified service. In this case, if the nodename argument is null, then the IP address portion of the socket address structure shall be set to INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6 address.

This makes sense. If you specify AI_PASSIVE, you can bind()/listen()/accept() on the returned address. If nodename is null, the returned address binds to all network interfaces so you can use any of the computer's IP addresses (e.g. ethernet LAN IP, Wi-Fi LAN IP, loopback address, etc.). Summary: use AI_PASSIVE on the server (for a TCP socket).

Continuing:

If the AI_PASSIVE flag is not specified, the returned address information shall be suitable for a call to connect() (for a connection-mode protocol) or for a call to connect(), sendto(), or sendmsg() (for a connectionless protocol). In this case, if the nodename argument is null, then the IP address portion of the socket address structure shall be set to the loopback address.

This also makes sense. If you don't specify AI_PASSIVE, you can connect()/sendto()/sendmsg() on the returned address. If nodename is null, you get the loopback address. Summary: don't use AI_PASSIVE on the client (for a TCP socket).

Continuing:

The AI_PASSIVE flag shall be ignored if the nodename argument is not null.

Huh? What does it even mean to ignore the AI_PASSIVE flag? From the first two quotes, it sounds like AI_PASSIVE is only used to determine whether you get addresses suitable for server/client use, and in both of those cases it sounds like a null nodename just gives you a INADDR_ANY address (for server) or loopback address (for client). What good does it do to ignore the AI_PASSIVE flag?

What does this last quote really mean? How does it affect the first two quotes?


回答1:


The Linux manpage for gettaddrinfo(2) describes it slightly differently (and a bit more consistently):

If the AI_PASSIVE flag is specified in hints.ai_flags, and node is NULL, then the returned socket addresses will be suitable for bind(2)ing a socket that will accept(2) connections. The returned socket address will contain the "wildcard address" [...]. If node is not NULL, then the AI_PASSIVE flag is ignored.

If the AI_PASSIVE flag is not set in hints.ai_flags, then the returned socket addresses will be suitable for use with connect(2), sendto(2), or sendmsg(2). If node is NULL, then the network address will be set to the loopback interface address [...].

Of course, the Linux manpage is not authoritative other than for Linux, but I offer it as a widely-used interpretation. In particular, note that it specifies that you get a server socket only if AI_PASSIVE is given and node is NULL. That still leaves some ambiguity as to what it means to "ignore" AI_PASSIVE, but I think it nevertheless points to the interpretation taken by Linux: you always get address info suitable for a client socket if node is not NULL.

You could perhaps rationalize it this way: "The AI_PASSIVE flag shall be ignored" should be interpreted as "if the AI_PASSIVE flag is set then that fact shall be ignored". That is, it shall be handled as if the flag were not set. I think that's additionally supported by the fact that this statement occurs in the same paragraph with the description of the behavior when AI_PASSIVE is set (in the official docs too, not just the Linux manpage).



来源:https://stackoverflow.com/questions/27829275/getaddrinfo-in-what-way-is-ai-passive-ignored-if-the-nodename-is-specified

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!