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