Only parse incoming packets with port numbers matching our expected responses

This commit is contained in:
Jeremy Lakeman 2012-10-02 16:13:12 +09:30
parent 8cc5f8152e
commit 9a7c18c9f6
4 changed files with 82 additions and 67 deletions

View File

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

View File

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

View File

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

View File

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