f8d72298e28162d01ec4d7bc1095f30683ab6cc6
[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.18 2000/06/30 12:41:06 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   conn_list_t *old;
395 cp
396   if(debug_lvl > 1)
397     syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->real_hostname);
398
399   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     {
401        syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
402               cl->real_hostname);
403        return -1;
404     }
405     
406   cl->vpn_hostname = hostlookup(htonl(cl->vpn_ip));
407
408   if(cl->protocol_version != PROT_CURRENT)
409     {
410       syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
411              cl->protocol_version);
412       return -1;
413     }
414
415   if(cl->status.outgoing)
416     {
417       /* First check if the host we connected to is already in our
418          connection list. If so, we are probably making a loop, which
419          is not desirable.
420        */
421        
422       if(old=lookup_conn(cl->vpn_ip))
423         {
424           if(debug_lvl>0)
425             syslog(LOG_NOTICE, _("Uplink %s (%s) is already in our connection list"),
426               cl->vpn_hostname, cl->real_hostname);
427           cl->status.outgoing = 0;
428           old->status.outgoing = 1;
429           terminate_connection(cl);
430           return 0;
431         }
432
433       if(setup_vpn_connection(cl) < 0)
434         return -1;
435       send_basic_info(cl);
436     }
437   else
438     {
439         
440       if(setup_vpn_connection(cl) < 0)
441         return -1;
442       send_passphrase(cl);
443     }
444 cp
445   return 0;
446 }
447
448 int passphrase_h(conn_list_t *cl)
449 {
450 cp
451   cl->pp = xmalloc(sizeof(*(cl->pp)));
452
453   if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
454     {
455       syslog(LOG_ERR, _("Got bad PASSPHRASE from %s (%s)"),
456               cl->vpn_hostname, cl->real_hostname);
457       return -1;
458     }
459   cl->pp->len = strlen(cl->pp->phrase);
460     
461   if(debug_lvl > 1)
462     syslog(LOG_DEBUG, _("Got PASSPHRASE from %s (%s)"),
463               cl->vpn_hostname, cl->real_hostname);
464
465   if(cl->status.outgoing)
466     send_passphrase(cl);
467   else
468     send_public_key(cl);
469 cp
470   return 0;
471 }
472
473 int public_key_h(conn_list_t *cl)
474 {
475   char *g_n;
476   conn_list_t *old;
477 cp
478   if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
479     {
480        syslog(LOG_ERR, _("Got bad PUBLIC_KEY from %s (%s)"),
481               cl->vpn_hostname, cl->real_hostname);
482        return -1;
483     }  
484
485   if(debug_lvl > 1)
486     syslog(LOG_DEBUG, _("Got PUBLIC_KEY from %s (%s)"),
487               cl->vpn_hostname, cl->real_hostname);
488
489   if(verify_passphrase(cl, g_n))
490     {
491       /* intruder! */
492       syslog(LOG_ERR, _("Intruder from %s: passphrase for %s does not match!"),
493               cl->real_hostname, cl->vpn_hostname);
494       return -1;
495     }
496
497   if(cl->status.outgoing)
498     send_public_key(cl);
499   else
500     {
501       send_ack(cl);
502
503       /* Okay, before we active the connection, we check if there is another entry
504          in the connection list with the same vpn_ip. If so, it presumably is an
505          old connection that has timed out but we don't know it yet.
506        */
507
508       while(old = lookup_conn(cl->vpn_ip)) 
509         {
510           syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
511             cl->vpn_hostname, old->real_hostname, cl->real_hostname);
512           old->status.active = 0;
513           terminate_connection(old);
514         }
515         
516       cl->status.active = 1;
517
518       if(debug_lvl > 0)
519         syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
520                            cl->vpn_hostname, cl->real_hostname);
521
522       notify_others(cl, NULL, send_add_host);
523       notify_one(cl);
524     }
525 cp
526   return 0;
527 }
528
529 int ack_h(conn_list_t *cl)
530 {
531 cp
532   if(debug_lvl > 1)
533     syslog(LOG_DEBUG, _("Got ACK from %s (%s)"),
534               cl->vpn_hostname, cl->real_hostname);
535   
536   cl->status.active = 1;
537
538   syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
539               cl->vpn_hostname, cl->real_hostname);
540
541   notify_others(cl, NULL, send_add_host);
542   notify_one(cl);
543
544   upstreamindex = 0;
545 cp
546   return 0;
547 }
548
549 int termreq_h(conn_list_t *cl)
550 {
551 cp
552   if(!cl->status.active)
553     {
554       syslog(LOG_ERR, _("Got unauthorized TERMREQ from %s (%s)"),
555               cl->vpn_hostname, cl->real_hostname);
556       return -1;
557     }
558     
559   if(debug_lvl > 1)
560    syslog(LOG_DEBUG, _("Got TERMREQ from %s (%s)"),
561              cl->vpn_hostname, cl->real_hostname);
562   
563   cl->status.termreq = 1;
564
565   terminate_connection(cl);
566 cp
567   return 0;
568 }
569
570 int timeout_h(conn_list_t *cl)
571 {
572 cp
573   if(!cl->status.active)
574     {
575       syslog(LOG_ERR, _("Got unauthorized TIMEOUT from %s (%s)"),
576               cl->vpn_hostname, cl->real_hostname);
577       return -1;
578     }
579
580   if(debug_lvl > 1)
581     syslog(LOG_DEBUG, _("Got TIMEOUT from %s (%s)"),
582               cl->vpn_hostname, cl->real_hostname);
583
584   cl->status.termreq = 1;
585   terminate_connection(cl);
586 cp
587   return 0;
588 }
589
590 int del_host_h(conn_list_t *cl)
591 {
592   ip_t vpn_ip;
593   conn_list_t *fw;
594 cp
595   if(!cl->status.active)
596     {
597       syslog(LOG_ERR, _("Got unauthorized DEL_HOST from %s (%s)"),
598               cl->vpn_hostname, cl->real_hostname);
599       return -1;
600     }
601
602   if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
603     {
604        syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
605               cl->vpn_hostname, cl->real_hostname);
606        return -1;
607     }  
608
609   if(!(fw = lookup_conn(vpn_ip)))
610     {
611       syslog(LOG_ERR, _("Got DEL_HOST for %d.%d.%d.%d from %s (%s) which does not exist?"),
612              IP_ADDR_V(vpn_ip), cl->vpn_hostname, cl->real_hostname);
613       return 0;
614     }
615
616   /* Connections lists are really messed up if this happens */
617   if(vpn_ip == myself->vpn_ip)
618     {
619       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
620                cl->vpn_hostname, cl->real_hostname);
621       sighup = 1;
622       return 0;
623     }
624
625   if(debug_lvl > 1)
626     syslog(LOG_DEBUG, _("Got DEL_HOST for %s (%s) from %s (%s)"),
627            fw->vpn_hostname, fw->real_hostname, cl->vpn_hostname, cl->real_hostname);
628
629   notify_others(fw, cl, send_del_host);
630
631   fw->status.termreq = 1;
632   fw->status.active = 0;
633
634   terminate_connection(fw);
635 cp
636   return 0;
637 }
638
639 int ping_h(conn_list_t *cl)
640 {
641 cp
642   if(!cl->status.active)
643     {
644       syslog(LOG_ERR, _("Got unauthorized PING from %s (%s)"),
645               cl->vpn_hostname, cl->real_hostname);
646       return -1;
647     }
648
649   if(debug_lvl > 1)
650     syslog(LOG_DEBUG, _("Got PING from %s (%s)"),
651               cl->vpn_hostname, cl->real_hostname);
652
653   cl->status.pinged = 0;
654   cl->status.got_pong = 1;
655
656   send_pong(cl);
657 cp
658   return 0;
659 }
660
661 int pong_h(conn_list_t *cl)
662 {
663 cp
664   if(!cl->status.active)
665     {
666       syslog(LOG_ERR, _("Got unauthorized PONG from %s (%s)"),
667               cl->vpn_hostname, cl->real_hostname);
668       return -1;
669     }
670
671   if(debug_lvl > 1)
672     syslog(LOG_DEBUG, _("Got PONG from %s (%s)"),
673               cl->vpn_hostname, cl->real_hostname);
674
675   cl->status.got_pong = 1;
676 cp
677   return 0;
678 }
679
680 int add_host_h(conn_list_t *cl)
681 {
682   ip_t real_ip;
683   ip_t vpn_ip;
684   ip_t vpn_mask;
685   unsigned short port;
686   int flags;
687   conn_list_t *ncn, *old;
688 cp
689   if(!cl->status.active)
690     {
691       syslog(LOG_ERR, _("Got unauthorized ADD_HOST from %s (%s)"),
692               cl->vpn_hostname, cl->real_hostname);
693       return -1;
694     }
695     
696   if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
697     {
698        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"),
699               cl->vpn_hostname, cl->real_hostname);
700        return -1;
701     }  
702
703   if(old = lookup_conn(vpn_ip))
704     {
705       if((real_ip==old->real_ip) && (vpn_mask==old->vpn_mask) && (port==old->port))
706         {
707           if(debug_lvl>1)
708             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
709                    old->vpn_hostname, old->real_hostname, cl->vpn_hostname, cl->real_hostname);
710           goto skip_add_host;  /* One goto a day keeps the deeply nested if constructions away. */
711         }
712       else
713         {
714           if(debug_lvl>1)
715             syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"),
716                    old->vpn_hostname, old->real_hostname);
717           old->status.active = 0;
718           terminate_connection(old);
719         }
720     }
721   
722   /* Connections lists are really messed up if this happens */
723   if(vpn_ip == myself->vpn_ip)
724     {
725       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"),
726                cl->vpn_hostname, cl->real_hostname);
727       sighup = 1;
728       return 0;
729     }
730     
731   ncn = new_conn_list();
732   ncn->real_ip = real_ip;
733   ncn->real_hostname = hostlookup(htonl(real_ip));
734   ncn->vpn_ip = vpn_ip;
735   ncn->vpn_mask = vpn_mask;
736   ncn->vpn_hostname = hostlookup(htonl(vpn_ip));
737   ncn->port = port;
738   ncn->flags = flags;
739   ncn->nexthop = cl;
740   ncn->next = conn_list;
741   conn_list = ncn;
742   ncn->status.active = 1;
743
744   if(debug_lvl > 1)
745     syslog(LOG_DEBUG, _("Got ADD_HOST for %s (%s) from %s (%s)"),
746            ncn->vpn_hostname, ncn->real_hostname, cl->vpn_hostname, cl->real_hostname);
747
748 skip_add_host:
749
750   notify_others(ncn, cl, send_add_host);
751 cp
752   return 0;
753 }
754
755 int req_key_h(conn_list_t *cl)
756 {
757   ip_t to;
758   ip_t from;
759   conn_list_t *fw;
760 cp
761   if(!cl->status.active)
762     {
763       syslog(LOG_ERR, _("Got unauthorized REQ_KEY from %s (%s)"),
764               cl->vpn_hostname, cl->real_hostname);
765       return -1;
766     }
767
768   if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
769     {
770        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
771               cl->vpn_hostname, cl->real_hostname);
772        return -1;
773     }  
774
775   if(debug_lvl > 1)
776     syslog(LOG_DEBUG, _("Got REQ_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
777            IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
778
779   if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
780     {  /* hey! they want something from ME! :) */
781       send_key_answer(cl, from);
782       return 0;
783     }
784
785   fw = lookup_conn(to);
786   
787   if(!fw)
788     {
789       syslog(LOG_ERR, _("Attempting to forward REQ_KEY to %d.%d.%d.%d, which does not exist?"),
790              IP_ADDR_V(to));
791       return -1;
792     }
793
794   if(debug_lvl > 1)
795     syslog(LOG_DEBUG, _("Forwarding REQ_KEY to %s (%s)"),
796            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
797   
798   cl->buffer[cl->reqlen-1] = '\n';
799   
800   if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
801     {
802       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
803       return -1;
804     }
805 cp
806   return 0;
807 }
808
809 void set_keys(conn_list_t *cl, int expiry, char *key)
810 {
811   char *ek;
812 cp
813   if(!cl->public_key)
814     {
815       cl->public_key = xmalloc(sizeof(*cl->key));
816       cl->public_key->key = NULL;
817     }
818     
819   if(cl->public_key->key)
820     free(cl->public_key->key);
821   cl->public_key->length = strlen(key);
822   cl->public_key->expiry = expiry;
823   cl->public_key->key = xmalloc(cl->public_key->length + 1);
824   strcpy(cl->public_key->key, key);
825
826   ek = make_shared_key(key);
827   
828   if(!cl->key)
829     {
830       cl->key = xmalloc(sizeof(*cl->key));
831       cl->key->key = NULL;
832     }
833
834   if(cl->key->key)
835     free(cl->key->key);
836
837   cl->key->length = strlen(ek);
838   cl->key->expiry = expiry;
839   cl->key->key = xmalloc(cl->key->length + 1);
840   strcpy(cl->key->key, ek);
841 cp
842 }
843
844 int ans_key_h(conn_list_t *cl)
845 {
846   ip_t to;
847   ip_t from;
848   int expiry;
849   char *key;
850   conn_list_t *fw, *gk;
851 cp
852   if(!cl->status.active)
853     {
854       syslog(LOG_ERR, _("Got unauthorized ANS_KEY from %s (%s)"),
855               cl->vpn_hostname, cl->real_hostname);
856       return -1;
857     }
858
859   if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
860     {
861        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
862               cl->vpn_hostname, cl->real_hostname);
863        return -1;
864     }  
865
866   if(debug_lvl > 1)
867     syslog(LOG_DEBUG, _("Got ANS_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
868             IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
869
870   if(to == myself->vpn_ip)
871     {  /* hey! that key's for ME! :) */
872       gk = lookup_conn(from);
873
874       if(!gk)
875         {
876           syslog(LOG_ERR, _("Receiving ANS_KEY origin %d.%d.%d.%d from %s (%s), which does not exist?"),
877                  IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
878           return -1;
879         }
880
881       set_keys(gk, expiry, key);
882       gk->status.validkey = 1;
883       gk->status.waitingforkey = 0;
884       flush_queues(gk);
885       return 0;
886     }
887
888   fw = lookup_conn(to);
889   
890   if(!fw)
891     {
892       syslog(LOG_ERR, _("Attempting to forward ANS_KEY to %d.%d.%d.%d, which does not exist?"),
893              IP_ADDR_V(to));
894       return -1;
895     }
896
897   if(debug_lvl > 1)
898     syslog(LOG_DEBUG, _("Forwarding ANS_KEY to %s (%s)"),
899            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
900
901   cl->buffer[cl->reqlen-1] = '\n';
902
903   if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
904     {
905       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
906       return -1;
907     }
908 cp
909   return 0;
910 }
911
912 int key_changed_h(conn_list_t *cl)
913 {
914   ip_t from;
915   conn_list_t *ik;
916 cp
917   if(!cl->status.active)
918     {
919       syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from %s (%s)"),
920               cl->vpn_hostname, cl->real_hostname);
921       return -1;
922     }
923
924   if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
925     {
926        syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
927               cl->vpn_hostname, cl->real_hostname);
928        return -1;
929     }  
930
931   ik = lookup_conn(from);
932
933   if(!ik)
934     {
935       syslog(LOG_ERR, _("Got KEY_CHANGED origin %d.%d.%d.%d from %s (%s), which does not exist?"),
936              IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
937       return -1;
938     }
939
940   if(debug_lvl > 1)
941     syslog(LOG_DEBUG, _("Got KEY_CHANGED origin %s from %s (%s)"),
942             ik->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
943
944   ik->status.validkey = 0;
945   ik->status.waitingforkey = 0;
946
947   notify_others(ik, cl, send_key_changed);
948 cp
949   return 0;
950 }
951
952 int (*request_handlers[256])(conn_list_t*) = {
953   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
954   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
955   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
956   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
957   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
958   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
959   add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
960   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
961   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
962   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
963   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
964   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
965   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
966   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
967   req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
968   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
969   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
970   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
971   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
972   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0
973 };