Add stun lookup messages

This commit is contained in:
Jeremy Lakeman 2012-12-07 16:04:40 +10:30
parent 3a4f052470
commit 78aa01ad30
7 changed files with 150 additions and 8 deletions

View File

@ -125,6 +125,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define MAX_SIGNATURES 16
#define MDP_PORT_KEYMAPREQUEST 1
#define MDP_PORT_STUNREQ 4
#define MDP_PORT_STUN 5
#define MDP_PORT_PROBE 6
#define MDP_PORT_ECHO 7
#define MDP_PORT_DNALOOKUP 10

View File

@ -413,6 +413,7 @@ static int find_subscr_buffer(struct decode_context *context, struct overlay_buf
ob_append_bytes(context->please_explain->payload, id, len);
}else{
if (context)
context->previous=*subscriber;
}
return 0;

View File

@ -131,7 +131,16 @@ error:
return -1;
}
overlay_interface * overlay_interface_find(struct in_addr addr){
overlay_interface * overlay_interface_get_default(){
int i;
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_UP && overlay_interfaces[i].default_route)
return &overlay_interfaces[i];
}
return NULL;
}
overlay_interface * overlay_interface_find(struct in_addr addr, int return_default){
int i;
overlay_interface *ret = NULL;
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
@ -143,7 +152,7 @@ overlay_interface * overlay_interface_find(struct in_addr addr){
}
// check if this is a default interface
if (overlay_interfaces[i].default_route)
if (return_default && overlay_interfaces[i].default_route)
ret=&overlay_interfaces[i];
}
@ -186,7 +195,7 @@ overlay_interface_read_any(struct sched_ent *alarm){
struct in_addr src = ((struct sockaddr_in *)&src_addr)->sin_addr;
/* Try to identify the real interface that the packet arrived on */
interface = overlay_interface_find(src);
interface = overlay_interface_find(src, 0);
/* Drop the packet if we don't find a match */
if (!interface){

View File

@ -527,6 +527,8 @@ int overlay_mdp_check_binding(struct subscriber *subscriber, int port, int userG
case MDP_PORT_RHIZOME_RESPONSE:
case MDP_PORT_RHIZOME_REQUEST:
case MDP_PORT_PROBE:
case MDP_PORT_STUNREQ:
case MDP_PORT_STUN:
return 0;
}
}
@ -1017,7 +1019,7 @@ void overlay_mdp_poll(struct sched_ent *alarm)
schedule(&scans[i].alarm);
}
}else{
struct overlay_interface *interface = overlay_interface_find(scan->addr);
struct overlay_interface *interface = overlay_interface_find(scan->addr, 1);
if (!interface){
overlay_mdp_reply_error(alarm->poll.fd,recvaddr_un,recvaddrlen, 1, "Unable to find matching interface");
return;

View File

@ -314,7 +314,7 @@ overlay_mdp_service_probe(overlay_mdp_frame *mdp)
int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay_interface *interface){
if (interface==NULL)
interface = overlay_interface_find(addr.sin_addr);
interface = overlay_interface_find(addr.sin_addr, 1);
if (!interface)
return WHY("I don't know which interface to use");
@ -338,6 +338,8 @@ int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay
frame->payload = ob_new();
frame->send_copies=3;
// TODO call mdp payload encryption / signing without calling overlay_mdp_dispatch...
if ((!peer) || !(peer->reachable&REACHABLE))
my_subscriber->send_full=1;
@ -367,6 +369,128 @@ int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay
return 0;
}
// append the address of a unicast link into a packet buffer
static int overlay_append_unicast_address(struct subscriber *subscriber, struct overlay_buffer *buff)
{
if (!(subscriber->reachable & REACHABLE_UNICAST))
return 0;
if (subscriber->reachable & REACHABLE_ASSUMED)
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);
DEBUGF("Added STUN info for %s", alloca_tohex_sid(subscriber->sid));
return 0;
}
static int overlay_mdp_service_stun_req(overlay_mdp_frame *mdp)
{
DEBUGF("Processing STUN request from %s", alloca_tohex_sid(mdp->out.src.sid));
struct overlay_buffer *payload = ob_static(mdp->out.payload, mdp->out.payload_length);
ob_limitsize(payload, mdp->out.payload_length);
overlay_mdp_frame reply;
bzero(&reply, sizeof(reply));
reply.packetTypeAndFlags=MDP_TX;
bcopy(mdp->out.src.sid, reply.out.dst.sid, SID_SIZE);
bcopy(mdp->out.dst.sid, reply.out.src.sid, SID_SIZE);
reply.out.src.port=MDP_PORT_STUNREQ;
reply.out.dst.port=MDP_PORT_STUN;
struct overlay_buffer *replypayload = ob_static(reply.out.payload, sizeof(reply.out.payload));
ob_checkpoint(replypayload);
while(ob_remaining(payload)>0){
struct subscriber *subscriber=NULL;
if (overlay_address_parse(NULL, payload, &subscriber))
break;
if (!subscriber)
continue;
if (overlay_append_unicast_address(subscriber, replypayload))
break;
}
ob_rewind(replypayload);
reply.out.payload_length=ob_position(replypayload);
if (reply.out.payload_length)
overlay_mdp_dispatch(&reply,0 /* system generated */,
NULL,0);
ob_free(replypayload);
ob_free(payload);
return 0;
}
static int overlay_mdp_service_stun(overlay_mdp_frame *mdp)
{
struct overlay_buffer *buff = ob_static(mdp->out.payload, mdp->out.payload_length);
ob_limitsize(buff, mdp->out.payload_length);
DEBUGF("Processing STUN info from %s", alloca_tohex_sid(mdp->out.src.sid));
while(ob_remaining(buff)>0){
struct subscriber *subscriber=NULL;
struct sockaddr_in addr;
// TODO explain addresses, link expiry time, resolve differences between addresses...
if (overlay_address_parse(NULL, buff, &subscriber)){
break;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = ob_get_ui32(buff);
addr.sin_port = ob_get_ui16(buff);
if (!subscriber || (subscriber->reachable!=REACHABLE_NONE))
continue;
overlay_send_probe(subscriber, addr, NULL);
}
ob_free(buff);
return 0;
}
int overlay_send_stun_request(struct subscriber *server, struct subscriber *request){
if ((!server) || (!request))
return -1;
if (!(subscriber_is_reachable(server)&REACHABLE))
return -1;
// don't bother with a stun request if the peer is already reachable directly
// TODO link timeouts
if (subscriber_is_reachable(request)&REACHABLE_DIRECT)
return -1;
overlay_mdp_frame mdp;
bzero(&mdp, sizeof(mdp));
mdp.packetTypeAndFlags=MDP_TX;
bcopy(my_subscriber->sid, mdp.out.src.sid, SID_SIZE);
bcopy(server->sid, mdp.out.dst.sid, SID_SIZE);
mdp.out.src.port=MDP_PORT_STUN;
mdp.out.dst.port=MDP_PORT_STUNREQ;
struct overlay_buffer *payload = ob_static(mdp.out.payload, sizeof(mdp.out.payload));
overlay_address_append(NULL, payload, request);
mdp.out.payload_length=ob_position(payload);
DEBUGF("Sending STUN request to %s", alloca_tohex_sid(server->sid));
overlay_mdp_dispatch(&mdp,0 /* system generated */,
NULL,0);
ob_free(payload);
return 0;
}
int overlay_mdp_try_interal_services(overlay_mdp_frame *mdp)
{
IN();
@ -376,6 +500,8 @@ int overlay_mdp_try_interal_services(overlay_mdp_frame *mdp)
case MDP_PORT_DNALOOKUP: RETURN(overlay_mdp_service_dnalookup(mdp));
case MDP_PORT_ECHO: RETURN(overlay_mdp_service_echo(mdp));
case MDP_PORT_PROBE: RETURN(overlay_mdp_service_probe(mdp));
case MDP_PORT_STUNREQ: RETURN(overlay_mdp_service_stun_req(mdp));
case MDP_PORT_STUN: RETURN(overlay_mdp_service_stun(mdp));
case MDP_PORT_RHIZOME_REQUEST:
if (is_rhizome_mdp_server_running()) {
RETURN(overlay_mdp_service_rhizomerequest(mdp));

View File

@ -144,7 +144,7 @@ static void parse_frame(struct overlay_buffer *buff){
goto end;
// locate the interface we should send outgoing unicast packets to
overlay_interface *interface = overlay_interface_find(*addr);
overlay_interface *interface = overlay_interface_find(*addr, 1);
if (interface){
// always update the IP address we heard them from, even if we don't need to use it right now
context.sender->address.sin_family = AF_INET;

View File

@ -615,7 +615,8 @@ int overlay_route_node_info(overlay_mdp_nodeinfo *node_info);
int overlay_interface_register(char *name,
struct in_addr addr,
struct in_addr mask);
overlay_interface * overlay_interface_find(struct in_addr addr);
overlay_interface * overlay_interface_get_default();
overlay_interface * overlay_interface_find(struct in_addr addr, int return_default);
overlay_interface * overlay_interface_find_name(const char *name);
int overlay_broadcast_ensemble(int interface_number,
struct sockaddr_in *recipientaddr,
@ -712,6 +713,7 @@ void server_shutdown_check(struct sched_ent *alarm);
void overlay_mdp_poll(struct sched_ent *alarm);
int overlay_mdp_try_interal_services(overlay_mdp_frame *mdp);
int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay_interface *interface);
int overlay_send_stun_request(struct subscriber *server, struct subscriber *request);
void fd_periodicstats(struct sched_ent *alarm);
void rhizome_check_connections(struct sched_ent *alarm);