2 protocol.c -- handle the meta-protocol
3 Copyright (C) 1999,2000 Ivo Timmermans <itimmermans@bigfoot.com>,
4 2000 Guus Sliepen <guus@sliepen.warande.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 $Id: protocol.c,v 1.28.4.10 2000/06/27 12:58:04 guus Exp $
25 #include <sys/types.h>
30 #include <sys/socket.h>
45 char buffer[MAXBUFSIZE+1];
48 /* Outgoing request routines */
50 int send_ack(conn_list_t *cl)
54 syslog(LOG_DEBUG, _("Sending ACK to " IP_ADDR_S " (%s)"),
55 IP_ADDR_V(cl->vpn_ip), cl->hostname);
57 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", ACK);
59 if((write(cl->meta_socket, buffer, buflen)) < 0)
61 syslog(LOG_ERR, _("Send failed: %d:%d: %m"), __FILE__, __LINE__);
66 syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
67 IP_ADDR_V(cl->vpn_ip), cl->hostname);
72 int send_termreq(conn_list_t *cl)
76 syslog(LOG_DEBUG, _("Sending TERMREQ to " IP_ADDR_S " (%s)"),
77 IP_ADDR_V(cl->vpn_ip), cl->hostname);
79 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
81 if(write(cl->meta_socket, buffer, buflen) < 0)
84 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
91 int send_timeout(conn_list_t *cl)
95 syslog(LOG_DEBUG, _("Sending TIMEOUT to " IP_ADDR_S " (%s)"),
96 IP_ADDR_V(cl->vpn_ip), cl->hostname);
98 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
100 if((write(cl->meta_socket, buffer, buflen)) < 0)
102 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
109 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
113 syslog(LOG_DEBUG, _("Sending DEL_HOST for " IP_ADDR_S " to " IP_ADDR_S " (%s)"),
114 IP_ADDR_V(new_host->vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
116 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
118 if((write(cl->meta_socket, buffer, buflen)) < 0)
120 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
127 int send_ping(conn_list_t *cl)
131 syslog(LOG_DEBUG, _("Sending PING to " IP_ADDR_S " (%s)"),
132 IP_ADDR_V(cl->vpn_ip), cl->hostname);
134 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
136 if((write(cl->meta_socket, buffer, buflen)) < 0)
138 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
145 int send_pong(conn_list_t *cl)
149 syslog(LOG_DEBUG, _("Sending PONG to " IP_ADDR_S " (%s)"),
150 IP_ADDR_V(cl->vpn_ip), cl->hostname);
152 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
154 if((write(cl->meta_socket, buffer, buflen)) < 0)
156 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
163 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
169 real_ip = new_host->real_ip;
170 hostname = new_host->hostname;
171 flags = new_host->flags;
173 /* If we need to propagate information about a new host that wants us to export
174 * it's indirectdata flag, we set the INDIRECTDATA flag and unset the EXPORT...
175 * flag, and set it's real_ip to our vpn_ip, so that net.c send_packet() will
179 if(flags & EXPORTINDIRECTDATA)
181 flags &= ~EXPORTINDIRECTDATA;
182 flags |= INDIRECTDATA;
183 real_ip = myself->vpn_ip;
184 hostname = myself->hostname;
188 syslog(LOG_DEBUG, _("Sending ADD_HOST for " IP_ADDR_S " (%s) to " IP_ADDR_S " (%s)"),
189 IP_ADDR_V(new_host->vpn_ip), hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
191 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx/%lx:%x %d\n", ADD_HOST, real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port, flags);
193 if((write(cl->meta_socket, buffer, buflen)) < 0)
195 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
202 int send_key_changed(conn_list_t *cl, conn_list_t *src)
206 syslog(LOG_DEBUG, _("Sending KEY_CHANGED origin " IP_ADDR_S " to " IP_ADDR_S " (%s)"),
207 IP_ADDR_V(src->vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
209 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
211 if((write(cl->meta_socket, buffer, buflen)) < 0)
213 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
220 void send_key_changed_all(void)
224 for(p = conn_list; p != NULL; p = p->next)
225 if(p->status.meta && p->status.active)
226 send_key_changed(p, myself);
230 int send_basic_info(conn_list_t *cl)
234 syslog(LOG_DEBUG, _("Sending BASIC_INFO to %s"),
237 buflen = snprintf(buffer, MAXBUFSIZE, "%d %d %lx/%lx:%x %d\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port, myself->flags);
239 if((write(cl->meta_socket, buffer, buflen)) < 0)
241 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
248 int send_passphrase(conn_list_t *cl)
252 encrypt_passphrase(&tmp);
255 syslog(LOG_DEBUG, _("Sending PASSPHRASE to " IP_ADDR_S " (%s)"),
256 IP_ADDR_V(cl->vpn_ip), cl->hostname);
258 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
260 if((write(cl->meta_socket, buffer, buflen)) < 0)
262 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
269 int send_public_key(conn_list_t *cl)
273 syslog(LOG_DEBUG, _("Sending PUBLIC_KEY to " IP_ADDR_S " (%s)"),
274 IP_ADDR_V(cl->vpn_ip), cl->hostname);
276 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
278 if((write(cl->meta_socket, buffer, buflen)) < 0)
280 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
287 /* WDN doet deze functie? (GS)
288 int send_calculate(conn_list_t *cl, char *k)
291 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", CALCULATE, k);
293 if((write(cl->meta_socket, buffer, buflen)) < 0)
295 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
303 int send_key_request(ip_t to)
307 fw = lookup_conn(to);
310 syslog(LOG_ERR, _("Attempting to send REQ_KEY to " IP_ADDR_S ", which does not exist?"),
316 syslog(LOG_DEBUG, _("Sending REQ_KEY to " IP_ADDR_S " (%s)"),
317 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
319 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
321 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
323 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
326 fw->status.waitingforkey = 1;
331 int send_key_answer(conn_list_t *cl, ip_t to)
336 fw = lookup_conn(to);
340 syslog(LOG_ERR, _("Attempting to send ANS_KEY to " IP_ADDR_S ", which does not exist?"),
346 syslog(LOG_DEBUG, _("Sending ANS_KEY to " IP_ADDR_S " (%s)"),
347 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
349 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
351 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
353 syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
361 notify all my direct connections of a new host
362 that was added to the vpn, with the exception
363 of the source of the announcement.
365 int notify_others(conn_list_t *new, conn_list_t *source,
366 int (*function)(conn_list_t*, conn_list_t*))
370 for(p = conn_list; p != NULL; p = p->next)
371 if(p != new && p != source && p->status.meta && p->status.active)
378 notify one connection of everything
381 int notify_one(conn_list_t *new)
385 for(p = conn_list; p != NULL; p = p->next)
386 if(p != new && p->status.active)
387 send_add_host(new, p);
393 The incoming request handlers
396 int basic_info_h(conn_list_t *cl)
400 syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->hostname);
402 if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx %d", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port, &cl->flags) != 5)
404 syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
406 if(cl->status.outgoing)
408 /* If we get here, it means that our uplink uses the wrong protocol.
409 If we don't do anything, we will reconnect every 5 seconds. Pretty dumb.
410 So we disable the outgoing flag, so that we won't reconnect anymore.
411 This still allows other tinc daemons to connect to us.
413 syslog(LOG_ERR, _("Warning: disabling uplink!"));
414 cl->status.outgoing = 0;
419 if(cl->protocol_version != PROT_CURRENT)
421 syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
422 cl->protocol_version);
426 if(cl->status.outgoing)
428 if(setup_vpn_connection(cl) < 0)
434 if(setup_vpn_connection(cl) < 0)
442 int passphrase_h(conn_list_t *cl)
445 cl->pp = xmalloc(sizeof(*(cl->pp)));
447 if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
449 syslog(LOG_ERR, _("Got bad PASSPHRASE from " IP_ADDR_S " (%s)"),
450 IP_ADDR_V(cl->vpn_ip), cl->hostname);
453 cl->pp->len = strlen(cl->pp->phrase);
456 syslog(LOG_DEBUG, _("Got PASSPHRASE from " IP_ADDR_S " (%s)"),
457 IP_ADDR_V(cl->vpn_ip), cl->hostname);
459 if(cl->status.outgoing)
467 int public_key_h(conn_list_t *cl)
472 if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
474 syslog(LOG_ERR, _("Got bad PUBLIC_KEY from " IP_ADDR_S " (%s)"),
475 IP_ADDR_V(cl->vpn_ip), cl->hostname);
480 syslog(LOG_DEBUG, _("Got PUBLIC_KEY from " IP_ADDR_S " (%s)"),
481 IP_ADDR_V(cl->vpn_ip), cl->hostname);
483 if(verify_passphrase(cl, g_n))
486 syslog(LOG_ERR, _("Intruder: passphrase does not match!"));
490 if(cl->status.outgoing)
496 /* Okay, before we active the connection, we check if there is another entry
497 in the connection list with the same vpn_ip. If so, it presumably is an
498 old connection that has timed out but we don't know it yet. Because our
499 conn_list entry is not active, lookup_conn will skip ourself. */
501 while(old=lookup_conn(cl->vpn_ip))
502 terminate_connection(old);
504 cl->status.active = 1;
505 notify_others(cl, NULL, send_add_host);
512 int ack_h(conn_list_t *cl)
516 syslog(LOG_DEBUG, _("Got ACK from " IP_ADDR_S " (%s)"),
517 IP_ADDR_V(cl->vpn_ip), cl->hostname);
519 cl->status.active = 1;
520 syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
521 IP_ADDR_V(cl->vpn_ip), cl->hostname);
526 int termreq_h(conn_list_t *cl)
529 if(!cl->status.active)
531 syslog(LOG_ERR, _("Got unauthorized TERMREQ from " IP_ADDR_S " (%s)"),
532 IP_ADDR_V(cl->vpn_ip), cl->hostname);
537 syslog(LOG_DEBUG, _("Got TERMREQ from " IP_ADDR_S " (%s)"),
538 IP_ADDR_V(cl->vpn_ip), cl->hostname);
540 cl->status.termreq = 1;
542 if(cl->status.active)
543 notify_others(cl, NULL, send_del_host);
545 cl->status.active = 0;
547 terminate_connection(cl);
552 int timeout_h(conn_list_t *cl)
555 if(!cl->status.active)
557 syslog(LOG_ERR, _("Got unauthorized TIMEOUT from " IP_ADDR_S " (%s)"),
558 IP_ADDR_V(cl->vpn_ip), cl->hostname);
563 syslog(LOG_DEBUG, _("Got TIMEOUT from " IP_ADDR_S " (%s)"),
564 IP_ADDR_V(cl->vpn_ip), cl->hostname);
566 cl->status.termreq = 1;
567 terminate_connection(cl);
572 int del_host_h(conn_list_t *cl)
577 if(!cl->status.active)
579 syslog(LOG_ERR, _("Got unauthorized DEL_HOST from " IP_ADDR_S " (%s)"),
580 IP_ADDR_V(cl->vpn_ip), cl->hostname);
584 if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
586 syslog(LOG_ERR, _("Got bad DEL_HOST from " IP_ADDR_S " (%s)"),
587 IP_ADDR_V(cl->vpn_ip), cl->hostname);
592 syslog(LOG_DEBUG, _("Got DEL_HOST for " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
593 IP_ADDR_V(vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
595 if(!(fw = lookup_conn(vpn_ip)))
597 syslog(LOG_ERR, _("Got DEL_HOST for " IP_ADDR_S " from " IP_ADDR_S " (%s) which does not exist?"),
598 IP_ADDR_V(vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
602 notify_others(fw, cl, send_del_host);
604 fw->status.termreq = 1;
605 fw->status.active = 0;
607 terminate_connection(fw);
612 int ping_h(conn_list_t *cl)
615 if(!cl->status.active)
617 syslog(LOG_ERR, _("Got unauthorized PING from " IP_ADDR_S " (%s)"),
618 IP_ADDR_V(cl->vpn_ip), cl->hostname);
623 syslog(LOG_DEBUG, _("Got PING from " IP_ADDR_S " (%s)"),
624 IP_ADDR_V(cl->vpn_ip), cl->hostname);
626 cl->status.pinged = 0;
627 cl->status.got_pong = 1;
634 int pong_h(conn_list_t *cl)
637 if(!cl->status.active)
639 syslog(LOG_ERR, _("Got unauthorized PONG from " IP_ADDR_S " (%s)"),
640 IP_ADDR_V(cl->vpn_ip), cl->hostname);
645 syslog(LOG_DEBUG, _("Got PONG from " IP_ADDR_S " (%s)"),
646 IP_ADDR_V(cl->vpn_ip), cl->hostname);
648 cl->status.got_pong = 1;
653 int add_host_h(conn_list_t *cl)
660 conn_list_t *ncn, *fw;
662 if(!cl->status.active)
664 syslog(LOG_ERR, _("Got unauthorized ADD_HOST from " IP_ADDR_S " (%s)"),
665 IP_ADDR_V(cl->vpn_ip), cl->hostname);
669 if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
671 syslog(LOG_ERR, _("Got bad ADD_HOST from " IP_ADDR_S " (%s)"),
672 IP_ADDR_V(cl->vpn_ip), cl->hostname);
677 Suggestion of Hans Bayle
679 if((fw = lookup_conn(vpn_ip)))
681 if(fw->nexthop == cl)
682 notify_others(fw, cl, send_add_host);
684 syslog(LOG_DEBUG, _("Invalid ADD_HOST from " IP_ADDR_S " (%s)"),
685 IP_ADDR_V(cl->vpn_ip), cl->hostname);
689 ncn = new_conn_list();
690 ncn->real_ip = real_ip;
691 ncn->hostname = hostlookup(htonl(real_ip));
692 ncn->vpn_ip = vpn_ip;
693 ncn->vpn_mask = vpn_mask;
697 ncn->next = conn_list;
699 ncn->status.active = 1;
702 syslog(LOG_DEBUG, _("Got ADD_HOST for " IP_ADDR_S " (%s) from " IP_ADDR_S " (%s)"),
703 IP_ADDR_V(ncn->vpn_ip), ncn->hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
705 notify_others(ncn, cl, send_add_host);
710 int req_key_h(conn_list_t *cl)
716 if(!cl->status.active)
718 syslog(LOG_ERR, _("Got unauthorized REQ_KEY from " IP_ADDR_S " (%s)"),
719 IP_ADDR_V(cl->vpn_ip), cl->hostname);
723 if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
725 syslog(LOG_ERR, _("Got bad REQ_KEY from " IP_ADDR_S " (%s)"),
726 IP_ADDR_V(cl->vpn_ip), cl->hostname);
731 syslog(LOG_DEBUG, _("Got REQ_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
732 IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
734 if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
735 { /* hey! they want something from ME! :) */
736 send_key_answer(cl, from);
740 fw = lookup_conn(to);
744 syslog(LOG_ERR, _("Attempting to forward REQ_KEY to " IP_ADDR_S ", which does not exist?"),
750 syslog(LOG_DEBUG, _("Forwarding REQ_KEY to " IP_ADDR_S " (%s)"),
751 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
753 cl->buffer[cl->reqlen-1] = '\n';
755 if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
757 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
764 void set_keys(conn_list_t *cl, int expiry, char *key)
770 cl->public_key = xmalloc(sizeof(*cl->key));
771 cl->public_key->key = NULL;
774 if(cl->public_key->key)
775 free(cl->public_key->key);
776 cl->public_key->length = strlen(key);
777 cl->public_key->expiry = expiry;
778 cl->public_key->key = xmalloc(cl->public_key->length + 1);
779 strcpy(cl->public_key->key, key);
781 ek = make_shared_key(key);
785 cl->key = xmalloc(sizeof(*cl->key));
792 cl->key->length = strlen(ek);
793 cl->key->expiry = expiry;
794 cl->key->key = xmalloc(cl->key->length + 1);
795 strcpy(cl->key->key, ek);
799 int ans_key_h(conn_list_t *cl)
805 conn_list_t *fw, *gk;
807 if(!cl->status.active)
809 syslog(LOG_ERR, _("Got unauthorized ANS_KEY from " IP_ADDR_S " (%s)"),
810 IP_ADDR_V(cl->vpn_ip), cl->hostname);
814 if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
816 syslog(LOG_ERR, _("Got bad ANS_KEY from " IP_ADDR_S " (%s)"),
817 IP_ADDR_V(cl->vpn_ip), cl->hostname);
822 syslog(LOG_DEBUG, _("Got ANS_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
823 IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
825 if(to == myself->vpn_ip)
826 { /* hey! that key's for ME! :) */
827 gk = lookup_conn(from);
831 syslog(LOG_ERR, _("Receiving ANS_KEY from " IP_ADDR_S ", which does not exist?"),
836 set_keys(gk, expiry, key);
837 gk->status.validkey = 1;
838 gk->status.waitingforkey = 0;
843 fw = lookup_conn(to);
847 syslog(LOG_ERR, _("Attempting to forward ANS_KEY to " IP_ADDR_S ", which does not exist?"),
853 syslog(LOG_DEBUG, _("Forwarding ANS_KEY to " IP_ADDR_S " (%s)"),
854 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
856 cl->buffer[cl->reqlen-1] = '\n';
858 if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
860 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
867 int key_changed_h(conn_list_t *cl)
872 if(!cl->status.active)
874 syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from " IP_ADDR_S " (%s)"),
875 IP_ADDR_V(cl->vpn_ip), cl->hostname);
879 if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
881 syslog(LOG_ERR, _("Got bad KEY_CHANGED from " IP_ADDR_S " (%s)"),
882 IP_ADDR_V(cl->vpn_ip), cl->hostname);
887 syslog(LOG_DEBUG, _("Got KEY_CHANGED origin " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
888 IP_ADDR_V(from), IP_ADDR_V(cl->vpn_ip), cl->hostname);
890 ik = lookup_conn(from);
894 syslog(LOG_ERR, _("Got KEY_CHANGED from " IP_ADDR_S ", which does not exist?"),
899 ik->status.validkey = 0;
900 ik->status.waitingforkey = 0;
902 notify_others(ik, cl, send_key_changed);
907 int (*request_handlers[256])(conn_list_t*) = {
908 0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
909 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
910 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
911 termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
912 ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
914 add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
915 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
916 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
917 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
918 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
919 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
920 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
921 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
922 req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
923 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
924 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
925 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
926 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
927 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0