Add Guus' name and shift out old protocol requests
[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.26 2000/09/10 16:15:35 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 /* Generic outgoing request routine - takes care of logging and error detection as well */
48
49 int send_request(conn_list_t *cl, const char *format, int request, /*args*/ ...)
50 {
51   va_list args;
52   char *buffer = NULL;
53 cp
54   if(debug_lvl >= DEBUG_PROTOCOL)
55     syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), requestname[request], cl->id, cl->hostname);
56
57   va_start(args, format);
58   len = vasprintf(&buffer, format, args);
59   va_end(args);
60
61   if(len < 0 || !buffer)
62     {
63       syslog(LOG_ERR, _("Error during vasprintf(): %m"));
64       return -1;
65     }
66
67   if(debug_lvl >= DEBUG_META)
68     syslog(LOG_DEBUG, _("Sending meta data to %s (%s): %s"), cl->id, cl->hostname, buffer);
69
70   if(cl->status.encryptout)
71     {
72       /* FIXME: Do encryption */
73     }
74
75   if((write(cl->meta_socket, buffer, buflen)) < 0)
76     {
77       syslog(LOG_ERR, _("Sending meta data failed:  %m"));
78       return -1;
79     }
80 cp  
81 }
82
83 /* Connection protocol:
84
85    Client               Server
86    send_id(*)
87                         send_challenge
88    send_chal_reply(*)                   
89                         send_id
90    send_challenge
91                         send_chal_reply
92    send_ack
93                         send_ack
94
95    (*) Unencrypted.
96 */      
97
98 int send_id(conn_list_t *cl)
99 {
100 cp
101   return send_request(cl, "%d %s %d-%d %s", ID, myself->id, myself->min_version, myself->max_version, opt2str(myself->options));
102 }
103
104 int id_h(conn_list_t *cl)
105 {
106   conn_list_t *old;
107   char *options;
108 cp
109   if(sscanf(cl->buffer, "%*d %as %d-%d %as", &cl->id, &cl->min_version, &cl->max_version, &options) != 4)
110     {
111        syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname);
112        return -1;
113     }
114     
115   /* Check if version ranges overlap */
116   
117   if((cl->min_version > myself->max_version) || (cl->max_version < myself_min_version) || (cl->min_version > cl->max_version))
118     {
119       syslog(LOG_ERR, _("Peer %s uses incompatible version (%d-%d)"), cl->hostname, cl->min_version, cl->max_version);
120       return -1;
121     }
122
123   /* Check if option string is valid */
124   
125   if(str2opt(options) == -1)
126     {
127       syslog(LOG_ERR, _("Peer %s uses invalid option string"), cl->hostname);
128       return -1;
129     }
130     
131   /* Check if identity is a valid name */
132   
133   if(!check_id(cl->id))
134     {
135       syslog(LOG_ERR, _("Peer %s uses invalid identity name"), cl->hostname);
136       return -1;
137     }
138     
139   /* Load information about peer */
140   
141   if(!read_id(cl))
142     {
143       syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->id);
144       return -1;
145     }
146
147
148   /* First check if the host we connected to is already in our
149      connection list. If so, we are probably making a loop, which
150      is not desirable.
151    */
152
153   if(cl->status.outgoing)
154     {
155       if((old=lookup_id(cl->id)))
156         {
157           if(debug_lvl > DEBUG_CONNECTIONS)
158             syslog(LOG_NOTICE, _("Uplink %s (%s) is already in our connection list"), cl->id, cl->hostname);
159           cl->status.outgoing = 0;
160           old->status.outgoing = 1;
161           terminate_connection(cl);
162           return 0;
163         }
164     }
165
166   /* Since we know the identity now, we can encrypt the meta channel */
167   
168   cl->status.encryptout = 1;
169
170   /* Send a challenge to verify the identity */
171
172   cl->allow_request = CHAL_REPLY;
173 cp
174   return send_challenge(cl);
175 }
176
177 int send_challenge(conn_list_t *cl)
178 {
179   char *buffer;
180   int keylength;
181   int x;
182 cp
183   if(cl->chal_hash)
184     free(cl->chal_hash);
185   
186   /* Allocate buffers for the challenge and the hash */
187   
188   cl->chal_hash = xmalloc(SHA_DIGEST_LEN);
189   keylength = BN_num_bytes(cl->metakey.n);
190   buffer = xmalloc(keylength*2);
191
192   /* Copy random data and the public key to the buffer */
193   
194   RAND_bytes(buffer, keylength);
195   BN_bn2bin(cl->metakey.n, buffer+keylength);
196
197   /* Calculate the hash from that */
198
199   SHA1(buffer, keylength*2, cl->chal_hash);
200
201   /* Convert the random data to a hexadecimal formatted string */
202
203   bin2hex(buffer,buffer,keylength);
204   buffer[keylength*2] = '\0';
205
206   /* Send the challenge */
207   
208   cl->allow_request = CHAL_REPLY;
209   x = send_request(cl, "%d %s", CHALLENGE, buffer);
210   free(buffer);
211 cp
212   return x;
213 }
214
215 int challenge_h(conn_list_t *cl)
216 {
217   char *challenge;
218 cp
219   if(sscanf(cl->buffer, "%*d %as", &cl->id, &challenge) != 1)
220     {
221        syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->id, cl->hostname);
222        return -1;
223     }
224
225   /* Rest is done by send_chal_reply() */
226   
227   x = send_chal_reply(cl, challenge);
228   free(challenge);
229 cp
230   return x;
231 }
232
233 int send_chal_reply(conn_list_t *cl, char *challenge)
234 {
235   char *buffer;
236   int keylength;
237   char *hash;
238   int x;
239 cp
240   keylength = BN_num_bytes(myself->meyakey.n);
241
242   /* Check if the length of the challenge is all right */
243
244   if(strlen(challenge) != keylength*2)
245     {
246       syslog(LOG_ERROR, _("Intruder: wrong challenge length from %s (%s)"), cl->id, cl->hostname);
247       return -1;
248     }
249
250   /* Allocate buffers for the challenge and the hash */
251   
252   buffer = xmalloc(keylength*2);
253   hash = xmalloc(SHA_DIGEST_LEN*2+1);
254
255   /* Copy the incoming random data and our public key to the buffer */
256
257   hex2bin(challenge, buffer, keylength); 
258   BN_bn2bin(myself->metakey.n, buffer+keylength);
259
260   /* Calculate the hash from that */
261   
262   SHA1(buffer, keylength*2, hash);
263   free(buffer);
264
265   /* Convert the hash to a hexadecimal formatted string */
266
267   bin2hex(hash,hash,SHA_DIGEST_LEN);
268   hash[SHA_DIGEST_LEN*2] = '\0';
269
270   /* Send the reply */
271
272   if(cl->status.outgoing)
273     cl->allow_resuest = ID;
274   else
275     cl->allow_request = ACK;
276
277   x = send_request(cl, "%d %s", CHAL_REPLY, hash);
278   free(hash);
279 cp
280   return x;
281
282
283 int chal_reply_h(conn_list_t *cl)
284 {
285   char *hash;
286 cp
287   if(sscanf(cl->buffer, "%*d %as", &cl->id, &hash) != 2)
288     {
289        syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->id, cl->hostname);
290        return -1;
291     }
292
293   /* Check if the length of the hash is all right */
294   
295   if(strlen(hash) != SHA_DIGEST_LEN*2)
296     {
297       syslog(LOG_ERROR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->id, cl->hostname);
298       return -1;
299     }
300     
301   /* Convert the hash to binary format */
302   
303   hex2bin(hash, hash, SHA_DIGEST_LEN);
304   
305   /* Verify the incoming hash with the calculated hash */
306   
307   if{!memcmp(hash, cl->chal_hash, SHA_DIGEST_LEN)}
308     {
309       syslog(LOG_ERROR, _("Intruder: wrong challenge reply from %s (%s)"), cl->id, cl->hostname);
310       return -1;
311     }
312
313   /* Identity has now been positively verified.
314      If we are accepting this new connection, then send our identity,
315      if we are making this connecting, acknowledge.
316    */
317    
318   free(hash);
319   free(cl->chal_hash);
320
321 cp
322   if(cl->status.outgoing)
323     {
324       cl->allow_request = ACK;
325       return send_ack(cl);
326     }
327   else
328     {
329       cl->allow_request = CHALLENGE;
330       return send_id(cl);
331     }
332 }
333
334 int send_ack(conn_list_t *cl)
335 {
336 cp
337   return send_request(cl, "%d", ACK);
338 }
339
340 int ack_h(conn_list_t *cl)
341 {
342   conn_list_t old;
343 cp
344   /* Okay, before we active the connection, we check if there is another entry
345      in the connection list with the same vpn_ip. If so, it presumably is an
346      old connection that has timed out but we don't know it yet.
347    */
348
349   while((old = lookup_id(cl->id))) 
350     {
351       if(debug_lvl > DEBUG_CONNECTIONS)
352         syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
353         cl->id, old->hostname, cl->hostname);
354       old->status.active = 0;
355       terminate_connection(old);
356     }
357
358   /* Activate this connection */
359
360   cl->allow_request = ALL;
361   cl->status.active = 1;
362
363   if(debug_lvl > DEBUG_CONNECTIONS)
364     syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->id, cl->hostname);
365
366   /* Exchange information about other tinc daemons */
367
368   notify_others(cl, NULL, send_add_host);
369   notify_one(cl);
370
371   upstreamindex = 0;
372
373 cp
374   if(cl->status.outgoing)
375     return 0;
376   else
377     return send_ack(cl);
378 }
379
380 /* Address and subnet information exchange */
381
382 int send_add_subnet(conn_list_t *cl, conn_list_t *other, subnet_t *subnet)
383 {
384 cp
385   return send_meta(cl, "%d %s %d %s", ADD_SUBNET, other->id, subnet->type, net2str(subnet));
386 }
387
388 int add_subnet_h(conn_list_t *cl)
389 {
390 }
391
392 int send_del_subnet(conn_list_t *cl, conn_list_t *other, subnet_t *subnet)
393 {
394 cp
395   return send_meta(cl, "%d %s %d %s", DEL_SUBNET, other->id, subnet->type, net2str(subnet));
396 }
397
398 int del_subnet_h(conn_list_t *cl)
399 {
400 }
401
402 /* New and closed connections notification */
403
404 int send_add_host(conn_list_t *cl, conn_list_t *other)
405 {
406 cp
407   return send_meta(cl, "%d %lx:%d", ADD_HOST, other->id, other->address, other->port);
408 }
409
410 int add_host_h(conn_list_t *cl)
411 {
412 }
413
414 int send_del_host(conn_list_t *cl, conn_list_t *other)
415 {
416 cp
417   return send_meta(cl, "%d %lx:%d", DEL_HOST, other->id, other->address, other->port);
418 }
419
420 int del_host_h(conn_list_t *cl)
421 {
422 }
423
424 /* Status and error notification routines */
425
426 int send_status(conn_list_t *cl, int statusno, char *statusstring)
427 {
428 cp
429   if(!statusstring)
430     statusstring = status_text[statusno];
431 cp
432   return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
433 }
434
435 int status_h(conn_list_t *cl)
436 {
437   int statusno;
438   char *statusstring;
439 cp
440   if(sscanf(cl->buffer, "%*d %d %as", &statusno, &statusstring) != 2)
441     {
442        syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"), cl->id, cl->hostname);
443        return -1;
444     }
445
446   if(debug_lvl > DEBUG_STATUS)
447     {
448       syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"), cl->id, cl->hostname, status_text[statusno], statusstring);
449     }
450
451 cp
452   free(statusstring);
453   return 0;
454 }
455
456 int send_error(conn_list_t *cl, int errno, char *errstring)
457 {
458 cp
459   if(!errorstring)
460     errorstring = error_text[errno];
461   return send_request(cl, "%d %d %s", ERROR, errno, errstring);
462 }
463
464 int error_h(conn_list_t *cl)
465 {
466   int errno;
467   char *errorstring;
468 cp
469   if(sscanf(cl->buffer, "%*d %d %as", &errno, &errorstring) != 2)
470     {
471        syslog(LOG_ERR, _("Got bad error from %s (%s)"), cl->id, cl->hostname);
472        return -1;
473     }
474
475   if(debug_lvl > DEBUG_error)
476     {
477       syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"), cl->id, cl->hostname, error_text[errno], errorstring);
478     }
479
480 cp
481   free(errorstring);
482   return 0;
483 }
484
485 int send_termreq(conn_list_t *cl)
486 {
487 }
488
489 int termreq_h(conn_list_t *cl)
490 {
491 }
492
493 /* Keepalive routines */
494
495 int send_ping(conn_list_t *cl)
496 {
497 cp
498   return send_meta(cl, "%d", PING);
499 }
500
501 int ping_h(conn_list_t *cl)
502 {
503 }
504
505 int send_pong(conn_list_t *cl)
506 {
507 cp
508   return send_meta(cl, "%d", PONG);
509 }
510
511 int pong_h(conn_list_t *cl)
512 {
513 }
514
515 /* Key exchange */
516
517 int send_req_key(conn_list_t *cl, conn_list_t *source)
518 {
519 cp
520   return send_meta(cl, "%d %s", REQ_KEY, source->id);
521 }
522
523 int req_key_h(conn_list_t *cl)
524 {
525 }
526
527 int send_key(conn_list_t *cl)
528 {
529 }
530
531 int key_h(conn_list_t *cl)
532 {
533 }
534
535
536
537
538 /* Old routines */
539
540
541 int send_termreq(conn_list_t *cl)
542 {
543 cp
544   if(debug_lvl > 1)
545     syslog(LOG_DEBUG, _("Sending TERMREQ to %s (%s)"),
546            cl->vpn_hostname, cl->real_hostname);
547
548   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
549
550   if(write(cl->meta_socket, buffer, buflen) < 0)
551     {
552       if(debug_lvl > 1)
553         syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
554       return -1;
555     }
556 cp
557   return 0;
558 }
559
560 int send_timeout(conn_list_t *cl)
561 {
562 cp
563   if(debug_lvl > 1)
564     syslog(LOG_DEBUG, _("Sending TIMEOUT to %s (%s)"),
565            cl->vpn_hostname, cl->real_hostname);
566
567   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
568
569   if((write(cl->meta_socket, buffer, buflen)) < 0)
570     {
571       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
572       return -1;
573     }
574 cp
575   return 0;
576 }
577
578 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
579 {
580 cp
581   if(debug_lvl > 1)
582     syslog(LOG_DEBUG, _("Sending DEL_HOST for %s (%s) to %s (%s)"),
583            new_host->vpn_hostname, new_host->real_hostname, cl->vpn_hostname, cl->real_hostname);
584
585   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
586
587   if((write(cl->meta_socket, buffer, buflen)) < 0)
588     {
589       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
590       return -1;
591     }
592 cp
593   return 0;
594 }
595
596 int send_tcppacket(conn_list_t *cl, void *data, int len)
597 {
598 cp
599   if(debug_lvl > 3)
600     syslog(LOG_DEBUG, _("Sending PACKET to %s (%s)"),
601            cl->vpn_hostname, cl->real_hostname);
602
603   buflen = snprintf(buffer, MAXBUFSIZE, "%d %d\n", PACKET, len);
604
605   if((write(cl->meta_socket, buffer, buflen)) < 0)
606     {
607       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
608       return -1;
609     }
610     
611   if((write(cl->meta_socket, data, len)) < 0)
612     {
613       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
614       return -1;
615     }
616 cp
617   return 0;
618 }
619
620 int send_ping(conn_list_t *cl)
621 {
622 cp
623   if(debug_lvl > 1)
624     syslog(LOG_DEBUG, _("Sending PING to %s (%s)"),
625            cl->vpn_hostname, cl->real_hostname);
626
627   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
628
629   if((write(cl->meta_socket, buffer, buflen)) < 0)
630     {
631       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
632       return -1;
633     }
634 cp
635   return 0;
636 }
637
638 int send_pong(conn_list_t *cl)
639 {
640 cp
641   if(debug_lvl > 1)
642     syslog(LOG_DEBUG, _("Sending PONG to %s (%s)"),
643            cl->vpn_hostname, cl->real_hostname);
644
645   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
646
647   if((write(cl->meta_socket, buffer, buflen)) < 0)
648     {
649       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
650       return -1;
651     }
652 cp
653   return 0;
654 }
655
656 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
657 {
658   ip_t real_ip;
659   int flags;
660   char *hostname;
661 cp
662   real_ip = new_host->real_ip;
663   hostname = new_host->real_hostname;
664   flags = new_host->flags;
665   
666   /* If we need to propagate information about a new host that wants us to export
667    * it's indirectdata flag, we set the INDIRECTDATA flag and unset the EXPORT...
668    * flag, and set it's real_ip to our vpn_ip, so that net.c send_packet() will
669    * work correctly.
670    */
671      
672   if(flags & EXPORTINDIRECTDATA)
673     {
674       flags &= ~EXPORTINDIRECTDATA;
675       flags |= INDIRECTDATA;
676       real_ip = myself->vpn_ip;
677       hostname = myself->real_hostname;
678     }
679
680   if(debug_lvl > 1)
681     syslog(LOG_DEBUG, _("Sending ADD_HOST for %s (%s) to %s (%s)"),
682            new_host->vpn_hostname, hostname, cl->vpn_hostname, cl->real_hostname);
683
684   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);
685
686   if((write(cl->meta_socket, buffer, buflen)) < 0)
687     {
688       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
689       return -1;
690     }
691 cp
692   return 0;
693 }
694
695 int send_key_changed(conn_list_t *cl, conn_list_t *src)
696 {
697 cp
698   if(debug_lvl > 1)
699     syslog(LOG_DEBUG, _("Sending KEY_CHANGED origin %s to %s (%s)"),
700            src->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
701
702   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
703
704   if((write(cl->meta_socket, buffer, buflen)) < 0)
705     {
706       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
707       return -1;
708     }
709 cp
710   return 0;
711 }
712
713 void send_key_changed_all(void)
714 {
715   conn_list_t *p;
716 cp
717   for(p = conn_list; p != NULL; p = p->next)
718     if(p->status.meta && p->status.active)
719       send_key_changed(p, myself);
720 cp
721 }
722
723
724 int send_key_request(ip_t to)
725 {
726   conn_list_t *fw;
727 cp
728   fw = lookup_conn(to);
729   if(!fw)
730     {
731       syslog(LOG_ERR, _("Attempting to send REQ_KEY to %d.%d.%d.%d, which does not exist?"),
732              IP_ADDR_V(to));
733       return -1;
734     }
735
736   if(debug_lvl > 1)
737     syslog(LOG_DEBUG, _("Sending REQ_KEY to %s (%s)"),
738            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
739
740   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
741
742   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
743     {
744       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
745       return -1;
746     }
747   fw->status.waitingforkey = 1;
748 cp
749   return 0;
750 }
751
752 int send_key_answer(conn_list_t *cl, ip_t to)
753 {
754   conn_list_t *fw;
755 cp
756
757   fw = lookup_conn(to);
758   
759   if(!fw)
760     {
761       syslog(LOG_ERR, _("Attempting to send ANS_KEY to %d.%d.%d.%d, which does not exist?"),
762              IP_ADDR_V(to));
763       return -1;
764     }
765
766  if(debug_lvl > 1)
767     syslog(LOG_DEBUG, _("Sending ANS_KEY to %s (%s)"),
768            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
769
770   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
771
772   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
773     {
774       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
775       return -1;
776     }
777 cp
778   return 0;
779 }
780
781 /*
782   notify all my direct connections of a new host
783   that was added to the vpn, with the exception
784   of the source of the announcement.
785 */
786 int notify_others(conn_list_t *new, conn_list_t *source,
787                   int (*function)(conn_list_t*, conn_list_t*))
788 {
789   conn_list_t *p;
790 cp
791   for(p = conn_list; p != NULL; p = p->next)
792     if(p != new && p != source && p->status.meta && p->status.active)
793       function(p, new);
794 cp
795   return 0;
796 }
797
798 /*
799   notify one connection of everything
800   i have connected
801 */
802 int notify_one(conn_list_t *new)
803 {
804   conn_list_t *p;
805 cp
806   for(p = conn_list; p != NULL; p = p->next)
807     if(p != new && p->status.active)
808       send_add_host(new, p);
809 cp
810   return 0;
811 }
812
813 /*
814   The incoming request handlers
815 */
816
817
818 int termreq_h(conn_list_t *cl)
819 {
820 cp
821   if(!cl->status.active)
822     {
823       syslog(LOG_ERR, _("Got unauthorized TERMREQ from %s (%s)"),
824               cl->vpn_hostname, cl->real_hostname);
825       return -1;
826     }
827     
828   if(debug_lvl > 1)
829    syslog(LOG_DEBUG, _("Got TERMREQ from %s (%s)"),
830              cl->vpn_hostname, cl->real_hostname);
831   
832   cl->status.termreq = 1;
833
834   terminate_connection(cl);
835 cp
836   return 0;
837 }
838
839 int timeout_h(conn_list_t *cl)
840 {
841 cp
842   if(!cl->status.active)
843     {
844       syslog(LOG_ERR, _("Got unauthorized TIMEOUT from %s (%s)"),
845               cl->vpn_hostname, cl->real_hostname);
846       return -1;
847     }
848
849   if(debug_lvl > 1)
850     syslog(LOG_DEBUG, _("Got TIMEOUT from %s (%s)"),
851               cl->vpn_hostname, cl->real_hostname);
852
853   cl->status.termreq = 1;
854   terminate_connection(cl);
855 cp
856   return 0;
857 }
858
859 int del_host_h(conn_list_t *cl)
860 {
861   ip_t vpn_ip;
862   conn_list_t *fw;
863 cp
864   if(!cl->status.active)
865     {
866       syslog(LOG_ERR, _("Got unauthorized DEL_HOST from %s (%s)"),
867               cl->vpn_hostname, cl->real_hostname);
868       return -1;
869     }
870
871   if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
872     {
873        syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
874               cl->vpn_hostname, cl->real_hostname);
875        return -1;
876     }  
877
878   if(!(fw = lookup_conn(vpn_ip)))
879     {
880       syslog(LOG_ERR, _("Got DEL_HOST for %d.%d.%d.%d from %s (%s) which does not exist?"),
881              IP_ADDR_V(vpn_ip), cl->vpn_hostname, cl->real_hostname);
882       return 0;
883     }
884
885   /* Connections lists are really messed up if this happens */
886   if(vpn_ip == myself->vpn_ip)
887     {
888       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
889                cl->vpn_hostname, cl->real_hostname);
890       sighup = 1;
891       return 0;
892     }
893
894   if(debug_lvl > 1)
895     syslog(LOG_DEBUG, _("Got DEL_HOST for %s (%s) from %s (%s)"),
896            fw->vpn_hostname, fw->real_hostname, cl->vpn_hostname, cl->real_hostname);
897
898   notify_others(fw, cl, send_del_host);
899
900   fw->status.termreq = 1;
901   fw->status.active = 0;
902
903   terminate_connection(fw);
904 cp
905   return 0;
906 }
907
908 int tcppacket_h(conn_list_t *cl)
909 {
910   int len;
911 cp
912   if(!cl->status.active)
913     {
914       syslog(LOG_ERR, _("Got unauthorized PACKET from %s (%s)"),
915               cl->vpn_hostname, cl->real_hostname);
916       return -1;
917     }
918
919   if(sscanf(cl->buffer, "%*d %d", &len) != 1)
920     {
921        syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"),
922               cl->vpn_hostname, cl->real_hostname);
923        return -1;
924     }  
925
926   if(len > MTU)
927     {
928        syslog(LOG_ERR, _("Got too big PACKET from %s (%s)"),
929               cl->vpn_hostname, cl->real_hostname);
930        return -1;
931     }  
932
933   if(debug_lvl > 3)
934     syslog(LOG_DEBUG, _("Got PACKET length %d from %s (%s)"), len,
935               cl->vpn_hostname, cl->real_hostname);
936
937   cl->tcppacket=len;
938 cp
939   return 0;
940 }
941
942
943 int ping_h(conn_list_t *cl)
944 {
945 cp
946   if(!cl->status.active)
947     {
948       syslog(LOG_ERR, _("Got unauthorized PING from %s (%s)"),
949               cl->vpn_hostname, cl->real_hostname);
950       return -1;
951     }
952
953   if(debug_lvl > 1)
954     syslog(LOG_DEBUG, _("Got PING from %s (%s)"),
955               cl->vpn_hostname, cl->real_hostname);
956
957   cl->status.pinged = 0;
958   cl->status.got_pong = 1;
959
960   send_pong(cl);
961 cp
962   return 0;
963 }
964
965 int pong_h(conn_list_t *cl)
966 {
967 cp
968   if(!cl->status.active)
969     {
970       syslog(LOG_ERR, _("Got unauthorized PONG 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 PONG from %s (%s)"),
977               cl->vpn_hostname, cl->real_hostname);
978
979   cl->status.got_pong = 1;
980 cp
981   return 0;
982 }
983
984 int add_host_h(conn_list_t *cl)
985 {
986   ip_t real_ip;
987   ip_t vpn_ip;
988   ip_t vpn_mask;
989   unsigned short port;
990   int flags;
991   conn_list_t *ncn, *old;
992 cp
993   if(!cl->status.active)
994     {
995       syslog(LOG_ERR, _("Got unauthorized ADD_HOST from %s (%s)"),
996               cl->vpn_hostname, cl->real_hostname);
997       return -1;
998     }
999     
1000   if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
1001     {
1002        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"),
1003               cl->vpn_hostname, cl->real_hostname);
1004        return -1;
1005     }  
1006
1007   if((old = lookup_conn(vpn_ip)))
1008     {
1009       if((real_ip==old->real_ip) && (vpn_mask==old->vpn_mask) && (port==old->port))
1010         {
1011           if(debug_lvl>1)
1012             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
1013                    old->vpn_hostname, old->real_hostname, cl->vpn_hostname, cl->real_hostname);
1014           goto skip_add_host;  /* One goto a day keeps the deeply nested if constructions away. */
1015         }
1016       else
1017         {
1018           if(debug_lvl>1)
1019             syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"),
1020                    old->vpn_hostname, old->real_hostname);
1021           old->status.active = 0;
1022           terminate_connection(old);
1023         }
1024     }
1025   
1026   /* Connections lists are really messed up if this happens */
1027   if(vpn_ip == myself->vpn_ip)
1028     {
1029       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"),
1030                cl->vpn_hostname, cl->real_hostname);
1031       sighup = 1;
1032       return 0;
1033     }
1034     
1035   ncn = new_conn_list();
1036   ncn->real_ip = real_ip;
1037   ncn->real_hostname = hostlookup(htonl(real_ip));
1038   ncn->vpn_ip = vpn_ip;
1039   ncn->vpn_mask = vpn_mask;
1040   ncn->vpn_hostname = hostlookup(htonl(vpn_ip));
1041   ncn->port = port;
1042   ncn->flags = flags;
1043   ncn->nexthop = cl;
1044   ncn->next = conn_list;
1045   conn_list = ncn;
1046   ncn->status.active = 1;
1047
1048   if(debug_lvl > 1)
1049     syslog(LOG_DEBUG, _("Got ADD_HOST for %s (%s) from %s (%s)"),
1050            ncn->vpn_hostname, ncn->real_hostname, cl->vpn_hostname, cl->real_hostname);
1051
1052   notify_others(ncn, cl, send_add_host);
1053
1054 skip_add_host:
1055 cp
1056   return 0;
1057 }
1058
1059 int req_key_h(conn_list_t *cl)
1060 {
1061   ip_t to;
1062   ip_t from;
1063   conn_list_t *fw;
1064 cp
1065   if(!cl->status.active)
1066     {
1067       syslog(LOG_ERR, _("Got unauthorized REQ_KEY from %s (%s)"),
1068               cl->vpn_hostname, cl->real_hostname);
1069       return -1;
1070     }
1071
1072   if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
1073     {
1074        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1075               cl->vpn_hostname, cl->real_hostname);
1076        return -1;
1077     }  
1078
1079   if(debug_lvl > 1)
1080     syslog(LOG_DEBUG, _("Got REQ_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
1081            IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
1082
1083   if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
1084     {  /* hey! they want something from ME! :) */
1085       send_key_answer(cl, from);
1086       return 0;
1087     }
1088
1089   fw = lookup_conn(to);
1090   
1091   if(!fw)
1092     {
1093       syslog(LOG_ERR, _("Attempting to forward REQ_KEY to %d.%d.%d.%d, which does not exist?"),
1094              IP_ADDR_V(to));
1095       return -1;
1096     }
1097
1098   if(debug_lvl > 1)
1099     syslog(LOG_DEBUG, _("Forwarding REQ_KEY to %s (%s)"),
1100            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
1101   
1102   cl->buffer[cl->reqlen-1] = '\n';
1103   
1104   if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
1105     {
1106       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
1107       return -1;
1108     }
1109 cp
1110   return 0;
1111 }
1112
1113 void set_keys(conn_list_t *cl, int expiry, char *key)
1114 {
1115   char *ek;
1116 cp
1117   if(!cl->public_key)
1118     {
1119       cl->public_key = xmalloc(sizeof(*cl->key));
1120       cl->public_key->key = NULL;
1121     }
1122     
1123   if(cl->public_key->key)
1124     free(cl->public_key->key);
1125   cl->public_key->length = strlen(key);
1126   cl->public_key->expiry = expiry;
1127   cl->public_key->key = xmalloc(cl->public_key->length + 1);
1128   strcpy(cl->public_key->key, key);
1129
1130   ek = make_shared_key(key);
1131   
1132   if(!cl->key)
1133     {
1134       cl->key = xmalloc(sizeof(*cl->key));
1135       cl->key->key = NULL;
1136     }
1137
1138   if(cl->key->key)
1139     free(cl->key->key);
1140
1141   cl->key->length = strlen(ek);
1142   cl->key->expiry = expiry;
1143   cl->key->key = xmalloc(cl->key->length + 1);
1144   strcpy(cl->key->key, ek);
1145 cp
1146 }
1147
1148 int ans_key_h(conn_list_t *cl)
1149 {
1150   ip_t to;
1151   ip_t from;
1152   int expiry;
1153   char *key;
1154   conn_list_t *fw, *gk;
1155 cp
1156   if(!cl->status.active)
1157     {
1158       syslog(LOG_ERR, _("Got unauthorized ANS_KEY from %s (%s)"),
1159               cl->vpn_hostname, cl->real_hostname);
1160       return -1;
1161     }
1162
1163   if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
1164     {
1165        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1166               cl->vpn_hostname, cl->real_hostname);
1167        return -1;
1168     }  
1169
1170   if(debug_lvl > 1)
1171     syslog(LOG_DEBUG, _("Got ANS_KEY origin %d.%d.%d.%d destination %d.%d.%d.%d from %s (%s)"),
1172             IP_ADDR_V(from), IP_ADDR_V(to), cl->vpn_hostname, cl->real_hostname);
1173
1174   if(to == myself->vpn_ip)
1175     {  /* hey! that key's for ME! :) */
1176       gk = lookup_conn(from);
1177
1178       if(!gk)
1179         {
1180           syslog(LOG_ERR, _("Receiving ANS_KEY origin %d.%d.%d.%d from %s (%s), which does not exist?"),
1181                  IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
1182           return -1;
1183         }
1184
1185       set_keys(gk, expiry, key);
1186       gk->status.validkey = 1;
1187       gk->status.waitingforkey = 0;
1188       flush_queues(gk);
1189       return 0;
1190     }
1191
1192   fw = lookup_conn(to);
1193   
1194   if(!fw)
1195     {
1196       syslog(LOG_ERR, _("Attempting to forward ANS_KEY to %d.%d.%d.%d, which does not exist?"),
1197              IP_ADDR_V(to));
1198       return -1;
1199     }
1200
1201   if(debug_lvl > 1)
1202     syslog(LOG_DEBUG, _("Forwarding ANS_KEY to %s (%s)"),
1203            fw->nexthop->vpn_hostname, fw->nexthop->real_hostname);
1204
1205   cl->buffer[cl->reqlen-1] = '\n';
1206
1207   if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
1208     {
1209       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
1210       return -1;
1211     }
1212 cp
1213   return 0;
1214 }
1215
1216 int key_changed_h(conn_list_t *cl)
1217 {
1218   ip_t from;
1219   conn_list_t *ik;
1220 cp
1221   if(!cl->status.active)
1222     {
1223       syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from %s (%s)"),
1224               cl->vpn_hostname, cl->real_hostname);
1225       return -1;
1226     }
1227
1228   if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
1229     {
1230        syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1231               cl->vpn_hostname, cl->real_hostname);
1232        return -1;
1233     }  
1234
1235   ik = lookup_conn(from);
1236
1237   if(!ik)
1238     {
1239       syslog(LOG_ERR, _("Got KEY_CHANGED origin %d.%d.%d.%d from %s (%s), which does not exist?"),
1240              IP_ADDR_V(from), cl->vpn_hostname, cl->real_hostname);
1241       return -1;
1242     }
1243
1244   if(debug_lvl > 1)
1245     syslog(LOG_DEBUG, _("Got KEY_CHANGED origin %s from %s (%s)"),
1246             ik->vpn_hostname, cl->vpn_hostname, cl->real_hostname);
1247
1248   ik->status.validkey = 0;
1249   ik->status.waitingforkey = 0;
1250
1251   notify_others(ik, cl, send_key_changed);
1252 cp
1253   return 0;
1254 }
1255
1256 /* "Complete overhaul". */
1257
1258 int (*request_handlers[])(conn_list_t*) = {
1259   id_h, challenge_h, chal_reply_h, ack_h,
1260   status_h, error_h, termreq_h,
1261   add_host_h, del_host_h,
1262   ping_h, pong_h,
1263 };
1264
1265 char (*request_name[]) = {
1266   "ID", "CHALLENGE", "CHAL_REPLY", "ACK",
1267   "STATUS", "ERROR", "TERMREQ",
1268   "ADD_HOST", "DEL_HOST",
1269   "PING", "PONG",
1270 };