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