Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 08 Apr 2015 14:21:11 -0700
From:      Yuri <yuri@rawbw.com>
To:        net@freebsd.org
Cc:        Daniel Corbe <corbe@corbe.net>
Subject:   Re: Socket bound to 0.0.0.0 never receives broadcasts with non-zero IP source address
Message-ID:  <55259BC7.6040502@rawbw.com>
In-Reply-To: <878ue2n6lu.fsf@corbe.net>
References:  <55248957.60109@rawbw.com> <878ue2n6lu.fsf@corbe.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On 04/08/2015 05:32, Daniel Corbe wrote:
> If nobody answers this question by the time I get home I'll try and
> help; however, in the mean time I do have a couple of suggestions.
>
> Have you tried writing the equivalent program in C using the sockets
> API?  IE is this a python specific problem or a sockets problem in
> general?
>
> The second thing is you may just want to try using raw sockets instead.

I verified before with ktrace, and now, following your suggestion, 
rewrote it in C, and result is the same.
When I change SOCK_DGRAM->SOCK_RAW it keeps getting some other packets, 
sin_port doesn't seem to matter. Also, UDP is the practically important 
case.

Unless there is some reasonable explanation why ip source address can 
influence reception, I believe this is a bug in kernel. And pretty 
important one, because it can hurt DHCP servers.

Yuri


--- C program exhibiting the problem ---

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>

#define CK(func, call...) if ((call) < 0) {perror(#func); exit(1);}

int main() {
   int sock, one = 1;
   ssize_t count;
   struct sockaddr_in sa;
   char buffer[4096];
   struct sockaddr_storage src_addr;

   struct iovec iov[1];
   iov[0].iov_base=buffer;
   iov[0].iov_len=sizeof(buffer);

   struct msghdr msg;
   msg.msg_name=&src_addr;
   msg.msg_namelen=sizeof(src_addr);
   msg.msg_iov=iov;
   msg.msg_iovlen=1;
   msg.msg_control=0;
   msg.msg_controllen=0;

   CK(socket, sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))
   CK(setsockopt, setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, 
sizeof(one)))
   CK(setsockopt, setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &one, 
sizeof(one)))
   sa.sin_family = AF_INET;
   sa.sin_addr.s_addr = htonl(INADDR_ANY);
   //sa.sin_port = htons(67);
   sa.sin_port = htons(1767);
   CK(bind, bind(sock, (const struct sockaddr*)&sa, sizeof(sa)))

   printf("Waiting for broadcast\n");
   CK(recvmsg, count = recvmsg(sock, &msg, 0))
   printf("Received broadcast packet: %zd bytes\n", count);

   return 0;
}




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?55259BC7.6040502>