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