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