- Removed all IP_ADDR_S macros, because gettext doesn't like them. Each
[tinc] / src / protocol.c
1 /*
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>
5
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.
10
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.
15
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.
19
20     $Id: protocol.c,v 1.28.4.15 2000/06/29 13:04:15 guus Exp $
21 */
22
23 #include "config.h"
24
25 #include <sys/types.h>
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <syslog.h>
30 #include <sys/socket.h>
31 #include <unistd.h>
32 #include <stdio.h>
33
34 #include <utils.h>
35 #include <xalloc.h>
36
37 #include "conf.h"
38 #include "encr.h"
39 #include "net.h"
40 #include "netutl.h"
41 #include "protocol.h"
42
43 #include "system.h"
44
45 char buffer[MAXBUFSIZE+1];
46 int buflen;
47
48 /* Outgoing request routines */
49
50 int send_ack(conn_list_t *cl)
51 {
52 cp
53   if(debug_lvl > 1)
54     syslog(LOG_DEBUG, _("Sending ACK to %s (%s)"),
55            cl->vpn_hostname, cl->real_hostname);
56
57   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", ACK);
58
59   if((write(cl->meta_socket, buffer, buflen)) < 0)
60     {
61       syslog(LOG_ERR, _("Send failed: %d:%d: %m"), __FILE__, __LINE__);
62       return -1;
63     }
64 cp
65   return 0;
66 }
67
68 int send_termreq(conn_list_t *cl)
69 {
70 cp
71   if(debug_lvl > 1)
72     syslog(LOG_DEBUG, _("Sending TERMREQ to %s (%s)"),
73            cl->vpn_hostname, cl->real_hostname);
74
75   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
76
77   if(write(cl->meta_socket, buffer, buflen) < 0)
78     {
79       if(debug_lvl > 1)
80         syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
81       return -1;
82     }
83 cp
84   return 0;
85 }
86
87 int send_timeout(conn_list_t *cl)
88 {
89 cp
90   if(debug_lvl > 1)
91     syslog(LOG_DEBUG, _("Sending TIMEOUT to %s (%s)"),
92            cl->vpn_hostname, cl->real_hostname);
93
94   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
95
96   if((write(cl->meta_socket, buffer, buflen)) < 0)
97     {
98       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
99       return -1;
100     }
101 cp
102   return 0;
103 }
104
105 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
106 {
107 cp
108   if(debug_lvl > 1)
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);
111
112   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
113
114   if((write(cl->meta_socket, buffer, buflen)) < 0)
115     {
116       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
117       return -1;
118     }
119 cp
120   return 0;
121 }
122
123 int send_ping(conn_list_t *cl)
124 {
125 cp
126   if(debug_lvl > 1)
127     syslog(LOG_DEBUG, _("Sending PING to %s (%s)"),
128            cl->vpn_hostname, cl->real_hostname);
129
130   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
131
132   if((write(cl->meta_socket, buffer, buflen)) < 0)
133     {
134       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
135       return -1;
136     }
137 cp
138   return 0;
139 }
140
141 int send_pong(conn_list_t *cl)
142 {
143 cp
144   if(debug_lvl > 1)
145     syslog(LOG_DEBUG, _("Sending PONG to %s (%s)"),
146            cl->vpn_hostname, cl->real_hostname);
147
148   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
149
150   if((write(cl->meta_socket, buffer, buflen)) < 0)
151     {
152       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
153       return -1;
154     }
155 cp
156   return 0;
157 }
158
159 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
160 {
161   ip_t real_ip;
162   int flags;
163   char *hostname;
164 cp
165   real_ip = new_host->real_ip;
166   hostname = new_host->real_hostname;
167   flags = new_host->flags;
168   
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
172    * work correctly.
173    */
174      
175   if(flags & EXPORTINDIRECTDATA)
176     {
177       flags &= ~EXPORTINDIRECTDATA;
178       flags |= INDIRECTDATA;
179       real_ip = myself->vpn_ip;
180       hostname = myself->real_hostname;
181     }
182
183   if(debug_lvl > 1)
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);
186
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);
188
189   if((write(cl->meta_socket, buffer, buflen)) < 0)
190     {
191       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
192       return -1;
193     }
194 cp
195   return 0;
196 }
197
198 int send_key_changed(conn_list_t *cl, conn_list_t *src)
199 {
200 cp
201   if(debug_lvl > 1)
202     syslog(LOG_DEBUG, _("Sending KEY_CHANGED origin %s to %s (%s)"),
203            src->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
204
205   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
206
207   if((write(cl->meta_socket, buffer, buflen)) < 0)
208     {
209       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
210       return -1;
211     }
212 cp
213   return 0;
214 }
215
216 void send_key_changed_all(void)
217 {
218   conn_list_t *p;
219 cp
220   for(p = conn_list; p != NULL; p = p->next)
221     if(p->status.meta && p->status.active)
222       send_key_changed(p, myself);
223 cp
224 }
225
226 int send_basic_info(conn_list_t *cl)
227 {
228 cp
229   if(debug_lvl > 1)
230     syslog(LOG_DEBUG, _("Sending BASIC_INFO to %s"),
231            cl->real_hostname);
232
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);
234
235   if((write(cl->meta_socket, buffer, buflen)) < 0)
236     {
237       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
238       return -1;
239     }
240 cp
241   return 0;
242 }
243
244 int send_passphrase(conn_list_t *cl)
245 {
246   passphrase_t tmp;
247 cp
248   encrypt_passphrase(&tmp);
249
250   if(debug_lvl > 1)
251     syslog(LOG_DEBUG, _("Sending PASSPHRASE to %s (%s)"),
252            cl->vpn_hostname, cl->real_hostname);
253
254   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
255
256   if((write(cl->meta_socket, buffer, buflen)) < 0)
257     {
258       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
259       return -1;
260     }
261 cp
262   return 0;
263 }
264
265 int send_public_key(conn_list_t *cl)
266 {
267 cp
268   if(debug_lvl > 1)
269     syslog(LOG_DEBUG, _("Sending PUBLIC_KEY to %s (%s)"),
270            cl->vpn_hostname, cl->real_hostname);
271
272   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
273
274   if((write(cl->meta_socket, buffer, buflen)) < 0)
275     {
276       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
277       return -1;
278     }
279 cp
280   return 0;
281 }
282
283 /* WDN doet deze functie? (GS)
284 int send_calculate(conn_list_t *cl, char *k)
285 {
286 cp
287   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", CALCULATE, k);
288
289   if((write(cl->meta_socket, buffer, buflen)) < 0)
290     {
291       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
292       return -1;
293     }
294 cp
295   return 0;
296 }
297 */
298
299 int send_key_request(ip_t to)
300 {
301   conn_list_t *fw;
302 cp
303   fw = lookup_conn(to);
304   if(!fw)
305     {
306       syslog(LOG_ERR, _("Attempting to send REQ_KEY to %d.%d.%d.%d, which does not exist?"),
307              IP_ADDR_V(to));
308       return -1;
309     }
310
311   if(debug_lvl > 1)
312     syslog(LOG_DEBUG, _("Sending REQ_KEY to %s (%s)"),
313            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
314
315   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
316
317   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
318     {
319       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
320       return -1;
321     }
322   fw->status.waitingforkey = 1;
323 cp
324   return 0;
325 }
326
327 int send_key_answer(conn_list_t *cl, ip_t to)
328 {
329   conn_list_t *fw;
330 cp
331
332   fw = lookup_conn(to);
333   
334   if(!fw)
335     {
336       syslog(LOG_ERR, _("Attempting to send ANS_KEY to %d.%d.%d.%d, which does not exist?"),
337              IP_ADDR_V(to));
338       return -1;
339     }
340
341  if(debug_lvl > 1)
342     syslog(LOG_DEBUG, _("Sending ANS_KEY to %s (%s)"),
343            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
344
345   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
346
347   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
348     {
349       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
350       return -1;
351     }
352 cp
353   return 0;
354 }
355
356 /*
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.
360 */
361 int notify_others(conn_list_t *new, conn_list_t *source,
362                   int (*function)(conn_list_t*, conn_list_t*))
363 {
364   conn_list_t *p;
365 cp
366   for(p = conn_list; p != NULL; p = p->next)
367     if(p != new && p != source && p->status.meta && p->status.active)
368       function(p, new);
369 cp
370   return 0;
371 }
372
373 /*
374   notify one connection of everything
375   i have connected
376 */
377 int notify_one(conn_list_t *new)
378 {
379   conn_list_t *p;
380 cp
381   for(p = conn_list; p != NULL; p = p->next)
382     if(p != new && p->status.active)
383       send_add_host(new, p);
384 cp
385   return 0;
386 }
387
388 /*
389   The incoming request handlers
390 */
391
392 int basic_info_h(conn_list_t *cl)
393 {
394 cp
395   if(debug_lvl > 1)
396     syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->real_hostname);
397
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)
399     {
400        syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
401               cl->real_hostname);
402        return -1;
403     }
404     
405   cl->vpn_hostname = hostlookup(htonl(cl->vpn_ip));
406
407   if(cl->protocol_version != PROT_CURRENT)
408     {
409       syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
410              cl->protocol_version);
411       return -1;
412     }
413
414   if(cl->status.outgoing)
415     {
416       if(setup_vpn_connection(cl) < 0)
417         return -1;
418       send_basic_info(cl);
419     }
420   else
421     {
422       if(setup_vpn_connection(cl) < 0)
423         return -1;
424       send_passphrase(cl);
425     }
426 cp
427   return 0;
428 }
429
430 int passphrase_h(conn_list_t *cl)
431 {
432 cp
433   cl->pp = xmalloc(sizeof(*(cl->pp)));
434
435   if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
436     {
437       syslog(LOG_ERR, _("Got bad PASSPHRASE from %s (%s)"),
438               cl->vpn_hostname, cl->real_hostname);
439       return -1;
440     }
441   cl->pp->len = strlen(cl->pp->phrase);
442     
443   if(debug_lvl > 1)
444     syslog(LOG_DEBUG, _("Got PASSPHRASE from %s (%s)"),
445               cl->vpn_hostname, cl->real_hostname);
446
447   if(cl->status.outgoing)
448     send_passphrase(cl);
449   else
450     send_public_key(cl);
451 cp
452   return 0;
453 }
454
455 int public_key_h(conn_list_t *cl)
456 {
457   char *g_n;
458   conn_list_t *old;
459 cp
460   if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
461     {
462        syslog(LOG_ERR, _("Got bad PUBLIC_KEY from %s (%s)"),
463               cl->vpn_hostname, cl->real_hostname);
464        return -1;
465     }  
466
467   if(debug_lvl > 1)
468     syslog(LOG_DEBUG, _("Got PUBLIC_KEY from %s (%s)"),
469               cl->vpn_hostname, cl->real_hostname);
470
471   if(verify_passphrase(cl, g_n))
472     {
473       /* intruder! */
474       syslog(LOG_ERR, _("Intruder: passphrase does not match!"));
475       return -1;
476     }
477
478   if(cl->status.outgoing)
479     send_public_key(cl);
480   else
481     {
482       send_ack(cl);
483
484       /* Okay, before we active the connection, we check if there is another entry
485          in the connection list with the same vpn_ip. If so, it presumably is an
486          old connection that has timed out but we don't know it yet. Because our
487          conn_list entry is not active, lookup_conn will skip ourself. */
488
489       while(old = lookup_conn(cl->vpn_ip)) 
490         terminate_connection(old);
491
492       cl->status.active = 1;
493
494       if(debug_lvl > 0)
495         syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
496                            cl->vpn_hostname, cl->real_hostname);
497
498       notify_others(cl, NULL, send_add_host);
499       notify_one(cl);
500     }
501 cp
502   return 0;
503 }
504
505 int ack_h(conn_list_t *cl)
506 {
507 cp
508   if(debug_lvl > 1)
509     syslog(LOG_DEBUG, _("Got ACK from %s (%s)"),
510               cl->vpn_hostname, cl->real_hostname);
511   
512   cl->status.active = 1;
513
514   syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
515               cl->vpn_hostname, cl->real_hostname);
516
517   notify_others(cl, NULL, send_add_host);
518   notify_one(cl);
519
520   upstreamindex = 0;
521 cp
522   return 0;
523 }
524
525 int termreq_h(conn_list_t *cl)
526 {
527 cp
528   if(!cl->status.active)
529     {
530       syslog(LOG_ERR, _("Got unauthorized TERMREQ from %s (%s)"),
531               cl->vpn_hostname, cl->real_hostname);
532       return -1;
533     }
534     
535   if(debug_lvl > 1)
536    syslog(LOG_DEBUG, _("Got TERMREQ from %s (%s)"),
537              cl->vpn_hostname, cl->real_hostname);
538   
539   cl->status.termreq = 1;
540
541   if(cl->status.active)
542     notify_others(cl, NULL, send_del_host);
543
544   cl->status.active = 0;
545
546   terminate_connection(cl);
547 cp
548   return 0;
549 }
550
551 int timeout_h(conn_list_t *cl)
552 {
553 cp
554   if(!cl->status.active)
555     {
556       syslog(LOG_ERR, _("Got unauthorized TIMEOUT from %s (%s)"),
557               cl->vpn_hostname, cl->real_hostname);
558       return -1;
559     }
560
561   if(debug_lvl > 1)
562     syslog(LOG_DEBUG, _("Got TIMEOUT from %s (%s)"),
563               cl->vpn_hostname, cl->real_hostname);
564
565   cl->status.termreq = 1;
566   terminate_connection(cl);
567 cp
568   return 0;
569 }
570
571 int del_host_h(conn_list_t *cl)
572 {
573   ip_t vpn_ip;
574   conn_list_t *fw;
575 cp
576   if(!cl->status.active)
577     {
578       syslog(LOG_ERR, _("Got unauthorized DEL_HOST from %s (%s)"),
579               cl->vpn_hostname, cl->real_hostname);
580       return -1;
581     }
582
583   if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
584     {
585        syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
586               cl->vpn_hostname, cl->real_hostname);
587        return -1;
588     }  
589
590   if(!(fw = lookup_conn(vpn_ip)))
591     {
592       syslog(LOG_ERR, _("Got DEL_HOST for %d.%d.%d.%d from %s (%s) which does not exist?"),
593              IP_ADDR_V(vpn_ip), cl->vpn_hostname, cl->real_hostname);
594       return 0;
595     }
596
597   if(debug_lvl > 1)
598     syslog(LOG_DEBUG, _("Got DEL_HOST for %s (%s) from %s (%s)"),
599            fw->vpn_hostname, fw->real_hostname, cl->vpn_hostname, cl->real_hostname);
600
601   notify_others(fw, cl, send_del_host);
602
603   fw->status.termreq = 1;
604   fw->status.active = 0;
605
606   terminate_connection(fw);
607 cp
608   return 0;
609 }
610
611 int ping_h(conn_list_t *cl)
612 {
613 cp
614   if(!cl->status.active)
615     {
616       syslog(LOG_ERR, _("Got unauthorized PING from %s (%s)"),
617               cl->vpn_hostname, cl->real_hostname);
618       return -1;
619     }
620
621   if(debug_lvl > 1)
622     syslog(LOG_DEBUG, _("Got PING from %s (%s)"),
623               cl->vpn_hostname, cl->real_hostname);
624
625   cl->status.pinged = 0;
626   cl->status.got_pong = 1;
627
628   send_pong(cl);
629 cp
630   return 0;
631 }
632
633 int pong_h(conn_list_t *cl)
634 {
635 cp
636   if(!cl->status.active)
637     {
638       syslog(LOG_ERR, _("Got unauthorized PONG from %s (%s)"),
639               cl->vpn_hostname, cl->real_hostname);
640       return -1;
641     }
642
643   if(debug_lvl > 1)
644     syslog(LOG_DEBUG, _("Got PONG from %s (%s)"),
645               cl->vpn_hostname, cl->real_hostname);
646
647   cl->status.got_pong = 1;
648 cp
649   return 0;
650 }
651
652 int add_host_h(conn_list_t *cl)
653 {
654   ip_t real_ip;
655   ip_t vpn_ip;
656   ip_t vpn_mask;
657   unsigned short port;
658   int flags;
659   conn_list_t *ncn, *old;
660 cp
661   if(!cl->status.active)
662     {
663       syslog(LOG_ERR, _("Got unauthorized ADD_HOST from %s (%s)"),
664               cl->vpn_hostname, cl->real_hostname);
665       return -1;
666     }
667     
668   if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
669     {
670        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"),
671               cl->vpn_hostname, cl->real_hostname);
672        return -1;
673     }  
674
675   while(old = lookup_conn(vpn_ip))
676       terminate_connection(old);
677     
678   ncn = new_conn_list();
679   ncn->real_ip = real_ip;
680   ncn->real_hostname = hostlookup(htonl(real_ip));
681   ncn->vpn_ip = vpn_ip;
682   ncn->vpn_mask = vpn_mask;
683   ncn->vpn_hostname = hostlookup(htonl(vpn_ip));
684   ncn->port = port;
685   ncn->flags = flags;
686   ncn->nexthop = cl;
687   ncn->next = conn_list;
688   conn_list = ncn;
689   ncn->status.active = 1;
690
691   if(debug_lvl > 1)
692     syslog(LOG_DEBUG, _("Got ADD_HOST for %s (%s) from %s (%s)"),
693            ncn->vpn_hostname, ncn->real_hostname, cl->vpn_hostname, cl->real_hostname);
694
695   notify_others(ncn, cl, send_add_host);
696 cp
697   return 0;
698 }
699
700 int req_key_h(conn_list_t *cl)
701 {
702   ip_t to;
703   ip_t from;
704   conn_list_t *fw;
705 cp
706   if(!cl->status.active)
707     {
708       syslog(LOG_ERR, _("Got unauthorized REQ_KEY from %s (%s)"),
709               cl->vpn_hostname, cl->real_hostname);
710       return -1;
711     }
712
713   if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
714     {
715        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
716               cl->vpn_hostname, cl->real_hostname);
717        return -1;
718     }  
719
720   if(debug_lvl > 1)
721     syslog(LOG_DEBUG, _("Got REQ_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
722            IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
723
724   if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
725     {  /* hey! they want something from ME! :) */
726       send_key_answer(cl, from);
727       return 0;
728     }
729
730   fw = lookup_conn(to);
731   
732   if(!fw)
733     {
734       syslog(LOG_ERR, _("Attempting to forward REQ_KEY to %d.%d.%d.%d, which does not exist?"),
735              IP_ADDR_V(to));
736       return -1;
737     }
738
739   if(debug_lvl > 1)
740     syslog(LOG_DEBUG, _("Forwarding REQ_KEY to %s (%s)"),
741            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
742   
743   cl->buffer[cl->reqlen-1] = '\n';
744   
745   if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
746     {
747       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
748       return -1;
749     }
750 cp
751   return 0;
752 }
753
754 void set_keys(conn_list_t *cl, int expiry, char *key)
755 {
756   char *ek;
757 cp
758   if(!cl->public_key)
759     {
760       cl->public_key = xmalloc(sizeof(*cl->key));
761       cl->public_key->key = NULL;
762     }
763     
764   if(cl->public_key->key)
765     free(cl->public_key->key);
766   cl->public_key->length = strlen(key);
767   cl->public_key->expiry = expiry;
768   cl->public_key->key = xmalloc(cl->public_key->length + 1);
769   strcpy(cl->public_key->key, key);
770
771   ek = make_shared_key(key);
772   
773   if(!cl->key)
774     {
775       cl->key = xmalloc(sizeof(*cl->key));
776       cl->key->key = NULL;
777     }
778
779   if(cl->key->key)
780     free(cl->key->key);
781
782   cl->key->length = strlen(ek);
783   cl->key->expiry = expiry;
784   cl->key->key = xmalloc(cl->key->length + 1);
785   strcpy(cl->key->key, ek);
786 cp
787 }
788
789 int ans_key_h(conn_list_t *cl)
790 {
791   ip_t to;
792   ip_t from;
793   int expiry;
794   char *key;
795   conn_list_t *fw, *gk;
796 cp
797   if(!cl->status.active)
798     {
799       syslog(LOG_ERR, _("Got unauthorized ANS_KEY from %s (%s)"),
800               cl->vpn_hostname, cl->real_hostname);
801       return -1;
802     }
803
804   if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
805     {
806        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
807               cl->vpn_hostname, cl->real_hostname);
808        return -1;
809     }  
810
811   if(debug_lvl > 1)
812     syslog(LOG_DEBUG, _("Got ANS_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
813             IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
814
815   if(to == myself->vpn_ip)
816     {  /* hey! that key's for ME! :) */
817       gk = lookup_conn(from);
818
819       if(!gk)
820         {
821           syslog(LOG_ERR, _("Receiving ANS_KEY origin %d.%d.%d.%d from %s (%s), which does not exist?"),
822                  IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
823           return -1;
824         }
825
826       set_keys(gk, expiry, key);
827       gk->status.validkey = 1;
828       gk->status.waitingforkey = 0;
829       flush_queues(gk);
830       return 0;
831     }
832
833   fw = lookup_conn(to);
834   
835   if(!fw)
836     {
837       syslog(LOG_ERR, _("Attempting to forward ANS_KEY to %d.%d.%d.%d, which does not exist?"),
838              IP_ADDR_V(to));
839       return -1;
840     }
841
842   if(debug_lvl > 1)
843     syslog(LOG_DEBUG, _("Forwarding ANS_KEY to %s (%s)"),
844            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
845
846   cl->buffer[cl->reqlen-1] = '\n';
847
848   if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
849     {
850       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
851       return -1;
852     }
853 cp
854   return 0;
855 }
856
857 int key_changed_h(conn_list_t *cl)
858 {
859   ip_t from;
860   conn_list_t *ik;
861 cp
862   if(!cl->status.active)
863     {
864       syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from %s (%s)"),
865               cl->vpn_hostname, cl->real_hostname);
866       return -1;
867     }
868
869   if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
870     {
871        syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
872               cl->vpn_hostname, cl->real_hostname);
873        return -1;
874     }  
875
876   ik = lookup_conn(from);
877
878   if(!ik)
879     {
880       syslog(LOG_ERR, _("Got KEY_CHANGED origin %d.%d.%d.%d from %s (%s), which does not exist?"),
881              IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
882       return -1;
883     }
884
885   if(debug_lvl > 1)
886     syslog(LOG_DEBUG, _("Got KEY_CHANGED origin %s from %s (%s)"),
887             ik->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
888
889   ik->status.validkey = 0;
890   ik->status.waitingforkey = 0;
891
892   notify_others(ik, cl, send_key_changed);
893 cp
894   return 0;
895 }
896
897 int (*request_handlers[256])(conn_list_t*) = {
898   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
899   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
900   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
902   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
903   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
904   add_host_h, basic_info_h, passphrase_h, public_key_h, 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,
908   0, 0, 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,  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   req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
913   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, 0, 0, 0, 0,
915   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
916   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
917   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0
918 };