Removed calling add_queue for tcponly packets.
[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.23 2000/08/08 13:47:57 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 > 3)
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, _("Sending PACKET data 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 > MTU)
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   if(debug_lvl > 3)
697     syslog(LOG_DEBUG, _("Got PACKET length %d from %s (%s)"), len,
698               cl->vpn_hostname, cl->real_hostname);
699
700   /* Evil kludge comming up */
701   while(len)
702     {
703        if(debug_lvl > 3)
704          syslog(LOG_DEBUG, _("Direct read count=%d len=%d rp=%p socket=%d"), count, len, ((char *)&rp)+count, cl->meta_socket);
705
706        result=read(cl->meta_socket,((char *)&rp)+count,len);
707        if(result<0)
708          {
709            syslog(LOG_ERR, _("Error while receiving PACKET data from %s (%s): %m"),
710               cl->vpn_hostname, cl->real_hostname);
711            return -1;
712          }
713        count+=result;
714        len-=result;
715     }
716
717   total_socket_in += len;
718
719   rp.data.len = ntohs(rp.data.len);
720   rp.len = ntohs(rp.len);
721   rp.from = ntohl(rp.from);
722
723   if(rp.len >= 0)
724     {
725       f = lookup_conn(rp.from);
726       if(!f)
727         {
728           syslog(LOG_ERR, _("Got packet from %s (%s) with unknown origin %d.%d.%d.%d?"),
729                  cl->vpn_hostname, cl->real_hostname, IP_ADDR_V(rp.from));
730           return -1;
731         }
732
733       if(f->status.validkey)
734         xrecv(f, &rp);
735       else
736         {
737 /*        add_queue(&(f->rq), &rp, rp.len);  We can't do this since rp is on the stack */
738           if(!cl->status.waitingforkey)
739             send_key_request(rp.from);
740         }
741
742       if(my_key_expiry <= time(NULL))
743         regenerate_keys();
744     }
745 cp
746   return 0;
747 }
748
749
750 int ping_h(conn_list_t *cl)
751 {
752 cp
753   if(!cl->status.active)
754     {
755       syslog(LOG_ERR, _("Got unauthorized PING from %s (%s)"),
756               cl->vpn_hostname, cl->real_hostname);
757       return -1;
758     }
759
760   if(debug_lvl > 1)
761     syslog(LOG_DEBUG, _("Got PING from %s (%s)"),
762               cl->vpn_hostname, cl->real_hostname);
763
764   cl->status.pinged = 0;
765   cl->status.got_pong = 1;
766
767   send_pong(cl);
768 cp
769   return 0;
770 }
771
772 int pong_h(conn_list_t *cl)
773 {
774 cp
775   if(!cl->status.active)
776     {
777       syslog(LOG_ERR, _("Got unauthorized PONG from %s (%s)"),
778               cl->vpn_hostname, cl->real_hostname);
779       return -1;
780     }
781
782   if(debug_lvl > 1)
783     syslog(LOG_DEBUG, _("Got PONG from %s (%s)"),
784               cl->vpn_hostname, cl->real_hostname);
785
786   cl->status.got_pong = 1;
787 cp
788   return 0;
789 }
790
791 int add_host_h(conn_list_t *cl)
792 {
793   ip_t real_ip;
794   ip_t vpn_ip;
795   ip_t vpn_mask;
796   unsigned short port;
797   int flags;
798   conn_list_t *ncn, *old;
799 cp
800   if(!cl->status.active)
801     {
802       syslog(LOG_ERR, _("Got unauthorized ADD_HOST from %s (%s)"),
803               cl->vpn_hostname, cl->real_hostname);
804       return -1;
805     }
806     
807   if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
808     {
809        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"),
810               cl->vpn_hostname, cl->real_hostname);
811        return -1;
812     }  
813
814   if((old = lookup_conn(vpn_ip)))
815     {
816       if((real_ip==old->real_ip) && (vpn_mask==old->vpn_mask) && (port==old->port))
817         {
818           if(debug_lvl>1)
819             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
820                    old->vpn_hostname, old->real_hostname, cl->vpn_hostname, cl->real_hostname);
821           goto skip_add_host;  /* One goto a day keeps the deeply nested if constructions away. */
822         }
823       else
824         {
825           if(debug_lvl>1)
826             syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"),
827                    old->vpn_hostname, old->real_hostname);
828           old->status.active = 0;
829           terminate_connection(old);
830         }
831     }
832   
833   /* Connections lists are really messed up if this happens */
834   if(vpn_ip == myself->vpn_ip)
835     {
836       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"),
837                cl->vpn_hostname, cl->real_hostname);
838       sighup = 1;
839       return 0;
840     }
841     
842   ncn = new_conn_list();
843   ncn->real_ip = real_ip;
844   ncn->real_hostname = hostlookup(htonl(real_ip));
845   ncn->vpn_ip = vpn_ip;
846   ncn->vpn_mask = vpn_mask;
847   ncn->vpn_hostname = hostlookup(htonl(vpn_ip));
848   ncn->port = port;
849   ncn->flags = flags;
850   ncn->nexthop = cl;
851   ncn->next = conn_list;
852   conn_list = ncn;
853   ncn->status.active = 1;
854
855   if(debug_lvl > 1)
856     syslog(LOG_DEBUG, _("Got ADD_HOST for %s (%s) from %s (%s)"),
857            ncn->vpn_hostname, ncn->real_hostname, cl->vpn_hostname, cl->real_hostname);
858
859   notify_others(ncn, cl, send_add_host);
860
861 skip_add_host:
862 cp
863   return 0;
864 }
865
866 int req_key_h(conn_list_t *cl)
867 {
868   ip_t to;
869   ip_t from;
870   conn_list_t *fw;
871 cp
872   if(!cl->status.active)
873     {
874       syslog(LOG_ERR, _("Got unauthorized REQ_KEY from %s (%s)"),
875               cl->vpn_hostname, cl->real_hostname);
876       return -1;
877     }
878
879   if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
880     {
881        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
882               cl->vpn_hostname, cl->real_hostname);
883        return -1;
884     }  
885
886   if(debug_lvl > 1)
887     syslog(LOG_DEBUG, _("Got REQ_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
888            IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
889
890   if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
891     {  /* hey! they want something from ME! :) */
892       send_key_answer(cl, from);
893       return 0;
894     }
895
896   fw = lookup_conn(to);
897   
898   if(!fw)
899     {
900       syslog(LOG_ERR, _("Attempting to forward REQ_KEY to %d.%d.%d.%d, which does not exist?"),
901              IP_ADDR_V(to));
902       return -1;
903     }
904
905   if(debug_lvl > 1)
906     syslog(LOG_DEBUG, _("Forwarding REQ_KEY to %s (%s)"),
907            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
908   
909   cl->buffer[cl->reqlen-1] = '\n';
910   
911   if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
912     {
913       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
914       return -1;
915     }
916 cp
917   return 0;
918 }
919
920 void set_keys(conn_list_t *cl, int expiry, char *key)
921 {
922   char *ek;
923 cp
924   if(!cl->public_key)
925     {
926       cl->public_key = xmalloc(sizeof(*cl->key));
927       cl->public_key->key = NULL;
928     }
929     
930   if(cl->public_key->key)
931     free(cl->public_key->key);
932   cl->public_key->length = strlen(key);
933   cl->public_key->expiry = expiry;
934   cl->public_key->key = xmalloc(cl->public_key->length + 1);
935   strcpy(cl->public_key->key, key);
936
937   ek = make_shared_key(key);
938   
939   if(!cl->key)
940     {
941       cl->key = xmalloc(sizeof(*cl->key));
942       cl->key->key = NULL;
943     }
944
945   if(cl->key->key)
946     free(cl->key->key);
947
948   cl->key->length = strlen(ek);
949   cl->key->expiry = expiry;
950   cl->key->key = xmalloc(cl->key->length + 1);
951   strcpy(cl->key->key, ek);
952 cp
953 }
954
955 int ans_key_h(conn_list_t *cl)
956 {
957   ip_t to;
958   ip_t from;
959   int expiry;
960   char *key;
961   conn_list_t *fw, *gk;
962 cp
963   if(!cl->status.active)
964     {
965       syslog(LOG_ERR, _("Got unauthorized ANS_KEY from %s (%s)"),
966               cl->vpn_hostname, cl->real_hostname);
967       return -1;
968     }
969
970   if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
971     {
972        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
973               cl->vpn_hostname, cl->real_hostname);
974        return -1;
975     }  
976
977   if(debug_lvl > 1)
978     syslog(LOG_DEBUG, _("Got ANS_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
979             IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
980
981   if(to == myself->vpn_ip)
982     {  /* hey! that key's for ME! :) */
983       gk = lookup_conn(from);
984
985       if(!gk)
986         {
987           syslog(LOG_ERR, _("Receiving ANS_KEY origin %d.%d.%d.%d from %s (%s), which does not exist?"),
988                  IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
989           return -1;
990         }
991
992       set_keys(gk, expiry, key);
993       gk->status.validkey = 1;
994       gk->status.waitingforkey = 0;
995       flush_queues(gk);
996       return 0;
997     }
998
999   fw = lookup_conn(to);
1000   
1001   if(!fw)
1002     {
1003       syslog(LOG_ERR, _("Attempting to forward ANS_KEY to %d.%d.%d.%d, which does not exist?"),
1004              IP_ADDR_V(to));
1005       return -1;
1006     }
1007
1008   if(debug_lvl > 1)
1009     syslog(LOG_DEBUG, _("Forwarding ANS_KEY to %s (%s)"),
1010            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
1011
1012   cl->buffer[cl->reqlen-1] = '\n';
1013
1014   if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
1015     {
1016       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
1017       return -1;
1018     }
1019 cp
1020   return 0;
1021 }
1022
1023 int key_changed_h(conn_list_t *cl)
1024 {
1025   ip_t from;
1026   conn_list_t *ik;
1027 cp
1028   if(!cl->status.active)
1029     {
1030       syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from %s (%s)"),
1031               cl->vpn_hostname, cl->real_hostname);
1032       return -1;
1033     }
1034
1035   if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
1036     {
1037        syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1038               cl->vpn_hostname, cl->real_hostname);
1039        return -1;
1040     }  
1041
1042   ik = lookup_conn(from);
1043
1044   if(!ik)
1045     {
1046       syslog(LOG_ERR, _("Got KEY_CHANGED origin %d.%d.%d.%d from %s (%s), which does not exist?"),
1047              IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
1048       return -1;
1049     }
1050
1051   if(debug_lvl > 1)
1052     syslog(LOG_DEBUG, _("Got KEY_CHANGED origin %s from %s (%s)"),
1053             ik->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
1054
1055   ik->status.validkey = 0;
1056   ik->status.waitingforkey = 0;
1057
1058   notify_others(ik, cl, send_key_changed);
1059 cp
1060   return 0;
1061 }
1062
1063 int (*request_handlers[256])(conn_list_t*) = {
1064   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
1065   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1066   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1067   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
1068   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
1069   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1070   add_host_h, basic_info_h, passphrase_h, public_key_h, 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   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1074   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1075   tcppacket_h, 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   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1079   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1080   req_key_h, ans_key_h, key_changed_h, 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, 0, 0, 0, 0,
1088   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1089   0, 0, 0, 0, 0, 0
1090 };