From f9287149dd24388edcf81a77c369601eb80198a9 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Thu, 6 Sep 2012 15:21:31 +0930 Subject: [PATCH] Setup unicast return address when receiving unicast packet --- overlay_address.c | 21 ++++++++++++++++++++- overlay_address.h | 1 + overlay_olsr.c | 10 ++++------ overlay_packetformats.c | 13 +++++++++++++ overlay_route.c | 3 ++- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/overlay_address.c b/overlay_address.c index 071745a0..d3b3f7f3 100644 --- a/overlay_address.c +++ b/overlay_address.c @@ -160,13 +160,32 @@ int subscriber_is_reachable(struct subscriber *subscriber){ if (subscriber->reachable==REACHABLE_DIRECT && !(subscriber->interface - && subscriber->interface->state==INTERFACE_STATE_UP) + && subscriber->interface->state==INTERFACE_STATE_UP) ) return REACHABLE_NONE; return subscriber->reachable; } +// mark the subscriber as reachable via reply unicast packet +int reachable_unicast(struct subscriber *subscriber, overlay_interface *interface, struct in_addr addr, int port){ + if (subscriber->reachable!=REACHABLE_NONE) + return WHYF("Subscriber %s is already reachable", alloca_tohex_sid(subscriber->sid)); + + if (subscriber->node) + return WHYF("Subscriber %s is already known for overlay routing", alloca_tohex_sid(subscriber->sid)); + + subscriber->interface = interface; + subscriber->reachable = REACHABLE_DIRECT; + subscriber->address.sin_family = AF_INET; + subscriber->address.sin_addr = addr; + subscriber->address.sin_port = port; + + // may be used in tests + DEBUGF("ADD DIRECT ROUTE TO %s via %s", alloca_tohex_sid(subscriber->sid), inet_ntoa(addr)); + return 0; +} + // generate a new random broadcast address int overlay_broadcast_generate_address(struct broadcast *addr) { diff --git a/overlay_address.h b/overlay_address.h index d2d72292..9067663b 100644 --- a/overlay_address.h +++ b/overlay_address.h @@ -98,6 +98,7 @@ extern struct subscriber *my_subscriber; struct subscriber *find_subscriber(const unsigned char *sid, int len, int create); void enum_subscribers(struct subscriber *start, int(*callback)(struct subscriber *, void *), void *context); int subscriber_is_reachable(struct subscriber *subscriber); +int reachable_unicast(struct subscriber *subscriber, overlay_interface *interface, struct in_addr addr, int port); int overlay_broadcast_drop_check(struct broadcast *addr); int overlay_broadcast_generate_address(struct broadcast *addr); diff --git a/overlay_olsr.c b/overlay_olsr.c index 8aa9cb41..fc440ea2 100644 --- a/overlay_olsr.c +++ b/overlay_olsr.c @@ -136,13 +136,10 @@ static void parse_frame(struct overlay_buffer *buff){ if (frame.source->reachable==REACHABLE_NONE){ // locate the interface we should send outgoing unicast packets to - frame.source->interface = overlay_interface_find(*addr); - if (frame.source->interface){ - frame.source->reachable=REACHABLE_DIRECT; - frame.source->address.sin_family=AF_INET; - frame.source->address.sin_addr=*addr; + overlay_interface *interface = overlay_interface_find(*addr); + if (interface){ // assume the port number of the other servald matches our local port number configuration - frame.source->address.sin_port=frame.source->interface->port; + reachable_unicast(frame.source, interface, *addr, interface->port); } } @@ -214,6 +211,7 @@ 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"); } diff --git a/overlay_packetformats.c b/overlay_packetformats.c index cafc8127..85b1fb9b 100644 --- a/overlay_packetformats.c +++ b/overlay_packetformats.c @@ -269,6 +269,19 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s goto next; } + // HACK, change to packet transmitter when packet format includes that. + if (f.type!=OF_TYPE_SELFANNOUNCE && + f.source->reachable == REACHABLE_NONE && + !f.source->node && + !interface->fileP && + recvaddr->sa_family==AF_INET){ + struct sockaddr_in *addr=(struct sockaddr_in *)recvaddr; + + // mark this subscriber as reachable directly via unicast. + reachable_unicast(f.source, interface, addr->sin_addr, addr->sin_port); + } + + f.payload = ob_slice(b, b->position, next_payload - b->position); if (!f.payload){ WHY("Payload length is longer than remaining packet size"); diff --git a/overlay_route.c b/overlay_route.c index 882dfcca..ca8d60f7 100644 --- a/overlay_route.c +++ b/overlay_route.c @@ -183,7 +183,8 @@ overlay_node *get_node(struct subscriber *subscriber, int create){ subscriber->node = (overlay_node *)malloc(sizeof(overlay_node)); memset(subscriber->node,0,sizeof(overlay_node)); subscriber->node->subscriber = subscriber; - + // if we're taking over routing calculations, make sure we invalidate any other calculations first + subscriber->reachable=REACHABLE_NONE; // This info message is used by tests; don't alter or remove it. INFOF("ADD OVERLAY NODE sid=%s", alloca_tohex_sid(subscriber->sid)); }