[PATCH 5/6] site: Clearer processing for name-addressed packets

Ian Jackson ijackson at chiark.greenend.org.uk
Wed Jul 17 14:07:52 BST 2013


We are going to introduce a new packet which (like MSG1) is addressed
by name rather than the site id.  To make this easier:
 * Change st->setupsig and st->setupsiglen to st->namesig and
   st->namesiglen, which contain only the portion of the packet with
   the local and remote site names, and no longer the type.
 * Break out a function named_for_us which does the length check
   and name addressing comparison.
 * Make site_incoming extract the message type earlier, and use
   the message type to choose how to check the address.
 * Eliminate checking dest==0 for name-addressed packets.

This last point constitutes a change to the implemented protocol.  The
old code would treat a packet as name-addressed iff the destination
"index" was zero.  However, the requirement to send a zero in this
field is not documented.  After this patch, peers which send MSG1 with
a non-zero destination index will have their messages honoured rather
than discarded.  But we do document the restriction.

There is no other significant functional change: peers which send
non-MSG1s with zero destination index will have their packets rejected
both before and afterwards (although there may be a change in whether
a NAK is sent and in logging) but anyway those peers are broken
because all of our generated indexes are nonzero.

Signed-off-by: Ian Jackson <ijackson at chiark.greenend.org.uk>
---
 NOTES  |    3 ++
 site.c |  107 +++++++++++++++++++++++++++++++++------------------------------
 2 files changed, 59 insertions(+), 51 deletions(-)

diff --git a/NOTES b/NOTES
index 09c083e..477104f 100644
--- a/NOTES
+++ b/NOTES
@@ -202,6 +202,9 @@ Messages:
 
 1) A->B: *,iA,msg1,A,B,protorange-A,nA
 
