Filled up the protocol structs with unused bytes.
[tinc] / src / protocol.c
1 /*
2     protocol.c -- handle the meta-protocol
3     Copyright (C) 1999 Ivo Timmermans <zarq@iname.com>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "config.h"
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <syslog.h>
25 #include <sys/socket.h>
26 #include <unistd.h>
27
28 #include <utils.h>
29 #include <xalloc.h>
30
31 #include "conf.h"
32 #include "encr.h"
33 #include "net.h"
34 #include "netutl.h"
35 #include "protocol.h"
36
37 int send_ack(conn_list_t *cl)
38 {
39   unsigned char tmp = ACK;
40 cp
41   if(debug_lvl > 2)
42     syslog(LOG_DEBUG, "Send ACK to %s", cl->hostname);
43
44   syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
45   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
46     {
47       syslog(LOG_ERR, "send failed: %d:%d: %m", __FILE__, __LINE__);
48       return -1;
49     }
50 cp
51   return 0;
52 }
53
54 int send_termreq(conn_list_t *cl)
55 {
56   termreq_t tmp;
57 cp
58   memset(&tmp, 0, sizeof(tmp));
59   tmp.type = TERMREQ;
60   tmp.vpn_ip = myself->vpn_ip;
61
62   if(debug_lvl > 2)
63     syslog(LOG_DEBUG, "Send TERMREQ(" IP_ADDR_S ") to " IP_ADDR_S, IP_ADDR_V(tmp.vpn_ip),
64            IP_ADDR_V(cl->vpn_ip));
65
66   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
67     {
68       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
69       return -1;
70     }
71 cp
72   return 0;
73 }
74
75 int send_timeout(conn_list_t *cl)
76 {
77   termreq_t tmp;
78 cp
79   memset(&tmp, 0, sizeof(tmp));
80   tmp.type = PINGTIMEOUT;
81   tmp.vpn_ip = myself->vpn_ip;
82
83   if(debug_lvl > 2)
84     syslog(LOG_DEBUG, "Send TIMEOUT(" IP_ADDR_S ") to " IP_ADDR_S, IP_ADDR_V(tmp.vpn_ip),
85            IP_ADDR_V(cl->vpn_ip));
86
87   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
88     {
89       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
90       return -1;
91     }
92 cp
93   return 0;
94 }
95
96 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
97 {
98   del_host_t tmp;
99 cp
100   memset(&tmp, 0, sizeof(tmp));
101   tmp.type = DEL_HOST;
102   tmp.vpn_ip = new_host->vpn_ip;
103
104   if(debug_lvl > 2)
105     syslog(LOG_DEBUG, "Sending delete host %lx to " IP_ADDR_S,
106            tmp.vpn_ip, IP_ADDR_V(cl->vpn_ip));
107
108   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
109     {
110       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
111       return -1;
112     }
113 cp
114   return 0;
115 }
116
117 int send_ping(conn_list_t *cl)
118 {
119   unsigned char tmp = PING;
120 cp
121   if(debug_lvl > 3)
122     syslog(LOG_DEBUG, "pinging " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
123
124   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
125     {
126       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
127       return -1;
128     }
129 cp
130   return 0;
131 }
132
133 int send_pong(conn_list_t *cl)
134 {
135   unsigned char tmp = PONG;
136 cp
137   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
138     {
139       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
140       return -1;
141     }
142 cp
143   return 0;
144 }
145
146 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
147 {
148   add_host_t tmp;
149 cp
150   memset(&tmp, 0, sizeof(tmp));
151   tmp.type = ADD_HOST;
152   tmp.real_ip = new_host->real_ip;
153   tmp.vpn_ip = new_host->vpn_ip;
154   tmp.vpn_mask = new_host->vpn_mask;
155   tmp.portnr = new_host->port;
156
157   if(debug_lvl > 2)
158     syslog(LOG_DEBUG, "Sending add host (%lx/%lx %lx:%hd) to " IP_ADDR_S,
159            tmp.vpn_ip, tmp.vpn_mask, tmp.real_ip, tmp.portnr,
160            IP_ADDR_V(cl->vpn_ip));
161
162   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
163     {
164       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
165       return -1;
166     }
167 cp
168   return 0;
169 }
170
171 int send_key_changed(conn_list_t *cl, conn_list_t *src)
172 {
173   key_changed_t tmp;
174 cp
175   memset(&tmp, 0, sizeof(tmp));
176   tmp.type = KEY_CHANGED;
177   tmp.from = src->vpn_ip;
178
179   if(debug_lvl > 2)
180     syslog(LOG_DEBUG, "Sending KEY_CHANGED (%lx) to " IP_ADDR_S,
181            tmp.from, IP_ADDR_V(cl->vpn_ip));
182
183   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
184     {
185       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
186       return -1;
187     }
188 cp
189   return 0;
190 }
191
192 void send_key_changed2(void)
193 {
194   conn_list_t *p;
195 cp
196   for(p = conn_list; p != NULL; p = p->next)
197     if(p->status.meta && p->protocol_version > PROT_3)
198       send_key_changed(p, myself);
199 cp
200 }
201
202 int send_basic_info(conn_list_t *cl)
203 {
204   basic_info_t tmp;
205 cp
206   memset(&tmp, 0, sizeof(tmp));
207   tmp.type = BASIC_INFO;
208   tmp.protocol = PROT_CURRENT;
209
210   tmp.portnr = myself->port;
211   tmp.vpn_ip = myself->vpn_ip;
212   tmp.vpn_mask = myself->vpn_mask;
213
214   if(debug_lvl > 2)
215     syslog(LOG_DEBUG, "Send BASIC_INFO(%d,%hd," IP_ADDR_S "," IP_ADDR_S ") to " IP_ADDR_S,
216            tmp.protocol, tmp.portnr, IP_ADDR_V(tmp.vpn_ip), IP_ADDR_V(tmp.vpn_mask),
217            IP_ADDR_V(cl->real_ip));
218
219   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
220     {
221       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
222       return -1;
223     }
224 cp
225   return 0;
226 }
227
228 int send_passphrase(conn_list_t *cl)
229 {
230   passphrase_t tmp;
231 cp
232   memset(&tmp, 0, sizeof(tmp));
233   tmp.type = PASSPHRASE;
234   encrypt_passphrase(&tmp);
235
236   if(debug_lvl > 2)
237     syslog(LOG_DEBUG, "Send PASSPHRASE(%hd,...) to " IP_ADDR_S, tmp.len,
238            IP_ADDR_V(cl->vpn_ip));
239
240   if((write(cl->meta_socket, &tmp, tmp.len+3)) < 0)
241     {
242       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
243       return -1;
244     }
245 cp
246   return 0;
247 }
248
249 int send_public_key(conn_list_t *cl)
250 {
251   public_key_t *tmp;
252 cp
253   tmp = (public_key_t*)xmalloc(strlen(my_public_key_base36)+sizeof(*tmp));
254   memset(tmp, 0, sizeof(*tmp));
255   tmp->type = PUBLIC_KEY;
256   tmp->len = strlen(my_public_key_base36);
257   strcpy(&tmp->key, my_public_key_base36);
258
259   if(debug_lvl > 2)
260     syslog(LOG_DEBUG, "Send PUBLIC_KEY(%hd,%s) to " IP_ADDR_S, tmp->len, &tmp->key,
261            IP_ADDR_V(cl->vpn_ip));
262
263   if((write(cl->meta_socket, tmp, tmp->len+sizeof(*tmp))) < 0)
264     {
265       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
266       return -1;
267     }
268 cp
269   return 0;
270 }
271
272 int send_calculate(conn_list_t *cl, char *k)
273 {
274   calculate_t *tmp;
275 cp
276   tmp = xmalloc(strlen(k)+sizeof(*tmp));
277   memset(tmp, 0, sizeof(*tmp));
278   tmp->type = CALCULATE;
279   tmp->len = strlen(k);
280   strcpy(&tmp->key, k);
281
282   if((write(cl->meta_socket, tmp, tmp->len+sizeof(*tmp))) < 0)
283     {
284       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
285       return -1;
286     }
287 cp
288   return 0;
289 }
290
291 int send_key_request(ip_t to)
292 {
293   key_req_t *tmp;
294   conn_list_t *fw;
295 cp
296   tmp = xmalloc(sizeof(*tmp));
297   memset(tmp, 0, sizeof(*tmp));
298   tmp->type = REQ_KEY;
299   tmp->to = to;
300   tmp->from = myself->vpn_ip;
301   tmp->len = 0;
302
303   fw = lookup_conn(to);
304   if(!fw)
305     {
306       syslog(LOG_ERR, "Attempting to send key request to " IP_ADDR_S ", which does not exist?",
307              IP_ADDR_V(to));
308       return -1;
309     }
310
311   if(debug_lvl > 2)
312     syslog(LOG_DEBUG, "Sending out request for public key to " IP_ADDR_S,
313            IP_ADDR_V(fw->nexthop->vpn_ip));
314   if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)) < 0)
315     {
316       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
317       return -1;
318     }
319   fw->status.waitingforkey = 1;
320 cp
321   return 0;
322 }
323
324 int send_key_answer(conn_list_t *cl, ip_t to)
325 {
326   key_req_t *tmp;
327   conn_list_t *fw;
328 cp
329   tmp = xmalloc(sizeof(*tmp)+strlen(my_public_key_base36));
330   memset(tmp, 0, sizeof(*tmp));
331   tmp->type = ANS_KEY;
332   tmp->to = to;
333   tmp->from = myself->vpn_ip;
334   tmp->expiry = my_key_expiry;
335   tmp->len = strlen(my_public_key_base36);
336   strcpy(&tmp->key, my_public_key_base36);
337
338   fw = lookup_conn(to);
339   
340   if(!fw)
341   {
342     syslog(LOG_ERR, "Attempting to send key answer to " IP_ADDR_S ", which does not exist?",
343            IP_ADDR_V(to));
344     return -1;
345   }
346   
347   if(debug_lvl > 2)
348     syslog(LOG_DEBUG, "Sending public key to " IP_ADDR_S,
349            IP_ADDR_V(fw->nexthop->vpn_ip));
350   if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)+tmp->len) < 0)
351     {
352       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
353       return -1;
354     }
355 cp
356   return 0;
357 }
358
359 /*
360   notify all my direct connections of a new host
361   that was added to the vpn, with the exception
362   of the source of the announcement.
363 */
364 int notify_others(conn_list_t *new, conn_list_t *source,
365                   int (*function)(conn_list_t*, conn_list_t*))
366 {
367   conn_list_t *p;
368 cp
369   for(p = conn_list; p != NULL; p = p->next)
370     if(p != new && p != source && p->status.meta && p->protocol_version > PROT_3)
371       function(p, new);
372 cp
373   return 0;
374 }
375
376 /*
377   notify one connection of everything
378   i have connected
379 */
380 int notify_one(conn_list_t *new)
381 {
382   conn_list_t *p;
383 cp
384   for(p = conn_list; p != NULL; p = p->next)
385     if(p != new && p->protocol_version > PROT_3)
386       send_add_host(new, p);
387 cp
388   return 0;
389 }
390
391 /*
392   The incoming request handlers
393 */
394
395 int basic_info_h(conn_list_t *cl, unsigned char *d, int len)
396 {
397   basic_info_t *tmp = (basic_info_t*)d;
398 cp
399   cl->protocol_version = tmp->protocol;
400   cl->port = tmp->portnr;
401   cl->vpn_ip = tmp->vpn_ip;
402   cl->vpn_mask = tmp->vpn_mask;
403
404   if(cl->protocol_version < PROT_CURRENT)
405     {
406       syslog(LOG_ERR, "Peer uses protocol version %d which is too old.",
407              cl->protocol_version);
408       return -1;
409     }
410
411   if(debug_lvl > 2)
412     syslog(LOG_DEBUG, "got BASIC_INFO(%hd," IP_ADDR_S "," IP_ADDR_S ")", cl->port,
413            IP_ADDR_V(cl->vpn_ip), IP_ADDR_V(cl->vpn_mask));
414   if(debug_lvl > 1)
415     syslog(LOG_DEBUG, "Peer uses protocol version %d",
416            cl->protocol_version);
417
418   if(cl->status.outgoing)
419     {
420       if(setup_vpn_connection(cl) < 0)
421         return -1;
422       send_basic_info(cl);
423     }
424   else
425     {
426       if(setup_vpn_connection(cl) < 0)
427         return -1;
428       send_passphrase(cl);
429     }
430
431   cl->status.active = 0;
432 cp
433   return 0;
434 }
435
436 int passphrase_h(conn_list_t *cl, unsigned char *d, int len)
437 {
438   passphrase_t *tmp = (passphrase_t*)d;
439 cp
440   cl->pp = xmalloc(tmp->len+3);
441   memcpy(cl->pp, tmp, tmp->len+3);
442
443   if(debug_lvl > 2)
444     syslog(LOG_DEBUG, "got PASSPHRASE(%hd,...)", cl->pp->len);
445
446   if(cl->status.outgoing)
447     send_passphrase(cl);
448   else
449     send_public_key(cl);
450 cp
451   return 0;
452 }
453
454 int public_key_h(conn_list_t *cl, unsigned char *d, int len)
455 {
456   char *g_n;
457   public_key_t *tmp = (public_key_t*)d;
458 cp
459   if(debug_lvl > 2)
460     syslog(LOG_DEBUG, "got PUBLIC_KEY(%hd,%s)", tmp->len, &tmp->key);
461
462   g_n = xmalloc(tmp->len+1);
463   strcpy(g_n, &tmp->key);
464
465   if(verify_passphrase(cl, g_n))
466     {
467       /* intruder! */
468       syslog(LOG_ERR, "Intruder: passphrase does not match.");
469       return -1;
470     }
471
472   if(debug_lvl > 2)
473     syslog(LOG_INFO, "Passphrase OK");
474
475   if(cl->status.outgoing)
476     send_public_key(cl);
477   else
478     send_ack(cl);
479
480   cl->status.active = 1;
481   notify_others(cl, NULL, send_add_host);
482   notify_one(cl);
483 cp
484   return 0;
485 }
486
487 int ack_h(conn_list_t *cl, unsigned char *d, int len)
488 {
489 cp
490   if(debug_lvl > 2)
491     syslog(LOG_DEBUG, "got ACK");
492   
493   cl->status.active = 1;
494   syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
495
496   /*
497                         === FIXME ===
498     Now I'm going to cheat. The meta protocol is actually
499     a stream of requests, that may come in in the same TCP
500     packet. This is the only place that it will happen,
501     though.
502     I may change it in the future, if it appears that this
503     is not retainable.
504   */
505   if(len > 1) /* An ADD_HOST follows */
506     {
507       if(request_handlers[d[1]] == NULL)
508         syslog(LOG_ERR, "Unknown request %d.", d[1]);
509       if(request_handlers[d[1]](cl, d + 1, len - 1) < 0)
510         return -1;
511     }
512 cp
513   return 0;
514 }
515
516 int termreq_h(conn_list_t *cl, unsigned char *d, int len)
517 {
518 cp
519   syslog(LOG_NOTICE, IP_ADDR_S " wants to quit", IP_ADDR_V(cl->vpn_ip));
520   cl->status.termreq = 1;
521   terminate_connection(cl);
522
523   notify_others(cl, NULL, send_del_host);
524 cp
525   return 0;
526 }
527
528 int timeout_h(conn_list_t *cl, unsigned char *d, int len)
529 {
530 cp
531   syslog(LOG_NOTICE, IP_ADDR_S " says it's gotten a timeout from us", IP_ADDR_V(cl->vpn_ip));
532   cl->status.termreq = 1;
533   terminate_connection(cl);
534 cp
535   return 0;
536 }
537
538 int del_host_h(conn_list_t *cl, unsigned char *d, int len)
539 {
540   del_host_t *tmp = (del_host_t*)d;
541   conn_list_t *fw;
542 cp
543   if(debug_lvl > 2)
544     syslog(LOG_DEBUG, "got DEL_HOST for " IP_ADDR_S,
545            IP_ADDR_V(tmp->vpn_ip));
546
547   if(!(fw = lookup_conn(tmp->vpn_ip)))
548     {
549       syslog(LOG_ERR, "Somebody wanted to delete " IP_ADDR_S " which does not exist?",
550              IP_ADDR_V(tmp->vpn_ip));
551       return 0;
552     }
553
554   notify_others(cl, fw, send_del_host);
555
556   fw->status.termreq = 1;
557   terminate_connection(fw);
558 cp
559   return 0;
560 }
561
562 int ping_h(conn_list_t *cl, unsigned char *d, int len)
563 {
564 cp
565   if(debug_lvl > 3)
566     syslog(LOG_DEBUG, "responding to ping from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
567   cl->status.pinged = 0;
568   cl->status.got_pong = 1;
569
570   send_pong(cl);
571 cp
572   return 0;
573 }
574
575 int pong_h(conn_list_t *cl, unsigned char *d, int len)
576 {
577 cp
578   if(debug_lvl > 3)
579     syslog(LOG_DEBUG, "ok, got pong from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
580   cl->status.got_pong = 1;
581 cp
582   return 0;
583 }
584
585 int add_host_h(conn_list_t *cl, unsigned char *d, int len)
586 {
587   add_host_t *tmp = (add_host_t*)d;
588   conn_list_t *ncn, *fw;
589 cp
590   if(debug_lvl > 2)
591     syslog(LOG_DEBUG, "Add host request from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
592   if(debug_lvl > 3)
593     syslog(LOG_DEBUG, "got ADD_HOST(" IP_ADDR_S "," IP_ADDR_S ",%hd)",
594            IP_ADDR_V(tmp->vpn_ip), IP_ADDR_V(tmp->vpn_mask), tmp->portnr);
595
596   /*
597     Suggestion of Hans Bayle
598   */
599   if((fw = lookup_conn(tmp->vpn_ip)))
600     {
601       notify_others(fw, cl, send_add_host);
602       return 0;
603     }
604
605   ncn = new_conn_list();
606   ncn->real_ip = tmp->real_ip;
607   ncn->vpn_ip = tmp->vpn_ip;
608   ncn->vpn_mask = tmp->vpn_mask;
609   ncn->port = tmp->portnr;
610   ncn->hostname = hostlookup(tmp->real_ip);
611   ncn->nexthop = cl;
612   ncn->next = conn_list;
613   conn_list = ncn;
614   ncn->status.active = 1;
615   notify_others(ncn, cl, send_add_host);
616
617   /*
618     again, i'm cheating here. see the comment in ack_h.
619     Naughty zarq! Now you see what cheating will get you... [GS]
620   */
621   if(len > sizeof(*tmp)) /* Another ADD_HOST follows */
622     {
623       if(request_handlers[d[sizeof(*tmp)]] == NULL)
624         syslog(LOG_ERR, "Unknown request %d.", d[sizeof(*tmp)]);
625       if(request_handlers[d[sizeof(*tmp)]](cl, d + sizeof(*tmp), len - sizeof(*tmp)) < 0)
626         return -1;
627     }
628 cp
629   return 0;
630 }
631
632 int req_key_h(conn_list_t *cl, unsigned char *d, int len)
633 {
634   key_req_t *tmp = (key_req_t*)d;
635   conn_list_t *fw;
636 cp
637   if(debug_lvl > 2)
638     syslog(LOG_DEBUG, "got REQ_KEY from " IP_ADDR_S " for " IP_ADDR_S,
639            IP_ADDR_V(tmp->from), IP_ADDR_V(tmp->to));
640
641   if((tmp->to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
642     {  /* hey! they want something from ME! :) */
643       send_key_answer(cl, tmp->from);
644       return 0;
645     }
646
647   fw = lookup_conn(tmp->to);
648   
649   if(!fw)
650   {
651     syslog(LOG_ERR, "Attempting to forward key request to " IP_ADDR_S ", which does not exist?",
652            IP_ADDR_V(tmp->to));
653     return -1;
654   }
655
656   if(debug_lvl > 3)
657     syslog(LOG_DEBUG, "Forwarding request for public key to " IP_ADDR_S,
658            IP_ADDR_V(fw->nexthop->vpn_ip));
659   if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)) < 0)
660     {
661       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
662       return -1;
663     }
664 cp
665   return 0;
666 }
667
668 void set_keys(conn_list_t *cl, key_req_t *k)
669 {
670   char *ek;
671 cp
672   if(!cl->public_key)
673     {
674       cl->public_key = xmalloc(sizeof(*cl->key));
675       cl->public_key->key = NULL;
676     }
677   if(cl->public_key->key)
678     free(cl->public_key->key);
679   cl->public_key->length = k->len;
680   cl->public_key->expiry = k->expiry;
681   cl->public_key->key = xmalloc(k->len + 1);
682   strcpy(cl->public_key->key, &(k->key));
683
684   ek = make_shared_key(&(k->key));
685   if(!cl->key)
686     {
687       cl->key = xmalloc(sizeof(*cl->key));
688       cl->key->key = NULL;
689     }
690   if(cl->key->key)
691     free(cl->key->key);
692   cl->key->length = strlen(ek);
693   cl->key->expiry = k->expiry;
694   cl->key->key = xmalloc(strlen(ek) + 1);
695   strcpy(cl->key->key, ek);
696 cp
697 }
698
699 int ans_key_h(conn_list_t *cl, unsigned char *d, int len)
700 {
701   key_req_t *tmp = (key_req_t*)d;
702   conn_list_t *fw, *gk;
703 cp
704   if(debug_lvl > 3)
705     syslog(LOG_DEBUG, "got ANS_KEY from " IP_ADDR_S " for " IP_ADDR_S,
706            IP_ADDR_V(tmp->from), IP_ADDR_V(tmp->to));
707
708   if(tmp->to == myself->vpn_ip)
709     {  /* hey! that key's for ME! :) */
710       if(debug_lvl > 2)
711         syslog(LOG_DEBUG, "Yeah! key arrived. Now do something with it.");
712       gk = lookup_conn(tmp->from);
713
714       if(!gk)
715         {
716           syslog(LOG_ERR, "Receiving key from " IP_ADDR_S ", which does not exist?",
717                  IP_ADDR_V(tmp->from));
718           return -1;
719         }
720
721       set_keys(gk, tmp);
722       gk->status.validkey = 1;
723       gk->status.waitingforkey = 0;
724       flush_queues(gk);
725       return 0;
726     }
727
728   fw = lookup_conn(tmp->to);
729   
730   if(!fw)
731   {
732     syslog(LOG_ERR, "Attempting to forward key to " IP_ADDR_S ", which does not exist?",
733            IP_ADDR_V(tmp->to));
734     return -1;
735   }
736
737   if(debug_lvl > 2)
738     syslog(LOG_DEBUG, "Forwarding public key to " IP_ADDR_S,
739            IP_ADDR_V(fw->nexthop->vpn_ip));
740   if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)+tmp->len) < 0)
741     {
742       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
743       return -1;
744     }
745 cp
746   return 0;
747 }
748
749 int key_changed_h(conn_list_t *cl, unsigned char *d, int len)
750 {
751   key_changed_t *tmp = (key_changed_t*)d;
752   conn_list_t *ik;
753 cp
754   if(debug_lvl > 2)
755     syslog(LOG_DEBUG, "got KEY_CHANGED from " IP_ADDR_S,
756            IP_ADDR_V(tmp->from));
757
758   ik = lookup_conn(tmp->from);
759
760   if(!ik)
761     {
762       syslog(LOG_ERR, "Got changed key from " IP_ADDR_S ", which does not exist?",
763              IP_ADDR_V(tmp->from));
764       return -1;
765     }
766
767   ik->status.validkey = 0;
768   ik->status.waitingforkey = 0;
769
770   if(debug_lvl > 3)
771     syslog(LOG_DEBUG, "Forwarding key invalidation request");
772
773   notify_others(cl, ik, send_key_changed);
774 cp
775   return 0;
776 }
777
778 int (*request_handlers[256])(conn_list_t*, unsigned char*, int) = {
779   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
780   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
781   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
782   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
783   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
784   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
785   add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
786   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
787   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
788   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
789   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
790   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
791   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
792   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
793   req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
794   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
795   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
796   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
797   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
798   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0
799 };