Reputation:
From what I understand struct addrinfo is used to prep the socket address structure and struct sockaddr contains socket address information. But what does that actually mean? struct addrinfo contains a pointer to a struct sockaddr. Why keep them separate? Why can't we combine all things within sockaddr into addr_info?
I'm just guessing here but is the reason for their separation is to save space when passing structs? For example in the bind() call, all it needs is the port number and the internet address. So both of these are grouped in a struct sockaddr. So, we can just pass this small struct instead of the larger struct addrinfo?
struct addrinfo {
int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
int ai_socktype; // SOCK_STREAM, SOCK_DGRAM
int ai_protocol; // use 0 for "any"
size_t ai_addrlen; // size of ai_addr in bytes
struct sockaddr *ai_addr; // struct sockaddr_in or _in6
char *ai_canonname; // full canonical hostname
struct addrinfo *ai_next; // linked list, next node
};
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
Upvotes: 41
Views: 33326
Reputation: 25908
struct addrinfo
is returned by getaddrinfo()
, and contains, on success, a linked list of such struct
s for a specified hostname and/or service.
The ai_addr
member isn't actually a struct sockaddr
, because that struct
is merely a generic one that contains common members for all the others, and is used in order to determine what type of struct you actually have. Depending upon what you pass to getaddrinfo()
, and what that function found out, ai_addr
might actually be a pointer to struct sockaddr_in
, or struct sockaddr_in6
, or whatever else, depending upon what is appropriate for that particular address entry. This is one good reason why they're kept "separate", because that member might point to one of a bunch of different types of struct
s, which it couldn't do if you tried to hardcode all the members into struct addrinfo
, because those different struct
s have different members.
This is probably the easiest way to get this information if you have a hostname, but it's not the only way. For an IPv4 connection, you can just populate a struct sockaddr_in
structure yourself, if you want to and you have the data to do so, and avoid going through the rigamarole of calling getaddrinfo()
, which you might have to wait for if it needs to go out into the internet to collect the information for you. You don't have to use struct addrinfo
at all.
Upvotes: 31