Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get an addres of AF_INET6 socket with recvfrom

recvfrom requires the 5-th parameter to be a pointer to sockaddr structure and the 6-th parameter to be a pointer to a socklen_t.

man recvfrom (3) says:

If the actual length of the address is greater than the length of the supplied sockaddr structure, the stored address shall be truncated.

I don't get it how can I retrieve an address of a sending socket with AF_INET6 address family since the size of sockaddr_in6 is greater than sockaddr thus it would be truncated by recvfrom.

Do I get it right that recvfrom can not retrieve addresses larger than sizeof(sockaddr)?

Do I get it right that even if I define an instance of sockaddr_in6 cast it's address to sockaddr* and pass it to recvfrom, the function would not be able to know that enough space is available to store the address?

like image 621
Kolyunya Avatar asked Dec 06 '22 05:12

Kolyunya


1 Answers

It's correct to cast it to sockaddr* .

Further more, people use often sockaddr_storage, because it is defined as

The header shall define the sockaddr_storage structure. This structure shall be:

  • Large enough to accommodate all supported protocol-specific address structures
  • Aligned at an appropriate boundary so that pointers to it can be cast as pointers to protocol-specific address structures and used to access the fields of those structures without alignment problems

In this way you can use it for several protocols, so you're not boundedn to only IPv6 or IPv4.

So you can do

struct sockaddr_storage addr;
socklen_t sa_len = sizeof(addr);

recvfrom (sock, buffer, sizeof (buffer), (struct sockaddr*) &addr, &sa_len);

If you need to know what kinf of sockaddr is, you can check the mandatory sa_family_t ss_family field present in each sockaddr struct.

You may also be interested in this link or this one.

like image 90
Ottavio Campana Avatar answered Dec 08 '22 18:12

Ottavio Campana