mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 10:46:23 +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 MAX_SIGNATURES 16
|
||||||
|
|
||||||
#define MDP_PORT_KEYMAPREQUEST 1
|
#define MDP_PORT_KEYMAPREQUEST 1
|
||||||
|
#define MDP_PORT_STUNREQ 4
|
||||||
|
#define MDP_PORT_STUN 5
|
||||||
#define MDP_PORT_PROBE 6
|
#define MDP_PORT_PROBE 6
|
||||||
#define MDP_PORT_ECHO 7
|
#define MDP_PORT_ECHO 7
|
||||||
#define MDP_PORT_DNALOOKUP 10
|
#define MDP_PORT_DNALOOKUP 10
|
||||||
|
@ -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);
|
ob_append_bytes(context->please_explain->payload, id, len);
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
if (context)
|
||||||
context->previous=*subscriber;
|
context->previous=*subscriber;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -131,7 +131,16 @@ error:
|
|||||||
return -1;
|
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;
|
int i;
|
||||||
overlay_interface *ret = NULL;
|
overlay_interface *ret = NULL;
|
||||||
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
|
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
|
// 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];
|
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;
|
struct in_addr src = ((struct sockaddr_in *)&src_addr)->sin_addr;
|
||||||
|
|
||||||
/* Try to identify the real interface that the packet arrived on */
|
/* 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 */
|
/* Drop the packet if we don't find a match */
|
||||||
if (!interface){
|
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_RESPONSE:
|
||||||
case MDP_PORT_RHIZOME_REQUEST:
|
case MDP_PORT_RHIZOME_REQUEST:
|
||||||
case MDP_PORT_PROBE:
|
case MDP_PORT_PROBE:
|
||||||
|
case MDP_PORT_STUNREQ:
|
||||||
|
case MDP_PORT_STUN:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1017,7 +1019,7 @@ void overlay_mdp_poll(struct sched_ent *alarm)
|
|||||||
schedule(&scans[i].alarm);
|
schedule(&scans[i].alarm);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
struct overlay_interface *interface = overlay_interface_find(scan->addr);
|
struct overlay_interface *interface = overlay_interface_find(scan->addr, 1);
|
||||||
if (!interface){
|
if (!interface){
|
||||||
overlay_mdp_reply_error(alarm->poll.fd,recvaddr_un,recvaddrlen, 1, "Unable to find matching interface");
|
overlay_mdp_reply_error(alarm->poll.fd,recvaddr_un,recvaddrlen, 1, "Unable to find matching interface");
|
||||||
return;
|
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){
|
int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay_interface *interface){
|
||||||
if (interface==NULL)
|
if (interface==NULL)
|
||||||
interface = overlay_interface_find(addr.sin_addr);
|
interface = overlay_interface_find(addr.sin_addr, 1);
|
||||||
|
|
||||||
if (!interface)
|
if (!interface)
|
||||||
return WHY("I don't know which interface to use");
|
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->payload = ob_new();
|
||||||
frame->send_copies=3;
|
frame->send_copies=3;
|
||||||
|
|
||||||
|
// TODO call mdp payload encryption / signing without calling overlay_mdp_dispatch...
|
||||||
|
|
||||||
if ((!peer) || !(peer->reachable&REACHABLE))
|
if ((!peer) || !(peer->reachable&REACHABLE))
|
||||||
my_subscriber->send_full=1;
|
my_subscriber->send_full=1;
|
||||||
|
|
||||||
@ -367,6 +369,128 @@ int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay
|
|||||||
return 0;
|
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)
|
int overlay_mdp_try_interal_services(overlay_mdp_frame *mdp)
|
||||||
{
|
{
|
||||||
IN();
|
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_DNALOOKUP: RETURN(overlay_mdp_service_dnalookup(mdp));
|
||||||
case MDP_PORT_ECHO: RETURN(overlay_mdp_service_echo(mdp));
|
case MDP_PORT_ECHO: RETURN(overlay_mdp_service_echo(mdp));
|
||||||
case MDP_PORT_PROBE: RETURN(overlay_mdp_service_probe(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:
|
case MDP_PORT_RHIZOME_REQUEST:
|
||||||
if (is_rhizome_mdp_server_running()) {
|
if (is_rhizome_mdp_server_running()) {
|
||||||
RETURN(overlay_mdp_service_rhizomerequest(mdp));
|
RETURN(overlay_mdp_service_rhizomerequest(mdp));
|
||||||
|
@ -144,7 +144,7 @@ static void parse_frame(struct overlay_buffer *buff){
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
// locate the interface we should send outgoing unicast packets to
|
// 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){
|
if (interface){
|
||||||
// always update the IP address we heard them from, even if we don't need to use it right now
|
// 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;
|
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,
|
int overlay_interface_register(char *name,
|
||||||
struct in_addr addr,
|
struct in_addr addr,
|
||||||
struct in_addr mask);
|
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);
|
overlay_interface * overlay_interface_find_name(const char *name);
|
||||||
int overlay_broadcast_ensemble(int interface_number,
|
int overlay_broadcast_ensemble(int interface_number,
|
||||||
struct sockaddr_in *recipientaddr,
|
struct sockaddr_in *recipientaddr,
|
||||||
@ -712,6 +713,7 @@ void server_shutdown_check(struct sched_ent *alarm);
|
|||||||
void overlay_mdp_poll(struct sched_ent *alarm);
|
void overlay_mdp_poll(struct sched_ent *alarm);
|
||||||
int overlay_mdp_try_interal_services(overlay_mdp_frame *mdp);
|
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_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 fd_periodicstats(struct sched_ent *alarm);
|
||||||
void rhizome_check_connections(struct sched_ent *alarm);
|
void rhizome_check_connections(struct sched_ent *alarm);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user