diff --git a/overlay_link.c b/overlay_link.c index 29450e4c..96cc8440 100644 --- a/overlay_link.c +++ b/overlay_link.c @@ -207,10 +207,11 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest if (destination->interface->socket_type==SOCK_STREAM) return 0; - // XXXTODO throttle probes... -// time_ms_t now = gettime_ms(); -// if (peer && peer->last_probe+1000>now) -// return -1; + time_ms_t now = gettime_ms(); + // though unicast probes don't typically use the same network destination, + // we should still try to throttle when we can + if (destination->last_tx + destination->tick_ms > now) + return -1; struct overlay_frame *frame=malloc(sizeof(struct overlay_frame)); bzero(frame,sizeof(struct overlay_frame)); @@ -219,14 +220,10 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest frame->next_hop = frame->destination = peer; frame->ttl=1; frame->queue=queue; - frame->destination_count=1; - frame->destinations[0].destination=add_destination_ref(destination); + frame->destinations[frame->destination_count++].destination=add_destination_ref(destination); frame->payload = ob_new(); frame->source_full = 1; // TODO call mdp payload encryption / signing without calling overlay_mdp_dispatch... - // XXXTODO rate limit -// if (peer) -// peer->last_probe=gettime_ms(); if (overlay_mdp_encode_ports(frame->payload, MDP_PORT_ECHO, MDP_PORT_PROBE)){ op_free(frame); @@ -258,43 +255,25 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest // append the address of a unicast link into a packet buffer static int overlay_append_unicast_address(struct subscriber *subscriber, struct overlay_buffer *buff) { - return -1; - /*XXXTODO - if (subscriber->reachable & REACHABLE_ASSUMED || !(subscriber->reachable & REACHABLE_UNICAST)){ + if (subscriber->destination + && subscriber->destination->unicast + && subscriber->destination->address.sin_family==AF_INET){ + if (overlay_address_append(NULL, buff, subscriber)) + return -1; + if (ob_append_ui32(buff, subscriber->destination->address.sin_addr.s_addr)) + return -1; + if (ob_append_ui16(buff, subscriber->destination->address.sin_port)) + return -1; + ob_checkpoint(buff); + if (config.debug.overlayrouting) + DEBUGF("Added STUN info for %s", alloca_tohex_sid(subscriber->sid)); + }else{ if (config.debug.overlayrouting) DEBUGF("Unable to give address of %s, %d", alloca_tohex_sid(subscriber->sid),subscriber->reachable); - return 0; } - - if (overlay_address_append(NULL, buff, subscriber)) - return -1; - if (ob_append_ui32(buff, subscriber->address.sin_addr.s_addr)) - return -1; - if (ob_append_ui16(buff, subscriber->address.sin_port)) - return -1; - ob_checkpoint(buff); - if (config.debug.overlayrouting) - DEBUGF("Added STUN info for %s", alloca_tohex_sid(subscriber->sid)); return 0; - */ } -// append the address of all neighbour unicast links into a packet buffer -/* - static int overlay_append_local_unicasts(struct subscriber *subscriber, void *context) - { - struct overlay_buffer *buff = context; - if ((!subscriber->interface) || - (!(subscriber->reachable & REACHABLE_UNICAST)) || - (subscriber->reachable & REACHABLE_ASSUMED)) - return 0; - if ((subscriber->address.sin_addr.s_addr & subscriber->interface->netmask.s_addr) != - (subscriber->interface->address.sin_addr.s_addr & subscriber->interface->netmask.s_addr)) - return 0; - return overlay_append_unicast_address(subscriber, buff); - } - */ - int overlay_mdp_service_stun_req(overlay_mdp_frame *mdp) { if (config.debug.overlayrouting) diff --git a/overlay_queue.c b/overlay_queue.c index b40fe8c6..1d8fa97f 100644 --- a/overlay_queue.c +++ b/overlay_queue.c @@ -232,7 +232,7 @@ overlay_init_packet(struct outgoing_packet *packet, int packet_version, packet->buffer=ob_new(); packet->packet_version = packet_version; packet->context.packet_version = packet_version; - packet->destination = destination; + packet->destination = add_destination_ref(destination); if (destination->sequence_number<0) packet->seq=-1; else @@ -473,8 +473,9 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim // fill a packet from our outgoing queues and send it static int overlay_fill_send_packet(struct outgoing_packet *packet, time_ms_t now) { - int i; IN(); + int i; + int ret=0; // while we're looking at queues, work out when to schedule another packet unschedule(&next_packet); next_packet.alarm=0; @@ -492,9 +493,11 @@ overlay_fill_send_packet(struct outgoing_packet *packet, time_ms_t now) { overlay_broadcast_ensemble(packet->destination, ob_ptr(packet->buffer), ob_position(packet->buffer)); ob_free(packet->buffer); - RETURN(1); + ret=1; } - RETURN(0); + if (packet->destination) + release_destination_ref(packet->destination); + RETURN(ret); OUT(); } diff --git a/route_link.c b/route_link.c index d4890f75..f8587a38 100644 --- a/route_link.c +++ b/route_link.c @@ -72,7 +72,7 @@ struct link_in{ time_ms_t link_timeout; // unicast or broadcast? - char unicast; + int unicast; int ack_sequence; uint64_t ack_mask; @@ -582,7 +582,7 @@ static void clean_neighbours(time_ms_t now) while(*list){ struct link_in *link = *list; if (link->interface->state!=INTERFACE_STATE_UP || link->link_timeout < now){ - if (config.debug.linkstate && config.debug.verbose) + if (config.debug.linkstate) DEBUGF("LINK STATE; link expired from neighbour %s on interface %s", alloca_tohex_sid(n->subscriber->sid), link->interface->name); @@ -598,6 +598,11 @@ static void clean_neighbours(time_ms_t now) struct link_out *link = *out; if (link->destination->interface->state!=INTERFACE_STATE_UP || link->timeout < now){ *out = link->_next; + if (config.debug.linkstate) + DEBUGF("LINK STATE; %s link_out expired for neighbour %s on interface %s", + link->destination->unicast?"unicast":"broadcast", + alloca_tohex_sid(n->subscriber->sid), + link->destination->interface->name); release_destination_ref(link->destination); free(link); }else{ @@ -663,7 +668,7 @@ static int neighbour_find_best_link(struct neighbour *n) if (n->best_link != best_link){ n->best_link = best_link; n->next_neighbour_update = gettime_ms()+5; - if (config.debug.linkstate && config.debug.verbose){ + if (config.debug.linkstate){ if (best_link){ DEBUGF("LINK STATE; best link from neighbour %s is %s on interface %s", alloca_tohex_sid(n->subscriber->sid), @@ -838,7 +843,7 @@ static void update_alarm(time_ms_t limit){ } } -struct link_in * get_neighbour_link(struct neighbour *neighbour, struct overlay_interface *interface, int sender_interface, char unicast) +struct link_in * get_neighbour_link(struct neighbour *neighbour, struct overlay_interface *interface, int sender_interface, int unicast) { struct link_in *link = neighbour->links; if (unicast){ @@ -861,7 +866,7 @@ struct link_in * get_neighbour_link(struct neighbour *neighbour, struct overlay_ link->ack_sequence = -1; link->ack_mask = 0; link->_next = neighbour->links; - if (config.debug.linkstate && config.debug.verbose) + if (config.debug.linkstate) DEBUGF("LINK STATE; new possible %s link from neighbour %s on interface %s/%d", unicast?"unicast":"broadcast", alloca_tohex_sid(neighbour->subscriber->sid), @@ -1011,7 +1016,14 @@ static struct link_out *create_out_link(struct neighbour *neighbour, overlay_int ret->destination = create_unicast_destination(addr, interface); else ret->destination = add_destination_ref(interface->destination); - ret->timeout = gettime_ms()+ret->destination->tick_ms*2; + + if (config.debug.linkstate) + DEBUGF("LINK STATE; Create possible %s link_out for neighbour %s on interface %s", + unicast?"unicast":"broadcast", + alloca_tohex_sid(neighbour->subscriber->sid), + interface->name); + + ret->timeout = gettime_ms()+ret->destination->tick_ms*3; update_alarm(gettime_ms()+5); } return ret; @@ -1040,20 +1052,17 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un time_ms_t now = gettime_ms(); if (!neighbour->out_links){ + // if this packet arrived in an IPv4 packet, assume we need to send them unicast packets - if (context->addr.sin_family==AF_INET && context->addr.sin_port!=0 && context->addr.sin_addr.s_addr!=0){ - if (config.debug.linkstate && config.debug.verbose) - DEBUGF("Assuming reachable via unicast"); + if (context->addr.sin_family==AF_INET && context->addr.sin_port!=0 && context->addr.sin_addr.s_addr!=0) create_out_link(neighbour, context->interface, context->addr, 1); - } + // if this packet arrived from the same IPv4 subnet, or a different type of network, assume they can hear our broadcasts if (context->addr.sin_family!=AF_INET || (context->addr.sin_addr.s_addr & context->interface->netmask.s_addr) - == (context->interface->address.sin_addr.s_addr& context->interface->netmask.s_addr)){ - if (config.debug.linkstate && config.debug.verbose) - DEBUGF("Assuming reachable via broadcast"); + == (context->interface->address.sin_addr.s_addr & context->interface->netmask.s_addr)) create_out_link(neighbour, context->interface, context->addr, 0); - } + } link->ack_counter --;