fc23c8e22625ac678d95ff1c2d7de957336a2f54
[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 cp
348  if(debug_lvl > 2)
349     syslog(LOG_DEBUG, "Sending public key to " IP_ADDR_S,
350            IP_ADDR_V(fw->nexthop->vpn_ip));
351 cp
352   if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)+tmp->len) < 0)
353     {
354       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
355       return -1;
356     }
357 cp
358   return 0;
359 }
360
361 /*
362   notify all my direct connections of a new host
363   that was added to the vpn, with the exception
364   of the source of the announcement.
365 */
366 int notify_others(conn_list_t *new, conn_list_t *source,
367                   int (*function)(conn_list_t*, conn_list_t*))
368 {
369   conn_list_t *p;
370 cp
371   for(p = conn_list; p != NULL; p = p->next)
372     if(p != new && p != source && p->status.meta && p->protocol_version > PROT_3)
373       function(p, new);
374 cp
375   return 0;
376 }
377
378 /*
379   notify one connection of everything
380   i have connected
381 */
382 int notify_one(conn_list_t *new)
383 {
384   conn_list_t *p;
385 cp
386   for(p = conn_list; p != NULL; p = p->next)
387     if(p != new && p->protocol_version > PROT_3)
388       send_add_host(new, p);
389 cp
390   return 0;
391 }
392
393 /*
394   The incoming request handlers
395 */
396
397 int basic_info_h(conn_list_t *cl)
398 {
399   basic_info_t tmp;
400 cp
401   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
402     {
403       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
404       return -1;
405     }
406
407   cl->protocol_version = tmp.protocol;
408   cl->port = tmp.portnr;
409   cl->vpn_ip = tmp.vpn_ip;
410   cl->vpn_mask = tmp.vpn_mask;
411
412   if(cl->protocol_version < PROT_CURRENT)
413     {
414       syslog(LOG_ERR, "Peer uses protocol version %d which is too old.",
415              cl->protocol_version);
416       return -1;
417     }
418
419   if(debug_lvl > 2)
420     syslog(LOG_DEBUG, "got BASIC_INFO(%hd," IP_ADDR_S "," IP_ADDR_S ")", cl->port,
421            IP_ADDR_V(cl->vpn_ip), IP_ADDR_V(cl->vpn_mask));
422   if(debug_lvl > 1)
423     syslog(LOG_DEBUG, "Peer uses protocol version %d",
424            cl->protocol_version);
425
426   if(cl->status.outgoing)
427     {
428       if(setup_vpn_connection(cl) < 0)
429         return -1;
430       send_basic_info(cl);
431     }
432   else
433     {
434       if(setup_vpn_connection(cl) < 0)
435         return -1;
436       send_passphrase(cl);
437     }
438
439   cl->status.active = 0;
440 cp
441   return 0;
442 }
443
444 int passphrase_h(conn_list_t *cl)
445 {
446   char unused;
447   unsigned short int len;
448 cp
449   if(read(cl->meta_socket, &unused, sizeof(unused)) <= 0)
450     {
451       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
452       return -1;
453     }
454
455   if(read(cl->meta_socket, &len, sizeof(len)) <= 0)
456     {
457       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
458       return -1;
459     }
460   
461   cl->pp = xmalloc(len+4);
462
463   cl->pp->len = len;
464   if(read(cl->meta_socket, &(cl->pp->phrase), len) <= 0)
465     {
466       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
467       return -1;
468     }
469   
470   if(debug_lvl > 2)
471     syslog(LOG_DEBUG, "got PASSPHRASE(%hd,...)", len);
472
473   if(cl->status.outgoing)
474     send_passphrase(cl);
475   else
476     send_public_key(cl);
477 cp
478   return 0;
479 }
480
481 int public_key_h(conn_list_t *cl)
482 {
483   char *g_n;
484   unsigned short int len;
485   char unused;
486 cp
487   if(read(cl->meta_socket, &unused, sizeof(unused)) <= 0)
488     {
489       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
490       return -1;
491     }
492   if(read(cl->meta_socket, &len, sizeof(len)) <= 0)
493     {
494       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
495       return -1;
496     }
497
498   g_n = xmalloc(len+2);
499
500   if(read(cl->meta_socket, g_n, len+2) <= 0)
501     {
502       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
503       return -1;
504     }
505
506   if(debug_lvl > 2)
507     syslog(LOG_DEBUG, "got PUBLIC_KEY(%hd,%s)", len, g_n);
508
509   if(verify_passphrase(cl, g_n))
510     {
511       /* intruder! */
512       syslog(LOG_ERR, "Intruder: passphrase does not match.");
513       return -1;
514     }
515
516   if(debug_lvl > 2)
517     syslog(LOG_INFO, "Passphrase OK");
518
519   if(cl->status.outgoing)
520     send_public_key(cl);
521   else
522     send_ack(cl);
523
524   cl->status.active = 1;
525   notify_others(cl, NULL, send_add_host);
526   notify_one(cl);
527 cp
528   return 0;
529 }
530
531 int ack_h(conn_list_t *cl)
532 {
533 cp
534   if(debug_lvl > 2)
535     syslog(LOG_DEBUG, "got ACK");
536   
537   cl->status.active = 1;
538   syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
539 cp
540   return 0;
541 }
542
543 int termreq_h(conn_list_t *cl)
544 {
545 cp
546   syslog(LOG_NOTICE, IP_ADDR_S " wants to quit", IP_ADDR_V(cl->vpn_ip));
547   cl->status.termreq = 1;
548   terminate_connection(cl);
549
550   notify_others(cl, NULL, send_del_host);
551 cp
552   return 0;
553 }
554
555 int timeout_h(conn_list_t *cl)
556 {
557 cp
558   syslog(LOG_NOTICE, IP_ADDR_S " says it's gotten a timeout from us", IP_ADDR_V(cl->vpn_ip));
559   cl->status.termreq = 1;
560   terminate_connection(cl);
561 cp
562   return 0;
563 }
564
565 int del_host_h(conn_list_t *cl)
566 {
567   del_host_t tmp;
568   conn_list_t *fw;
569 cp
570   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
571     {
572       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
573       return -1;
574     }
575
576   if(debug_lvl > 2)
577     syslog(LOG_DEBUG, "got DEL_HOST for " IP_ADDR_S,
578            IP_ADDR_V(tmp.vpn_ip));
579
580   if(!(fw = lookup_conn(tmp.vpn_ip)))
581     {
582       syslog(LOG_ERR, "Somebody wanted to delete " IP_ADDR_S " which does not exist?",
583              IP_ADDR_V(tmp.vpn_ip));
584       return 0;
585     }
586
587   notify_others(cl, fw, send_del_host);
588
589   fw->status.termreq = 1;
590   terminate_connection(fw);
591 cp
592   return 0;
593 }
594
595 int ping_h(conn_list_t *cl)
596 {
597 cp
598   if(debug_lvl > 3)
599     syslog(LOG_DEBUG, "responding to ping from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
600   cl->status.pinged = 0;
601   cl->status.got_pong = 1;
602
603   send_pong(cl);
604 cp
605   return 0;
606 }
607
608 int pong_h(conn_list_t *cl)
609 {
610 cp
611   if(debug_lvl > 3)
612     syslog(LOG_DEBUG, "ok, got pong from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
613   cl->status.got_pong = 1;
614 cp
615   return 0;
616 }
617
618 int add_host_h(conn_list_t *cl)
619 {
620   add_host_t tmp;
621   conn_list_t *ncn, *fw;
622 cp
623   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
624     {
625       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
626       return -1;
627     }
628
629   if(debug_lvl > 2)
630     syslog(LOG_DEBUG, "Add host request from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
631   if(debug_lvl > 3)
632     syslog(LOG_DEBUG, "got ADD_HOST(" IP_ADDR_S "," IP_ADDR_S ",%hd)",
633            IP_ADDR_V(tmp.vpn_ip), IP_ADDR_V(tmp.vpn_mask), tmp.portnr);
634
635   /*
636     Suggestion of Hans Bayle
637   */
638   if((fw = lookup_conn(tmp.vpn_ip)))
639     {
640       notify_others(fw, cl, send_add_host);
641       return 0;
642     }
643
644   ncn = new_conn_list();
645   ncn->real_ip = tmp.real_ip;
646   ncn->vpn_ip = tmp.vpn_ip;
647   ncn->vpn_mask = tmp.vpn_mask;
648   ncn->port = tmp.portnr;
649   ncn->hostname = hostlookup(tmp.real_ip);
650   ncn->nexthop = cl;
651   ncn->next = conn_list;
652   conn_list = ncn;
653   ncn->status.active = 1;
654   notify_others(ncn, cl, send_add_host);
655 cp
656   return 0;
657 }
658
659 int req_key_h(conn_list_t *cl)
660 {
661   key_req_t tmp;
662   conn_list_t *fw;
663 cp
664   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
665     {
666       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
667       return -1;
668     }
669
670   if(debug_lvl > 2)
671     syslog(LOG_DEBUG, "got REQ_KEY from " IP_ADDR_S " for " IP_ADDR_S,
672            IP_ADDR_V(tmp.from), IP_ADDR_V(tmp.to));
673
674   if((tmp.to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
675     {  /* hey! they want something from ME! :) */
676       send_key_answer(cl, tmp.from);
677       return 0;
678     }
679
680   fw = lookup_conn(tmp.to);
681   
682   if(!fw)
683     {
684       syslog(LOG_ERR, "Attempting to forward key request to " IP_ADDR_S ", which does not exist?",
685              IP_ADDR_V(tmp.to));
686       return -1;
687     }
688
689   if(debug_lvl > 3)
690     syslog(LOG_DEBUG, "Forwarding request for public key to " IP_ADDR_S,
691            IP_ADDR_V(fw->nexthop->vpn_ip));
692   
693   tmp.type = REQ_KEY;
694   tmp.key = 0;
695   if(write(fw->nexthop->meta_socket, &tmp, sizeof(tmp)) < 0)
696     {
697       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
698       return -1;
699     }
700 cp
701   return 0;
702 }
703
704 void set_keys(conn_list_t *cl, key_req_t *k, char *key)
705 {
706   char *ek;
707 cp
708   if(!cl->public_key)
709     {
710       cl->public_key = xmalloc(sizeof(*cl->key));
711       cl->public_key->key = NULL;
712     }
713   if(cl->public_key->key)
714     free(cl->public_key->key);
715   cl->public_key->length = k->len;
716   cl->public_key->expiry = k->expiry;
717   cl->public_key->key = xmalloc(k->len + 1);
718   strcpy(cl->public_key->key, key);
719
720   ek = make_shared_key(key);
721   if(!cl->key)
722     {
723       cl->key = xmalloc(sizeof(*cl->key));
724       cl->key->key = NULL;
725     }
726   if(cl->key->key)
727     free(cl->key->key);
728   cl->key->length = strlen(ek);
729   cl->key->expiry = k->expiry;
730   cl->key->key = xmalloc(strlen(ek) + 1);
731   strcpy(cl->key->key, ek);
732 cp
733 }
734
735 int ans_key_h(conn_list_t *cl)
736 {
737   key_req_t tmp;
738   conn_list_t *fw, *gk;
739   char *key;
740 cp
741   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-2) <= 0)
742     {
743       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
744       return -1;
745     }
746
747   key = xmalloc(tmp.len);
748
749   if(read(cl->meta_socket, key, tmp.len + 1) <= 0)
750     {
751       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
752       return -1;
753     }
754
755   if(debug_lvl > 3)
756     syslog(LOG_DEBUG, "got ANS_KEY from " IP_ADDR_S " for " IP_ADDR_S,
757            IP_ADDR_V(tmp.from), IP_ADDR_V(tmp.to));
758
759   if(tmp.to == myself->vpn_ip)
760     {  /* hey! that key's for ME! :) */
761       if(debug_lvl > 2)
762         syslog(LOG_DEBUG, "Yeah! key arrived. Now do something with it.");
763       gk = lookup_conn(tmp.from);
764
765       if(!gk)
766         {
767           syslog(LOG_ERR, "Receiving key from " IP_ADDR_S ", which does not exist?",
768                  IP_ADDR_V(tmp.from));
769           return -1;
770         }
771
772       set_keys(gk, &tmp, key);
773       gk->status.validkey = 1;
774       gk->status.waitingforkey = 0;
775       flush_queues(gk);
776       return 0;
777     }
778
779   fw = lookup_conn(tmp.to);
780   
781   if(!fw)
782     {
783       syslog(LOG_ERR, "Attempting to forward key to " IP_ADDR_S ", which does not exist?",
784              IP_ADDR_V(tmp.to));
785       return -1;
786     }
787
788   if(debug_lvl > 2)
789     syslog(LOG_DEBUG, "Forwarding public key to " IP_ADDR_S,
790            IP_ADDR_V(fw->nexthop->vpn_ip));
791   tmp.type = ANS_KEY;
792   if(write(fw->nexthop->meta_socket, &tmp, sizeof(tmp) -1) < 0)
793     {
794       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
795       return -1;
796     }
797   if(write(fw->nexthop->meta_socket, key, tmp.len + 1) < 0)
798     {
799       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
800       return -1;
801     }
802 cp
803   return 0;
804 }
805
806 int key_changed_h(conn_list_t *cl)
807 {
808   key_changed_t tmp;
809   conn_list_t *ik;
810 cp
811   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
812     {
813       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
814       return -1;
815     }
816
817   if(debug_lvl > 2)
818     syslog(LOG_DEBUG, "got KEY_CHANGED from " IP_ADDR_S,
819            IP_ADDR_V(tmp.from));
820
821   ik = lookup_conn(tmp.from);
822
823   if(!ik)
824     {
825       syslog(LOG_ERR, "Got changed key from " IP_ADDR_S ", which does not exist?",
826              IP_ADDR_V(tmp.from));
827       return -1;
828     }
829
830   ik->status.validkey = 0;
831   ik->status.waitingforkey = 0;
832
833   if(debug_lvl > 3)
834     syslog(LOG_DEBUG, "Forwarding key invalidation request");
835
836   notify_others(cl, ik, send_key_changed);
837 cp
838   return 0;
839 }
840
841 int (*request_handlers[256])(conn_list_t*) = {
842   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
843   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
844   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
845   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
846   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
847   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
848   add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
849   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
850   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
851   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
852   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
853   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
854   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
855   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
856   req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
857   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
858   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
859   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
860   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
861   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0
862 };