IPV6 UDP Socket recvfrom problem

Hi all,

While writing an IPv6 udp server application I hit something strange ( or I am very tired:) )

I wrote a test code to repeat the situation:
http://pastebin.com/MB8yECa1

there are two tests in test program..

In first test, I use below code to get a message from udp socket:

Code:
  struct sockaddr client_addr;
  socklen_t addr_len = sizeof(struct sockaddr);
  recvfrom(server_socket, buffer, UDP_SIZE, 0, &client_addr,  &addr_len);

I use sockaddr structure to get from address as written in man page

Code:
[B]ssize_t
recvfrom(int s, void * restrict buf, size_t len, int flags,
         struct sockaddr * restrict from, socklen_t * restrict fromlen);
[/B]

The problem is that recvfrom does not work properly when a pointer to a valid sockaddr structure is used in arguments. Recvfrom receives the message and copies only 16 bytes (the value of addr_len after recvfrom call) of information to client_addr structure. 16 bytes is not sufficient because real "from" object is 28 bytes (the value of client_addr->sa_len).

In addition, in man pages it is written that "The fromlen(addr_len in my case) argument is a value-result argument, initialized to the size of the buffer associated with from, and modified on return to indicate the actual size of the address stored there.". But as you can see when you execute test code addr_len is equal to 16 after recvfrom call. Recvfrom did not changed the value of addr_len. As a result I thought that recvfrom only copies (sizeof(struct sockaddr)) bytes. This is not a problem in IPv4 because in IPv4 16 bytes is sufficient for from address.

In test 2 I wrote a work around for this problem. I use a buffer of 32 bytes instead of sockaddr structure. Recvfrom fills buffer properly and addr_len is set to 28 after recvfrom call..

In test code, test 1 is between lines 86-109 and test 2 is between lines 113-136.

Is recvfrom works incorrectly or am I missing something?

thanks in advance...


Output of test_udp..

Code:
shell# gcc test_udp.c
shell# ./a.out  1
RESULT OF TEST 1 ( bug?)
Before recvfrom addr_len=16
After recvfrom addr_len=16, client_addr->sa_len=28
remote addr (should be): '2001:b12:12::151'
remote addr (inet_ntop): '2001:b12:12::'

shell# ./a.out 2
RESULT OF TEST 2
Before recvfrom addr_len=100
After recvfrom addr_len=28, client_addr->sa_len=28
remote addr (should be):'2001:b12:12::151'
remote addr (inet_ntop):'2001:b12:12::151'
 
Back
Top