site: support multiple transforms
[secnet] / site.c
1 /* site.c - manage communication with a remote network site */
2
3 /* The 'site' code doesn't know anything about the structure of the
4 packets it's transmitting. In fact, under the new netlink
5 configuration scheme it doesn't need to know anything at all about
6 IP addresses, except how to contact its peer. This means it could
7 potentially be used to tunnel other protocols too (IPv6, IPX, plain
8 old Ethernet frames) if appropriate netlink code can be written
9 (and that ought not to be too hard, eg. using the TUN/TAP device to
10 pretend to be an Ethernet interface). */
11
12 /* At some point in the future the netlink code will be asked for
13 configuration information to go in the PING/PONG packets at the end
14 of the key exchange. */
15
16 #include "secnet.h"
17 #include <stdio.h>
18 #include <string.h>
19 #include <limits.h>
20 #include <assert.h>
21 #include <sys/socket.h>
22
23 #include <sys/mman.h>
24 #include "util.h"
25 #include "unaligned.h"
26 #include "magic.h"
27
28 #define SETUP_BUFFER_LEN 2048
29
30 #define DEFAULT_KEY_LIFETIME (3600*1000) /* [ms] */
31 #define DEFAULT_KEY_RENEGOTIATE_GAP (5*60*1000) /* [ms] */
32 #define DEFAULT_SETUP_RETRIES 5
33 #define DEFAULT_SETUP_RETRY_INTERVAL (2*1000) /* [ms] */
34 #define DEFAULT_WAIT_TIME (20*1000) /* [ms] */
35
36 #define DEFAULT_MOBILE_KEY_LIFETIME (2*24*3600*1000) /* [ms] */
37 #define DEFAULT_MOBILE_KEY_RENEGOTIATE_GAP (12*3600*1000) /* [ms] */
38 #define DEFAULT_MOBILE_SETUP_RETRIES 30
39 #define DEFAULT_MOBILE_SETUP_RETRY_INTERVAL (1*1000) /* [ms] */
40 #define DEFAULT_MOBILE_WAIT_TIME (10*1000) /* [ms] */
41
42 #define DEFAULT_MOBILE_PEER_EXPIRY (2*60) /* [s] */
43 #define DEFAULT_MOBILE_PEERS_MAX 3 /* send at most this many copies (default) */
44
45 /* Each site can be in one of several possible states. */
46
47 /* States:
48 SITE_STOP - nothing is allowed to happen; tunnel is down;
49 all session keys have been erased
50 -> SITE_RUN upon external instruction
51 SITE_RUN - site up, maybe with valid key
52 -> SITE_RESOLVE upon outgoing packet and no valid key
53 we start name resolution for the other end of the tunnel
54 -> SITE_SENTMSG2 upon valid incoming message 1 and suitable time
55 we send an appropriate message 2
56 SITE_RESOLVE - waiting for name resolution
57 -> SITE_SENTMSG1 upon successful resolution
58 we send an appropriate message 1
59 -> SITE_SENTMSG2 upon valid incoming message 1 (then abort resolution)
60 we abort resolution and
61 -> SITE_WAIT on timeout or resolution failure
62 SITE_SENTMSG1
63 -> SITE_SENTMSG2 upon valid incoming message 1 from higher priority end
64 -> SITE_SENTMSG3 upon valid incoming message 2
65 -> SITE_WAIT on timeout
66 SITE_SENTMSG2
67 -> SITE_SENTMSG4 upon valid incoming message 3
68 -> SITE_WAIT on timeout
69 SITE_SENTMSG3
70 -> SITE_SENTMSG5 upon valid incoming message 4
71 -> SITE_WAIT on timeout
72 SITE_SENTMSG4
73 -> SITE_RUN upon valid incoming message 5
74 -> SITE_WAIT on timeout
75 SITE_SENTMSG5
76 -> SITE_RUN upon valid incoming message 6
77 -> SITE_WAIT on timeout
78 SITE_WAIT - failed to establish key; do nothing for a while
79 -> SITE_RUN on timeout
80 */
81
82 #define SITE_STOP 0
83 #define SITE_RUN 1
84 #define SITE_RESOLVE 2
85 #define SITE_SENTMSG1 3
86 #define SITE_SENTMSG2 4
87 #define SITE_SENTMSG3 5
88 #define SITE_SENTMSG4 6
89 #define SITE_SENTMSG5 7
90 #define SITE_WAIT 8
91
92 static cstring_t state_name(uint32_t state)
93 {
94 switch (state) {
95 case 0: return "STOP";
96 case 1: return "RUN";
97 case 2: return "RESOLVE";
98 case 3: return "SENTMSG1";
99 case 4: return "SENTMSG2";
100 case 5: return "SENTMSG3";
101 case 6: return "SENTMSG4";
102 case 7: return "SENTMSG5";
103 case 8: return "WAIT";
104 default: return "*bad state*";
105 }
106 }
107
108 #define NONCELEN 8
109
110 #define LOG_UNEXPECTED 0x00000001
111 #define LOG_SETUP_INIT 0x00000002
112 #define LOG_SETUP_TIMEOUT 0x00000004
113 #define LOG_ACTIVATE_KEY 0x00000008
114 #define LOG_TIMEOUT_KEY 0x00000010
115 #define LOG_SEC 0x00000020
116 #define LOG_STATE 0x00000040
117 #define LOG_DROP 0x00000080
118 #define LOG_DUMP 0x00000100
119 #define LOG_ERROR 0x00000400
120 #define LOG_PEER_ADDRS 0x00000800
121
122 static struct flagstr log_event_table[]={
123 { "unexpected", LOG_UNEXPECTED },
124 { "setup-init", LOG_SETUP_INIT },
125 { "setup-timeout", LOG_SETUP_TIMEOUT },
126 { "activate-key", LOG_ACTIVATE_KEY },
127 { "timeout-key", LOG_TIMEOUT_KEY },
128 { "security", LOG_SEC },
129 { "state-change", LOG_STATE },
130 { "packet-drop", LOG_DROP },
131 { "dump-packets", LOG_DUMP },
132 { "errors", LOG_ERROR },
133 { "peer-addrs", LOG_PEER_ADDRS },
134 { "default", LOG_SETUP_INIT|LOG_SETUP_TIMEOUT|
135 LOG_ACTIVATE_KEY|LOG_TIMEOUT_KEY|LOG_SEC|LOG_ERROR },
136 { "all", 0xffffffff },
137 { NULL, 0 }
138 };
139
140
141 /***** TRANSPORT PEERS declarations *****/
142
143 /* Details of "mobile peer" semantics:
144
145 - We record mobile_peers_max peer address/port numbers ("peers")
146 for key setup, and separately mobile_peers_max for data
147 transfer. If these lists fill up, we retain the newest peers.
148 (For non-mobile peers we only record one of each.)
149
150 - Outgoing packets are sent to every recorded peer in the
151 applicable list.
152
153 - Data transfer peers are straightforward: whenever we successfully
154 process a data packet, we record the peer. Also, whenever we
155 successfully complete a key setup, we merge the key setup
156 peers into the data transfer peers.
157
158 (For "non-mobile" peers we simply copy the peer used for
159 successful key setup, and don't change the peer otherwise.)
160
161 - Key setup peers are slightly more complicated.
162
163 Whenever we receive and successfully process a key exchange
164 packet, we record the peer.
165
166 Whenever we try to initiate a key setup, we copy the list of data
167 transfer peers and use it for key setup. But we also look to see
168 if the config supplies an address and port number and if so we
169 add that as a key setup peer (possibly evicting one of the data
170 transfer peers we just copied).
171
172 (For "non-mobile" peers, if we if we have a configured peer
173 address and port, we always use that; otherwise if we have a
174 current data peer address we use that; otherwise we do not
175 attempt to initiate a key setup for lack of a peer address.)
176
177 "Record the peer" means
178 1. expire any peers last seen >120s ("mobile-peer-expiry") ago
179 2. add the peer of the just received packet to the applicable list
180 (possibly evicting older entries)
181 NB that we do not expire peers until an incoming packet arrives.
182
183 */
184
185 #define MAX_MOBILE_PEERS_MAX 5 /* send at most this many copies, compiled max */
186
187 typedef struct {
188 struct timeval last;
189 struct comm_addr addr;
190 } transport_peer;
191
192 typedef struct {
193 /* configuration information */
194 /* runtime information */
195 int npeers;
196 transport_peer peers[MAX_MOBILE_PEERS_MAX];
197 } transport_peers;
198
199 static void transport_peers_clear(struct site *st, transport_peers *peers);
200 static int transport_peers_valid(transport_peers *peers);
201 static void transport_peers_copy(struct site *st, transport_peers *dst,
202 const transport_peers *src);
203
204 static void transport_setup_msgok(struct site *st, const struct comm_addr *a);
205 static void transport_data_msgok(struct site *st, const struct comm_addr *a);
206 static bool_t transport_compute_setupinit_peers(struct site *st,
207 const struct comm_addr *configured_addr /* 0 if none or not found */);
208 static void transport_record_peer(struct site *st, transport_peers *peers,
209 const struct comm_addr *addr, const char *m);
210
211 static void transport_xmit(struct site *st, transport_peers *peers,
212 struct buffer_if *buf, bool_t candebug);
213
214 /***** END of transport peers declarations *****/
215
216
217 struct data_key {
218 struct transform_inst_if *transform;
219 uint64_t key_timeout; /* End of life of current key */
220 uint32_t remote_session_id;
221 };
222
223 struct site {
224 closure_t cl;
225 struct site_if ops;
226 /* configuration information */
227 string_t localname;
228 string_t remotename;
229 bool_t peer_mobile; /* Mobile client support */
230 int32_t transport_peers_max;
231 string_t tunname; /* localname<->remotename by default, used in logs */
232 string_t address; /* DNS name for bootstrapping, optional */
233 int remoteport; /* Port for bootstrapping, optional */
234 struct netlink_if *netlink;
235 struct comm_if **comms;
236 int ncomms;
237 struct resolver_if *resolver;
238 struct log_if *log;
239 struct random_if *random;
240 struct rsaprivkey_if *privkey;
241 struct rsapubkey_if *pubkey;
242 struct transform_if **transforms;
243 int ntransforms;
244 struct dh_if *dh;
245 struct hash_if *hash;
246
247 uint32_t index; /* Index of this site */
248 uint32_t local_capabilities;
249 int32_t setup_retries; /* How many times to send setup packets */
250 int32_t setup_retry_interval; /* Initial timeout for setup packets */
251 int32_t wait_timeout; /* How long to wait if setup unsuccessful */
252 int32_t mobile_peer_expiry; /* How long to remember 2ary addresses */
253 int32_t key_lifetime; /* How long a key lasts once set up */
254 int32_t key_renegotiate_time; /* If we see traffic (or a keepalive)
255 after this time, initiate a new
256 key exchange */
257
258 bool_t setup_priority; /* Do we have precedence if both sites emit
259 message 1 simultaneously? */
260 uint32_t log_events;
261
262 /* runtime information */
263 uint32_t state;
264 uint64_t now; /* Most recently seen time */
265
266 /* The currently established session */
267 struct data_key current;
268 struct data_key auxiliary_key;
269 bool_t auxiliary_is_new;
270 uint64_t renegotiate_key_time; /* When we can negotiate a new key */
271 uint64_t auxiliary_renegotiate_key_time;
272 transport_peers peers; /* Current address(es) of peer for data traffic */
273
274 /* The current key setup protocol exchange. We can only be
275 involved in one of these at a time. There's a potential for
276 denial of service here (the attacker keeps sending a setup
277 packet; we keep trying to continue the exchange, and have to
278 timeout before we can listen for another setup packet); perhaps
279 we should keep a list of 'bad' sources for setup packets. */
280 uint32_t remote_capabilities;
281 struct transform_if *chosen_transform;
282 uint32_t setup_session_id;
283 transport_peers setup_peers;
284 uint8_t localN[NONCELEN]; /* Nonces for key exchange */
285 uint8_t remoteN[NONCELEN];
286 struct buffer_if buffer; /* Current outgoing key exchange packet */
287 struct buffer_if scratch;
288 int32_t retries; /* Number of retries remaining */
289 uint64_t timeout; /* Timeout for current state */
290 uint8_t *dhsecret;
291 uint8_t *sharedsecret;
292 uint32_t sharedsecretlen, sharedsecretallocd;
293 struct transform_inst_if *new_transform; /* For key setup/verify */
294 };
295
296 static void slog(struct site *st, uint32_t event, cstring_t msg, ...)
297 {
298 va_list ap;
299 char buf[240];
300 uint32_t class;
301
302 va_start(ap,msg);
303
304 if (event&st->log_events) {
305 switch(event) {
306 case LOG_UNEXPECTED: class=M_INFO; break;
307 case LOG_SETUP_INIT: class=M_INFO; break;
308 case LOG_SETUP_TIMEOUT: class=M_NOTICE; break;
309 case LOG_ACTIVATE_KEY: class=M_INFO; break;
310 case LOG_TIMEOUT_KEY: class=M_INFO; break;
311 case LOG_SEC: class=M_SECURITY; break;
312 case LOG_STATE: class=M_DEBUG; break;
313 case LOG_DROP: class=M_DEBUG; break;
314 case LOG_DUMP: class=M_DEBUG; break;
315 case LOG_ERROR: class=M_ERR; break;
316 case LOG_PEER_ADDRS: class=M_DEBUG; break;
317 default: class=M_ERR; break;
318 }
319
320 vsnprintf(buf,sizeof(buf),msg,ap);
321 st->log->log(st->log->st,class,"%s: %s",st->tunname,buf);
322 }
323 va_end(ap);
324 }
325
326 static void set_link_quality(struct site *st);
327 static void delete_keys(struct site *st, cstring_t reason, uint32_t loglevel);
328 static void delete_one_key(struct site *st, struct data_key *key,
329 const char *reason /* may be 0 meaning don't log*/,
330 const char *which /* ignored if !reasonn */,
331 uint32_t loglevel /* ignored if !reasonn */);
332 static bool_t initiate_key_setup(struct site *st, cstring_t reason);
333 static void enter_state_run(struct site *st);
334 static bool_t enter_state_resolve(struct site *st);
335 static bool_t enter_new_state(struct site *st,uint32_t next);
336 static void enter_state_wait(struct site *st);
337 static void activate_new_key(struct site *st);
338
339 static bool_t is_transform_valid(struct transform_inst_if *transform)
340 {
341 return transform && transform->valid(transform->st);
342 }
343
344 static bool_t current_valid(struct site *st)
345 {
346 return is_transform_valid(st->current.transform);
347 }
348
349 #define DEFINE_CALL_TRANSFORM(fwdrev) \
350 static int call_transform_##fwdrev(struct site *st, \
351 struct transform_inst_if *transform, \
352 struct buffer_if *buf, \
353 const char **errmsg) \
354 { \
355 if (!is_transform_valid(transform)) { \
356 *errmsg="transform not set up"; \
357 return 1; \
358 } \
359 return transform->fwdrev(transform->st,buf,errmsg); \
360 }
361
362 DEFINE_CALL_TRANSFORM(forwards)
363 DEFINE_CALL_TRANSFORM(reverse)
364
365 static void dispose_transform(struct transform_inst_if **transform_var)
366 {
367 struct transform_inst_if *transform=*transform_var;
368 if (transform) {
369 transform->delkey(transform->st);
370 transform->destroy(transform->st);
371 }
372 *transform_var = 0;
373 }
374
375 #define CHECK_AVAIL(b,l) do { if ((b)->size<(l)) return False; } while(0)
376 #define CHECK_EMPTY(b) do { if ((b)->size!=0) return False; } while(0)
377 #define CHECK_TYPE(b,t) do { uint32_t type; \
378 CHECK_AVAIL((b),4); \
379 type=buf_unprepend_uint32((b)); \
380 if (type!=(t)) return False; } while(0)
381
382 struct parsedname {
383 int32_t len;
384 uint8_t *name;
385 struct buffer_if extrainfo;
386 };
387
388 struct msg {
389 uint8_t *hashstart;
390 uint32_t dest;
391 uint32_t source;
392 struct parsedname remote;
393 struct parsedname local;
394 uint32_t remote_capabilities;
395 int capab_transformnum;
396 uint8_t *nR;
397 uint8_t *nL;
398 int32_t pklen;
399 char *pk;
400 int32_t hashlen;
401 int32_t siglen;
402 char *sig;
403 };
404
405 static void set_new_transform(struct site *st, char *pk)
406 {
407 /* Make room for the shared key */
408 st->sharedsecretlen=st->chosen_transform->keylen?:st->dh->ceil_len;
409 assert(st->sharedsecretlen);
410 if (st->sharedsecretlen > st->sharedsecretallocd) {
411 st->sharedsecretallocd=st->sharedsecretlen;
412 st->sharedsecret=realloc(st->sharedsecret,st->sharedsecretallocd);
413 }
414 if (!st->sharedsecret) fatal_perror("site:sharedsecret");
415
416 /* Generate the shared key */
417 st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,pk,
418 st->sharedsecret,st->sharedsecretlen);
419
420 /* Set up the transform */
421 struct transform_if *generator=st->chosen_transform;
422 struct transform_inst_if *generated=generator->create(generator->st);
423 generated->setkey(generated->st,st->sharedsecret,
424 st->sharedsecretlen,st->setup_priority);
425 dispose_transform(&st->new_transform);
426 st->new_transform=generated;
427
428 slog(st,LOG_SETUP_INIT,"key exchange negotiated transform"
429 " %d (capabilities ours=%#"PRIx32" theirs=%#"PRIx32")",
430 st->chosen_transform->capab_transformnum,
431 st->local_capabilities, st->remote_capabilities);
432 }
433
434 struct xinfoadd {
435 int32_t lenpos, afternul;
436 };
437 static void append_string_xinfo_start(struct buffer_if *buf,
438 struct xinfoadd *xia,
439 const char *str)
440 /* Helps construct one of the names with additional info as found
441 * in MSG1..4. Call this function first, then append all the
442 * desired extra info (not including the nul byte) to the buffer,
443 * then call append_string_xinfo_done. */
444 {
445 xia->lenpos = buf->size;
446 buf_append_string(buf,str);
447 buf_append_uint8(buf,0);
448 xia->afternul = buf->size;
449 }
450 static void append_string_xinfo_done(struct buffer_if *buf,
451 struct xinfoadd *xia)
452 {
453 /* we just need to adjust the string length */
454 if (buf->size == xia->afternul) {
455 /* no extra info, strip the nul too */
456 buf_unappend_uint8(buf);
457 } else {
458 put_uint16(buf->start+xia->lenpos, buf->size-(xia->lenpos+2));
459 }
460 }
461
462 /* Build any of msg1 to msg4. msg5 and msg6 are built from the inside
463 out using a transform of config data supplied by netlink */
464 static bool_t generate_msg(struct site *st, uint32_t type, cstring_t what)
465 {
466 void *hst;
467 uint8_t *hash;
468 string_t dhpub, sig;
469
470 st->retries=st->setup_retries;
471 BUF_ALLOC(&st->buffer,what);
472 buffer_init(&st->buffer,0);
473 buf_append_uint32(&st->buffer,
474 (type==LABEL_MSG1?0:st->setup_session_id));
475 buf_append_uint32(&st->buffer,st->index);
476 buf_append_uint32(&st->buffer,type);
477
478 struct xinfoadd xia;
479 append_string_xinfo_start(&st->buffer,&xia,st->localname);
480 if ((st->local_capabilities & CAPAB_EARLY) || (type != LABEL_MSG1)) {
481 buf_append_uint32(&st->buffer,st->local_capabilities);
482 }
483 append_string_xinfo_done(&st->buffer,&xia);
484
485 buf_append_string(&st->buffer,st->remotename);
486 memcpy(buf_append(&st->buffer,NONCELEN),st->localN,NONCELEN);
487 if (type==LABEL_MSG1) return True;
488 memcpy(buf_append(&st->buffer,NONCELEN),st->remoteN,NONCELEN);
489 if (type==LABEL_MSG2) return True;
490
491 if (hacky_par_mid_failnow()) return False;
492
493 if (type==LABEL_MSG3BIS)
494 buf_append_uint8(&st->buffer,st->chosen_transform->capab_transformnum);
495
496 dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len);
497 buf_append_string(&st->buffer,dhpub);
498 free(dhpub);
499 hash=safe_malloc(st->hash->len, "generate_msg");
500 hst=st->hash->init();
501 st->hash->update(hst,st->buffer.start,st->buffer.size);
502 st->hash->final(hst,hash);
503 sig=st->privkey->sign(st->privkey->st,hash,st->hash->len);
504 buf_append_string(&st->buffer,sig);
505 free(sig);
506 free(hash);
507 return True;
508 }
509
510 static bool_t unpick_name(struct buffer_if *msg, struct parsedname *nm)
511 {
512 CHECK_AVAIL(msg,2);
513 nm->len=buf_unprepend_uint16(msg);
514 CHECK_AVAIL(msg,nm->len);
515 nm->name=buf_unprepend(msg,nm->len);
516 uint8_t *nul=memchr(nm->name,0,nm->len);
517 if (!nul) {
518 buffer_readonly_view(&nm->extrainfo,0,0);
519 } else {
520 buffer_readonly_view(&nm->extrainfo, nul+1, msg->start-(nul+1));
521 nm->len=nul-nm->name;
522 }
523 return True;
524 }
525
526 static bool_t unpick_msg(struct site *st, uint32_t type,
527 struct buffer_if *msg, struct msg *m)
528 {
529 m->capab_transformnum=-1;
530 m->hashstart=msg->start;
531 CHECK_AVAIL(msg,4);
532 m->dest=buf_unprepend_uint32(msg);
533 CHECK_AVAIL(msg,4);
534 m->source=buf_unprepend_uint32(msg);
535 CHECK_TYPE(msg,type);
536 if (!unpick_name(msg,&m->remote)) return False;
537 m->remote_capabilities=0;
538 if (m->remote.extrainfo.size) {
539 CHECK_AVAIL(&m->remote.extrainfo,4);
540 m->remote_capabilities=buf_unprepend_uint32(&m->remote.extrainfo);
541 }
542 if (!unpick_name(msg,&m->local)) return False;
543 CHECK_AVAIL(msg,NONCELEN);
544 m->nR=buf_unprepend(msg,NONCELEN);
545 if (type==LABEL_MSG1) {
546 CHECK_EMPTY(msg);
547 return True;
548 }
549 CHECK_AVAIL(msg,NONCELEN);
550 m->nL=buf_unprepend(msg,NONCELEN);
551 if (type==LABEL_MSG2) {
552 CHECK_EMPTY(msg);
553 return True;
554 }
555 if (type==LABEL_MSG3BIS) {
556 CHECK_AVAIL(msg,1);
557 m->capab_transformnum = buf_unprepend_uint8(msg);
558 } else {
559 m->capab_transformnum = CAPAB_TRANSFORMNUM_ANCIENT;
560 }
561 CHECK_AVAIL(msg,2);
562 m->pklen=buf_unprepend_uint16(msg);
563 CHECK_AVAIL(msg,m->pklen);
564 m->pk=buf_unprepend(msg,m->pklen);
565 m->hashlen=msg->start-m->hashstart;
566 CHECK_AVAIL(msg,2);
567 m->siglen=buf_unprepend_uint16(msg);
568 CHECK_AVAIL(msg,m->siglen);
569 m->sig=buf_unprepend(msg,m->siglen);
570 CHECK_EMPTY(msg);
571 return True;
572 }
573
574 static bool_t name_matches(const struct parsedname *nm, const char *expected)
575 {
576 int expected_len=strlen(expected);
577 return
578 nm->len == expected_len &&
579 !memcmp(nm->name, expected, expected_len);
580 }
581
582 static bool_t check_msg(struct site *st, uint32_t type, struct msg *m,
583 cstring_t *error)
584 {
585 if (type==LABEL_MSG1) return True;
586
587 /* Check that the site names and our nonce have been sent
588 back correctly, and then store our peer's nonce. */
589 if (!name_matches(&m->remote,st->remotename)) {
590 *error="wrong remote site name";
591 return False;
592 }
593 if (!name_matches(&m->local,st->localname)) {
594 *error="wrong local site name";
595 return False;
596 }
597 if (memcmp(m->nL,st->localN,NONCELEN)!=0) {
598 *error="wrong locally-generated nonce";
599 return False;
600 }
601 if (type==LABEL_MSG2) return True;
602 if (!consttime_memeq(m->nR,st->remoteN,NONCELEN)!=0) {
603 *error="wrong remotely-generated nonce";
604 return False;
605 }
606 /* MSG3 has complicated rules about capabilities, which are
607 * handled in process_msg3. */
608 if (type==LABEL_MSG3 || type==LABEL_MSG3BIS) return True;
609 if (m->remote_capabilities!=st->remote_capabilities) {
610 *error="remote capabilities changed";
611 return False;
612 }
613 if (type==LABEL_MSG4) return True;
614 *error="unknown message type";
615 return False;
616 }
617
618 static bool_t generate_msg1(struct site *st)
619 {
620 st->random->generate(st->random->st,NONCELEN,st->localN);
621 return generate_msg(st,LABEL_MSG1,"site:MSG1");
622 }
623
624 static bool_t process_msg1(struct site *st, struct buffer_if *msg1,
625 const struct comm_addr *src, struct msg *m)
626 {
627 /* We've already determined we're in an appropriate state to
628 process an incoming MSG1, and that the MSG1 has correct values
629 of A and B. */
630
631 transport_record_peer(st,&st->setup_peers,src,"msg1");
632 st->setup_session_id=m->source;
633 st->remote_capabilities=m->remote_capabilities;
634 memcpy(st->remoteN,m->nR,NONCELEN);
635 return True;
636 }
637
638 static bool_t generate_msg2(struct site *st)
639 {
640 st->random->generate(st->random->st,NONCELEN,st->localN);
641 return generate_msg(st,LABEL_MSG2,"site:MSG2");
642 }
643
644 static bool_t process_msg2(struct site *st, struct buffer_if *msg2,
645 const struct comm_addr *src)
646 {
647 struct msg m;
648 cstring_t err;
649
650 if (!unpick_msg(st,LABEL_MSG2,msg2,&m)) return False;
651 if (!check_msg(st,LABEL_MSG2,&m,&err)) {
652 slog(st,LOG_SEC,"msg2: %s",err);
653 return False;
654 }
655 st->setup_session_id=m.source;
656 st->remote_capabilities=m.remote_capabilities;
657
658 /* Select the transform to use */
659
660 uint32_t remote_transforms = st->remote_capabilities & CAPAB_TRANSFORM_MASK;
661 if (!remote_transforms)
662 /* old secnets only had this one transform */
663 remote_transforms = 1UL << CAPAB_TRANSFORMNUM_ANCIENT;
664
665 struct transform_if *ti;
666 int i;
667 for (i=0; i<st->ntransforms; i++) {
668 ti=st->transforms[i];
669 if ((1UL << ti->capab_transformnum) & remote_transforms)
670 goto transform_found;
671 }
672 slog(st,LOG_ERROR,"no transforms in common"
673 " (us %#"PRIx32"; them: %#"PRIx32")",
674 st->local_capabilities & CAPAB_TRANSFORM_MASK,
675 remote_transforms);
676 return False;
677 transform_found:
678 st->chosen_transform=ti;
679
680 memcpy(st->remoteN,m.nR,NONCELEN);
681 return True;
682 }
683
684 static bool_t generate_msg3(struct site *st)
685 {
686 /* Now we have our nonce and their nonce. Think of a secret key,
687 and create message number 3. */
688 st->random->generate(st->random->st,st->dh->len,st->dhsecret);
689 return generate_msg(st,
690 (st->remote_capabilities & CAPAB_TRANSFORM_MASK
691 ? LABEL_MSG3BIS : LABEL_MSG3),
692 "site:MSG3");
693 }
694
695 static bool_t process_msg3(struct site *st, struct buffer_if *msg3,
696 const struct comm_addr *src, uint32_t msgtype)
697 {
698 struct msg m;
699 uint8_t *hash;
700 void *hst;
701 cstring_t err;
702
703 assert(msgtype==LABEL_MSG3 || msgtype==LABEL_MSG3BIS);
704
705 if (!unpick_msg(st,msgtype,msg3,&m)) return False;
706 if (!check_msg(st,msgtype,&m,&err)) {
707 slog(st,LOG_SEC,"msg3: %s",err);
708 return False;
709 }
710 uint32_t capab_adv_late = m.remote_capabilities
711 & ~st->remote_capabilities & CAPAB_EARLY;
712 if (capab_adv_late) {
713 slog(st,LOG_SEC,"msg3 impermissibly adds early capability flag(s)"
714 " %#"PRIx32" (was %#"PRIx32", now %#"PRIx32")",
715 capab_adv_late, st->remote_capabilities, m.remote_capabilities);
716 return False;
717 }
718 st->remote_capabilities|=m.remote_capabilities;
719
720 struct transform_if *ti;
721 int i;
722 for (i=0; i<st->ntransforms; i++) {
723 ti=st->transforms[i];
724 if (ti->capab_transformnum == m.capab_transformnum)
725 goto transform_found;
726 }
727 slog(st,LOG_SEC,"peer chose unknown-to-us transform %d!",
728 m.capab_transformnum);
729 return False;
730 transform_found:
731 st->chosen_transform=ti;
732
733 /* Check signature and store g^x mod m */
734 hash=safe_malloc(st->hash->len, "process_msg3");
735 hst=st->hash->init();
736 st->hash->update(hst,m.hashstart,m.hashlen);
737 st->hash->final(hst,hash);
738 /* Terminate signature with a '0' - cheating, but should be ok */
739 m.sig[m.siglen]=0;
740 if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
741 slog(st,LOG_SEC,"msg3 signature failed check!");
742 free(hash);
743 return False;
744 }
745 free(hash);
746
747 /* Terminate their DH public key with a '0' */
748 m.pk[m.pklen]=0;
749 /* Invent our DH secret key */
750 st->random->generate(st->random->st,st->dh->len,st->dhsecret);
751
752 /* Generate the shared key and set up the transform */
753 set_new_transform(st,m.pk);
754
755 return True;
756 }
757
758 static bool_t generate_msg4(struct site *st)
759 {
760 /* We have both nonces, their public key and our private key. Generate
761 our public key, sign it and send it to them. */
762 return generate_msg(st,LABEL_MSG4,"site:MSG4");
763 }
764
765 static bool_t process_msg4(struct site *st, struct buffer_if *msg4,
766 const struct comm_addr *src)
767 {
768 struct msg m;
769 uint8_t *hash;
770 void *hst;
771 cstring_t err;
772
773 if (!unpick_msg(st,LABEL_MSG4,msg4,&m)) return False;
774 if (!check_msg(st,LABEL_MSG4,&m,&err)) {
775 slog(st,LOG_SEC,"msg4: %s",err);
776 return False;
777 }
778
779 /* Check signature and store g^x mod m */
780 hash=safe_malloc(st->hash->len, "process_msg4");
781 hst=st->hash->init();
782 st->hash->update(hst,m.hashstart,m.hashlen);
783 st->hash->final(hst,hash);
784 /* Terminate signature with a '0' - cheating, but should be ok */
785 m.sig[m.siglen]=0;
786 if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
787 slog(st,LOG_SEC,"msg4 signature failed check!");
788 free(hash);
789 return False;
790 }
791 free(hash);
792
793 /* Terminate their DH public key with a '0' */
794 m.pk[m.pklen]=0;
795
796 /* Generate the shared key and set up the transform */
797 set_new_transform(st,m.pk);
798
799 return True;
800 }
801
802 struct msg0 {
803 uint32_t dest;
804 uint32_t source;
805 uint32_t type;
806 };
807
808 static bool_t unpick_msg0(struct site *st, struct buffer_if *msg0,
809 struct msg0 *m)
810 {
811 CHECK_AVAIL(msg0,4);
812 m->dest=buf_unprepend_uint32(msg0);
813 CHECK_AVAIL(msg0,4);
814 m->source=buf_unprepend_uint32(msg0);
815 CHECK_AVAIL(msg0,4);
816 m->type=buf_unprepend_uint32(msg0);
817 return True;
818 /* Leaves transformed part of buffer untouched */
819 }
820
821 static bool_t generate_msg5(struct site *st)
822 {
823 cstring_t transform_err;
824
825 BUF_ALLOC(&st->buffer,"site:MSG5");
826 /* We are going to add four words to the message */
827 buffer_init(&st->buffer,st->new_transform->max_start_pad+(4*4));
828 /* Give the netlink code an opportunity to put its own stuff in the
829 message (configuration information, etc.) */
830 buf_prepend_uint32(&st->buffer,LABEL_MSG5);
831 if (call_transform_forwards(st,st->new_transform,
832 &st->buffer,&transform_err))
833 return False;
834 buf_prepend_uint32(&st->buffer,LABEL_MSG5);
835 buf_prepend_uint32(&st->buffer,st->index);
836 buf_prepend_uint32(&st->buffer,st->setup_session_id);
837
838 st->retries=st->setup_retries;
839 return True;
840 }
841
842 static bool_t process_msg5(struct site *st, struct buffer_if *msg5,
843 const struct comm_addr *src,
844 struct transform_inst_if *transform)
845 {
846 struct msg0 m;
847 cstring_t transform_err;
848
849 if (!unpick_msg0(st,msg5,&m)) return False;
850
851 if (call_transform_reverse(st,transform,msg5,&transform_err)) {
852 /* There's a problem */
853 slog(st,LOG_SEC,"process_msg5: transform: %s",transform_err);
854 return False;
855 }
856 /* Buffer should now contain untransformed PING packet data */
857 CHECK_AVAIL(msg5,4);
858 if (buf_unprepend_uint32(msg5)!=LABEL_MSG5) {
859 slog(st,LOG_SEC,"MSG5/PING packet contained wrong label");
860 return False;
861 }
862 /* Older versions of secnet used to write some config data here
863 * which we ignore. So we don't CHECK_EMPTY */
864 return True;
865 }
866
867 static void create_msg6(struct site *st, struct transform_inst_if *transform,
868 uint32_t session_id)
869 {
870 cstring_t transform_err;
871
872 BUF_ALLOC(&st->buffer,"site:MSG6");
873 /* We are going to add four words to the message */
874 buffer_init(&st->buffer,transform->max_start_pad+(4*4));
875 /* Give the netlink code an opportunity to put its own stuff in the
876 message (configuration information, etc.) */
877 buf_prepend_uint32(&st->buffer,LABEL_MSG6);
878 int problem = call_transform_forwards(st,transform,
879 &st->buffer,&transform_err);
880 assert(!problem);
881 buf_prepend_uint32(&st->buffer,LABEL_MSG6);
882 buf_prepend_uint32(&st->buffer,st->index);
883 buf_prepend_uint32(&st->buffer,session_id);
884 }
885
886 static bool_t generate_msg6(struct site *st)
887 {
888 if (!is_transform_valid(st->new_transform))
889 return False;
890 create_msg6(st,st->new_transform,st->setup_session_id);
891 st->retries=1; /* Peer will retransmit MSG5 if this packet gets lost */
892 return True;
893 }
894
895 static bool_t process_msg6(struct site *st, struct buffer_if *msg6,
896 const struct comm_addr *src)
897 {
898 struct msg0 m;
899 cstring_t transform_err;
900
901 if (!unpick_msg0(st,msg6,&m)) return False;
902
903 if (call_transform_reverse(st,st->new_transform,msg6,&transform_err)) {
904 /* There's a problem */
905 slog(st,LOG_SEC,"process_msg6: transform: %s",transform_err);
906 return False;
907 }
908 /* Buffer should now contain untransformed PING packet data */
909 CHECK_AVAIL(msg6,4);
910 if (buf_unprepend_uint32(msg6)!=LABEL_MSG6) {
911 slog(st,LOG_SEC,"MSG6/PONG packet contained invalid data");
912 return False;
913 }
914 /* Older versions of secnet used to write some config data here
915 * which we ignore. So we don't CHECK_EMPTY */
916 return True;
917 }
918
919 static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0,
920 const struct comm_addr *src)
921 {
922 cstring_t transform_err, auxkey_err, newkey_err="n/a";
923 struct msg0 m;
924 uint32_t problem;
925
926 if (!unpick_msg0(st,msg0,&m)) return False;
927
928 /* Keep a copy so we can try decrypting it with multiple keys */
929 buffer_copy(&st->scratch, msg0);
930
931 problem = call_transform_reverse(st,st->current.transform,
932 msg0,&transform_err);
933 if (!problem) {
934 if (!st->auxiliary_is_new)
935 delete_one_key(st,&st->auxiliary_key,
936 "peer has used new key","auxiliary key",LOG_SEC);
937 return True;
938 }
939 if (problem==2)
940 goto skew;
941
942 buffer_copy(msg0, &st->scratch);
943 problem = call_transform_reverse(st,st->auxiliary_key.transform,
944 msg0,&auxkey_err);
945 if (problem==0) {
946 slog(st,LOG_DROP,"processing packet which uses auxiliary key");
947 if (st->auxiliary_is_new) {
948 /* We previously timed out in state SENTMSG5 but it turns
949 * out that our peer did in fact get our MSG5 and is
950 * using the new key. So we should switch to it too. */
951 /* This is a bit like activate_new_key. */
952 struct data_key t;
953 t=st->current;
954 st->current=st->auxiliary_key;
955 st->auxiliary_key=t;
956
957 delete_one_key(st,&st->auxiliary_key,"peer has used new key",
958 "previous key",LOG_SEC);
959 st->auxiliary_is_new=0;
960 st->renegotiate_key_time=st->auxiliary_renegotiate_key_time;
961 }
962 return True;
963 }
964 if (problem==2)
965 goto skew;
966
967 if (st->state==SITE_SENTMSG5) {
968 buffer_copy(msg0, &st->scratch);
969 problem = call_transform_reverse(st,st->new_transform,
970 msg0,&newkey_err);
971 if (!problem) {
972 /* It looks like we didn't get the peer's MSG6 */
973 /* This is like a cut-down enter_new_state(SITE_RUN) */
974 slog(st,LOG_STATE,"will enter state RUN (MSG0 with new key)");
975 BUF_FREE(&st->buffer);
976 st->timeout=0;
977 activate_new_key(st);
978 return True; /* do process the data in this packet */
979 }
980 if (problem==2)
981 goto skew;
982 }
983
984 slog(st,LOG_SEC,"transform: %s (aux: %s, new: %s)",
985 transform_err,auxkey_err,newkey_err);
986 initiate_key_setup(st,"incoming message would not decrypt");
987 send_nak(src,m.dest,m.source,m.type,msg0,"message would not decrypt");
988 return False;
989
990 skew:
991 slog(st,LOG_DROP,"transform: %s (merely skew)",transform_err);
992 return False;
993 }
994
995 static bool_t process_msg0(struct site *st, struct buffer_if *msg0,
996 const struct comm_addr *src)
997 {
998 uint32_t type;
999
1000 if (!decrypt_msg0(st,msg0,src))
1001 return False;
1002
1003 CHECK_AVAIL(msg0,4);
1004 type=buf_unprepend_uint32(msg0);
1005 switch(type) {
1006 case LABEL_MSG7:
1007 /* We must forget about the current session. */
1008 delete_keys(st,"request from peer",LOG_SEC);
1009 return True;
1010 case LABEL_MSG9:
1011 /* Deliver to netlink layer */
1012 st->netlink->deliver(st->netlink->st,msg0);
1013 transport_data_msgok(st,src);
1014 /* See whether we should start negotiating a new key */
1015 if (st->now > st->renegotiate_key_time)
1016 initiate_key_setup(st,"incoming packet in renegotiation window");
1017 return True;
1018 default:
1019 slog(st,LOG_SEC,"incoming encrypted message of type %08x "
1020 "(unknown)",type);
1021 break;
1022 }
1023 return False;
1024 }
1025
1026 static void dump_packet(struct site *st, struct buffer_if *buf,
1027 const struct comm_addr *addr, bool_t incoming)
1028 {
1029 uint32_t dest=get_uint32(buf->start);
1030 uint32_t source=get_uint32(buf->start+4);
1031 uint32_t msgtype=get_uint32(buf->start+8);
1032
1033 if (st->log_events & LOG_DUMP)
1034 slilog(st->log,M_DEBUG,"%s: %s: %08x<-%08x: %08x:",
1035 st->tunname,incoming?"incoming":"outgoing",
1036 dest,source,msgtype);
1037 }
1038
1039 static uint32_t site_status(void *st)
1040 {
1041 return 0;
1042 }
1043
1044 static bool_t send_msg(struct site *st)
1045 {
1046 if (st->retries>0) {
1047 transport_xmit(st, &st->setup_peers, &st->buffer, True);
1048 st->timeout=st->now+st->setup_retry_interval;
1049 st->retries--;
1050 return True;
1051 } else if (st->state==SITE_SENTMSG5) {
1052 slog(st,LOG_SETUP_TIMEOUT,"timed out sending MSG5, stashing new key");
1053 /* We stash the key we have produced, in case it turns out that
1054 * our peer did see our MSG5 after all and starts using it. */
1055 /* This is a bit like some of activate_new_key */
1056 struct transform_inst_if *t;
1057 t=st->auxiliary_key.transform;
1058 st->auxiliary_key.transform=st->new_transform;
1059 st->new_transform=t;
1060 dispose_transform(&st->new_transform);
1061
1062 st->auxiliary_is_new=1;
1063 st->auxiliary_key.key_timeout=st->now+st->key_lifetime;
1064 st->auxiliary_renegotiate_key_time=st->now+st->key_renegotiate_time;
1065 st->auxiliary_key.remote_session_id=st->setup_session_id;
1066
1067 enter_state_wait(st);
1068 return False;
1069 } else {
1070 slog(st,LOG_SETUP_TIMEOUT,"timed out sending key setup packet "
1071 "(in state %s)",state_name(st->state));
1072 enter_state_wait(st);
1073 return False;
1074 }
1075 }
1076
1077 static void site_resolve_callback(void *sst, struct in_addr *address)
1078 {
1079 struct site *st=sst;
1080 struct comm_addr ca_buf, *ca_use;
1081
1082 if (st->state!=SITE_RESOLVE) {
1083 slog(st,LOG_UNEXPECTED,"site_resolve_callback called unexpectedly");
1084 return;
1085 }
1086 if (address) {
1087 FILLZERO(ca_buf);
1088 ca_buf.comm=st->comms[0];
1089 ca_buf.sin.sin_family=AF_INET;
1090 ca_buf.sin.sin_port=htons(st->remoteport);
1091 ca_buf.sin.sin_addr=*address;
1092 ca_use=&ca_buf;
1093 } else {
1094 slog(st,LOG_ERROR,"resolution of %s failed",st->address);
1095 ca_use=0;
1096 }
1097 if (transport_compute_setupinit_peers(st,ca_use)) {
1098 enter_new_state(st,SITE_SENTMSG1);
1099 } else {
1100 /* Can't figure out who to try to to talk to */
1101 slog(st,LOG_SETUP_INIT,"key exchange failed: cannot find peer address");
1102 enter_state_run(st);
1103 }
1104 }
1105
1106 static bool_t initiate_key_setup(struct site *st, cstring_t reason)
1107 {
1108 if (st->state!=SITE_RUN) return False;
1109 slog(st,LOG_SETUP_INIT,"initiating key exchange (%s)",reason);
1110 if (st->address) {
1111 slog(st,LOG_SETUP_INIT,"resolving peer address");
1112 return enter_state_resolve(st);
1113 } else if (transport_compute_setupinit_peers(st,0)) {
1114 return enter_new_state(st,SITE_SENTMSG1);
1115 }
1116 slog(st,LOG_SETUP_INIT,"key exchange failed: no address for peer");
1117 return False;
1118 }
1119
1120 static void activate_new_key(struct site *st)
1121 {
1122 struct transform_inst_if *t;
1123
1124 /* We have three transform instances, which we swap between old,
1125 active and setup */
1126 t=st->auxiliary_key.transform;
1127 st->auxiliary_key.transform=st->current.transform;
1128 st->current.transform=st->new_transform;
1129 st->new_transform=t;
1130 dispose_transform(&st->new_transform);
1131
1132 st->timeout=0;
1133 st->auxiliary_is_new=0;
1134 st->auxiliary_key.key_timeout=st->current.key_timeout;
1135 st->current.key_timeout=st->now+st->key_lifetime;
1136 st->renegotiate_key_time=st->now+st->key_renegotiate_time;
1137 transport_peers_copy(st,&st->peers,&st->setup_peers);
1138 st->current.remote_session_id=st->setup_session_id;
1139
1140 slog(st,LOG_ACTIVATE_KEY,"new key activated");
1141 enter_state_run(st);
1142 }
1143
1144 static void delete_one_key(struct site *st, struct data_key *key,
1145 cstring_t reason, cstring_t which, uint32_t loglevel)
1146 {
1147 if (!is_transform_valid(key->transform)) return;
1148 if (reason) slog(st,loglevel,"%s deleted (%s)",which,reason);
1149 dispose_transform(&key->transform);
1150 key->key_timeout=0;
1151 }
1152
1153 static void delete_keys(struct site *st, cstring_t reason, uint32_t loglevel)
1154 {
1155 if (current_valid(st)) {
1156 slog(st,loglevel,"session closed (%s)",reason);
1157
1158 delete_one_key(st,&st->current,0,0,0);
1159 set_link_quality(st);
1160 }
1161 delete_one_key(st,&st->auxiliary_key,0,0,0);
1162 }
1163
1164 static void state_assert(struct site *st, bool_t ok)
1165 {
1166 if (!ok) fatal("site:state_assert");
1167 }
1168
1169 static void enter_state_stop(struct site *st)
1170 {
1171 st->state=SITE_STOP;
1172 st->timeout=0;
1173 delete_keys(st,"entering state STOP",LOG_TIMEOUT_KEY);
1174 dispose_transform(&st->new_transform);
1175 }
1176
1177 static void set_link_quality(struct site *st)
1178 {
1179 uint32_t quality;
1180 if (current_valid(st))
1181 quality=LINK_QUALITY_UP;
1182 else if (st->state==SITE_WAIT || st->state==SITE_STOP)
1183 quality=LINK_QUALITY_DOWN;
1184 else if (st->address)
1185 quality=LINK_QUALITY_DOWN_CURRENT_ADDRESS;
1186 else if (transport_peers_valid(&st->peers))
1187 quality=LINK_QUALITY_DOWN_STALE_ADDRESS;
1188 else
1189 quality=LINK_QUALITY_DOWN;
1190
1191 st->netlink->set_quality(st->netlink->st,quality);
1192 }
1193
1194 static void enter_state_run(struct site *st)
1195 {
1196 slog(st,LOG_STATE,"entering state RUN");
1197 st->state=SITE_RUN;
1198 st->timeout=0;
1199
1200 st->setup_session_id=0;
1201 transport_peers_clear(st,&st->setup_peers);
1202 memset(st->localN,0,NONCELEN);
1203 memset(st->remoteN,0,NONCELEN);
1204 dispose_transform(&st->new_transform);
1205 memset(st->dhsecret,0,st->dh->len);
1206 memset(st->sharedsecret,0,st->sharedsecretlen);
1207 set_link_quality(st);
1208 }
1209
1210 static bool_t enter_state_resolve(struct site *st)
1211 {
1212 state_assert(st,st->state==SITE_RUN);
1213 slog(st,LOG_STATE,"entering state RESOLVE");
1214 st->state=SITE_RESOLVE;
1215 st->resolver->request(st->resolver->st,st->address,
1216 site_resolve_callback,st);
1217 return True;
1218 }
1219
1220 static bool_t enter_new_state(struct site *st, uint32_t next)
1221 {
1222 bool_t (*gen)(struct site *st);
1223 int r;
1224
1225 slog(st,LOG_STATE,"entering state %s",state_name(next));
1226 switch(next) {
1227 case SITE_SENTMSG1:
1228 state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE);
1229 gen=generate_msg1;
1230 break;
1231 case SITE_SENTMSG2:
1232 state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE ||
1233 st->state==SITE_SENTMSG1 || st->state==SITE_WAIT);
1234 gen=generate_msg2;
1235 break;
1236 case SITE_SENTMSG3:
1237 state_assert(st,st->state==SITE_SENTMSG1);
1238 BUF_FREE(&st->buffer);
1239 gen=generate_msg3;
1240 break;
1241 case SITE_SENTMSG4:
1242 state_assert(st,st->state==SITE_SENTMSG2);
1243 BUF_FREE(&st->buffer);
1244 gen=generate_msg4;
1245 break;
1246 case SITE_SENTMSG5:
1247 state_assert(st,st->state==SITE_SENTMSG3);
1248 BUF_FREE(&st->buffer);
1249 gen=generate_msg5;
1250 break;
1251 case SITE_RUN:
1252 state_assert(st,st->state==SITE_SENTMSG4);
1253 BUF_FREE(&st->buffer);
1254 gen=generate_msg6;
1255 break;
1256 default:
1257 gen=NULL;
1258 fatal("enter_new_state(%s): invalid new state",state_name(next));
1259 break;
1260 }
1261
1262 if (hacky_par_start_failnow()) return False;
1263
1264 r= gen(st) && send_msg(st);
1265
1266 hacky_par_end(&r,
1267 st->setup_retries, st->setup_retry_interval,
1268 send_msg, st);
1269
1270 if (r) {
1271 st->state=next;
1272 if (next==SITE_RUN) {
1273 BUF_FREE(&st->buffer); /* Never reused */
1274 st->timeout=0; /* Never retransmit */
1275 activate_new_key(st);
1276 }
1277 return True;
1278 }
1279 slog(st,LOG_ERROR,"error entering state %s",state_name(next));
1280 st->buffer.free=False; /* Unconditionally use the buffer; it may be
1281 in either state, and enter_state_wait() will
1282 do a BUF_FREE() */
1283 enter_state_wait(st);
1284 return False;
1285 }
1286
1287 /* msg7 tells our peer that we're about to forget our key */
1288 static bool_t send_msg7(struct site *st, cstring_t reason)
1289 {
1290 cstring_t transform_err;
1291
1292 if (current_valid(st) && st->buffer.free
1293 && transport_peers_valid(&st->peers)) {
1294 BUF_ALLOC(&st->buffer,"site:MSG7");
1295 buffer_init(&st->buffer,st->current.transform->max_start_pad+(4*3));
1296 buf_append_uint32(&st->buffer,LABEL_MSG7);
1297 buf_append_string(&st->buffer,reason);
1298 if (call_transform_forwards(st, st->current.transform,
1299 &st->buffer, &transform_err))
1300 goto free_out;
1301 buf_prepend_uint32(&st->buffer,LABEL_MSG0);
1302 buf_prepend_uint32(&st->buffer,st->index);
1303 buf_prepend_uint32(&st->buffer,st->current.remote_session_id);
1304 transport_xmit(st,&st->peers,&st->buffer,True);
1305 BUF_FREE(&st->buffer);
1306 free_out:
1307 return True;
1308 }
1309 return False;
1310 }
1311
1312 /* We go into this state if our peer becomes uncommunicative. Similar to
1313 the "stop" state, we forget all session keys for a while, before
1314 re-entering the "run" state. */
1315 static void enter_state_wait(struct site *st)
1316 {
1317 slog(st,LOG_STATE,"entering state WAIT");
1318 st->timeout=st->now+st->wait_timeout;
1319 st->state=SITE_WAIT;
1320 set_link_quality(st);
1321 BUF_FREE(&st->buffer); /* will have had an outgoing packet in it */
1322 /* XXX Erase keys etc. */
1323 }
1324
1325 static inline void site_settimeout(uint64_t timeout, int *timeout_io)
1326 {
1327 if (timeout) {
1328 int64_t offset=timeout-*now;
1329 if (offset<0) offset=0;
1330 if (offset>INT_MAX) offset=INT_MAX;
1331 if (*timeout_io<0 || offset<*timeout_io)
1332 *timeout_io=offset;
1333 }
1334 }
1335
1336 static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
1337 int *timeout_io)
1338 {
1339 struct site *st=sst;
1340
1341 *nfds_io=0; /* We don't use any file descriptors */
1342 st->now=*now;
1343
1344 /* Work out when our next timeout is. The earlier of 'timeout' or
1345 'current.key_timeout'. A stored value of '0' indicates no timeout
1346 active. */
1347 site_settimeout(st->timeout, timeout_io);
1348 site_settimeout(st->current.key_timeout, timeout_io);
1349 site_settimeout(st->auxiliary_key.key_timeout, timeout_io);
1350
1351 return 0; /* success */
1352 }
1353
1354 static void check_expiry(struct site *st, struct data_key *key,
1355 const char *which)
1356 {
1357 if (key->key_timeout && *now>key->key_timeout) {
1358 delete_one_key(st,key,"maximum life exceeded",which,LOG_TIMEOUT_KEY);
1359 }
1360 }
1361
1362 /* NB site_afterpoll will be called before site_beforepoll is ever called */
1363 static void site_afterpoll(void *sst, struct pollfd *fds, int nfds)
1364 {
1365 struct site *st=sst;
1366
1367 st->now=*now;
1368 if (st->timeout && *now>st->timeout) {
1369 st->timeout=0;
1370 if (st->state>=SITE_SENTMSG1 && st->state<=SITE_SENTMSG5) {
1371 if (!hacky_par_start_failnow())
1372 send_msg(st);
1373 } else if (st->state==SITE_WAIT) {
1374 enter_state_run(st);
1375 } else {
1376 slog(st,LOG_ERROR,"site_afterpoll: unexpected timeout, state=%d",
1377 st->state);
1378 }
1379 }
1380 check_expiry(st,&st->current,"current key");
1381 check_expiry(st,&st->auxiliary_key,"auxiliary key");
1382 }
1383
1384 /* This function is called by the netlink device to deliver packets
1385 intended for the remote network. The packet is in "raw" wire
1386 format, but is guaranteed to be word-aligned. */
1387 static void site_outgoing(void *sst, struct buffer_if *buf)
1388 {
1389 struct site *st=sst;
1390 cstring_t transform_err;
1391
1392 if (st->state==SITE_STOP) {
1393 BUF_FREE(buf);
1394 return;
1395 }
1396
1397 /* In all other states we consider delivering the packet if we have
1398 a valid key and a valid address to send it to. */
1399 if (current_valid(st) && transport_peers_valid(&st->peers)) {
1400 /* Transform it and send it */
1401 if (buf->size>0) {
1402 buf_prepend_uint32(buf,LABEL_MSG9);
1403 if (call_transform_forwards(st, st->current.transform,
1404 buf, &transform_err))
1405 goto free_out;
1406 buf_prepend_uint32(buf,LABEL_MSG0);
1407 buf_prepend_uint32(buf,st->index);
1408 buf_prepend_uint32(buf,st->current.remote_session_id);
1409 transport_xmit(st,&st->peers,buf,False);
1410 }
1411 free_out:
1412 BUF_FREE(buf);
1413 return;
1414 }
1415
1416 slog(st,LOG_DROP,"discarding outgoing packet of size %d",buf->size);
1417 BUF_FREE(buf);
1418 initiate_key_setup(st,"outgoing packet");
1419 }
1420
1421 static bool_t named_for_us(struct site *st, const struct buffer_if *buf_in,
1422 uint32_t type, struct msg *m)
1423 /* For packets which are identified by the local and remote names.
1424 * If it has our name and our peer's name in it it's for us. */
1425 {
1426 struct buffer_if buf[1];
1427 buffer_readonly_clone(buf,buf_in);
1428 return unpick_msg(st,type,buf,m)
1429 && name_matches(&m->remote,st->remotename)
1430 && name_matches(&m->local,st->localname);
1431 }
1432
1433 /* This function is called by the communication device to deliver
1434 packets from our peers. */
1435 static bool_t site_incoming(void *sst, struct buffer_if *buf,
1436 const struct comm_addr *source)
1437 {
1438 struct site *st=sst;
1439
1440 if (buf->size < 12) return False;
1441
1442 uint32_t dest=get_uint32(buf->start);
1443 uint32_t msgtype=get_uint32(buf->start+8);
1444 struct msg named_msg;
1445
1446 if (msgtype==LABEL_MSG1) {
1447 if (!named_for_us(st,buf,msgtype,&named_msg))
1448 return False;
1449 /* It's a MSG1 addressed to us. Decide what to do about it. */
1450 dump_packet(st,buf,source,True);
1451 if (st->state==SITE_RUN || st->state==SITE_RESOLVE ||
1452 st->state==SITE_WAIT) {
1453 /* We should definitely process it */
1454 if (process_msg1(st,buf,source,&named_msg)) {
1455 slog(st,LOG_SETUP_INIT,"key setup initiated by peer");
1456 enter_new_state(st,SITE_SENTMSG2);
1457 } else {
1458 slog(st,LOG_ERROR,"failed to process incoming msg1");
1459 }
1460 BUF_FREE(buf);
1461 return True;
1462 } else if (st->state==SITE_SENTMSG1) {
1463 /* We've just sent a message 1! They may have crossed on
1464 the wire. If we have priority then we ignore the
1465 incoming one, otherwise we process it as usual. */
1466 if (st->setup_priority) {
1467 BUF_FREE(buf);
1468 slog(st,LOG_DUMP,"crossed msg1s; we are higher "
1469 "priority => ignore incoming msg1");
1470 return True;
1471 } else {
1472 slog(st,LOG_DUMP,"crossed msg1s; we are lower "
1473 "priority => use incoming msg1");
1474 if (process_msg1(st,buf,source,&named_msg)) {
1475 BUF_FREE(&st->buffer); /* Free our old message 1 */
1476 enter_new_state(st,SITE_SENTMSG2);
1477 } else {
1478 slog(st,LOG_ERROR,"failed to process an incoming "
1479 "crossed msg1 (we have low priority)");
1480 }
1481 BUF_FREE(buf);
1482 return True;
1483 }
1484 }
1485 /* The message 1 was received at an unexpected stage of the
1486 key setup. XXX POLICY - what do we do? */
1487 slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
1488 BUF_FREE(buf);
1489 return True;
1490 }
1491 if (dest==st->index) {
1492 /* Explicitly addressed to us */
1493 if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
1494 switch (msgtype) {
1495 case LABEL_NAK:
1496 /* If the source is our current peer then initiate a key setup,
1497 because our peer's forgotten the key */
1498 if (get_uint32(buf->start+4)==st->current.remote_session_id) {
1499 initiate_key_setup(st,"received a NAK");
1500 } else {
1501 slog(st,LOG_SEC,"bad incoming NAK");
1502 }
1503 break;
1504 case LABEL_MSG0:
1505 process_msg0(st,buf,source);
1506 break;
1507 case LABEL_MSG1:
1508 /* Setup packet: should not have been explicitly addressed
1509 to us */
1510 slog(st,LOG_SEC,"incoming explicitly addressed msg1");
1511 break;
1512 case LABEL_MSG2:
1513 /* Setup packet: expected only in state SENTMSG1 */
1514 if (st->state!=SITE_SENTMSG1) {
1515 slog(st,LOG_UNEXPECTED,"unexpected MSG2");
1516 } else if (process_msg2(st,buf,source)) {
1517 transport_setup_msgok(st,source);
1518 enter_new_state(st,SITE_SENTMSG3);
1519 } else {
1520 slog(st,LOG_SEC,"invalid MSG2");
1521 }
1522 break;
1523 case LABEL_MSG3:
1524 case LABEL_MSG3BIS:
1525 /* Setup packet: expected only in state SENTMSG2 */
1526 if (st->state!=SITE_SENTMSG2) {
1527 slog(st,LOG_UNEXPECTED,"unexpected MSG3");
1528 } else if (process_msg3(st,buf,source,msgtype)) {
1529 transport_setup_msgok(st,source);
1530 enter_new_state(st,SITE_SENTMSG4);
1531 } else {
1532 slog(st,LOG_SEC,"invalid MSG3");
1533 }
1534 break;
1535 case LABEL_MSG4:
1536 /* Setup packet: expected only in state SENTMSG3 */
1537 if (st->state!=SITE_SENTMSG3) {
1538 slog(st,LOG_UNEXPECTED,"unexpected MSG4");
1539 } else if (process_msg4(st,buf,source)) {
1540 transport_setup_msgok(st,source);
1541 enter_new_state(st,SITE_SENTMSG5);
1542 } else {
1543 slog(st,LOG_SEC,"invalid MSG4");
1544 }
1545 break;
1546 case LABEL_MSG5:
1547 /* Setup packet: expected only in state SENTMSG4 */
1548 /* (may turn up in state RUN if our return MSG6 was lost
1549 and the new key has already been activated. In that
1550 case we discard it. The peer will realise that we
1551 are using the new key when they see our data packets.
1552 Until then the peer's data packets to us get discarded. */
1553 if (st->state==SITE_SENTMSG4) {
1554 if (process_msg5(st,buf,source,st->new_transform)) {
1555 transport_setup_msgok(st,source);
1556 enter_new_state(st,SITE_RUN);
1557 } else {
1558 slog(st,LOG_SEC,"invalid MSG5");
1559 }
1560 } else if (st->state==SITE_RUN) {
1561 if (process_msg5(st,buf,source,st->current.transform)) {
1562 slog(st,LOG_DROP,"got MSG5, retransmitting MSG6");
1563 transport_setup_msgok(st,source);
1564 create_msg6(st,st->current.transform,
1565 st->current.remote_session_id);
1566 transport_xmit(st,&st->peers,&st->buffer,True);
1567 BUF_FREE(&st->buffer);
1568 } else {
1569 slog(st,LOG_SEC,"invalid MSG5 (in state RUN)");
1570 }
1571 } else {
1572 slog(st,LOG_UNEXPECTED,"unexpected MSG5");
1573 }
1574 break;
1575 case LABEL_MSG6:
1576 /* Setup packet: expected only in state SENTMSG5 */
1577 if (st->state!=SITE_SENTMSG5) {
1578 slog(st,LOG_UNEXPECTED,"unexpected MSG6");
1579 } else if (process_msg6(st,buf,source)) {
1580 BUF_FREE(&st->buffer); /* Free message 5 */
1581 transport_setup_msgok(st,source);
1582 activate_new_key(st);
1583 } else {
1584 slog(st,LOG_SEC,"invalid MSG6");
1585 }
1586 break;
1587 default:
1588 slog(st,LOG_SEC,"received message of unknown type 0x%08x",
1589 msgtype);
1590 break;
1591 }
1592 BUF_FREE(buf);
1593 return True;
1594 }
1595
1596 return False;
1597 }
1598
1599 static void site_control(void *vst, bool_t run)
1600 {
1601 struct site *st=vst;
1602 if (run) enter_state_run(st);
1603 else enter_state_stop(st);
1604 }
1605
1606 static void site_phase_hook(void *sst, uint32_t newphase)
1607 {
1608 struct site *st=sst;
1609
1610 /* The program is shutting down; tell our peer */
1611 send_msg7(st,"shutting down");
1612 }
1613
1614 static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
1615 list_t *args)
1616 {
1617 static uint32_t index_sequence;
1618 struct site *st;
1619 item_t *item;
1620 dict_t *dict;
1621 int i;
1622
1623 st=safe_malloc(sizeof(*st),"site_apply");
1624
1625 st->cl.description="site";
1626 st->cl.type=CL_SITE;
1627 st->cl.apply=NULL;
1628 st->cl.interface=&st->ops;
1629 st->ops.st=st;
1630 st->ops.control=site_control;
1631 st->ops.status=site_status;
1632
1633 /* First parameter must be a dict */
1634 item=list_elem(args,0);
1635 if (!item || item->type!=t_dict)
1636 cfgfatal(loc,"site","parameter must be a dictionary\n");
1637
1638 dict=item->data.dict;
1639 st->localname=dict_read_string(dict, "local-name", True, "site", loc);
1640 st->remotename=dict_read_string(dict, "name", True, "site", loc);
1641
1642 st->peer_mobile=dict_read_bool(dict,"mobile",False,"site",loc,False);
1643 bool_t local_mobile=
1644 dict_read_bool(dict,"local-mobile",False,"site",loc,False);
1645
1646 /* Sanity check (which also allows the 'sites' file to include
1647 site() closures for all sites including our own): refuse to
1648 talk to ourselves */
1649 if (strcmp(st->localname,st->remotename)==0) {
1650 Message(M_DEBUG,"site %s: local-name==name -> ignoring this site\n",
1651 st->localname);
1652 if (st->peer_mobile != local_mobile)
1653 cfgfatal(loc,"site","site %s's peer-mobile=%d"
1654 " but our local-mobile=%d\n",
1655 st->localname, st->peer_mobile, local_mobile);
1656 free(st);
1657 return NULL;
1658 }
1659 if (st->peer_mobile && local_mobile) {
1660 Message(M_WARNING,"site %s: site is mobile but so are we"
1661 " -> ignoring this site\n", st->remotename);
1662 free(st);
1663 return NULL;
1664 }
1665
1666 assert(index_sequence < 0xffffffffUL);
1667 st->index = ++index_sequence;
1668 st->local_capabilities = 0;
1669 st->netlink=find_cl_if(dict,"link",CL_NETLINK,True,"site",loc);
1670
1671 #define GET_CLOSURE_LIST(dictkey,things,nthings,CL_TYPE) do{ \
1672 list_t *things##_cfg=dict_lookup(dict,dictkey); \
1673 if (!things##_cfg) \
1674 cfgfatal(loc,"site","closure list \"%s\" not found\n",dictkey); \
1675 st->nthings=list_length(things##_cfg); \
1676 st->things=safe_malloc_ary(sizeof(*st->things),st->nthings,dictkey "s"); \
1677 assert(st->nthings); \
1678 for (i=0; i<st->nthings; i++) { \
1679 item_t *item=list_elem(things##_cfg,i); \
1680 if (item->type!=t_closure) \
1681 cfgfatal(loc,"site","%s is not a closure\n",dictkey); \
1682 closure_t *cl=item->data.closure; \
1683 if (cl->type!=CL_TYPE) \
1684 cfgfatal(loc,"site","%s closure wrong type\n",dictkey); \
1685 st->things[i]=cl->interface; \
1686 } \
1687 }while(0)
1688
1689 GET_CLOSURE_LIST("comm",comms,ncomms,CL_COMM);
1690
1691 st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
1692 st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
1693 st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
1694
1695 st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
1696 st->address=dict_read_string(dict, "address", False, "site", loc);
1697 if (st->address)
1698 st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
1699 else st->remoteport=0;
1700 st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
1701
1702 GET_CLOSURE_LIST("transform",transforms,ntransforms,CL_TRANSFORM);
1703
1704 st->dh=find_cl_if(dict,"dh",CL_DH,True,"site",loc);
1705 st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
1706
1707 #define DEFAULT(D) (st->peer_mobile || local_mobile \
1708 ? DEFAULT_MOBILE_##D : DEFAULT_##D)
1709 #define CFG_NUMBER(k,D) dict_read_number(dict,(k),False,"site",loc,DEFAULT(D));
1710
1711 st->key_lifetime= CFG_NUMBER("key-lifetime", KEY_LIFETIME);
1712 st->setup_retries= CFG_NUMBER("setup-retries", SETUP_RETRIES);
1713 st->setup_retry_interval= CFG_NUMBER("setup-timeout", SETUP_RETRY_INTERVAL);
1714 st->wait_timeout= CFG_NUMBER("wait-time", WAIT_TIME);
1715
1716 st->mobile_peer_expiry= dict_read_number(
1717 dict,"mobile-peer-expiry",False,"site",loc,DEFAULT_MOBILE_PEER_EXPIRY);
1718
1719 st->transport_peers_max= !st->peer_mobile ? 1 : dict_read_number(
1720 dict,"mobile-peers-max",False,"site",loc,DEFAULT_MOBILE_PEERS_MAX);
1721 if (st->transport_peers_max<1 ||
1722 st->transport_peers_max>=MAX_MOBILE_PEERS_MAX) {
1723 cfgfatal(loc,"site","mobile-peers-max must be in range 1.."
1724 STRING(MAX_MOBILE_PEERS_MAX) "\n");
1725 }
1726
1727 if (st->key_lifetime < DEFAULT(KEY_RENEGOTIATE_GAP)*2)
1728 st->key_renegotiate_time=st->key_lifetime/2;
1729 else
1730 st->key_renegotiate_time=st->key_lifetime-DEFAULT(KEY_RENEGOTIATE_GAP);
1731 st->key_renegotiate_time=dict_read_number(
1732 dict,"renegotiate-time",False,"site",loc,st->key_renegotiate_time);
1733 if (st->key_renegotiate_time > st->key_lifetime) {
1734 cfgfatal(loc,"site",
1735 "renegotiate-time must be less than key-lifetime\n");
1736 }
1737
1738 st->log_events=string_list_to_word(dict_lookup(dict,"log-events"),
1739 log_event_table,"site");
1740
1741 st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
1742 "site_apply");
1743 sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
1744
1745 /* The information we expect to see in incoming messages of type 1 */
1746 /* fixme: lots of unchecked overflows here, but the results are only
1747 corrupted packets rather than undefined behaviour */
1748 st->setup_priority=(strcmp(st->localname,st->remotename)>0);
1749
1750 buffer_new(&st->buffer,SETUP_BUFFER_LEN);
1751
1752 buffer_new(&st->scratch,0);
1753 BUF_ALLOC(&st->scratch,"site:scratch");
1754
1755 /* We are interested in poll(), but only for timeouts. We don't have
1756 any fds of our own. */
1757 register_for_poll(st, site_beforepoll, site_afterpoll, 0, "site");
1758 st->timeout=0;
1759
1760 st->remote_capabilities=0;
1761 st->chosen_transform=0;
1762 st->current.key_timeout=0;
1763 st->auxiliary_key.key_timeout=0;
1764 transport_peers_clear(st,&st->peers);
1765 transport_peers_clear(st,&st->setup_peers);
1766 /* XXX mlock these */
1767 st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
1768 st->sharedsecretlen=st->sharedsecretallocd=0;
1769 st->sharedsecret=0;
1770
1771 /* We need to compute some properties of our comms and transports */
1772 #define COMPUTE_WORST(things,pad) \
1773 int things##_worst_##pad=0; \
1774 for (i=0; i<st->n##things; i++) { \
1775 int thispad=st->things[i]->pad; \
1776 if (thispad > things##_worst_##pad) \
1777 things##_worst_##pad=thispad; \
1778 }
1779 COMPUTE_WORST(comms,min_start_pad)
1780 COMPUTE_WORST(transforms,max_start_pad)
1781
1782 for (i=0; i<st->ntransforms; i++) {
1783 struct transform_if *ti=st->transforms[i];
1784 uint32_t capbit = 1UL << ti->capab_transformnum;
1785 if (st->local_capabilities & capbit)
1786 slog(st,LOG_ERROR,"transformnum capability bit"
1787 " %d (%#"PRIx32") reused", ti->capab_transformnum, capbit);
1788 st->local_capabilities |= capbit;
1789 }
1790
1791 /* We need to register the remote networks with the netlink device */
1792 st->netlink->reg(st->netlink->st, site_outgoing, st,
1793 transforms_worst_max_start_pad+(4*4)+
1794 comms_worst_min_start_pad);
1795
1796 for (i=0; i<st->ncomms; i++)
1797 st->comms[i]->request_notify(st->comms[i]->st, st, site_incoming);
1798
1799 st->current.transform=0;
1800 st->auxiliary_key.transform=0;
1801 st->new_transform=0;
1802 st->auxiliary_is_new=0;
1803
1804 enter_state_stop(st);
1805
1806 add_hook(PHASE_SHUTDOWN,site_phase_hook,st);
1807
1808 return new_closure(&st->cl);
1809 }
1810
1811 void site_module(dict_t *dict)
1812 {
1813 add_closure(dict,"site",site_apply);
1814 }
1815
1816
1817 /***** TRANSPORT PEERS definitions *****/
1818
1819 static void transport_peers_debug(struct site *st, transport_peers *dst,
1820 const char *didwhat,
1821 int nargs, const struct comm_addr *args,
1822 size_t stride) {
1823 int i;
1824 char *argp;
1825
1826 if (!(st->log_events & LOG_PEER_ADDRS))
1827 return; /* an optimisation */
1828
1829 slog(st, LOG_PEER_ADDRS, "peers (%s) %s nargs=%d => npeers=%d",
1830 (dst==&st->peers ? "data" :
1831 dst==&st->setup_peers ? "setup" : "UNKNOWN"),
1832 didwhat, nargs, dst->npeers);
1833
1834 for (i=0, argp=(void*)args;
1835 i<nargs;
1836 i++, (argp+=stride?stride:sizeof(*args))) {
1837 const struct comm_addr *ca=(void*)argp;
1838 slog(st, LOG_PEER_ADDRS, " args: addrs[%d]=%s",
1839 i, ca->comm->addr_to_string(ca->comm->st,ca));
1840 }
1841 for (i=0; i<dst->npeers; i++) {
1842 struct timeval diff;
1843 timersub(tv_now,&dst->peers[i].last,&diff);
1844 const struct comm_addr *ca=&dst->peers[i].addr;
1845 slog(st, LOG_PEER_ADDRS, " peers: addrs[%d]=%s T-%ld.%06ld",
1846 i, ca->comm->addr_to_string(ca->comm->st,ca),
1847 (unsigned long)diff.tv_sec, (unsigned long)diff.tv_usec);
1848 }
1849 }
1850
1851 static int transport_peer_compar(const void *av, const void *bv) {
1852 const transport_peer *a=av;
1853 const transport_peer *b=bv;
1854 /* put most recent first in the array */
1855 if (timercmp(&a->last, &b->last, <)) return +1;
1856 if (timercmp(&a->last, &b->last, >)) return -11;
1857 return 0;
1858 }
1859
1860 static void transport_peers_expire(struct site *st, transport_peers *peers) {
1861 /* peers must be sorted first */
1862 int previous_peers=peers->npeers;
1863 struct timeval oldest;
1864 oldest.tv_sec = tv_now->tv_sec - st->mobile_peer_expiry;
1865 oldest.tv_usec = tv_now->tv_usec;
1866 while (peers->npeers>1 &&
1867 timercmp(&peers->peers[peers->npeers-1].last, &oldest, <))
1868 peers->npeers--;
1869 if (peers->npeers != previous_peers)
1870 transport_peers_debug(st,peers,"expire", 0,0,0);
1871 }
1872
1873 static void transport_record_peer(struct site *st, transport_peers *peers,
1874 const struct comm_addr *addr, const char *m) {
1875 int slot, changed=0;
1876
1877 for (slot=0; slot<peers->npeers; slot++)
1878 if (!memcmp(&peers->peers[slot].addr, addr, sizeof(*addr)))
1879 goto found;
1880
1881 changed=1;
1882 if (peers->npeers==st->transport_peers_max)
1883 slot=st->transport_peers_max;
1884 else
1885 slot=peers->npeers++;
1886
1887 found:
1888 peers->peers[slot].addr=*addr;
1889 peers->peers[slot].last=*tv_now;
1890
1891 if (peers->npeers>1)
1892 qsort(peers->peers, peers->npeers,
1893 sizeof(*peers->peers), transport_peer_compar);
1894
1895 if (changed || peers->npeers!=1)
1896 transport_peers_debug(st,peers,m, 1,addr,0);
1897 transport_peers_expire(st, peers);
1898 }
1899
1900 static bool_t transport_compute_setupinit_peers(struct site *st,
1901 const struct comm_addr *configured_addr /* 0 if none or not found */) {
1902
1903 if (!configured_addr && !transport_peers_valid(&st->peers))
1904 return False;
1905
1906 slog(st,LOG_SETUP_INIT,
1907 (!configured_addr ? "using only %d old peer address(es)"
1908 : "using configured address, and/or perhaps %d old peer address(es)"),
1909 st->peers);
1910
1911 /* Non-mobile peers havve st->peers.npeers==0 or ==1, since they
1912 * have transport_peers_max==1. The effect is that this code
1913 * always uses the configured address if supplied, or otherwise
1914 * the existing data peer if one exists; this is as desired. */
1915
1916 transport_peers_copy(st,&st->setup_peers,&st->peers);
1917
1918 if (configured_addr)
1919 transport_record_peer(st,&st->setup_peers,configured_addr,"setupinit");
1920
1921 assert(transport_peers_valid(&st->setup_peers));
1922 return True;
1923 }
1924
1925 static void transport_setup_msgok(struct site *st, const struct comm_addr *a) {
1926 if (st->peer_mobile)
1927 transport_record_peer(st,&st->setup_peers,a,"setupmsg");
1928 }
1929 static void transport_data_msgok(struct site *st, const struct comm_addr *a) {
1930 if (st->peer_mobile)
1931 transport_record_peer(st,&st->peers,a,"datamsg");
1932 }
1933
1934 static int transport_peers_valid(transport_peers *peers) {
1935 return peers->npeers;
1936 }
1937 static void transport_peers_clear(struct site *st, transport_peers *peers) {
1938 peers->npeers= 0;
1939 transport_peers_debug(st,peers,"clear",0,0,0);
1940 }
1941 static void transport_peers_copy(struct site *st, transport_peers *dst,
1942 const transport_peers *src) {
1943 dst->npeers=src->npeers;
1944 memcpy(dst->peers, src->peers, sizeof(*dst->peers) * dst->npeers);
1945 transport_peers_debug(st,dst,"copy",
1946 src->npeers, &src->peers->addr, sizeof(*src->peers));
1947 }
1948
1949 void transport_xmit(struct site *st, transport_peers *peers,
1950 struct buffer_if *buf, bool_t candebug) {
1951 int slot;
1952 transport_peers_expire(st, peers);
1953 for (slot=0; slot<peers->npeers; slot++) {
1954 transport_peer *peer=&peers->peers[slot];
1955 if (candebug)
1956 dump_packet(st, buf, &peer->addr, False);
1957 peer->addr.comm->sendmsg(peer->addr.comm->st, buf, &peer->addr);
1958 }
1959 }
1960
1961 /***** END of transport peers declarations *****/