chiark / gitweb /
Import release 0.1.2
[secnet.git] / site.c
1 /* site.c - manage communication with a remote network site */
2
3 #include "secnet.h"
4 #include <stdio.h>
5 /* MBM asserts the next one is needed for compilation under BSD. */
6 #include <sys/socket.h>
7
8 #include <sys/mman.h>
9 #include "util.h"
10 #include "unaligned.h"
11
12 #define SETUP_BUFFER_LEN 2048
13
14 #define DEFAULT_KEY_LIFETIME 3600000 /* One hour */
15 #define DEFAULT_KEY_RENEGOTIATE_GAP 300000 /* Five minutes */
16 #define DEFAULT_SETUP_RETRIES 5
17 #define DEFAULT_SETUP_TIMEOUT 1000
18 #define DEFAULT_WAIT_TIME 10000
19
20 /* Each site can be in one of several possible states. */
21
22 /* States:
23    SITE_STOP         - nothing is allowed to happen; tunnel is down;
24                        all session keys have been erased
25      -> SITE_RUN upon external instruction
26    SITE_RUN          - site up, maybe with valid key
27      -> SITE_RESOLVE upon outgoing packet and no valid key
28          we start name resolution for the other end of the tunnel
29      -> SITE_SENTMSG2 upon valid incoming message 1 and suitable time
30          we send an appropriate message 2
31    SITE_RESOLVE      - waiting for name resolution
32      -> SITE_SENTMSG1 upon successful resolution
33          we send an appropriate message 1
34      -> SITE_SENTMSG2 upon valid incoming message 1 (then abort resolution)
35          we abort resolution and 
36      -> SITE_WAIT on timeout or resolution failure
37    SITE_SENTMSG1
38      -> SITE_SENTMSG2 upon valid incoming message 1 from higher priority end
39      -> SITE_SENTMSG3 upon valid incoming message 2
40      -> SITE_WAIT on timeout
41    SITE_SENTMSG2
42      -> SITE_SENTMSG4 upon valid incoming message 3
43      -> SITE_WAIT on timeout
44    SITE_SENTMSG3
45      -> SITE_SENTMSG5 upon valid incoming message 4
46      -> SITE_WAIT on timeout
47    SITE_SENTMSG4
48      -> SITE_RUN upon valid incoming message 5
49      -> SITE_WAIT on timeout
50    SITE_SENTMSG5
51      -> SITE_RUN upon valid incoming message 6
52      -> SITE_WAIT on timeout
53    SITE_WAIT         - failed to establish key; do nothing for a while
54      -> SITE_RUN on timeout
55    */
56
57 #define SITE_STOP     0
58 #define SITE_RUN      1
59 #define SITE_RESOLVE  2
60 #define SITE_SENTMSG1 3
61 #define SITE_SENTMSG2 4
62 #define SITE_SENTMSG3 5
63 #define SITE_SENTMSG4 6
64 #define SITE_SENTMSG5 7
65 #define SITE_WAIT     8
66
67 #if 0
68 static string_t state_name(uint32_t state)
69 {
70     switch (state) {
71     case 0: return "SITE_STOP";
72     case 1: return "SITE_RUN";
73     case 2: return "SITE_RESOLVE";
74     case 3: return "SITE_SENTMSG1";
75     case 4: return "SITE_SENTMSG2";
76     case 5: return "SITE_SENTMSG3";
77     case 6: return "SITE_SENTMSG4";
78     case 7: return "SITE_SENTMSG5";
79     case 8: return "SITE_WAIT";
80     default: return "*bad state*";
81     }
82 }
83 #endif /* 0 */
84
85 #define LABEL_MSG0 0x00020200
86 #define LABEL_MSG1 0x01010101
87 #define LABEL_MSG2 0x02020202
88 #define LABEL_MSG3 0x03030303
89 #define LABEL_MSG4 0x04040404
90 #define LABEL_MSG5 0x05050505
91 #define LABEL_MSG6 0x06060606
92 #define LABEL_MSG7 0x07070707
93 #define LABEL_MSG8 0x08080808
94 #define LABEL_MSG9 0x09090909
95
96 #define NONCELEN 8
97
98 #define LOG_UNEXPECTED    0x00000001
99 #define LOG_SETUP_INIT    0x00000002
100 #define LOG_SETUP_TIMEOUT 0x00000004
101 #define LOG_ACTIVATE_KEY  0x00000008
102 #define LOG_TIMEOUT_KEY   0x00000010
103 #define LOG_SEC           0x00000020
104 #define LOG_STATE         0x00000040
105 #define LOG_DROP          0x00000080
106 #define LOG_DUMP          0x00000100
107 #define LOG_ERROR         0x00000400
108
109 static struct flagstr log_event_table[]={
110     { "unexpected", LOG_UNEXPECTED },
111     { "setup-init", LOG_SETUP_INIT },
112     { "setup-timeout", LOG_SETUP_TIMEOUT },
113     { "activate-key", LOG_ACTIVATE_KEY },
114     { "timeout-key", LOG_TIMEOUT_KEY },
115     { "security", LOG_SEC },
116     { "state-change", LOG_STATE },
117     { "packet-drop", LOG_DROP },
118     { "dump-packets", LOG_DUMP },
119     { "errors", LOG_ERROR },
120     { "all", 0xffffffff },
121     { NULL, 0 }
122 };
123
124 struct site {
125     closure_t cl;
126     struct site_if ops;
127 /* configuration information */
128     string_t localname;
129     string_t remotename;
130     string_t tunname; /* localname<->remotename by default */
131     string_t address; /* DNS name for bootstrapping, optional */
132     int remoteport;
133     struct netlink_if *netlink;
134     struct comm_if *comm;
135     struct resolver_if *resolver;
136     struct log_if *log;
137     struct random_if *random;
138     struct rsaprivkey_if *privkey;
139     struct subnet_list remotenets;
140     struct rsapubkey_if *pubkey;
141     struct transform_if *transform;
142     struct dh_if *dh;
143     struct hash_if *hash;
144
145     uint32_t setup_retries; /* How many times to send setup packets */
146     uint32_t setup_timeout; /* Initial timeout for setup packets */
147     uint32_t wait_timeout; /* How long to wait if setup unsuccessful */
148     uint32_t key_lifetime; /* How long a key lasts once set up */
149     uint32_t key_renegotiate_time; /* If we see traffic (or a keepalive)
150                                       after this time, initiate a new
151                                       key exchange */
152
153     bool_t keepalive; /* Always keep the tunnel up */
154
155     uint8_t *setupsig; /* Expected signature of incoming MSG1 packets */
156     uint32_t setupsiglen; /* Allows us to discard packets quickly if
157                              they are not for us */
158     bool_t setup_priority; /* Do we have precedence if both sites emit
159                               message 1 simultaneously? */
160     uint32_t log_events;
161
162 /* runtime information */
163     uint32_t state;
164     uint64_t now; /* Most recently seen time */
165
166     void *netlink_cid;
167
168     uint32_t remote_session_id;
169     struct transform_inst_if *current_transform;
170     bool_t current_valid;
171     uint64_t current_key_timeout; /* End of life of current key */
172     struct sockaddr_in peer; /* Current address of peer */
173     bool_t peer_valid; /* Peer address becomes invalid when key times out,
174                           but only if we have a DNS name for our peer */
175
176     uint32_t setup_session_id;
177     struct sockaddr_in setup_peer;
178     uint8_t localN[NONCELEN]; /* Nonces for key exchange */
179     uint8_t remoteN[NONCELEN];
180     struct buffer_if buffer; /* Current outgoing key exchange packet */
181     uint32_t retries; /* Number of retries remaining */
182     uint64_t timeout; /* Timeout for current state */
183     uint8_t *dhsecret;
184     uint8_t *sharedsecret;
185
186     struct transform_inst_if *new_transform; /* For key setup/verify */
187 };
188
189 static void slog(struct site *st, uint32_t event, string_t msg, ...)
190 {
191     va_list ap;
192     uint8_t buf[240];
193
194     va_start(ap,msg);
195
196     if (event&st->log_events) {
197         vsnprintf(buf,240,msg,ap);
198         st->log->log(st->log->st,0,"%s: %s",st->tunname,buf);
199     }
200     va_end(ap);
201 }
202
203 static void set_link_quality(struct site *st);
204 static bool_t initiate_key_setup(struct site *st);
205 static void enter_state_run(struct site *st);
206 static bool_t enter_state_resolve(struct site *st);
207 static bool_t enter_state_sentmsg1(struct site *st);
208 static bool_t enter_state_sentmsg2(struct site *st);
209 static bool_t enter_state_sentmsg3(struct site *st);
210 static bool_t enter_state_sentmsg4(struct site *st);
211 static bool_t enter_state_sentmsg5(struct site *st);
212 static void enter_state_wait(struct site *st);
213
214 #define CHECK_AVAIL(b,l) do { if ((b)->size<(l)) return False; } while(0)
215 #define CHECK_EMPTY(b) do { if ((b)->size!=0) return False; } while(0)
216 #define CHECK_TYPE(b,t) do { uint32_t type; \
217     CHECK_AVAIL((b),4); \
218     type=buf_unprepend_uint32((b)); \
219     if (type!=(t)) return False; } while(0)
220
221 struct msg {
222     uint8_t *hashstart;
223     uint32_t dest;
224     uint32_t source;
225     uint32_t remlen;
226     uint8_t *remote;
227     uint32_t loclen;
228     uint8_t *local;
229     uint8_t *nR;
230     uint8_t *nL;
231     uint32_t pklen;
232     uint8_t *pk;
233     uint32_t hashlen;
234     uint32_t siglen;
235     uint8_t *sig;
236 };
237
238 /* Build any of msg1 to msg4. msg5 and msg6 are built from the inside out
239    using a transform. */
240 static bool_t generate_msg(struct site *st, uint32_t type, string_t what)
241 {
242     void *hst;
243     uint8_t *hash=alloca(st->hash->len);
244     string_t dhpub, sig;
245
246     st->retries=st->setup_retries;
247     BUF_ALLOC(&st->buffer,what);
248     buffer_init(&st->buffer,0);
249     buf_append_uint32(&st->buffer,
250         (type==LABEL_MSG1?0:st->setup_session_id));
251     buf_append_uint32(&st->buffer,(uint32_t)st);
252     buf_append_uint32(&st->buffer,type);
253     buf_append_string(&st->buffer,st->localname);
254     buf_append_string(&st->buffer,st->remotename);
255     memcpy(buf_append(&st->buffer,NONCELEN),st->localN,NONCELEN);
256     if (type==LABEL_MSG1) return True;
257     memcpy(buf_append(&st->buffer,NONCELEN),st->remoteN,NONCELEN);
258     if (type==LABEL_MSG2) return True;
259     dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len);
260     buf_append_string(&st->buffer,dhpub);
261     free(dhpub);
262     hst=st->hash->init();
263     st->hash->update(hst,st->buffer.start,st->buffer.size);
264     st->hash->final(hst,hash);
265     sig=st->privkey->sign(st->privkey->st,hash,st->hash->len);
266     buf_append_string(&st->buffer,sig);
267     free(sig);
268     return True;
269 }
270
271 static bool_t unpick_msg(struct site *st, uint32_t type,
272                          struct buffer_if *msg, struct msg *m)
273 {
274     m->hashstart=msg->start;
275     CHECK_AVAIL(msg,4);
276     m->dest=buf_unprepend_uint32(msg);
277     CHECK_AVAIL(msg,4);
278     m->source=buf_unprepend_uint32(msg);
279     CHECK_TYPE(msg,type);
280     CHECK_AVAIL(msg,2);
281     m->remlen=buf_unprepend_uint16(msg);
282     CHECK_AVAIL(msg,m->remlen);
283     m->remote=buf_unprepend(msg,m->remlen);
284     CHECK_AVAIL(msg,2);
285     m->loclen=buf_unprepend_uint16(msg);
286     CHECK_AVAIL(msg,m->loclen);
287     m->local=buf_unprepend(msg,m->loclen);
288     CHECK_AVAIL(msg,NONCELEN);
289     m->nR=buf_unprepend(msg,NONCELEN);
290     if (type==LABEL_MSG1) {
291         CHECK_EMPTY(msg);
292         return True;
293     }
294     CHECK_AVAIL(msg,NONCELEN);
295     m->nL=buf_unprepend(msg,NONCELEN);
296     if (type==LABEL_MSG2) {
297         CHECK_EMPTY(msg);
298         return True;
299     }
300     CHECK_AVAIL(msg,2);
301     m->pklen=buf_unprepend_uint16(msg);
302     CHECK_AVAIL(msg,m->pklen);
303     m->pk=buf_unprepend(msg,m->pklen);
304     m->hashlen=msg->start-m->hashstart;
305     CHECK_AVAIL(msg,2);
306     m->siglen=buf_unprepend_uint16(msg);
307     CHECK_AVAIL(msg,m->siglen);
308     m->sig=buf_unprepend(msg,m->siglen);
309     CHECK_EMPTY(msg);
310     return True;
311 }
312
313 static bool_t generate_msg1(struct site *st)
314 {
315     st->random->generate(st->random->st,NONCELEN,st->localN);
316     return generate_msg(st,LABEL_MSG1,"site:MSG1");
317 }
318
319 static bool_t process_msg1(struct site *st, struct buffer_if *msg1,
320                            struct sockaddr_in *src)
321 {
322     struct msg m;
323
324     /* We've already determined we're in an appropriate state to
325        process an incoming MSG1, and that the MSG1 has correct values
326        of A and B. */
327
328     if (!unpick_msg(st,LABEL_MSG1,msg1,&m)) return False;
329
330     /* XXX save src as our peer address here? */
331     st->setup_peer=*src;
332
333     st->setup_session_id=m.source;
334     memcpy(st->remoteN,m.nR,NONCELEN);
335     return True;
336 }
337
338 static bool_t generate_msg2(struct site *st)
339 {
340     st->random->generate(st->random->st,NONCELEN,st->localN);
341     return generate_msg(st,LABEL_MSG2,"site:MSG2");
342 }
343
344 static bool_t process_msg2(struct site *st, struct buffer_if *msg2,
345                            struct sockaddr_in *src)
346 {
347     struct msg m;
348
349     if (!unpick_msg(st,LABEL_MSG2,msg2,&m)) return False;
350
351     /* Check that the site names and our nonce have been sent
352        back correctly, and then store our peer's nonce. */ 
353     if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
354         slog(st,LOG_SEC,"msg2: bad B (remote site name)");
355         return False;
356     }
357     if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
358         slog(st,LOG_SEC,"msg2: bad A (local site name)");
359         return False;
360     }
361     if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
362         slog(st,LOG_SEC,"msg2: bad nA (locally generated nonce)");
363         return False;
364     }
365     st->setup_session_id=m.source;
366     memcpy(st->remoteN,m.nR,NONCELEN);
367     return True;
368 }
369
370 static bool_t generate_msg3(struct site *st)
371 {
372     /* Now we have our nonce and their nonce. Think of a secret key,
373        and create message number 3. */
374     st->random->generate(st->random->st,st->dh->len,st->dhsecret);
375     return generate_msg(st,LABEL_MSG3,"site:MSG3");
376 }
377
378 static bool_t process_msg3(struct site *st, struct buffer_if *msg3,
379                            struct sockaddr_in *src)
380 {
381     struct msg m;
382     uint8_t *hash=alloca(st->hash->len);
383     void *hst;
384
385     if (!unpick_msg(st,LABEL_MSG3,msg3,&m)) return False;
386
387     /* Check that the site names and nonces have been sent back
388        correctly */
389     if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
390         slog(st,LOG_SEC,"msg3: bad A (remote site name)");
391         return False;
392     }
393     if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
394         slog(st,LOG_SEC,"msg3: bad B (local site name)");
395         return False;
396     }
397     if (memcmp(m.nR,st->remoteN,NONCELEN)!=0) {
398         slog(st,LOG_SEC,"msg3: bad nA (remotely generated nonce)");
399         return False;
400     }
401     if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
402         slog(st,LOG_SEC,"msg3: bad nB (locally generated nonce)");
403         return False;
404     }
405     
406     /* Check signature and store g^x mod m */
407     hst=st->hash->init();
408     st->hash->update(hst,m.hashstart,m.hashlen);
409     st->hash->final(hst,hash);
410     /* Terminate signature with a '0' - cheating, but should be ok */
411     m.sig[m.siglen]=0;
412     if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
413         slog(st,LOG_SEC,"msg3 signature failed check!");
414         return False;
415     }
416
417     /* Terminate their DH public key with a '0' */
418     m.pk[m.pklen]=0;
419     /* Invent our DH secret key */
420     st->random->generate(st->random->st,st->dh->len,st->dhsecret);
421
422     /* Generate the shared key */
423     st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,m.pk,
424                        st->sharedsecret,st->transform->keylen);
425
426     /* Set up the transform */
427     st->new_transform->setkey(st->new_transform->st,st->sharedsecret,
428                               st->transform->keylen);
429
430     return True;
431 }
432
433 static bool_t generate_msg4(struct site *st)
434 {
435     /* We have both nonces, their public key and our private key. Generate
436        our public key, sign it and send it to them. */
437     return generate_msg(st,LABEL_MSG4,"site:MSG4");
438 }
439
440 static bool_t process_msg4(struct site *st, struct buffer_if *msg4,
441                            struct sockaddr_in *src)
442 {
443     struct msg m;
444     uint8_t *hash=alloca(st->hash->len);
445     void *hst;
446
447     if (!unpick_msg(st,LABEL_MSG4,msg4,&m)) return False;
448
449     /* Check that the site names and nonces have been sent back
450        correctly */
451     if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
452         slog(st,LOG_SEC,"msg4: bad B (remote site name)");
453         return False;
454     }
455     if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
456         slog(st,LOG_SEC,"msg4: bad A (local site name)");
457         return False;
458     }
459     if (memcmp(m.nR,st->remoteN,NONCELEN)!=0) {
460         slog(st,LOG_SEC,"msg4: bad nB (remotely generated nonce)");
461         return False;
462     }
463     if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
464         slog(st,LOG_SEC,"msg4: bad nA (locally generated nonce)");
465         return False;
466     }
467     
468     /* Check signature and store g^x mod m */
469     hst=st->hash->init();
470     st->hash->update(hst,m.hashstart,m.hashlen);
471     st->hash->final(hst,hash);
472     /* Terminate signature with a '0' - cheating, but should be ok */
473     m.sig[m.siglen]=0;
474     if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
475         slog(st,LOG_SEC,"msg4 signature failed check!");
476         return False;
477     }
478
479     /* Terminate their DH public key with a '0' */
480     m.pk[m.pklen]=0;
481     /* Generate the shared key */
482     st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,m.pk,
483                        st->sharedsecret,st->transform->keylen);
484     /* Set up the transform */
485     st->new_transform->setkey(st->new_transform->st,st->sharedsecret,
486                               st->transform->keylen);
487
488     return True;
489 }
490
491 static bool_t generate_msg5(struct site *st)
492 {
493     string_t transform_err;
494
495     BUF_ALLOC(&st->buffer,"site:MSG5");
496     /* We are going to add three words to the transformed message */
497     buffer_init(&st->buffer,st->transform->max_start_pad+(4*3));
498     buf_append_uint32(&st->buffer,LABEL_MSG5);
499     st->new_transform->forwards(st->new_transform->st,&st->buffer,
500                                 &transform_err);
501     buf_prepend_uint32(&st->buffer,LABEL_MSG5);
502     buf_prepend_uint32(&st->buffer,(uint32_t)st);
503     buf_prepend_uint32(&st->buffer,st->setup_session_id);
504
505     st->retries=st->setup_retries;
506     return True;
507 }
508
509 struct msg0 {
510     uint32_t dest;
511     uint32_t source;
512     uint32_t type;
513 };
514
515 static bool_t unpick_msg0(struct site *st, struct buffer_if *msg0,
516                           struct msg0 *m)
517 {
518     CHECK_AVAIL(msg0,4);
519     m->dest=buf_unprepend_uint32(msg0);
520     CHECK_AVAIL(msg0,4);
521     m->source=buf_unprepend_uint32(msg0);
522     CHECK_AVAIL(msg0,4);
523     m->type=buf_unprepend_uint32(msg0);
524     return True;
525     /* Leaves transformed part of buffer untouched */
526 }
527
528 static bool_t process_msg5(struct site *st, struct buffer_if *msg5,
529                            struct sockaddr_in *src)
530 {
531     struct msg0 m;
532     string_t transform_err;
533
534     if (!unpick_msg0(st,msg5,&m)) return False;
535
536     if (st->new_transform->reverse(st->new_transform->st,
537                                    msg5,&transform_err)) {
538         /* There's a problem */
539         slog(st,LOG_SEC,"process_msg5: transform: %s",transform_err);
540         return False;
541     }
542     /* Buffer should now contain untransformed PING packet data */
543     CHECK_AVAIL(msg5,4);
544     if (buf_unprepend_uint32(msg5)!=LABEL_MSG5) {
545         slog(st,LOG_SEC,"MSG5/PING packet contained invalid data");
546         return False;
547     }
548     CHECK_EMPTY(msg5);
549     return True;
550 }
551
552 static bool_t generate_msg6(struct site *st)
553 {
554     string_t transform_err;
555
556     BUF_ALLOC(&st->buffer,"site:MSG6");
557     /* We are going to add three words to the transformed message */
558     buffer_init(&st->buffer,st->transform->max_start_pad+(4*3));
559     buf_append_uint32(&st->buffer,LABEL_MSG6);
560     st->new_transform->forwards(st->new_transform->st,&st->buffer,
561                                 &transform_err);
562     buf_prepend_uint32(&st->buffer,LABEL_MSG6);
563     buf_prepend_uint32(&st->buffer,(uint32_t)st);
564     buf_prepend_uint32(&st->buffer,st->setup_session_id);
565
566     st->retries=1; /* Peer will retransmit MSG5 if necessary */
567     return True;
568 }
569
570 static bool_t process_msg6(struct site *st, struct buffer_if *msg6,
571                            struct sockaddr_in *src)
572 {
573     struct msg0 m;
574     string_t transform_err;
575
576     if (!unpick_msg0(st,msg6,&m)) return False;
577
578     if (st->new_transform->reverse(st->new_transform->st,
579                                    msg6,&transform_err)) {
580         /* There's a problem */
581         slog(st,LOG_SEC,"process_msg6: transform: %s",transform_err);
582         return False;
583     }
584     /* Buffer should now contain untransformed PING packet data */
585     CHECK_AVAIL(msg6,4);
586     if (buf_unprepend_uint32(msg6)!=LABEL_MSG6) {
587         slog(st,LOG_SEC,"MSG6/PONG packet contained invalid data");
588         return False;
589     }
590     CHECK_EMPTY(msg6);
591     return True;
592 }
593
594 static bool_t process_msg0(struct site *st, struct buffer_if *msg0,
595                            struct sockaddr_in *src)
596 {
597     struct msg0 m;
598     string_t transform_err;
599     uint32_t type;
600
601     if (!st->current_valid) {
602         slog(st,LOG_DROP,"incoming message but no current key -> dropping");
603         return initiate_key_setup(st);
604     }
605
606     if (!unpick_msg0(st,msg0,&m)) return False;
607
608     if (st->current_transform->reverse(st->current_transform->st,
609                                        msg0,&transform_err)) {
610         /* There's a problem */
611         slog(st,LOG_SEC,"transform: %s",transform_err);
612         return False;
613     }
614     CHECK_AVAIL(msg0,4);
615     type=buf_unprepend_uint32(msg0);
616     switch(type) {
617     case LABEL_MSG9:
618         /* Deliver to netlink layer */
619         st->netlink->deliver(st->netlink->st,st->netlink_cid,msg0);
620         return True;
621         break;
622     default:
623         slog(st,LOG_SEC,"incoming message of type %08x (unknown)",type);
624         break;
625     }
626     return False;
627 }
628
629 static void dump_packet(struct site *st, struct buffer_if *buf,
630                         struct sockaddr_in *addr, bool_t incoming)
631 {
632     uint32_t dest=ntohl(*(uint32_t *)buf->start);
633     uint32_t source=ntohl(*(uint32_t *)(buf->start+4));
634     uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
635
636     if (st->log_events & LOG_DUMP)
637         log(st->log,0,"%s: %s: %08x<-%08x: %08x:",
638             st->tunname,incoming?"incoming":"outgoing",
639             dest,source,msgtype);
640 }
641
642 static uint32_t site_status(void *st)
643 {
644     return 0;
645 }
646
647 static bool_t send_msg(struct site *st)
648 {
649     if (st->retries>0) {
650         dump_packet(st,&st->buffer,&st->setup_peer,False);
651         st->comm->sendmsg(st->comm->st,&st->buffer,&st->setup_peer);
652         st->timeout=st->now+st->setup_timeout;
653         st->retries--;
654         return True;
655     } else {
656         slog(st,LOG_SETUP_TIMEOUT,"timed out sending key setup packet");
657         enter_state_wait(st);
658         return False;
659     }
660 }
661
662 static void site_resolve_callback(void *sst, struct in_addr *address)
663 {
664     struct site *st=sst;
665
666     if (st->state!=SITE_RESOLVE) {
667         slog(st,LOG_UNEXPECTED,"site_resolve_callback called unexpectedly");
668         return;
669     }
670     if (address) {
671         memset(&st->setup_peer,0,sizeof(st->setup_peer));
672         st->setup_peer.sin_family=AF_INET;
673         st->setup_peer.sin_port=htons(st->remoteport);
674         st->setup_peer.sin_addr=*address;
675         enter_state_sentmsg1(st);
676     } else {
677         /* Resolution failed */
678         slog(st,LOG_ERROR,"resolution of %s failed",st->address);
679         enter_state_run(st);
680     }
681 }
682
683 static bool_t initiate_key_setup(struct site *st)
684 {
685     if (st->state!=SITE_RUN) return False;
686     if (st->address) {
687         slog(st,LOG_SETUP_INIT,"initiating key exchange; resolving address");
688         return enter_state_resolve(st);
689     } else if (st->peer_valid) {
690         slog(st,LOG_SETUP_INIT,"initiating key exchange using old "
691              "peer address");
692         st->setup_peer=st->peer;
693         return enter_state_sentmsg1(st);
694     }
695     return False;
696 }
697
698 static void activate_new_key(struct site *st)
699 {
700     struct transform_inst_if *t;
701
702     t=st->current_transform;
703     st->current_transform=st->new_transform;
704     st->new_transform=t;
705
706     t->delkey(t->st);
707     st->timeout=0;
708     st->current_valid=True;
709     st->current_key_timeout=st->now+st->key_lifetime;
710     st->peer=st->setup_peer;
711     st->peer_valid=True;
712     st->remote_session_id=st->setup_session_id;
713
714     slog(st,LOG_ACTIVATE_KEY,"new key activated");
715     enter_state_run(st);
716 }
717
718 static void state_assert(struct site *st, bool_t ok)
719 {
720     if (!ok) fatal("state_assert\n");
721 }
722
723 static void enter_state_stop(struct site *st)
724 {
725     st->state=SITE_STOP;
726     st->timeout=0;
727     st->current_transform->delkey(st->current_transform->st);
728     st->current_valid=False;
729     st->current_key_timeout=0;
730     
731     st->peer_valid=False;
732
733     set_link_quality(st);
734     
735     st->new_transform->delkey(st->new_transform->st);
736 }
737
738 static void set_link_quality(struct site *st)
739 {
740     uint32_t quality;
741     if (st->current_valid)
742         quality=LINK_QUALITY_UP;
743     else if (st->state==SITE_WAIT || st->state==SITE_STOP)
744         quality=LINK_QUALITY_DOWN;
745     else if (st->address)
746         quality=LINK_QUALITY_DOWN_CURRENT_ADDRESS;
747     else if (st->peer_valid)
748         quality=LINK_QUALITY_DOWN_STALE_ADDRESS;
749     else
750         quality=LINK_QUALITY_DOWN;
751
752     st->netlink->set_quality(st->netlink->st,st->netlink_cid,quality);
753 }
754
755 static void enter_state_run(struct site *st)
756 {
757     slog(st,LOG_STATE,"entering state RUN");
758     st->state=SITE_RUN;
759     st->timeout=0;
760
761     set_link_quality(st);
762     /* XXX get rid of key setup data */
763 }
764
765 static bool_t enter_state_resolve(struct site *st)
766 {
767     state_assert(st,st->state==SITE_RUN);
768     slog(st,LOG_STATE,"entering state RESOLVE");
769     st->state=SITE_RESOLVE;
770     st->resolver->request(st->resolver->st,st->address,
771                           site_resolve_callback,st);
772     return True;
773 }
774
775 static bool_t enter_state_sentmsg1(struct site *st)
776 {
777     state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE);
778     slog(st,LOG_STATE,"entering state SENTMSG1");
779     if (generate_msg1(st) && send_msg(st)) {
780         st->state=SITE_SENTMSG1;
781         return True;
782     }
783     slog(st,LOG_ERROR,"error entering state SENTMSG1");
784     st->buffer.free=False; /* Can't tell which it was, but enter_state_wait()
785                               will do a BUF_FREE() */
786     enter_state_wait(st);
787     return False;
788 }
789
790 static bool_t enter_state_sentmsg2(struct site *st)
791 {
792     state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE ||
793                  st->state==SITE_SENTMSG1 || st->state==SITE_WAIT);
794     slog(st,LOG_STATE,"entering state SENTMSG2");
795     if (generate_msg2(st) && send_msg(st)) {
796         st->state=SITE_SENTMSG2;
797         return True;
798     }
799     slog(st,LOG_ERROR,"error entering state SENTMSG2");
800     st->buffer.free=False;
801     enter_state_wait(st);
802     return False;
803 }
804
805 static bool_t enter_state_sentmsg3(struct site *st)
806 {
807     state_assert(st,st->state==SITE_SENTMSG1);
808     slog(st,LOG_STATE,"entering state SENTMSG3");
809     BUF_FREE(&st->buffer); /* Free message 1 */
810     if (generate_msg3(st) && send_msg(st)) {
811         st->state=SITE_SENTMSG3;
812         return True;
813     }
814     slog(st,LOG_ERROR,"error entering state SENTMSG3");
815     st->buffer.free=False;
816     enter_state_wait(st);
817     return False;
818 }
819
820 static bool_t enter_state_sentmsg4(struct site *st)
821 {
822     state_assert(st,st->state==SITE_SENTMSG2);
823     slog(st,LOG_STATE,"entering state SENTMSG4");
824     BUF_FREE(&st->buffer); /* Free message 2 */
825     if (generate_msg4(st) && send_msg(st)) {
826         st->state=SITE_SENTMSG4;
827         return True;
828     }
829     slog(st,LOG_ERROR,"error entering state SENTMSG4");
830     st->buffer.free=False;
831     enter_state_wait(st);
832     return False;
833 }
834
835 static bool_t enter_state_sentmsg5(struct site *st)
836 {
837     state_assert(st,st->state==SITE_SENTMSG3);
838     slog(st,LOG_STATE,"entering state SENTMSG5");
839     BUF_FREE(&st->buffer); /* Free message 3 */
840
841     if (generate_msg5(st) && send_msg(st)) {
842         st->state=SITE_SENTMSG5;
843         return True;
844     }
845     slog(st,LOG_ERROR,"error entering state SENTMSG5");
846     st->buffer.free=False;
847     enter_state_wait(st);
848     
849     return False;
850 }
851
852 static bool_t send_msg6(struct site *st)
853 {
854     state_assert(st,st->state==SITE_SENTMSG4);
855     slog(st,LOG_STATE,"entering state RUN after sending msg6");
856     BUF_FREE(&st->buffer); /* Free message 4 */
857     if (generate_msg6(st) && send_msg(st)) {
858         BUF_FREE(&st->buffer); /* Never reused */
859         st->timeout=0; /* Never retransmit */
860         activate_new_key(st);
861         return True;
862     }
863     slog(st,LOG_ERROR,"error entering state RUN after sending msg6");
864     st->buffer.free=False;
865     enter_state_wait(st);
866     return False;
867 }
868
869 /* We go into this state if our peer becomes uncommunicative. Similar to
870    the "stop" state, we forget all session keys for a while, before
871    re-entering the "run" state. */
872 static void enter_state_wait(struct site *st)
873 {
874     slog(st,LOG_STATE,"entering state WAIT");
875     st->timeout=st->now+st->wait_timeout;
876     st->state=SITE_WAIT;
877     st->peer_valid=False;
878     set_link_quality(st);
879     BUF_FREE(&st->buffer); /* will have had an outgoing packet in it */
880     /* XXX Erase keys etc. */
881 }
882
883 static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
884                            int *timeout_io, const struct timeval *tv_now,
885                            uint64_t *now)
886 {
887     struct site *st=sst;
888
889     *nfds_io=0; /* We don't use any file descriptors */
890     st->now=*now;
891
892     /* Work out when our next timeout is. The earlier of 'timeout' or
893        'current_key_timeout'. A stored value of '0' indicates no timeout
894        active. */
895     if (st->timeout && st->timeout-*now < *timeout_io) {
896         *timeout_io=st->timeout-*now;
897     }
898
899     if (st->current_key_timeout && st->current_key_timeout-*now < *timeout_io)
900         *timeout_io=st->current_key_timeout-*now;
901
902     return 0; /* success */
903 }
904
905 /* NB site_afterpoll will be called before site_beforepoll is ever called */
906 static void site_afterpoll(void *sst, struct pollfd *fds, int nfds,
907                            const struct timeval *tv_now, uint64_t *now)
908 {
909     struct site *st=sst;
910
911     st->now=*now;
912     if (st->timeout && *now>st->timeout) {
913         /* Do stuff */
914         st->timeout=0;
915         if (st->state>=SITE_SENTMSG1 && st->state<=SITE_SENTMSG5)
916             send_msg(st);
917         else if (st->state==SITE_WAIT) {
918             enter_state_run(st);
919         } else {
920             slog(st,LOG_ERROR,"site_afterpoll: unexpected timeout, state=%d",
921                  st->state);
922         }
923     }
924     if (st->current_key_timeout && *now>st->current_key_timeout) {
925         slog(st,LOG_TIMEOUT_KEY,"maximum key life exceeded; session closed");
926         st->current_valid=False;
927         st->current_transform->delkey(st->current_transform->st);
928         st->current_key_timeout=0;
929         set_link_quality(st);
930     }
931 }
932
933 /* This function is called by the netlink device to deliver packets
934    intended for the remote network. The packet is in "raw" wire
935    format, but is guaranteed to be word-aligned. */
936 static void site_outgoing(void *sst, void *cid, struct buffer_if *buf)
937 {
938     struct site *st=sst;
939     string_t transform_err;
940     
941     if (st->state==SITE_STOP) {
942         BUF_FREE(buf);
943         return;
944     }
945
946     /* In all other states we consider delivering the packet if we have
947        a valid key and a valid address to send it to. */
948     if (st->current_valid && st->peer_valid) {
949         /* Transform it and send it */
950         if (buf->size>0) {
951             buf_prepend_uint32(buf,LABEL_MSG9);
952             st->current_transform->forwards(st->current_transform->st,
953                                             buf, &transform_err);
954             buf_prepend_uint32(buf,LABEL_MSG0);
955             buf_prepend_uint32(buf,(uint32_t)st);
956             buf_prepend_uint32(buf,st->remote_session_id);
957             st->comm->sendmsg(st->comm->st,buf,&st->peer);
958         }
959         BUF_FREE(buf);
960         return;
961     }
962
963     slog(st,LOG_DROP,"discarding outgoing packet of size %d",buf->size);
964     BUF_FREE(buf);
965     initiate_key_setup(st);
966 }
967
968 /* This function is called by the communication device to deliver
969    packets from our peers. */
970 static bool_t site_incoming(void *sst, struct buffer_if *buf,
971                             struct sockaddr_in *source)
972 {
973     struct site *st=sst;
974     uint32_t dest=ntohl(*(uint32_t *)buf->start);
975
976     if (dest==0) {
977         if (buf->size<(st->setupsiglen+8+NONCELEN)) return False;
978         /* It could be for any site - it should have LABEL_MSG1 and
979            might have our name and our peer's name in it */
980         if (memcmp(buf->start+8,st->setupsig,st->setupsiglen)==0) {
981             dump_packet(st,buf,source,True);
982             /* It's addressed to us. Decide what to do about it. */
983             if (st->state==SITE_RUN || st->state==SITE_RESOLVE ||
984                 st->state==SITE_WAIT) {
985                 /* We should definitely process it */
986                 if (process_msg1(st,buf,source)) {
987                     slog(st,LOG_SETUP_INIT,"key setup initiated by peer");
988                     enter_state_sentmsg2(st);
989                 } else {
990                     slog(st,LOG_ERROR,"failed to process incoming msg1");
991                 }
992                 BUF_FREE(buf);
993                 return True;
994             }
995             if (st->state==SITE_SENTMSG1) {
996                 /* We've just sent a message 1! They may have crossed on
997                    the wire. If we have priority then we ignore the
998                    incoming one, otherwise we process it as usual. */
999                 if (st->setup_priority) {
1000                     BUF_FREE(buf);
1001                     slog(st,LOG_DUMP,"crossed msg1s; we are higher "
1002                          "priority => ignore incoming msg1");
1003                     return True;
1004                 } else {
1005                     slog(st,LOG_DUMP,"crossed msg1s; we are lower "
1006                          "priority => use incoming msg1");
1007                     if (process_msg1(st,buf,source)) {
1008                         BUF_FREE(&st->buffer); /* Free our old message 1 */
1009                         enter_state_sentmsg2(st);
1010                     } else {
1011                         slog(st,LOG_ERROR,"failed to process an incoming "
1012                              "crossed msg1 (we have low priority)");
1013                     }
1014                     BUF_FREE(buf);
1015                     return True;
1016                 }
1017             }
1018             /* The message 1 was received at an unexpected stage of the
1019                key setup. XXX POLICY - what do we do? */
1020             slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
1021             BUF_FREE(buf);
1022             return True;
1023         }
1024         return False; /* Not for us. */
1025     }
1026     if (dest==(uint32_t)st) {
1027         uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
1028         /* Explicitly addressed to us */
1029         if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
1030         switch (msgtype) {
1031         case LABEL_MSG0:
1032             process_msg0(st,buf,source);
1033             break;
1034         case LABEL_MSG1:
1035             /* Setup packet: should not have been explicitly addressed
1036                to us */
1037             slog(st,LOG_SEC,"incoming explicitly addressed msg1");
1038             break;
1039         case LABEL_MSG2:
1040             /* Setup packet: expected only in state SENTMSG1 */
1041             if (st->state!=SITE_SENTMSG1) {
1042                 slog(st,LOG_UNEXPECTED,"unexpected MSG2");
1043             } else if (process_msg2(st,buf,source))
1044                 enter_state_sentmsg3(st);
1045             else {
1046                 slog(st,LOG_SEC,"invalid MSG2");
1047             }
1048             break;
1049         case LABEL_MSG3:
1050             /* Setup packet: expected only in state SENTMSG2 */
1051             if (st->state!=SITE_SENTMSG2) {
1052                 slog(st,LOG_UNEXPECTED,"unexpected MSG3");
1053             } else if (process_msg3(st,buf,source))
1054                 enter_state_sentmsg4(st);
1055             else {
1056                 slog(st,LOG_SEC,"invalid MSG3");
1057             }
1058             break;
1059         case LABEL_MSG4:
1060             /* Setup packet: expected only in state SENTMSG3 */
1061             if (st->state!=SITE_SENTMSG3) {
1062                 slog(st,LOG_UNEXPECTED,"unexpected MSG4");
1063             } else if (process_msg4(st,buf,source))
1064                 enter_state_sentmsg5(st);
1065             else {
1066                 slog(st,LOG_SEC,"invalid MSG4");
1067             }
1068             break;
1069         case LABEL_MSG5:
1070             /* Setup packet: expected only in state SENTMSG4 */
1071             /* (may turn up in state RUN if our return MSG6 was lost
1072                and the new key has already been activated. In that
1073                case we should treat it as an ordinary PING packet. We
1074                can't pass it to process_msg5() because the
1075                new_transform will now be null. XXX) */
1076             if (st->state!=SITE_SENTMSG4) {
1077                 slog(st,LOG_UNEXPECTED,"unexpected MSG5");
1078             } else if (process_msg5(st,buf,source)) {
1079                 send_msg6(st);
1080             } else {
1081                 slog(st,LOG_SEC,"invalid MSG5");
1082             }
1083             break;
1084         case LABEL_MSG6:
1085             /* Setup packet: expected only in state SENTMSG5 */
1086             if (st->state!=SITE_SENTMSG5) {
1087                 slog(st,LOG_UNEXPECTED,"unexpected MSG6");
1088             } else if (process_msg6(st,buf,source)) {
1089                 BUF_FREE(&st->buffer); /* Free message 5 */
1090                 activate_new_key(st);
1091             } else {
1092                 slog(st,LOG_SEC,"invalid MSG6");
1093             }
1094             break;
1095         case LABEL_MSG8:
1096             /* NAK packet: enter state where we ping and check for response */
1097             slog(st,LOG_ERROR,"received a NAK");
1098             break;
1099         default:
1100             slog(st,LOG_SEC,"received message of unknown type 0x%08x",
1101                  msgtype);
1102             break;
1103         }
1104         BUF_FREE(buf);
1105         return True;
1106     }
1107
1108     return False;
1109 }
1110
1111 static void site_control(void *vst, bool_t run)
1112 {
1113     struct site *st=vst;
1114     if (run) enter_state_run(st);
1115     else enter_state_stop(st);
1116 }
1117
1118 static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
1119                           list_t *args)
1120 {
1121     struct site *st;
1122     item_t *item;
1123     dict_t *dict;
1124
1125     st=safe_malloc(sizeof(*st),"site_apply");
1126
1127     st->cl.description="site";
1128     st->cl.type=CL_SITE;
1129     st->cl.apply=NULL;
1130     st->cl.interface=&st->ops;
1131     st->ops.st=st;
1132     st->ops.control=site_control;
1133     st->ops.status=site_status;
1134
1135     /* First parameter must be a dict */
1136     item=list_elem(args,0);
1137     if (!item || item->type!=t_dict)
1138         cfgfatal(loc,"site","parameter must be a dictionary\n");
1139     
1140     dict=item->data.dict;
1141     st->localname=dict_read_string(dict, "local-name", True, "site", loc);
1142     st->remotename=dict_read_string(dict, "name", True, "site", loc);
1143     /* Sanity check (which also allows the 'sites' file to include
1144        site() closures for all sites including our own): refuse to
1145        talk to ourselves */
1146     if (strcmp(st->localname,st->remotename)==0) {
1147         Message(M_INFO,"site %s: local-name==name -> ignoring this site\n",
1148                 st->localname);
1149         free(st);
1150         return NULL;
1151     }
1152     st->netlink=find_cl_if(dict,"netlink",CL_NETLINK,True,"site",loc);
1153     st->comm=find_cl_if(dict,"comm",CL_COMM,True,"site",loc);
1154     st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
1155     st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
1156     st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
1157
1158     st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
1159     st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
1160
1161     st->address=dict_read_string(dict, "address", False, "site", loc);
1162     dict_read_subnet_list(dict, "networks", True, "site", loc,
1163                           &st->remotenets);
1164     st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
1165
1166     st->transform=
1167         find_cl_if(dict,"transform",CL_TRANSFORM,True,"site",loc);
1168
1169     st->dh=find_cl_if(dict,"dh",CL_DH,True,"site",loc);
1170     st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
1171
1172     st->key_lifetime=dict_read_number(
1173         dict,"key-lifetime",False,"site",loc,DEFAULT_KEY_LIFETIME);
1174     if (st->key_lifetime < DEFAULT_KEY_RENEGOTIATE_GAP)
1175         st->key_renegotiate_time=st->key_lifetime/2;
1176     else
1177         st->key_renegotiate_time=st->key_lifetime-DEFAULT_KEY_RENEGOTIATE_GAP;
1178     st->setup_retries=dict_read_number(
1179         dict,"setup-retries",False,"site",loc,DEFAULT_SETUP_RETRIES);
1180     st->setup_timeout=dict_read_number(
1181         dict,"setup-timeout",False,"site",loc,DEFAULT_SETUP_TIMEOUT);
1182     st->wait_timeout=dict_read_number(
1183         dict,"wait-time",False,"site",loc,DEFAULT_WAIT_TIME);
1184     st->key_renegotiate_time=dict_read_number(
1185         dict,"renegotiate-time",False,"site",loc,st->key_lifetime);
1186     if (st->key_renegotiate_time > st->key_lifetime) {
1187         cfgfatal(loc,"site",
1188                  "renegotiate-time must be less than key-lifetime\n");
1189     }
1190     /* XXX keepalive will eventually default to True */
1191     st->keepalive=dict_read_bool(dict,"keepalive",False,"site",loc,False);
1192
1193     st->log_events=string_list_to_word(dict_lookup(dict,"log-events"),
1194                                        log_event_table,"site");
1195
1196     st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
1197                             "site_apply");
1198     sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
1199
1200     /* The information we expect to see in incoming messages of type 1 */
1201     /* XXX fix this bit for unaligned access */
1202     st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
1203     st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
1204     put_uint32(st->setupsig+0,LABEL_MSG1);
1205     put_uint16(st->setupsig+4,strlen(st->remotename));
1206     memcpy(&st->setupsig[6],st->remotename,strlen(st->remotename));
1207     put_uint16(st->setupsig+(6+strlen(st->remotename)),strlen(st->localname));
1208     memcpy(&st->setupsig[8+strlen(st->remotename)],st->localname,
1209            strlen(st->localname));
1210     st->setup_priority=(strcmp(st->localname,st->remotename)>0);
1211
1212     buffer_new(&st->buffer,SETUP_BUFFER_LEN);
1213
1214     /* We are interested in poll(), but only for timeouts. We don't have
1215        any fds of our own. */
1216     register_for_poll(st, site_beforepoll, site_afterpoll, 0, "site");
1217     st->timeout=0;
1218
1219     st->current_valid=False;
1220     st->current_key_timeout=0;
1221     st->peer_valid=False;
1222     /* XXX mlock these */
1223     st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
1224     st->sharedsecret=safe_malloc(st->transform->keylen,"site:sharedsecret");
1225
1226     /* We need to register the remote networks with the netlink device */
1227     st->netlink_cid=st->netlink->regnets(st->netlink->st, &st->remotenets,
1228                                          site_outgoing, st,
1229                                          st->transform->max_start_pad+(4*4),
1230                                          st->transform->max_end_pad,
1231                                          (st->address!=NULL), st->tunname);
1232     if (!st->netlink_cid) {
1233         Message(M_WARNING,"%s: netlink device did not let us register "
1234                 "our remote networks. This site will not start.\n",
1235                 st->tunname);
1236         return NULL; /* XXX should free site first */
1237     }
1238
1239     st->comm->request_notify(st->comm->st, st, site_incoming);
1240
1241     st->current_transform=st->transform->create(st->transform->st);
1242     st->new_transform=st->transform->create(st->transform->st);
1243
1244     enter_state_stop(st);
1245
1246     return new_closure(&st->cl);
1247 }
1248
1249 init_module site_module;
1250 void site_module(dict_t *dict)
1251 {
1252     add_closure(dict,"site",site_apply);
1253 }