[ntp:questions] Pool returns IPv6 address to IPv4 query

Rob nomail at example.com
Thu Nov 21 12:04:12 UTC 2013

Casper H.S  Dik <Casper.Dik at OrSPaMcle.COM> wrote:
> Rob <nomail at example.com> writes:
>>Uwe Klein <uwe at klein-habertwedt.de> wrote:
>>>> However, what I don't understand is why an IPv6 address does not fit
>>>> into a struct sockaddr, and why this fact is so badly documented.
>>>> It took me a lot of time to find why my queried IPv6 addresses were
>>>> truncated.
>>> struct sockaddr was a catch all and you had to also hand the size of the
>>> storage  into the call.
>>> forex:
>>>         int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
>>Yes, that is what I mean.  But it no longer works.
> Of course it still works; however, you may have missed that
> "struct sockaddr" isn't the same as "struct sockaddr_in"; these
> days you'd start with a "struct sockaddr_storage" and with
> socklen_t namelen = sizeof (struct sockaddr_in)

The function expects a struct sockaddr * so you would normally
  struct sockaddr sa;
  socklen_t len = sizeof(sa);
  getpeername(s, &sa, &len);

This always worked and was used in a lot of examples on the net.

When you are now supposed to use sockaddr_storage (why?), then the
parameter type of the function should have been changed in accordance.

> On return you'd determine what type of connection you got
> and you cast it to the proper type.

Of course.  But the problem is that a struct sockaddr is not large
enough to store the result in case of IPv6, and it gets truncated.
(because thankfully a size parameter is also passed, something that
was typically not done in early Unix library calls)

More information about the questions mailing list