From 58fae14ef2dfab7eb3330475c8f20f79af76c4c4 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Tue, 11 Sep 2012 15:20:44 +0930 Subject: [PATCH] Bind to interface address so unicast packets can be received & always bind to INADDR_ANY --- overlay_interface.c | 34 +++++++++++++++------------------- overlay_olsr.c | 9 ++++----- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/overlay_interface.c b/overlay_interface.c index a7dbeba0..1f28cd38 100644 --- a/overlay_interface.c +++ b/overlay_interface.c @@ -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); diff --git a/overlay_olsr.c b/overlay_olsr.c index 9424690b..1f4ce8ee 100644 --- a/overlay_olsr.c +++ b/overlay_olsr.c @@ -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);