[PATCH 5/5] site: interpret first two bytes of extrainfo as capabilities

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

Define the first two bytes of the additional data (after the nul in
site names in MSG2..4) in the sender's name field to be a capability
bitmask.  Currently no capability flags are defined.

To support this, replace extrainfo and its _len in struct parsedname
with a struct buffer_if.  We invent a new kind of buffer_if which is a
readonly view of another buffer; such a view can be initialised with
buffer_view_readonly.  This makes it convenient to parse the
extrainfo using our existing macros etc.

Signed-off-by: Ian Jackson <ijackson at chiark.greenend.org.uk>
 NOTES  |   11 +++++++++--
 site.c |   15 +++++++++------
 util.c |   11 +++++++++++
 util.h |    5 +++++
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/NOTES b/NOTES
index 5adea50..777ba7e 100644
--- a/NOTES
+++ b/NOTES
@@ -176,7 +176,7 @@ Definitions:
 A is the originating gateway machine name
 B is the destination gateway machine name
-A+ and B+ are the names with optional additional data, currently ignored
+A+ and B+ are the names with optional additional data, see below
 PK_A is the public RSA key of A
 PK_B is the public RSA key of B
 PK_A^-1 is the private RSA key of A
@@ -194,7 +194,14 @@ i? is appropriate index for receiver
 Note that 'i' may be re-used from one session to the next, whereas 'n'
 is always fresh.
-The protocol version selection stuff is not yet implemented.
+The optional additional data after the sender's name consists of some
+initial subset of the following list of items:
+ * A 16-bit integer with a set of capability flags, representing the
+   abilities of the sender.  No such flags are currently defined.
+The optional additional data after the receiver's name is not
+currently used.
diff --git a/site.c b/site.c
index 261052a..0264f23 100644
--- a/site.c
+++ b/site.c
@@ -349,8 +349,7 @@ static bool_t current_valid(struct site *st)
 struct parsedname {
     int32_t len;
     uint8_t *name;
-    int32_t extrainfo_len;
-    uint8_t *extrainfo;
+    struct buffer_if extrainfo;
 struct msg {
@@ -359,6 +358,7 @@ struct msg {
     uint32_t source;
     struct parsedname remote;
     struct parsedname local;
+    uint16_t remote_capabilities;
     uint8_t *nR;
     uint8_t *nL;
     int32_t pklen;
@@ -408,17 +408,16 @@ static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what)
 static bool_t unpick_name(struct buffer_if *msg, struct parsedname *nm)
+    struct buffer_if extrainfo;
     uint8_t *nul=memchr(nm->name,0,nm->len);
     if (!nul) {
-	nm->extrainfo_len=0;
-	nm->extrainfo=0;
+	buffer_readonly_view(&extrainfo,0,0);
     } else {
-	nm->extrainfo=nul+1;
-	nm->extrainfo_len=msg->start-nm->extrainfo;
+	buffer_readonly_view(&extrainfo, nul+1, msg->start-(nul+1));
     return True;
@@ -434,6 +433,10 @@ static bool_t unpick_msg(struct site *st, uint32_t type,
     if (!unpick_name(msg,&m->remote)) return False;
+    if (m->remote.extrainfo.len) {
+	CHECK_AVAIL(&m->remote.extrainfo,2);
+	m->remote_capabilities=buf_unprepend_uint16(&m->remote.extrainfo);
+    }
     if (!unpick_name(msg,&m->local)) return False;
diff --git a/util.c b/util.c
index e50218c..d47b944 100644
--- a/util.c
+++ b/util.c
@@ -301,6 +301,17 @@ void buffer_new(struct buffer_if *buf, int32_t len)
+void buffer_readonly_view(struct buffer_if *buf, const void *data, int32_t len)
+    buf->free=False;
+    buf->owner="READONLY";
+    buf->flags=0;
+    buf->loc.file=NULL;
+    buf->loc.line=0;
+    buf->size=buf->len=len;
+    buf->base=buf->start=(uint8_t*)data;
 void buffer_copy(struct buffer_if *dst, const struct buffer_if *src)
     if (dst->len < src->len) {
diff --git a/util.h b/util.h
index 2491fd5..451d749 100644
--- a/util.h
+++ b/util.h
@@ -29,6 +29,11 @@ extern void *buf_prepend(struct buffer_if *buf, int32_t amount);
 extern void *buf_unappend(struct buffer_if *buf, int32_t amount);
 extern void *buf_unprepend(struct buffer_if *buf, int32_t amount);
+extern void buffer_readonly_view(struct buffer_if*, const void*, int32_t len);
+  /* Caller must only use unappend, unprepend et al.
+   * buffer state before this can be undefined.  After use,
+   * it must NOT be freed. */
 extern void buf_append_string(struct buffer_if *buf, cstring_t s);
 extern void read_mpbin(MP_INT *a, uint8_t *bin, int binsize);

More information about the sgo-software-discuss mailing list