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.16 2000/06/29 17:09:06 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 %s (%s)"),
55 cl->vpn_hostname, cl->real_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__);
68 int send_termreq(conn_list_t *cl)
72 syslog(LOG_DEBUG, _("Sending TERMREQ to %s (%s)"),
73 cl->vpn_hostname, cl->real_hostname);
75 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
77 if(write(cl->meta_socket, buffer, buflen) < 0)
80 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
87 int send_timeout(conn_list_t *cl)
91 syslog(LOG_DEBUG, _("Sending TIMEOUT to %s (%s)"),
92 cl->vpn_hostname, cl->real_hostname);
94 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
96 if((write(cl->meta_socket, buffer, buflen)) < 0)
98 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
105 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
109 syslog(LOG_DEBUG, _("Sending DEL_HOST for %s (%s) to %s (%s)"),
110 new_host->vpn_hostname, new_host->real_hostname, cl->vpn_hostname, cl->real_hostname);
112 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
114 if((write(cl->meta_socket, buffer, buflen)) < 0)
116 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
123 int send_ping(conn_list_t *cl)
127 syslog(LOG_DEBUG, _("Sending PING to %s (%s)"),
128 cl->vpn_hostname, cl->real_hostname);
130 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
132 if((write(cl->meta_socket, buffer, buflen)) < 0)
134 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
141 int send_pong(conn_list_t *cl)
145 syslog(LOG_DEBUG, _("Sending PONG to %s (%s)"),
146 cl->vpn_hostname, cl->real_hostname);
148 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
150 if((write(cl->meta_socket, buffer, buflen)) < 0)
152 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
159 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
165 real_ip = new_host->real_ip;
166 hostname = new_host->real_hostname;
167 flags = new_host->flags;
169 /* If we need to propagate information about a new host that wants us to export
170 * it's indirectdata flag, we set the INDIRECTDATA flag and unset the EXPORT...
171 * flag, and set it's real_ip to our vpn_ip, so that net.c send_packet() will
175 if(flags & EXPORTINDIRECTDATA)
177 flags &= ~EXPORTINDIRECTDATA;
178 flags |= INDIRECTDATA;
179 real_ip = myself->vpn_ip;
180 hostname = myself->real_hostname;
184 syslog(LOG_DEBUG, _("Sending ADD_HOST for %s (%s) to %s (%s)"),
185 new_host->vpn_hostname, hostname, cl->vpn_hostname, cl->real_hostname);
187 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);
189 if((write(cl->meta_socket, buffer, buflen)) < 0)
191 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
198 int send_key_changed(conn_list_t *cl, conn_list_t *src)
202 syslog(LOG_DEBUG, _("Sending KEY_CHANGED origin %s to %s (%s)"),
203 src->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
205 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
207 if((write(cl->meta_socket, buffer, buflen)) < 0)
209 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
216 void send_key_changed_all(void)
220 for(p = conn_list; p != NULL; p = p->next)
221 if(p->status.meta && p->status.active)
222 send_key_changed(p, myself);
226 int send_basic_info(conn_list_t *cl)
230 syslog(LOG_DEBUG, _("Sending BASIC_INFO to %s"),
233 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);
235 if((write(cl->meta_socket, buffer, buflen)) < 0)
237 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
244 int send_passphrase(conn_list_t *cl)
248 encrypt_passphrase(&tmp);
251 syslog(LOG_DEBUG, _("Sending PASSPHRASE to %s (%s)"),
252 cl->vpn_hostname, cl->real_hostname);
254 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
256 if((write(cl->meta_socket, buffer, buflen)) < 0)
258 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
265 int send_public_key(conn_list_t *cl)
269 syslog(LOG_DEBUG, _("Sending PUBLIC_KEY to %s (%s)"),
270 cl->vpn_hostname, cl->real_hostname);
272 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
274 if((write(cl->meta_socket, buffer, buflen)) < 0)
276 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
283 /* WDN doet deze functie? (GS)
284 int send_calculate(conn_list_t *cl, char *k)
287 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", CALCULATE, k);
289 if((write(cl->meta_socket, buffer, buflen)) < 0)
291 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
299 int send_key_request(ip_t to)
303 fw = lookup_conn(to);
306 syslog(LOG_ERR, _("Attempting to send REQ_KEY to %d.%d.%d.%d, which does not exist?"),
312 syslog(LOG_DEBUG, _("Sending REQ_KEY to %s (%s)"),
313 fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
315 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
317 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
319 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
322 fw->status.waitingforkey = 1;
327 int send_key_answer(conn_list_t *cl, ip_t to)
332 fw = lookup_conn(to);
336 syslog(LOG_ERR, _("Attempting to send ANS_KEY to %d.%d.%d.%d, which does not exist?"),
342 syslog(LOG_DEBUG, _("Sending ANS_KEY to %s (%s)"),
343 fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
345 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
347 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
349 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
357 notify all my direct connections of a new host
358 that was added to the vpn, with the exception
359 of the source of the announcement.
361 int notify_others(conn_list_t *new, conn_list_t *source,
362 int (*function)(conn_list_t*, conn_list_t*))
366 for(p = conn_list; p != NULL; p = p->next)
367 if(p != new && p != source && p->status.meta && p->status.active)
374 notify one connection of everything
377 int notify_one(conn_list_t *new)
381 for(p = conn_list; p != NULL; p = p->next)
382 if(p != new && p->status.active)
383 send_add_host(new, p);
389 The incoming request handlers
392 int basic_info_h(conn_list_t *cl)
396 syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->real_hostname);
398 if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx %d", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port, &cl->flags) != 5)
400 syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
405 cl->vpn_hostname = hostlookup(htonl(cl->vpn_ip));
407 if(cl->protocol_version != PROT_CURRENT)
409 syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
410 cl->protocol_version);
414 if(cl->status.outgoing)
416 if(setup_vpn_connection(cl) < 0)
422 /* First check if the host we connected to is already in our
423 connection list. If so, we are probably making a loop, which
424 is not desirable. It should not happen though.
427 if(lookup_conn(cl->vpn_ip))
430 syslog(LOG_NOTICE, _("Uplink %s (%s) is already in our connection list, aborting connect"),
431 cl->vpn_hostname, cl->real_hostname);
435 if(setup_vpn_connection(cl) < 0)
443 int passphrase_h(conn_list_t *cl)
446 cl->pp = xmalloc(sizeof(*(cl->pp)));
448 if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
450 syslog(LOG_ERR, _("Got bad PASSPHRASE from %s (%s)"),
451 cl->vpn_hostname, cl->real_hostname);
454 cl->pp->len = strlen(cl->pp->phrase);
457 syslog(LOG_DEBUG, _("Got PASSPHRASE from %s (%s)"),
458 cl->vpn_hostname, cl->real_hostname);
460 if(cl->status.outgoing)
468 int public_key_h(conn_list_t *cl)
473 if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
475 syslog(LOG_ERR, _("Got bad PUBLIC_KEY from %s (%s)"),
476 cl->vpn_hostname, cl->real_hostname);
481 syslog(LOG_DEBUG, _("Got PUBLIC_KEY from %s (%s)"),
482 cl->vpn_hostname, cl->real_hostname);
484 if(verify_passphrase(cl, g_n))
487 syslog(LOG_ERR, _("Intruder from %s: passphrase for %s does not match!"),
488 cl->real_hostname, cl->vpn_hostname);
492 if(cl->status.outgoing)
498 /* Okay, before we active the connection, we check if there is another entry
499 in the connection list with the same vpn_ip. If so, it presumably is an
500 old connection that has timed out but we don't know it yet.
503 while(old = lookup_conn(cl->vpn_ip))
505 syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
506 cl->vpn_hostname, old->real_hostname, cl->real_hostname);
507 old->status.active = 0;
508 terminate_connection(old);
511 cl->status.active = 1;
514 syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
515 cl->vpn_hostname, cl->real_hostname);
517 notify_others(cl, NULL, send_add_host);
524 int ack_h(conn_list_t *cl)
528 syslog(LOG_DEBUG, _("Got ACK from %s (%s)"),
529 cl->vpn_hostname, cl->real_hostname);
531 cl->status.active = 1;
533 syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
534 cl->vpn_hostname, cl->real_hostname);
536 notify_others(cl, NULL, send_add_host);
544 int termreq_h(conn_list_t *cl)
547 if(!cl->status.active)
549 syslog(LOG_ERR, _("Got unauthorized TERMREQ from %s (%s)"),
550 cl->vpn_hostname, cl->real_hostname);
555 syslog(LOG_DEBUG, _("Got TERMREQ from %s (%s)"),
556 cl->vpn_hostname, cl->real_hostname);
558 cl->status.termreq = 1;
560 terminate_connection(cl);
565 int timeout_h(conn_list_t *cl)
568 if(!cl->status.active)
570 syslog(LOG_ERR, _("Got unauthorized TIMEOUT from %s (%s)"),
571 cl->vpn_hostname, cl->real_hostname);
576 syslog(LOG_DEBUG, _("Got TIMEOUT from %s (%s)"),
577 cl->vpn_hostname, cl->real_hostname);
579 cl->status.termreq = 1;
580 terminate_connection(cl);
585 int del_host_h(conn_list_t *cl)
590 if(!cl->status.active)
592 syslog(LOG_ERR, _("Got unauthorized DEL_HOST from %s (%s)"),
593 cl->vpn_hostname, cl->real_hostname);
597 if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
599 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
600 cl->vpn_hostname, cl->real_hostname);
604 if(!(fw = lookup_conn(vpn_ip)))
606 syslog(LOG_ERR, _("Got DEL_HOST for %d.%d.%d.%d from %s (%s) which does not exist?"),
607 IP_ADDR_V(vpn_ip), cl->vpn_hostname, cl->real_hostname);
612 syslog(LOG_DEBUG, _("Got DEL_HOST for %s (%s) from %s (%s)"),
613 fw->vpn_hostname, fw->real_hostname, cl->vpn_hostname, cl->real_hostname);
615 notify_others(fw, cl, send_del_host);
617 fw->status.termreq = 1;
618 fw->status.active = 0;
620 terminate_connection(fw);
625 int ping_h(conn_list_t *cl)
628 if(!cl->status.active)
630 syslog(LOG_ERR, _("Got unauthorized PING from %s (%s)"),
631 cl->vpn_hostname, cl->real_hostname);
636 syslog(LOG_DEBUG, _("Got PING from %s (%s)"),
637 cl->vpn_hostname, cl->real_hostname);
639 cl->status.pinged = 0;
640 cl->status.got_pong = 1;
647 int pong_h(conn_list_t *cl)
650 if(!cl->status.active)
652 syslog(LOG_ERR, _("Got unauthorized PONG from %s (%s)"),
653 cl->vpn_hostname, cl->real_hostname);
658 syslog(LOG_DEBUG, _("Got PONG from %s (%s)"),
659 cl->vpn_hostname, cl->real_hostname);
661 cl->status.got_pong = 1;
666 int add_host_h(conn_list_t *cl)
673 conn_list_t *ncn, *old;
675 if(!cl->status.active)
677 syslog(LOG_ERR, _("Got unauthorized ADD_HOST from %s (%s)"),
678 cl->vpn_hostname, cl->real_hostname);
682 if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
684 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"),
685 cl->vpn_hostname, cl->real_hostname);
689 if(old = lookup_conn(vpn_ip))
691 if((real_ip==old->real_ip) && (vpn_mask==old->vpn_mask) && (port==old->port))
694 syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
695 old->vpn_hostname, old->real_hostname, cl->vpn_hostname, cl->real_hostname);
696 goto skip_add_host; /* One goto a day keeps the deeply nested if constructions away. */
701 syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"),
702 old->vpn_hostname, old->real_hostname);
703 old->status.active = 0;
704 terminate_connection(old);
708 ncn = new_conn_list();
709 ncn->real_ip = real_ip;
710 ncn->real_hostname = hostlookup(htonl(real_ip));
711 ncn->vpn_ip = vpn_ip;
712 ncn->vpn_mask = vpn_mask;
713 ncn->vpn_hostname = hostlookup(htonl(vpn_ip));
717 ncn->next = conn_list;
719 ncn->status.active = 1;
722 syslog(LOG_DEBUG, _("Got ADD_HOST for %s (%s) from %s (%s)"),
723 ncn->vpn_hostname, ncn->real_hostname, cl->vpn_hostname, cl->real_hostname);
727 notify_others(ncn, cl, send_add_host);
732 int req_key_h(conn_list_t *cl)
738 if(!cl->status.active)
740 syslog(LOG_ERR, _("Got unauthorized REQ_KEY from %s (%s)"),
741 cl->vpn_hostname, cl->real_hostname);
745 if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
747 syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
748 cl->vpn_hostname, cl->real_hostname);
753 syslog(LOG_DEBUG, _("Got REQ_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
754 IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
756 if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
757 { /* hey! they want something from ME! :) */
758 send_key_answer(cl, from);
762 fw = lookup_conn(to);
766 syslog(LOG_ERR, _("Attempting to forward REQ_KEY to %d.%d.%d.%d, which does not exist?"),
772 syslog(LOG_DEBUG, _("Forwarding REQ_KEY to %s (%s)"),
773 fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
775 cl->buffer[cl->reqlen-1] = '\n';
777 if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
779 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
786 void set_keys(conn_list_t *cl, int expiry, char *key)
792 cl->public_key = xmalloc(sizeof(*cl->key));
793 cl->public_key->key = NULL;
796 if(cl->public_key->key)
797 free(cl->public_key->key);
798 cl->public_key->length = strlen(key);
799 cl->public_key->expiry = expiry;
800 cl->public_key->key = xmalloc(cl->public_key->length + 1);
801 strcpy(cl->public_key->key, key);
803 ek = make_shared_key(key);
807 cl->key = xmalloc(sizeof(*cl->key));
814 cl->key->length = strlen(ek);
815 cl->key->expiry = expiry;
816 cl->key->key = xmalloc(cl->key->length + 1);
817 strcpy(cl->key->key, ek);
821 int ans_key_h(conn_list_t *cl)
827 conn_list_t *fw, *gk;
829 if(!cl->status.active)
831 syslog(LOG_ERR, _("Got unauthorized ANS_KEY from %s (%s)"),
832 cl->vpn_hostname, cl->real_hostname);
836 if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
838 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
839 cl->vpn_hostname, cl->real_hostname);
844 syslog(LOG_DEBUG, _("Got ANS_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
845 IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
847 if(to == myself->vpn_ip)
848 { /* hey! that key's for ME! :) */
849 gk = lookup_conn(from);
853 syslog(LOG_ERR, _("Receiving ANS_KEY origin %d.%d.%d.%d from %s (%s), which does not exist?"),
854 IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
858 set_keys(gk, expiry, key);
859 gk->status.validkey = 1;
860 gk->status.waitingforkey = 0;
865 fw = lookup_conn(to);
869 syslog(LOG_ERR, _("Attempting to forward ANS_KEY to %d.%d.%d.%d, which does not exist?"),
875 syslog(LOG_DEBUG, _("Forwarding ANS_KEY to %s (%s)"),
876 fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
878 cl->buffer[cl->reqlen-1] = '\n';
880 if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
882 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
889 int key_changed_h(conn_list_t *cl)
894 if(!cl->status.active)
896 syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from %s (%s)"),
897 cl->vpn_hostname, cl->real_hostname);
901 if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
903 syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
904 cl->vpn_hostname, cl->real_hostname);
908 ik = lookup_conn(from);
912 syslog(LOG_ERR, _("Got KEY_CHANGED origin %d.%d.%d.%d from %s (%s), which does not exist?"),
913 IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
918 syslog(LOG_DEBUG, _("Got KEY_CHANGED origin %s from %s (%s)"),
919 ik->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
921 ik->status.validkey = 0;
922 ik->status.waitingforkey = 0;
924 notify_others(ik, cl, send_key_changed);
929 int (*request_handlers[256])(conn_list_t*) = {
930 0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
931 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
933 termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
934 ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
935 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
936 add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
937 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
938 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
939 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
940 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
941 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
942 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
943 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
944 req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
945 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
946 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
947 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
948 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
949 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0