mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-29 15:43:56 +00:00
Only parse incoming packets with port numbers matching our expected responses
This commit is contained in:
parent
8cc5f8152e
commit
9a7c18c9f6
@ -307,10 +307,53 @@ int app_echo(int argc, const char *const *argv, struct command_line_option *o, v
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lookup_send_request(unsigned char *srcsid, int srcport, unsigned char *dstsid, const char *did){
|
||||
int i;
|
||||
overlay_mdp_frame mdp;
|
||||
bzero(&mdp,sizeof(mdp));
|
||||
|
||||
|
||||
/* set source address to a local address, and pick a random port */
|
||||
mdp.out.src.port=srcport;
|
||||
bcopy(srcsid,mdp.out.src.sid,SID_SIZE);
|
||||
|
||||
/* Send to destination address and DNA lookup port */
|
||||
|
||||
if (dstsid){
|
||||
/* Send an encrypted unicast packet */
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
bcopy(dstsid, mdp.out.dst.sid, SID_SIZE);
|
||||
}else{
|
||||
/* Send a broadcast packet, flooding across the local mesh network */
|
||||
mdp.packetTypeAndFlags=MDP_TX|MDP_NOCRYPT;
|
||||
for(i=0;i<SID_SIZE;i++)
|
||||
mdp.out.dst.sid[i]=0xff;
|
||||
}
|
||||
mdp.out.dst.port=MDP_PORT_DNALOOKUP;
|
||||
|
||||
/* put DID into packet */
|
||||
bcopy(did,&mdp.out.payload[0],strlen(did)+1);
|
||||
mdp.out.payload_length=strlen(did)+1;
|
||||
|
||||
overlay_mdp_send(&mdp,0,0);
|
||||
|
||||
/* Also send an encrypted unicast request to a configured directory service */
|
||||
if (!dstsid){
|
||||
const char *directory_service = confValueGet("directory.service", NULL);
|
||||
if (directory_service){
|
||||
if (stowSid(mdp.out.dst.sid, 0, directory_service)==-1){
|
||||
WHYF("Invalid directory server SID %s", directory_service);
|
||||
}else{
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
overlay_mdp_send(&mdp,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int app_dna_lookup(int argc, const char *const *argv, struct command_line_option *o, void *context)
|
||||
{
|
||||
if (debug & DEBUG_VERBOSE) DEBUG_argv("command", argc, argv);
|
||||
int i;
|
||||
|
||||
/* Create the instance directory if it does not yet exist */
|
||||
if (create_serval_instance_dir() == -1)
|
||||
@ -344,8 +387,6 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option
|
||||
|
||||
/* use MDP to send the lookup request to MDP_PORT_DNALOOKUP, and wait for
|
||||
replies. */
|
||||
overlay_mdp_frame mdp;
|
||||
bzero(&mdp,sizeof(mdp));
|
||||
|
||||
/* Now repeatedly send resolution request and collect results until we reach
|
||||
timeout. */
|
||||
@ -357,34 +398,9 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option
|
||||
while (timeout > (now = gettime_ms()))
|
||||
{
|
||||
if ((last_tx+interval)<now)
|
||||
{
|
||||
/* Send a broadcast packet, flooding across the local mesh network */
|
||||
mdp.packetTypeAndFlags=MDP_TX|MDP_NOCRYPT;
|
||||
|
||||
/* set source address to a local address, and pick a random port */
|
||||
mdp.out.src.port=port;
|
||||
bcopy(&srcsid[0],&mdp.out.src.sid[0],SID_SIZE);
|
||||
|
||||
/* Send to broadcast address and DNA lookup port */
|
||||
for(i=0;i<SID_SIZE;i++) mdp.out.dst.sid[i]=0xff;
|
||||
mdp.out.dst.port=MDP_PORT_DNALOOKUP;
|
||||
|
||||
/* put DID into packet */
|
||||
bcopy(did,&mdp.out.payload[0],strlen(did)+1);
|
||||
mdp.out.payload_length=strlen(did)+1;
|
||||
{
|
||||
|
||||
overlay_mdp_send(&mdp,0,0);
|
||||
|
||||
/* Also send an encrypted unicast request to a configured directory service */
|
||||
const char *directory_service = confValueGet("directory.service", NULL);
|
||||
if (directory_service){
|
||||
if (stowSid(mdp.out.dst.sid, 0, directory_service)==-1){
|
||||
WHYF("Invalid directory server SID %s", directory_service);
|
||||
}else{
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
overlay_mdp_send(&mdp,0,0);
|
||||
}
|
||||
}
|
||||
lookup_send_request(srcsid, port, NULL, did);
|
||||
|
||||
last_tx=now;
|
||||
interval+=interval>>1;
|
||||
@ -395,7 +411,7 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option
|
||||
{
|
||||
overlay_mdp_frame rx;
|
||||
int ttl;
|
||||
while (overlay_mdp_recv(&rx,&ttl)==0)
|
||||
if (overlay_mdp_recv(&rx, port, &ttl)==0)
|
||||
{
|
||||
if (rx.packetTypeAndFlags==MDP_ERROR)
|
||||
{
|
||||
@ -784,7 +800,7 @@ int app_mdp_ping(int argc, const char *const *argv, struct command_line_option *
|
||||
|
||||
if (result>0) {
|
||||
int ttl=-1;
|
||||
while (overlay_mdp_recv(&mdp,&ttl)==0) {
|
||||
if (overlay_mdp_recv(&mdp, port, &ttl)==0) {
|
||||
switch(mdp.packetTypeAndFlags&MDP_TYPE_MASK) {
|
||||
case MDP_ERROR:
|
||||
WHYF("mdpping: overlay_mdp_recv: %s (code %d)", mdp.error.message, mdp.error.error);
|
||||
@ -1499,9 +1515,7 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option
|
||||
/* Asked for DID resolution, but did not get it, so do a DNA lookup
|
||||
here. We do this on the client side, so that we don't block the
|
||||
single-threaded server. */
|
||||
overlay_mdp_frame mdp_resolve;
|
||||
overlay_mdp_frame mdp_reply;
|
||||
bzero(&mdp_resolve,sizeof(mdp_resolve));
|
||||
int port=32768+(random()&0xffff);
|
||||
|
||||
unsigned char srcsid[SID_SIZE];
|
||||
@ -1517,15 +1531,8 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option
|
||||
now=gettime_ms();
|
||||
|
||||
if (now >= next_send){
|
||||
mdp_resolve.packetTypeAndFlags=MDP_TX;
|
||||
mdp_resolve.out.src.port=port;
|
||||
bcopy(&srcsid[0],&mdp_resolve.out.src.sid[0],SID_SIZE);
|
||||
bcopy(&mdp.nodeinfo.sid[0],&mdp_resolve.out.dst.sid[0],SID_SIZE);
|
||||
mdp_resolve.out.dst.port=MDP_PORT_DNALOOKUP;
|
||||
/* search for any DID */
|
||||
mdp_resolve.out.payload[0]=0;
|
||||
mdp_resolve.out.payload_length=1;
|
||||
overlay_mdp_send(&mdp_resolve,0,0);
|
||||
/* Send a unicast packet to this node, asking for any did */
|
||||
lookup_send_request(srcsid, port, mdp.nodeinfo.sid, "");
|
||||
next_send+=125;
|
||||
continue;
|
||||
}
|
||||
@ -1535,7 +1542,7 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option
|
||||
continue;
|
||||
|
||||
int ttl=-1;
|
||||
if (overlay_mdp_recv(&mdp_reply,&ttl))
|
||||
if (overlay_mdp_recv(&mdp_reply, port, &ttl))
|
||||
continue;
|
||||
|
||||
if ((mdp_reply.packetTypeAndFlags&MDP_TYPE_MASK)==MDP_ERROR){
|
||||
@ -1572,7 +1579,7 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option
|
||||
WHYF("Received malformed DNA reply: %s",
|
||||
alloca_toprint(160, (const char *)mdp_reply.in.payload, mdp_reply.in.payload_length));
|
||||
} else {
|
||||
/* Got a good DNA reply, copy it into place */
|
||||
/* Got a good DNA reply, copy it into place and stop polling */
|
||||
bcopy(did,mdp.nodeinfo.did,32);
|
||||
bcopy(name,mdp.nodeinfo.name,64);
|
||||
mdp.nodeinfo.resolve_did=1;
|
||||
|
@ -70,7 +70,7 @@ static void add_record(){
|
||||
int ttl;
|
||||
overlay_mdp_frame mdp;
|
||||
|
||||
if (overlay_mdp_recv(&mdp, &ttl))
|
||||
if (overlay_mdp_recv(&mdp, MDP_PORT_DIRECTORY, &ttl))
|
||||
return;
|
||||
|
||||
if (mdp.packetTypeAndFlags&MDP_NOCRYPT){
|
||||
|
48
mdp_client.c
48
mdp_client.c
@ -59,27 +59,30 @@ int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms)
|
||||
}
|
||||
}
|
||||
|
||||
if (overlay_mdp_client_poll(timeout_ms)<=0){
|
||||
/* Timeout */
|
||||
mdp->packetTypeAndFlags=MDP_ERROR;
|
||||
mdp->error.error=1;
|
||||
snprintf(mdp->error.message,128,"Timeout waiting for reply to MDP packet (packet was successfully sent).");
|
||||
return -1; /* WHY("Timeout waiting for server response"); */
|
||||
int port=mdp->out.dst.port;
|
||||
time_ms_t started = gettime_ms();
|
||||
|
||||
while(timeout_ms>=0 && overlay_mdp_client_poll(timeout_ms)>0){
|
||||
int ttl=-1;
|
||||
if (!overlay_mdp_recv(mdp, port, &ttl)) {
|
||||
/* If all is well, examine result and return error code provided */
|
||||
if ((mdp->packetTypeAndFlags&MDP_TYPE_MASK)==MDP_ERROR)
|
||||
return mdp->error.error;
|
||||
else
|
||||
/* Something other than an error has been returned */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// work out how much longer we can wait for a valid response
|
||||
time_ms_t now = gettime_ms();
|
||||
timeout_ms -= (now - started);
|
||||
}
|
||||
|
||||
int ttl=-1;
|
||||
if (!overlay_mdp_recv(mdp,&ttl)) {
|
||||
/* If all is well, examine result and return error code provided */
|
||||
if ((mdp->packetTypeAndFlags&MDP_TYPE_MASK)==MDP_ERROR)
|
||||
return mdp->error.error;
|
||||
else
|
||||
/* Something other than an error has been returned */
|
||||
return 0;
|
||||
} else {
|
||||
/* poll() said that there was data, but there isn't.
|
||||
So we will abort. */
|
||||
return WHY("poll() aborted");
|
||||
}
|
||||
/* Timeout */
|
||||
mdp->packetTypeAndFlags=MDP_ERROR;
|
||||
mdp->error.error=1;
|
||||
snprintf(mdp->error.message,128,"Timeout waiting for reply to MDP packet (packet was successfully sent).");
|
||||
return -1; /* WHY("Timeout waiting for server response"); */
|
||||
}
|
||||
|
||||
char overlay_mdp_client_socket_path[1024];
|
||||
@ -170,7 +173,7 @@ int overlay_mdp_client_poll(time_ms_t timeout_ms)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int overlay_mdp_recv(overlay_mdp_frame *mdp,int *ttl)
|
||||
int overlay_mdp_recv(overlay_mdp_frame *mdp, int port, int *ttl)
|
||||
{
|
||||
char mdp_socket_name[101];
|
||||
unsigned char recvaddrbuffer[1024];
|
||||
@ -204,11 +207,16 @@ int overlay_mdp_recv(overlay_mdp_frame *mdp,int *ttl)
|
||||
return WHY("Reply did not come from server");
|
||||
}
|
||||
|
||||
// silently drop incoming packets for the wrong port number
|
||||
if (port>0 && port != mdp->in.dst.port)
|
||||
return -1;
|
||||
|
||||
int expected_len = overlay_mdp_relevant_bytes(mdp);
|
||||
|
||||
if (len < expected_len){
|
||||
return WHYF("Expected packet length of %d, received only %lld bytes", expected_len, (long long) len);
|
||||
}
|
||||
|
||||
/* Valid packet received */
|
||||
return 0;
|
||||
} else
|
||||
|
@ -26,7 +26,7 @@ extern int mdp_client_socket;
|
||||
int overlay_mdp_client_init();
|
||||
int overlay_mdp_client_done();
|
||||
int overlay_mdp_client_poll(time_ms_t timeout_ms);
|
||||
int overlay_mdp_recv(overlay_mdp_frame *mdp,int *ttl);
|
||||
int overlay_mdp_recv(overlay_mdp_frame *mdp, int port, int *ttl);
|
||||
int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms);
|
||||
int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user