问题
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 thenodename
argument is null, then the IP address portion of the socket address structure shall be set toINADDR_ANY
for an IPv4 address orIN6ADDR_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 toconnect()
(for a connection-mode protocol) or for a call toconnect()
,sendto()
, orsendmsg()
(for a connectionless protocol). In this case, if thenodename
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 thenodename
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