Bind to interface address so unicast packets can be received & always bind to INADDR_ANY

This commit is contained in:
Jeremy Lakeman 2012-09-11 15:20:44 +09:30
parent fbe9980199
commit 58fae14ef2
2 changed files with 19 additions and 24 deletions

@ -356,24 +356,22 @@ overlay_interface_init_socket(int interface_index)
overlay_interface *const interface = &overlay_interfaces[interface_index];
interface->fileP = 0;
#ifdef __APPLE__
/*
On OSX and probably windows you can't bind to a broadcast address.
*/
const struct sockaddr *addr = (const struct sockaddr *)&interface->address;
/* On osx, UDP sockets bound to a specific interface can send broadcast packets just fine,
but can't receive broadcast packets
So we need a socket bound to INADDR_ANY for receiving them.
On linux you can bind to the broadcast address to receive broadcast packets per interface [or subnet],
but then you can't receive unicast packets on the same socket.
On osx, you can only receive broadcast packets if you bind to INADDR_ANY.
So the most portable way to do this is to bind to each interface's IP address for sending broadcasts
and receiving unicasts, and bind a separate socket to INADDR_ANY just for receiving broadcast packets.
Sending packets from INADDR_ANY would probably work, but gives us less control over which interfaces are sending packets.
But there may be some platforms that need some other combination for everything to work.
*/
overlay_interface_init_any(interface->port);
#else
/*
Bind to the broadcast address, so that we can reliably receive broadcast
traffic on linux platforms.
*/
const struct sockaddr *addr = (const struct sockaddr *)&interface->broadcast_address;
#endif
const struct sockaddr *addr = (const struct sockaddr *)&interface->address;
interface->alarm.poll.fd = overlay_bind_socket(addr, sizeof(interface->broadcast_address), interface->name);
if (interface->alarm.poll.fd<0){
@ -718,7 +716,8 @@ overlay_broadcast_ensemble(int interface_number,
}
else
{
DEBUGF("Sending overlay frame on %s to %s",interface->name,inet_ntoa(recipientaddr->sin_addr));
if (debug&DEBUG_OVERLAYINTERFACES)
DEBUGF("Sending %d byte overlay frame on %s to %s",len,interface->name,inet_ntoa(recipientaddr->sin_addr));
if(sendto(interface->alarm.poll.fd,
bytes, len, 0, (struct sockaddr *)recipientaddr, sizeof(struct sockaddr_in)) != len){
WHY_perror("sendto(c)");
@ -1147,9 +1146,6 @@ overlay_fill_send_packet(struct outgoing_packet *packet, time_ms_t now) {
if (debug&DEBUG_PACKETCONSTRUCTION)
dump("assembled packet",&packet->buffer->bytes[0],packet->buffer->position);
if (debug&DEBUG_OVERLAYINTERFACES)
DEBUGF("Sending %d byte packet",packet->buffer->position);
overlay_broadcast_ensemble(packet->i, &packet->dest, packet->buffer->bytes, packet->buffer->position);
}
ob_free(packet->buffer);

@ -151,8 +151,8 @@ static void parse_frame(struct overlay_buffer *buff){
frame.modifiers=ob_get(buff);
// dump("received headers", buff->bytes, buff->position);
// dump("received payload", buff->bytes+buff->position, buff->sizeLimit - buff->position);
if (debug&DEBUG_OVERLAYINTERFACES)
DEBUGF("Received %d byte payload via olsr", buff->sizeLimit - buff->position);
// the remaining bytes are an mdp payload, process it
frame.payload = buff;
@ -218,7 +218,6 @@ static int send_packet(unsigned char *header, int header_len, unsigned char *pay
.msg_iovlen=2,
};
DEBUGF("Sending broadcast via olsr");
if (sendmsg(read_watch.poll.fd, &msg, 0)<0){
return WHY_perror("Sending packet");
}
@ -240,8 +239,8 @@ int olsr_send(struct overlay_frame *frame){
overlay_broadcast_append(b, &frame->broadcast_id);
ob_append_byte(b, frame->modifiers);
// dump("sent headers", b->bytes, b->position);
// dump("sent payload", frame->payload->bytes, frame->payload->sizeLimit);
if (debug&DEBUG_OVERLAYINTERFACES)
DEBUGF("Sending %d byte payload via olsr", frame->payload->sizeLimit);
// send the packet
int ret = send_packet(b->bytes, b->position, frame->payload->bytes, frame->payload->sizeLimit);