X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=site.c;h=acbc2b62c99b9ed43e48b43a3d473becfdd404c3;hb=31dd07884afd1f1d87d398bf344e1ba3a71e293b;hp=bd633f3a8c249dabf0e6edf832363730d500d27f;hpb=ffafab086c4ca0f8532d3fa7990a44fa71d57136;p=secnet.git diff --git a/site.c b/site.c index bd633f3..acbc2b6 100644 --- a/site.c +++ b/site.c @@ -470,14 +470,15 @@ static bool_t current_valid(struct site *st) } #define DEFINE_CALL_TRANSFORM(fwdrev) \ -static int call_transform_##fwdrev(struct site *st, \ +static transform_apply_return \ +call_transform_##fwdrev(struct site *st, \ struct transform_inst_if *transform, \ struct buffer_if *buf, \ const char **errmsg) \ { \ if (!is_transform_valid(transform)) { \ *errmsg="transform not set up"; \ - return 1; \ + return transform_apply_err; \ } \ return transform->fwdrev(transform->st,buf,errmsg); \ } @@ -1029,8 +1030,9 @@ static void create_msg6(struct site *st, struct transform_inst_if *transform, /* Give the netlink code an opportunity to put its own stuff in the message (configuration information, etc.) */ buf_prepend_uint32(&st->buffer,LABEL_MSG6); - int problem = call_transform_forwards(st,transform, - &st->buffer,&transform_err); + transform_apply_return problem = + call_transform_forwards(st,transform, + &st->buffer,&transform_err); assert(!problem); buf_prepend_uint32(&st->buffer,LABEL_MSG6); buf_prepend_uint32(&st->buffer,st->index); @@ -1070,12 +1072,13 @@ static bool_t process_msg6(struct site *st, struct buffer_if *msg6, return True; } -static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0, +static transform_apply_return +decrypt_msg0(struct site *st, struct buffer_if *msg0, const struct comm_addr *src) { cstring_t transform_err, auxkey_err, newkey_err="n/a"; struct msg0 m; - uint32_t problem; + transform_apply_return problem; if (!unpick_msg0(st,msg0,&m)) return False; @@ -1088,15 +1091,15 @@ static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0, if (!st->auxiliary_is_new) delete_one_key(st,&st->auxiliary_key, "peer has used new key","auxiliary key",LOG_SEC); - return True; + return 0; } - if (problem==2) - goto skew; + if (transform_apply_return_badseq(problem)) + goto badseq; buffer_copy(msg0, &st->scratch); problem = call_transform_reverse(st,st->auxiliary_key.transform, msg0,&auxkey_err); - if (problem==0) { + if (!problem) { slog(st,LOG_DROP,"processing packet which uses auxiliary key"); if (st->auxiliary_is_new) { /* We previously timed out in state SENTMSG5 but it turns @@ -1113,10 +1116,10 @@ static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0, st->auxiliary_is_new=0; st->renegotiate_key_time=st->auxiliary_renegotiate_key_time; } - return True; + return 0; } - if (problem==2) - goto skew; + if (transform_apply_return_badseq(problem)) + goto badseq; if (st->state==SITE_SENTMSG5) { buffer_copy(msg0, &st->scratch); @@ -1129,20 +1132,21 @@ static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0, BUF_FREE(&st->buffer); st->timeout=0; activate_new_key(st); - return True; /* do process the data in this packet */ + return 0; /* do process the data in this packet */ } - if (problem==2) - goto skew; + if (transform_apply_return_badseq(problem)) + goto badseq; } slog(st,LOG_SEC,"transform: %s (aux: %s, new: %s)", transform_err,auxkey_err,newkey_err); initiate_key_setup(st,"incoming message would not decrypt",0); send_nak(src,m.dest,m.source,m.type,msg0,"message would not decrypt"); - return False; + assert(problem); + return problem; - skew: - slog(st,LOG_DROP,"transform: %s (merely skew)",transform_err); + badseq: + slog(st,LOG_DROP,"transform: %s (bad seq.)",transform_err); assert(problem); return problem; } @@ -1151,8 +1155,10 @@ static bool_t process_msg0(struct site *st, struct buffer_if *msg0, const struct comm_addr *src) { uint32_t type; + transform_apply_return problem; - if (!decrypt_msg0(st,msg0,src)) + problem = decrypt_msg0(st,msg0,src); + if (problem) return False; CHECK_AVAIL(msg0,4); @@ -1755,6 +1761,15 @@ static bool_t named_for_us(struct site *st, const struct buffer_if *buf_in, && name_matches(&m->local,st->localname); } +static bool_t we_have_priority(struct site *st, const struct msg *m) { + if ((st->local_capabilities & m->remote_capabilities) + && CAPAB_PRIORITY_MOBILE) { + if (st->local_mobile) return True; + if (st-> peer_mobile) return False; + } + return st->our_name_later; +} + /* This function is called by the communication device to deliver packets from our peers. It should return True if the packet is recognised as being for @@ -1796,7 +1811,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf, /* 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->our_name_later) { + if (we_have_priority(st,&named_msg)) { BUF_FREE(buf); if (!st->msg1_crossed_logged++) slog(st,LOG_SETUP_INIT,"crossed msg1s; we are higher " @@ -2161,6 +2176,9 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context, st->local_capabilities |= capbit; } + if (st->local_mobile || st->peer_mobile) + st->local_capabilities |= CAPAB_PRIORITY_MOBILE; + /* We need to register the remote networks with the netlink device */ uint32_t netlink_mtu; /* local virtual interface mtu */ st->netlink->reg(st->netlink->st, site_outgoing, st, &netlink_mtu);