a3fa5f1a402d0e2800059f202ad21193dcec58b2
[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.20 2000/08/07 14:52: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 /* Evil hack - TCP tunneling is bad */
124 int send_tcppacket(conn_list_t *cl, void *data, int len)
125 {
126 cp
127   if(debug_lvl > 1)
128     syslog(LOG_DEBUG, _("Sending PACKET to %s (%s)"),
129            cl->vpn_hostname, cl->real_hostname);
130
131   buflen = snprintf(buffer, MAXBUFSIZE, "%d %d\n", PACKET, len);
132
133   if((write(cl->meta_socket, buffer, buflen)) < 0)
134     {
135       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
136       return -1;
137     }
138
139   if((write(cl->meta_socket, data, len)) < 0)
140     {
141       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
142       return -1;
143     }
144   
145 cp
146   return 0;
147 }
148
149 int send_ping(conn_list_t *cl)
150 {
151 cp
152   if(debug_lvl > 1)
153     syslog(LOG_DEBUG, _("Sending PING to %s (%s)"),
154            cl->vpn_hostname, cl->real_hostname);
155
156   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
157
158   if((write(cl->meta_socket, buffer, buflen)) < 0)
159     {
160       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
161       return -1;
162     }
163 cp
164   return 0;
165 }
166
167 int send_pong(conn_list_t *cl)
168 {
169 cp
170   if(debug_lvl > 1)
171     syslog(LOG_DEBUG, _("Sending PONG to %s (%s)"),
172            cl->vpn_hostname, cl->real_hostname);
173
174   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
175
176   if((write(cl->meta_socket, buffer, buflen)) < 0)
177     {
178       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
179       return -1;
180     }
181 cp
182   return 0;
183 }
184
185 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
186 {
187   ip_t real_ip;
188   int flags;
189   char *hostname;
190 cp
191   real_ip = new_host->real_ip;
192   hostname = new_host->real_hostname;
193   flags = new_host->flags;
194   
195   /* If we need to propagate information about a new host that wants us to export
196    * it's indirectdata flag, we set the INDIRECTDATA flag and unset the EXPORT...
197    * flag, and set it's real_ip to our vpn_ip, so that net.c send_packet() will
198    * work correctly.
199    */
200      
201   if(flags & EXPORTINDIRECTDATA)
202     {
203       flags &= ~EXPORTINDIRECTDATA;
204       flags |= INDIRECTDATA;
205       real_ip = myself->vpn_ip;
206       hostname = myself->real_hostname;
207     }
208
209   if(debug_lvl > 1)
210     syslog(LOG_DEBUG, _("Sending ADD_HOST for %s (%s) to %s (%s)"),
211            new_host->vpn_hostname, hostname, cl->vpn_hostname, cl->real_hostname);
212
213   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);
214
215   if((write(cl->meta_socket, buffer, buflen)) < 0)
216     {
217       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
218       return -1;
219     }
220 cp
221   return 0;
222 }
223
224 int send_key_changed(conn_list_t *cl, conn_list_t *src)
225 {
226 cp
227   if(debug_lvl > 1)
228     syslog(LOG_DEBUG, _("Sending KEY_CHANGED origin %s to %s (%s)"),
229            src->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
230
231   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
232
233   if((write(cl->meta_socket, buffer, buflen)) < 0)
234     {
235       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
236       return -1;
237     }
238 cp
239   return 0;
240 }
241
242 void send_key_changed_all(void)
243 {
244   conn_list_t *p;
245 cp
246   for(p = conn_list; p != NULL; p = p->next)
247     if(p->status.meta && p->status.active)
248       send_key_changed(p, myself);
249 cp
250 }
251
252 int send_basic_info(conn_list_t *cl)
253 {
254 cp
255   if(debug_lvl > 1)
256     syslog(LOG_DEBUG, _("Sending BASIC_INFO to %s"),
257            cl->real_hostname);
258
259   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);
260
261   if((write(cl->meta_socket, buffer, buflen)) < 0)
262     {
263       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
264       return -1;
265     }
266 cp
267   return 0;
268 }
269
270 int send_passphrase(conn_list_t *cl)
271 {
272   passphrase_t tmp;
273 cp
274   encrypt_passphrase(&tmp);
275
276   if(debug_lvl > 1)
277     syslog(LOG_DEBUG, _("Sending PASSPHRASE to %s (%s)"),
278            cl->vpn_hostname, cl->real_hostname);
279
280   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
281
282   if((write(cl->meta_socket, buffer, buflen)) < 0)
283     {
284       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
285       return -1;
286     }
287 cp
288   return 0;
289 }
290
291 int send_public_key(conn_list_t *cl)
292 {
293 cp
294   if(debug_lvl > 1)
295     syslog(LOG_DEBUG, _("Sending PUBLIC_KEY to %s (%s)"),
296            cl->vpn_hostname, cl->real_hostname);
297
298   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
299
300   if((write(cl->meta_socket, buffer, buflen)) < 0)
301     {
302       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
303       return -1;
304     }
305 cp
306   return 0;
307 }
308
309 /* WDN doet deze functie? (GS)
310 int send_calculate(conn_list_t *cl, char *k)
311 {
312 cp
313   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", CALCULATE, k);
314
315   if((write(cl->meta_socket, buffer, buflen)) < 0)
316     {
317       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
318       return -1;
319     }
320 cp
321   return 0;
322 }
323 */
324
325 int send_key_request(ip_t to)
326 {
327   conn_list_t *fw;
328 cp
329   fw = lookup_conn(to);
330   if(!fw)
331     {
332       syslog(LOG_ERR, _("Attempting to send REQ_KEY to %d.%d.%d.%d, which does not exist?"),
333              IP_ADDR_V(to));
334       return -1;
335     }
336
337   if(debug_lvl > 1)
338     syslog(LOG_DEBUG, _("Sending REQ_KEY to %s (%s)"),
339            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
340
341   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
342
343   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
344     {
345       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
346       return -1;
347     }
348   fw->status.waitingforkey = 1;
349 cp
350   return 0;
351 }
352
353 int send_key_answer(conn_list_t *cl, ip_t to)
354 {
355   conn_list_t *fw;
356 cp
357
358   fw = lookup_conn(to);
359   
360   if(!fw)
361     {
362       syslog(LOG_ERR, _("Attempting to send ANS_KEY to %d.%d.%d.%d, which does not exist?"),
363              IP_ADDR_V(to));
364       return -1;
365     }
366
367  if(debug_lvl > 1)
368     syslog(LOG_DEBUG, _("Sending ANS_KEY to %s (%s)"),
369            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
370
371   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
372
373   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
374     {
375       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
376       return -1;
377     }
378 cp
379   return 0;
380 }
381
382 /*
383   notify all my direct connections of a new host
384   that was added to the vpn, with the exception
385   of the source of the announcement.
386 */
387 int notify_others(conn_list_t *new, conn_list_t *source,
388                   int (*function)(conn_list_t*, conn_list_t*))
389 {
390   conn_list_t *p;
391 cp
392   for(p = conn_list; p != NULL; p = p->next)
393     if(p != new && p != source && p->status.meta && p->status.active)
394       function(p, new);
395 cp
396   return 0;
397 }
398
399 /*
400   notify one connection of everything
401   i have connected
402 */
403 int notify_one(conn_list_t *new)
404 {
405   conn_list_t *p;
406 cp
407   for(p = conn_list; p != NULL; p = p->next)
408     if(p != new && p->status.active)
409       send_add_host(new, p);
410 cp
411   return 0;
412 }
413
414 /*
415   The incoming request handlers
416 */
417
418 int basic_info_h(conn_list_t *cl)
419 {
420   conn_list_t *old;
421 cp
422   if(debug_lvl > 1)
423     syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->real_hostname);
424
425   if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx %d", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port, &cl->flags) != 5)
426     {
427        syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
428               cl->real_hostname);
429        return -1;
430     }
431     
432   cl->vpn_hostname = hostlookup(htonl(cl->vpn_ip));
433
434   if(cl->protocol_version != PROT_CURRENT)
435     {
436       syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
437              cl->protocol_version);
438       return -1;
439     }
440
441   if(cl->status.outgoing)
442     {
443       /* First check if the host we connected to is already in our
444          connection list. If so, we are probably making a loop, which
445          is not desirable.
446        */
447        
448       if(old=lookup_conn(cl->vpn_ip))
449         {
450           if(debug_lvl>0)
451             syslog(LOG_NOTICE, _("Uplink %s (%s) is already in our connection list"),
452               cl->vpn_hostname, cl->real_hostname);
453           cl->status.outgoing = 0;
454           old->status.outgoing = 1;
455           terminate_connection(cl);
456           return 0;
457         }
458
459       if(setup_vpn_connection(cl) < 0)
460         return -1;
461       send_basic_info(cl);
462     }
463   else
464     {
465         
466       if(setup_vpn_connection(cl) < 0)
467         return -1;
468       send_passphrase(cl);
469     }
470 cp
471   return 0;
472 }
473
474 int passphrase_h(conn_list_t *cl)
475 {
476 cp
477   cl->pp = xmalloc(sizeof(*(cl->pp)));
478
479   if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
480     {
481       syslog(LOG_ERR, _("Got bad PASSPHRASE from %s (%s)"),
482               cl->vpn_hostname, cl->real_hostname);
483       return -1;
484     }
485   cl->pp->len = strlen(cl->pp->phrase);
486     
487   if(debug_lvl > 1)
488     syslog(LOG_DEBUG, _("Got PASSPHRASE from %s (%s)"),
489               cl->vpn_hostname, cl->real_hostname);
490
491   if(cl->status.outgoing)
492     send_passphrase(cl);
493   else
494     send_public_key(cl);
495 cp
496   return 0;
497 }
498
499 int public_key_h(conn_list_t *cl)
500 {
501   char *g_n;
502   conn_list_t *old;
503 cp
504   if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
505     {
506        syslog(LOG_ERR, _("Got bad PUBLIC_KEY from %s (%s)"),
507               cl->vpn_hostname, cl->real_hostname);
508        return -1;
509     }  
510
511   if(debug_lvl > 1)
512     syslog(LOG_DEBUG, _("Got PUBLIC_KEY from %s (%s)"),
513               cl->vpn_hostname, cl->real_hostname);
514
515   if(verify_passphrase(cl, g_n))
516     {
517       /* intruder! */
518       syslog(LOG_ERR, _("Intruder from %s: passphrase for %s does not match!"),
519               cl->real_hostname, cl->vpn_hostname);
520       return -1;
521     }
522
523   if(cl->status.outgoing)
524     send_public_key(cl);
525   else
526     {
527       send_ack(cl);
528
529       /* Okay, before we active the connection, we check if there is another entry
530          in the connection list with the same vpn_ip. If so, it presumably is an
531          old connection that has timed out but we don't know it yet.
532        */
533
534       while(old = lookup_conn(cl->vpn_ip)) 
535         {
536           if(debug_lvl > 1)
537             syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
538             cl->vpn_hostname, old->real_hostname, cl->real_hostname);
539           old->status.active = 0;
540           terminate_connection(old);
541         }
542         
543       cl->status.active = 1;
544
545       if(debug_lvl > 0)
546         syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
547                            cl->vpn_hostname, cl->real_hostname);
548
549       notify_others(cl, NULL, send_add_host);
550       notify_one(cl);
551     }
552 cp
553   return 0;
554 }
555
556 int ack_h(conn_list_t *cl)
557 {
558 cp
559   if(debug_lvl > 1)
560     syslog(LOG_DEBUG, _("Got ACK from %s (%s)"),
561               cl->vpn_hostname, cl->real_hostname);
562   
563   cl->status.active = 1;
564
565   if(debug_lvl > 0)
566     syslog(LOG_NOTICE, _("Connection with %s (%s) activated"),
567               cl->vpn_hostname, cl->real_hostname);
568
569   notify_others(cl, NULL, send_add_host);
570   notify_one(cl);
571
572   upstreamindex = 0;
573 cp
574   return 0;
575 }
576
577 int termreq_h(conn_list_t *cl)
578 {
579 cp
580   if(!cl->status.active)
581     {
582       syslog(LOG_ERR, _("Got unauthorized TERMREQ from %s (%s)"),
583               cl->vpn_hostname, cl->real_hostname);
584       return -1;
585     }
586     
587   if(debug_lvl > 1)
588    syslog(LOG_DEBUG, _("Got TERMREQ from %s (%s)"),
589              cl->vpn_hostname, cl->real_hostname);
590   
591   cl->status.termreq = 1;
592
593   terminate_connection(cl);
594 cp
595   return 0;
596 }
597
598 int timeout_h(conn_list_t *cl)
599 {
600 cp
601   if(!cl->status.active)
602     {
603       syslog(LOG_ERR, _("Got unauthorized TIMEOUT from %s (%s)"),
604               cl->vpn_hostname, cl->real_hostname);
605       return -1;
606     }
607
608   if(debug_lvl > 1)
609     syslog(LOG_DEBUG, _("Got TIMEOUT from %s (%s)"),
610               cl->vpn_hostname, cl->real_hostname);
611
612   cl->status.termreq = 1;
613   terminate_connection(cl);
614 cp
615   return 0;
616 }
617
618 int del_host_h(conn_list_t *cl)
619 {
620   ip_t vpn_ip;
621   conn_list_t *fw;
622 cp
623   if(!cl->status.active)
624     {
625       syslog(LOG_ERR, _("Got unauthorized DEL_HOST from %s (%s)"),
626               cl->vpn_hostname, cl->real_hostname);
627       return -1;
628     }
629
630   if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
631     {
632        syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
633               cl->vpn_hostname, cl->real_hostname);
634        return -1;
635     }  
636
637   if(!(fw = lookup_conn(vpn_ip)))
638     {
639       syslog(LOG_ERR, _("Got DEL_HOST for %d.%d.%d.%d from %s (%s) which does not exist?"),
640              IP_ADDR_V(vpn_ip), cl->vpn_hostname, cl->real_hostname);
641       return 0;
642     }
643
644   /* Connections lists are really messed up if this happens */
645   if(vpn_ip == myself->vpn_ip)
646     {
647       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
648                cl->vpn_hostname, cl->real_hostname);
649       sighup = 1;
650       return 0;
651     }
652
653   if(debug_lvl > 1)
654     syslog(LOG_DEBUG, _("Got DEL_HOST for %s (%s) from %s (%s)"),
655            fw->vpn_hostname, fw->real_hostname, cl->vpn_hostname, cl->real_hostname);
656
657   notify_others(fw, cl, send_del_host);
658
659   fw->status.termreq = 1;
660   fw->status.active = 0;
661
662   terminate_connection(fw);
663 cp
664   return 0;
665 }
666
667 int tcppacket_h(conn_list_t *cl)
668 {
669   char packet[1600];
670   int len;
671 cp
672   if(!cl->status.active)
673     {
674       syslog(LOG_ERR, _("Got unauthorized PACKET from %s (%s)"),
675               cl->vpn_hostname, cl->real_hostname);
676       return -1;
677     }
678
679   if(sscanf(cl->buffer, "%*d %d", &len) != 1)
680     {
681        syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"),
682               cl->vpn_hostname, cl->real_hostname);
683        return -1;
684     }  
685
686   if(len>1600)
687     {
688        syslog(LOG_ERR, _("Got too big PACKET from %s (%s)"),
689               cl->vpn_hostname, cl->real_hostname);
690        return -1;
691     }  
692
693   if(debug_lvl > 1)
694     syslog(LOG_DEBUG, _("Got PACKET from %s (%s)"),
695               cl->vpn_hostname, cl->real_hostname);
696
697   /* Evil kludge comming up */
698   if(read(cl->meta_socket,packet,len)!=len)
699     {
700        syslog(LOG_ERR, _("Error while receiving PACKET data from %s (%s)"),
701               cl->vpn_hostname, cl->real_hostname);
702        return -1;
703     }  
704
705   xrecv(cl,packet);    
706 cp
707   return 0;
708 }
709
710
711 int ping_h(conn_list_t *cl)
712 {
713 cp
714   if(!cl->status.active)
715     {
716       syslog(LOG_ERR, _("Got unauthorized PING from %s (%s)"),
717               cl->vpn_hostname, cl->real_hostname);
718       return -1;
719     }
720
721   if(debug_lvl > 1)
722     syslog(LOG_DEBUG, _("Got PING from %s (%s)"),
723               cl->vpn_hostname, cl->real_hostname);
724
725   cl->status.pinged = 0;
726   cl->status.got_pong = 1;
727
728   send_pong(cl);
729 cp
730   return 0;
731 }
732
733 int pong_h(conn_list_t *cl)
734 {
735 cp
736   if(!cl->status.active)
737     {
738       syslog(LOG_ERR, _("Got unauthorized PONG from %s (%s)"),
739               cl->vpn_hostname, cl->real_hostname);
740       return -1;
741     }
742
743   if(debug_lvl > 1)
744     syslog(LOG_DEBUG, _("Got PONG from %s (%s)"),
745               cl->vpn_hostname, cl->real_hostname);
746
747   cl->status.got_pong = 1;
748 cp
749   return 0;
750 }
751
752 int add_host_h(conn_list_t *cl)
753 {
754   ip_t real_ip;
755   ip_t vpn_ip;
756   ip_t vpn_mask;
757   unsigned short port;
758   int flags;
759   conn_list_t *ncn, *old;
760 cp
761   if(!cl->status.active)
762     {
763       syslog(LOG_ERR, _("Got unauthorized ADD_HOST from %s (%s)"),
764               cl->vpn_hostname, cl->real_hostname);
765       return -1;
766     }
767     
768   if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
769     {
770        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"),
771               cl->vpn_hostname, cl->real_hostname);
772        return -1;
773     }  
774
775   if(old = lookup_conn(vpn_ip))
776     {
777       if((real_ip==old->real_ip) && (vpn_mask==old->vpn_mask) && (port==old->port))
778         {
779           if(debug_lvl>1)
780             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
781                    old->vpn_hostname, old->real_hostname, cl->vpn_hostname, cl->real_hostname);
782           goto skip_add_host;  /* One goto a day keeps the deeply nested if constructions away. */
783         }
784       else
785         {
786           if(debug_lvl>1)
787             syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"),
788                    old->vpn_hostname, old->real_hostname);
789           old->status.active = 0;
790           terminate_connection(old);
791         }
792     }
793   
794   /* Connections lists are really messed up if this happens */
795   if(vpn_ip == myself->vpn_ip)
796     {
797       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"),
798                cl->vpn_hostname, cl->real_hostname);
799       sighup = 1;
800       return 0;
801     }
802     
803   ncn = new_conn_list();
804   ncn->real_ip = real_ip;
805   ncn->real_hostname = hostlookup(htonl(real_ip));
806   ncn->vpn_ip = vpn_ip;
807   ncn->vpn_mask = vpn_mask;
808   ncn->vpn_hostname = hostlookup(htonl(vpn_ip));
809   ncn->port = port;
810   ncn->flags = flags;
811   ncn->nexthop = cl;
812   ncn->next = conn_list;
813   conn_list = ncn;
814   ncn->status.active = 1;
815
816   if(debug_lvl > 1)
817     syslog(LOG_DEBUG, _("Got ADD_HOST for %s (%s) from %s (%s)"),
818            ncn->vpn_hostname, ncn->real_hostname, cl->vpn_hostname, cl->real_hostname);
819
820 skip_add_host:
821
822   notify_others(ncn, cl, send_add_host);
823 cp
824   return 0;
825 }
826
827 int req_key_h(conn_list_t *cl)
828 {
829   ip_t to;
830   ip_t from;
831   conn_list_t *fw;
832 cp
833   if(!cl->status.active)
834     {
835       syslog(LOG_ERR, _("Got unauthorized REQ_KEY from %s (%s)"),
836               cl->vpn_hostname, cl->real_hostname);
837       return -1;
838     }
839
840   if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
841     {
842        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
843               cl->vpn_hostname, cl->real_hostname);
844        return -1;
845     }  
846
847   if(debug_lvl > 1)
848     syslog(LOG_DEBUG, _("Got REQ_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
849            IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
850
851   if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
852     {  /* hey! they want something from ME! :) */
853       send_key_answer(cl, from);
854       return 0;
855     }
856
857   fw = lookup_conn(to);
858   
859   if(!fw)
860     {
861       syslog(LOG_ERR, _("Attempting to forward REQ_KEY to %d.%d.%d.%d, which does not exist?"),
862              IP_ADDR_V(to));
863       return -1;
864     }
865
866   if(debug_lvl > 1)
867     syslog(LOG_DEBUG, _("Forwarding REQ_KEY to %s (%s)"),
868            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
869   
870   cl->buffer[cl->reqlen-1] = '\n';
871   
872   if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
873     {
874       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
875       return -1;
876     }
877 cp
878   return 0;
879 }
880
881 void set_keys(conn_list_t *cl, int expiry, char *key)
882 {
883   char *ek;
884 cp
885   if(!cl->public_key)
886     {
887       cl->public_key = xmalloc(sizeof(*cl->key));
888       cl->public_key->key = NULL;
889     }
890     
891   if(cl->public_key->key)
892     free(cl->public_key->key);
893   cl->public_key->length = strlen(key);
894   cl->public_key->expiry = expiry;
895   cl->public_key->key = xmalloc(cl->public_key->length + 1);
896   strcpy(cl->public_key->key, key);
897
898   ek = make_shared_key(key);
899   
900   if(!cl->key)
901     {
902       cl->key = xmalloc(sizeof(*cl->key));
903       cl->key->key = NULL;
904     }
905
906   if(cl->key->key)
907     free(cl->key->key);
908
909   cl->key->length = strlen(ek);
910   cl->key->expiry = expiry;
911   cl->key->key = xmalloc(cl->key->length + 1);
912   strcpy(cl->key->key, ek);
913 cp
914 }
915
916 int ans_key_h(conn_list_t *cl)
917 {
918   ip_t to;
919   ip_t from;
920   int expiry;
921   char *key;
922   conn_list_t *fw, *gk;
923 cp
924   if(!cl->status.active)
925     {
926       syslog(LOG_ERR, _("Got unauthorized ANS_KEY from %s (%s)"),
927               cl->vpn_hostname, cl->real_hostname);
928       return -1;
929     }
930
931   if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
932     {
933        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
934               cl->vpn_hostname, cl->real_hostname);
935        return -1;
936     }  
937
938   if(debug_lvl > 1)
939     syslog(LOG_DEBUG, _("Got ANS_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
940             IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
941
942   if(to == myself->vpn_ip)
943     {  /* hey! that key's for ME! :) */
944       gk = lookup_conn(from);
945
946       if(!gk)
947         {
948           syslog(LOG_ERR, _("Receiving ANS_KEY origin %d.%d.%d.%d from %s (%s), which does not exist?"),
949                  IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
950           return -1;
951         }
952
953       set_keys(gk, expiry, key);
954       gk->status.validkey = 1;
955       gk->status.waitingforkey = 0;
956       flush_queues(gk);
957       return 0;
958     }
959
960   fw = lookup_conn(to);
961   
962   if(!fw)
963     {
964       syslog(LOG_ERR, _("Attempting to forward ANS_KEY to %d.%d.%d.%d, which does not exist?"),
965              IP_ADDR_V(to));
966       return -1;
967     }
968
969   if(debug_lvl > 1)
970     syslog(LOG_DEBUG, _("Forwarding ANS_KEY to %s (%s)"),
971            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
972
973   cl->buffer[cl->reqlen-1] = '\n';
974
975   if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
976     {
977       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
978       return -1;
979     }
980 cp
981   return 0;
982 }
983
984 int key_changed_h(conn_list_t *cl)
985 {
986   ip_t from;
987   conn_list_t *ik;
988 cp
989   if(!cl->status.active)
990     {
991       syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from %s (%s)"),
992               cl->vpn_hostname, cl->real_hostname);
993       return -1;
994     }
995
996   if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
997     {
998        syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
999               cl->vpn_hostname, cl->real_hostname);
1000        return -1;
1001     }  
1002
1003   ik = lookup_conn(from);
1004
1005   if(!ik)
1006     {
1007       syslog(LOG_ERR, _("Got KEY_CHANGED origin %d.%d.%d.%d from %s (%s), which does not exist?"),
1008              IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
1009       return -1;
1010     }
1011
1012   if(debug_lvl > 1)
1013     syslog(LOG_DEBUG, _("Got KEY_CHANGED origin %s from %s (%s)"),
1014             ik->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
1015
1016   ik->status.validkey = 0;
1017   ik->status.waitingforkey = 0;
1018
1019   notify_others(ik, cl, send_key_changed);
1020 cp
1021   return 0;
1022 }
1023
1024 int (*request_handlers[256])(conn_list_t*) = {
1025   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
1026   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1027   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1028   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
1029   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
1030   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1031   add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
1032   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1033   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1034   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1035   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1036   tcppacket_h, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1037   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1038   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1039   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1040   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1041   req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
1042   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1043   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1044   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1045   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1046   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1047   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1048   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1049   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1050   0, 0, 0, 0, 0, 0
1051 };