[PATCH 33/43] site.c, magic.h: Formalize the system of message variants.

Mark Wooding mdw at distorted.org.uk
Sun Apr 30 23:37:23 BST 2017

Ian Jackson <ijackson at chiark.greenend.org.uk> writes:

> This leaves us with only 4 bits of subtype.  I wonder if
>  +#define MSGVAR(i)     (((i & 0xf) << 4) ^ ((i & 0xf) << 28) ^ 
>                          ((i & 0xf0) << 24))
> would be better.

Oh, so we go

        0x00000000, 0x10000010, 0x20000020, ... 0xf00000f0,
        0x01000000, 0x00000010, 0x03000020, ... 0xe00000f0, 

That screws the ordering unless we decode.  And I'm depending on the
ordering for building and picking apart the agreed algorithm bytes.  It
also breaks the palindromy nature of the message labels, but I don't
think we can do anything about that sacrificing either base-code or
variant space.

While we're trading suggestions, here's my more advanced one.  Start 

> The trouble with this approach is that it changes the handling of
> unknown message variants, from "reject as unknown message type" to
> "mishandle as if we understood it".

You're right, of course.  A stupid oversight of mine.

> The alternative approach, of simply introducing MSG3TER (or, perhaps,
> MSG3v2), seems simpler.  There are 4 places where _all_ of the MSG3
> variants need to be named: type_is_msg34; check_msg; process_msg3;
> site_incoming's big switch.  These could all be handled with
>   /* use like this: `case LABEL_MSGv3ANY_CASE:' */
>   #define MSG3vANY_CASE   \
>            LABEL_MSG3:    \
>       case LABEL_MSG3v1:  \
>       case LABEL_MSG3v2

I'm not sure I completely follows.  The switch thing works fine for
`type_is_msg34' and `site_incoming'.  I don't think it's necessary for
both `check_msg' and `process_msg3' to have exhaustive lists -- indeed,
if `site_incoming' is made precise again, I don't think /either/ of them
need exhaustive lists.

It doesn't work in `unpick_msg' or `generate_msg', because the decision
we have to make isn't where to start in the code sequence (which
`switch' is fine at), but where to /stop/.

The important part of the change wasn't in the simplification of those
exhaustive lists -- that was just an opportunity I grabbed at without
thinking -- but in the flow of `unpick_msg' and `generate_msg', which
make essential use of the variant ordering.  Rather than just assume
that the message labels are ordered, which I guess I could have done, I
wanted to make the arrangement more formal.

Really, how important is the palindrome thing?  If we don't really care,
then I have the following suggestion (tested against the existing codes
and exhaustively checked for invertability on all 2^16 major and minor

        /* MAJ   MIN
         * abcd wxyz
         * 0d0d 0d0d
         * 000a bc00
         * z000 00z0
         * wxy0 0000

        #define MSGCODE(major, minor) \
                ((((uint32_t)(major)&0x0000000fu) <<  0) ^ \
                 (((uint32_t)(major)&0x0000000fu) <<  8) ^ \
                 (((uint32_t)(major)&0x0000000fu) << 16) ^ \
                 (((uint32_t)(major)&0x0000000fu) << 24) ^ \
                 (((uint32_t)(major)&0x0000fff0u) <<  4) ^ \
                 (((uint32_t)(minor)&0x0000000fu) <<  4) ^ \
                 (((uint32_t)(minor)&0x0000000fu) << 28) ^ \
                 (((uint32_t)(minor)&0x0000fff0u) << 16))

        #define MSGMAJOR(label) \
                ((((uint32_t)(label)&0x0000000fu) <<  0) ^ \
                 (((uint32_t)(label)&0x0000000fu) <<  4) ^ \
                 (((uint32_t)(label)&0x0000000fu) << 12) ^ \
                 (((uint32_t)(label)&0x000fff00u) >>  4))
        #define MSGMINOR(label) \
                ((((uint32_t)(label)&0x000000ffu) <<  8) ^ \
                 (((uint32_t)(label)&0x000000f0u) >>  4) ^ \
                 (((uint32_t)(label)&0xfff00000u) >> 16))

MSGCODE is complicated, but in practice will be used only on constants;
I expect MSGMAJOR to be used only on constants too.  Pleasingly,
MSGMINOR is relatively simple.  This means `MSG0' is actually major code
0x2020, minor code zero, but I don't think that's a major worry.

(I also tried a more number-theoretical encoding, but that didn't work

So: concrete proposal: I'll use this new encoding, define the existing
labels in terms of it, and the v1/v2 variants of MSG3 (I like the Latin,
but `quater' is quite long, and `quinquies' just isn't going to fly).
I'll use switch statements in `site_incoming' and `type_is_msg34'; I
propose to leave `check_msg' do only a major-number check for MSG3, and
do precise checking in `process_msg3' (despite the redundancy).  In
`generate_msg' and `unpick_msg' I'll use the minor number to control the
exit from the chosen-algorithm-number flow.

-- [mdw]

More information about the sgo-software-discuss mailing list