mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Add stun lookup messages
This commit is contained in:
parent
3a4f052470
commit
78aa01ad30
@ -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
|
||||
|
@ -413,7 +413,8 @@ static int find_subscr_buffer(struct decode_context *context, struct overlay_buf
|
||||
ob_append_bytes(context->please_explain->payload, id, len);
|
||||
|
||||
}else{
|
||||
context->previous=*subscriber;
|
||||
if (context)
|
||||
context->previous=*subscriber;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
4
serval.h
4
serval.h
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user