+i* must be encoded as 0.  (However, it is permitted for a site to use
+zero as its "index" for another site.)
+
 2) B->A: iA,iB,msg2,B,A,chosen-protocol,nB,nA
 
 (The order of B and A reverses in alternate messages so that the same
diff --git a/site.c b/site.c
index 5c73533..aecd64d 100644
--- a/site.c
+++ b/site.c
@@ -253,9 +253,9 @@ struct site {
 				      after this time, initiate a new
 				      key exchange */
 
-    uint8_t *setupsig; /* Expected signature of incoming MSG1 packets */
-    int32_t setupsiglen; /* Allows us to discard packets quickly if
-			    they are not for us */
+    uint8_t *namedsig; /* Names section of MSG1 packets */
+    int32_t namedsiglen; /* Allows us to discard name-addressed packets
+			    quickly if they are not for us */
     bool_t setup_priority; /* Do we have precedence if both sites emit
 			      message 1 simultaneously? */
     uint32_t log_events;
@@ -1220,6 +1220,18 @@ static void site_outgoing(void *sst, struct buffer_if *buf)
     initiate_key_setup(st,"outgoing packet");
 }
 
+static bool_t named_for_us(struct site *st, struct buffer_if *buf,
+			   int extralen)
+    /* For packets which are identified by the local and remote names.
+     * If it has our name and our peer's name in it it's for us. */
+{
+    if (buf->size<(st->namedsiglen+12+extralen))
+	return False;
+    if (memcmp(buf->start+12,st->namedsig,st->namedsiglen))
+	return False;
+    return True;
+}
+
 /* This function is called by the communication device to deliver
    packets from our peers. */
 static bool_t site_incoming(void *sst, struct buffer_if *buf,
@@ -1230,60 +1242,54 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
 
     if (buf->size < 12) return False;
 
+    uint32_t msgtype=ntohl(get_uint32(buf->start+8));
     uint32_t dest=ntohl(*(uint32_t *)buf->start);
 
-    if (dest==0) {
-	/* It could be for any site - it should have LABEL_MSG1 and
-	   might have our name and our peer's name in it */
-	if (buf->size<(st->setupsiglen+8+NONCELEN)) return False;
-	if (memcmp(buf->start+8,st->setupsig,st->setupsiglen)==0) {
-	    /* It's addressed to us. Decide what to do about it. */
-	    dump_packet(st,buf,source,True);
-	    if (st->state==SITE_RUN || st->state==SITE_RESOLVE ||
-		st->state==SITE_WAIT) {
-		/* We should definitely process it */
+    if (msgtype==LABEL_MSG1 && named_for_us(st,buf,NONCELEN)) {
+	/* It's a MSG1 addressed to us. Decide what to do about it. */
+	dump_packet(st,buf,source,True);
+	if (st->state==SITE_RUN || st->state==SITE_RESOLVE ||
+	    st->state==SITE_WAIT) {
+	    /* We should definitely process it */
+	    if (process_msg1(st,buf,source)) {
+		slog(st,LOG_SETUP_INIT,"key setup initiated by peer");
+		enter_new_state(st,SITE_SENTMSG2);
+	    } else {
+		slog(st,LOG_ERROR,"failed to process incoming msg1");
+	    }
+	    BUF_FREE(buf);
+	    return True;
+	} else if (st->state==SITE_SENTMSG1) {
+	    /* We've just sent a message 1! They may have crossed on
+	       the wire. If we have priority then we ignore the
+	       incoming one, otherwise we process it as usual. */
+	    if (st->setup_priority) {
+		BUF_FREE(buf);
+		slog(st,LOG_DUMP,"crossed msg1s; we are higher "
+		     "priority => ignore incoming msg1");
+		return True;
+	    } else {
+		slog(st,LOG_DUMP,"crossed msg1s; we are lower "
+		     "priority => use incoming msg1");
 		if (process_msg1(st,buf,source)) {
-		    slog(st,LOG_SETUP_INIT,"key setup initiated by peer");
+		    BUF_FREE(&st->buffer); /* Free our old message 1 */
 		    enter_new_state(st,SITE_SENTMSG2);
 		} else {
-		    slog(st,LOG_ERROR,"failed to process incoming msg1");
+		    slog(st,LOG_ERROR,"failed to process an incoming "
+			 "crossed msg1 (we have low priority)");
 		}
 		BUF_FREE(buf);
 		return True;
-	    } else if (st->state==SITE_SENTMSG1) {
-		/* We've just sent a message 1! They may have crossed on
-		   the wire. If we have priority then we ignore the
-		   incoming one, otherwise we process it as usual. */
-		if (st->setup_priority) {
-		    BUF_FREE(buf);
-		    slog(st,LOG_DUMP,"crossed msg1s; we are higher "
-			 "priority => ignore incoming msg1");
-		    return True;
-		} else {
-		    slog(st,LOG_DUMP,"crossed msg1s; we are lower "
-			 "priority => use incoming msg1");
-		    if (process_msg1(st,buf,source)) {
-			BUF_FREE(&st->buffer); /* Free our old message 1 */
-			enter_new_state(st,SITE_SENTMSG2);
-		    } else {
-			slog(st,LOG_ERROR,"failed to process an incoming "
-			     "crossed msg1 (we have low priority)");
-		    }
-		    BUF_FREE(buf);
-		    return True;
-		}
 	    }
-	    /* The message 1 was received at an unexpected stage of the
-	       key setup. XXX POLICY - what do we do? */
-	    slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
-	    BUF_FREE(buf);
-	    return True;
 	}
-	return False; /* Not for us. */
+	/* The message 1 was received at an unexpected stage of the
+	   key setup. XXX POLICY - what do we do? */
+	slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
+	BUF_FREE(buf);
+	return True;
     }
     if (dest==st->index) {
 	/* Explicitly addressed to us */
-	uint32_t msgtype=ntohl(get_uint32(buf->start+8));
 	if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
 	switch (msgtype) {
 	case LABEL_NAK:
@@ -1532,13 +1538,12 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     /* The information we expect to see in incoming messages of type 1 */
     /* fixme: lots of unchecked overflows here, but the results are only
        corrupted packets rather than undefined behaviour */
-    st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
-    st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
-    put_uint32(st->setupsig+0,LABEL_MSG1);
-    put_uint16(st->setupsig+4,strlen(st->remotename));
-    memcpy(&st->setupsig[6],st->remotename,strlen(st->remotename));
-    put_uint16(st->setupsig+(6+strlen(st->remotename)),strlen(st->localname));
-    memcpy(&st->setupsig[8+strlen(st->remotename)],st->localname,
+    st->namedsiglen=strlen(st->remotename)+strlen(st->localname)+4;
+    st->namedsig=safe_malloc(st->namedsiglen,"site_apply");
+    put_uint16(st->namedsig+0,strlen(st->remotename));
+    memcpy(&st->namedsig[2],st->remotename,strlen(st->remotename));
+    put_uint16(st->namedsig+(2+strlen(st->remotename)),strlen(st->localname));
+    memcpy(&st->namedsig[4+strlen(st->remotename)],st->localname,
 	   strlen(st->localname));
     st->setup_priority=(strcmp(st->localname,st->remotename)>0);
 
-- 
1.7.2.5




More information about the sgo-software-discuss mailing list