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.14 2000/06/28 13:41:02 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__);
68 int send_termreq(conn_list_t *cl)
72 syslog(LOG_DEBUG, _("Sending TERMREQ to " IP_ADDR_S " (%s)"),
73 IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S " (%s)"),
92 IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S " (%s) to " IP_ADDR_S " (%s)"),
110 IP_ADDR_V(new_host->vpn_ip), new_host->hostname, IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S " (%s)"),
128 IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S " (%s)"),
146 IP_ADDR_V(cl->vpn_ip), cl->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->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->hostname;
184 syslog(LOG_DEBUG, _("Sending ADD_HOST for " IP_ADDR_S " (%s) to " IP_ADDR_S " (%s)"),
185 IP_ADDR_V(new_host->vpn_ip), hostname, IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S " to " IP_ADDR_S " (%s)"),
203 IP_ADDR_V(src->vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S " (%s)"),
252 IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S " (%s)"),
270 IP_ADDR_V(cl->vpn_ip), cl->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 " IP_ADDR_S ", which does not exist?"),
312 syslog(LOG_DEBUG, _("Sending REQ_KEY to " IP_ADDR_S " (%s)"),
313 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->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 " IP_ADDR_S ", which does not exist?"),
342 syslog(LOG_DEBUG, _("Sending ANS_KEY to " IP_ADDR_S " (%s)"),
343 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->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->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 if(cl->protocol_version != PROT_CURRENT)
407 syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
408 cl->protocol_version);
412 if(cl->status.outgoing)
414 if(setup_vpn_connection(cl) < 0)
420 if(setup_vpn_connection(cl) < 0)
428 int passphrase_h(conn_list_t *cl)
431 cl->pp = xmalloc(sizeof(*(cl->pp)));
433 if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
435 syslog(LOG_ERR, _("Got bad PASSPHRASE from " IP_ADDR_S " (%s)"),
436 IP_ADDR_V(cl->vpn_ip), cl->hostname);
439 cl->pp->len = strlen(cl->pp->phrase);
442 syslog(LOG_DEBUG, _("Got PASSPHRASE from " IP_ADDR_S " (%s)"),
443 IP_ADDR_V(cl->vpn_ip), cl->hostname);
445 if(cl->status.outgoing)
453 int public_key_h(conn_list_t *cl)
458 if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
460 syslog(LOG_ERR, _("Got bad PUBLIC_KEY from " IP_ADDR_S " (%s)"),
461 IP_ADDR_V(cl->vpn_ip), cl->hostname);
466 syslog(LOG_DEBUG, _("Got PUBLIC_KEY from " IP_ADDR_S " (%s)"),
467 IP_ADDR_V(cl->vpn_ip), cl->hostname);
469 if(verify_passphrase(cl, g_n))
472 syslog(LOG_ERR, _("Intruder: passphrase does not match!"));
476 if(cl->status.outgoing)
482 /* Okay, before we active the connection, we check if there is another entry
483 in the connection list with the same vpn_ip. If so, it presumably is an
484 old connection that has timed out but we don't know it yet. Because our
485 conn_list entry is not active, lookup_conn will skip ourself. */
487 while(old = lookup_conn(cl->vpn_ip))
488 terminate_connection(old);
490 cl->status.active = 1;
493 syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
494 IP_ADDR_V(cl->vpn_ip), cl->hostname);
496 notify_others(cl, NULL, send_add_host);
503 int ack_h(conn_list_t *cl)
507 syslog(LOG_DEBUG, _("Got ACK from " IP_ADDR_S " (%s)"),
508 IP_ADDR_V(cl->vpn_ip), cl->hostname);
510 cl->status.active = 1;
512 syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
513 IP_ADDR_V(cl->vpn_ip), cl->hostname);
515 notify_others(cl, NULL, send_add_host);
523 int termreq_h(conn_list_t *cl)
526 if(!cl->status.active)
528 syslog(LOG_ERR, _("Got unauthorized TERMREQ from " IP_ADDR_S " (%s)"),
529 IP_ADDR_V(cl->vpn_ip), cl->hostname);
534 syslog(LOG_DEBUG, _("Got TERMREQ from " IP_ADDR_S " (%s)"),
535 IP_ADDR_V(cl->vpn_ip), cl->hostname);
537 cl->status.termreq = 1;
539 if(cl->status.active)
540 notify_others(cl, NULL, send_del_host);
542 cl->status.active = 0;
544 terminate_connection(cl);
549 int timeout_h(conn_list_t *cl)
552 if(!cl->status.active)
554 syslog(LOG_ERR, _("Got unauthorized TIMEOUT from " IP_ADDR_S " (%s)"),
555 IP_ADDR_V(cl->vpn_ip), cl->hostname);
560 syslog(LOG_DEBUG, _("Got TIMEOUT from " IP_ADDR_S " (%s)"),
561 IP_ADDR_V(cl->vpn_ip), cl->hostname);
563 cl->status.termreq = 1;
564 terminate_connection(cl);
569 int del_host_h(conn_list_t *cl)
574 if(!cl->status.active)
576 syslog(LOG_ERR, _("Got unauthorized DEL_HOST from " IP_ADDR_S " (%s)"),
577 IP_ADDR_V(cl->vpn_ip), cl->hostname);
581 if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
583 syslog(LOG_ERR, _("Got bad DEL_HOST from " IP_ADDR_S " (%s)"),
584 IP_ADDR_V(cl->vpn_ip), cl->hostname);
588 if(!(fw = lookup_conn(vpn_ip)))
590 syslog(LOG_ERR, _("Got DEL_HOST for " IP_ADDR_S " from " IP_ADDR_S " (%s) which does not exist?"),
591 IP_ADDR_V(vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
596 syslog(LOG_DEBUG, _("Got DEL_HOST for " IP_ADDR_S " (%s) from " IP_ADDR_S " (%s)"),
597 IP_ADDR_V(fw->vpn_ip), fw->hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
599 notify_others(fw, cl, send_del_host);
601 fw->status.termreq = 1;
602 fw->status.active = 0;
604 terminate_connection(fw);
609 int ping_h(conn_list_t *cl)
612 if(!cl->status.active)
614 syslog(LOG_ERR, _("Got unauthorized PING from " IP_ADDR_S " (%s)"),
615 IP_ADDR_V(cl->vpn_ip), cl->hostname);
620 syslog(LOG_DEBUG, _("Got PING from " IP_ADDR_S " (%s)"),
621 IP_ADDR_V(cl->vpn_ip), cl->hostname);
623 cl->status.pinged = 0;
624 cl->status.got_pong = 1;
631 int pong_h(conn_list_t *cl)
634 if(!cl->status.active)
636 syslog(LOG_ERR, _("Got unauthorized PONG from " IP_ADDR_S " (%s)"),
637 IP_ADDR_V(cl->vpn_ip), cl->hostname);
642 syslog(LOG_DEBUG, _("Got PONG from " IP_ADDR_S " (%s)"),
643 IP_ADDR_V(cl->vpn_ip), cl->hostname);
645 cl->status.got_pong = 1;
650 int add_host_h(conn_list_t *cl)
657 conn_list_t *ncn, *old;
659 if(!cl->status.active)
661 syslog(LOG_ERR, _("Got unauthorized ADD_HOST from " IP_ADDR_S " (%s)"),
662 IP_ADDR_V(cl->vpn_ip), cl->hostname);
666 if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
668 syslog(LOG_ERR, _("Got bad ADD_HOST from " IP_ADDR_S " (%s)"),
669 IP_ADDR_V(cl->vpn_ip), cl->hostname);
673 while(old = lookup_conn(vpn_ip))
674 terminate_connection(old);
676 ncn = new_conn_list();
677 ncn->real_ip = real_ip;
678 ncn->hostname = hostlookup(htonl(real_ip));
679 ncn->vpn_ip = vpn_ip;
680 ncn->vpn_mask = vpn_mask;
684 ncn->next = conn_list;
686 ncn->status.active = 1;
689 syslog(LOG_DEBUG, _("Got ADD_HOST for " IP_ADDR_S " (%s) from " IP_ADDR_S " (%s)"),
690 IP_ADDR_V(ncn->vpn_ip), ncn->hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
692 notify_others(ncn, cl, send_add_host);
697 int req_key_h(conn_list_t *cl)
703 if(!cl->status.active)
705 syslog(LOG_ERR, _("Got unauthorized REQ_KEY from " IP_ADDR_S " (%s)"),
706 IP_ADDR_V(cl->vpn_ip), cl->hostname);
710 if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
712 syslog(LOG_ERR, _("Got bad REQ_KEY from " IP_ADDR_S " (%s)"),
713 IP_ADDR_V(cl->vpn_ip), cl->hostname);
718 syslog(LOG_DEBUG, _("Got REQ_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
719 IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
721 if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
722 { /* hey! they want something from ME! :) */
723 send_key_answer(cl, from);
727 fw = lookup_conn(to);
731 syslog(LOG_ERR, _("Attempting to forward REQ_KEY to " IP_ADDR_S ", which does not exist?"),
737 syslog(LOG_DEBUG, _("Forwarding REQ_KEY to " IP_ADDR_S " (%s)"),
738 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
740 cl->buffer[cl->reqlen-1] = '\n';
742 if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
744 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
751 void set_keys(conn_list_t *cl, int expiry, char *key)
757 cl->public_key = xmalloc(sizeof(*cl->key));
758 cl->public_key->key = NULL;
761 if(cl->public_key->key)
762 free(cl->public_key->key);
763 cl->public_key->length = strlen(key);
764 cl->public_key->expiry = expiry;
765 cl->public_key->key = xmalloc(cl->public_key->length + 1);
766 strcpy(cl->public_key->key, key);
768 ek = make_shared_key(key);
772 cl->key = xmalloc(sizeof(*cl->key));
779 cl->key->length = strlen(ek);
780 cl->key->expiry = expiry;
781 cl->key->key = xmalloc(cl->key->length + 1);
782 strcpy(cl->key->key, ek);
786 int ans_key_h(conn_list_t *cl)
792 conn_list_t *fw, *gk;
794 if(!cl->status.active)
796 syslog(LOG_ERR, _("Got unauthorized ANS_KEY from " IP_ADDR_S " (%s)"),
797 IP_ADDR_V(cl->vpn_ip), cl->hostname);
801 if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
803 syslog(LOG_ERR, _("Got bad ANS_KEY from " IP_ADDR_S " (%s)"),
804 IP_ADDR_V(cl->vpn_ip), cl->hostname);
809 syslog(LOG_DEBUG, _("Got ANS_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
810 IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
812 if(to == myself->vpn_ip)
813 { /* hey! that key's for ME! :) */
814 gk = lookup_conn(from);
818 syslog(LOG_ERR, _("Receiving ANS_KEY from " IP_ADDR_S ", which does not exist?"),
823 set_keys(gk, expiry, key);
824 gk->status.validkey = 1;
825 gk->status.waitingforkey = 0;
830 fw = lookup_conn(to);
834 syslog(LOG_ERR, _("Attempting to forward ANS_KEY to " IP_ADDR_S ", which does not exist?"),
840 syslog(LOG_DEBUG, _("Forwarding ANS_KEY to " IP_ADDR_S " (%s)"),
841 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
843 cl->buffer[cl->reqlen-1] = '\n';
845 if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
847 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
854 int key_changed_h(conn_list_t *cl)
859 if(!cl->status.active)
861 syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from " IP_ADDR_S " (%s)"),
862 IP_ADDR_V(cl->vpn_ip), cl->hostname);
866 if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
868 syslog(LOG_ERR, _("Got bad KEY_CHANGED from " IP_ADDR_S " (%s)"),
869 IP_ADDR_V(cl->vpn_ip), cl->hostname);
874 syslog(LOG_DEBUG, _("Got KEY_CHANGED origin " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
875 IP_ADDR_V(from), IP_ADDR_V(cl->vpn_ip), cl->hostname);
877 ik = lookup_conn(from);
881 syslog(LOG_ERR, _("Got KEY_CHANGED from " IP_ADDR_S ", which does not exist?"),
886 ik->status.validkey = 0;
887 ik->status.waitingforkey = 0;
889 notify_others(ik, cl, send_key_changed);
894 int (*request_handlers[256])(conn_list_t*) = {
895 0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
896 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
897 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
898 termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
899 ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
900 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901 add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
902 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
903 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
904 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
905 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
906 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
907 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
908 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
909 req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
910 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
911 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
912 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
914 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0