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