Setup unicast return address when receiving unicast packet

This commit is contained in:
Jeremy Lakeman 2012-09-06 15:21:31 +09:30
parent adde23dfd0
commit f9287149dd
5 changed files with 40 additions and 8 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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");
}

View File

@ -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");

View File

@ -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));
}