Move CABAL branch to its rightful place: the trunk.

This commit is contained in:
Guus Sliepen 2004-03-21 13:22:24 +00:00
commit 42e01abd54
97 changed files with 3300 additions and 1616 deletions

View file

@ -1,4 +0,0 @@
Makefile Makefile.in aclocal.m4 config.cache config.log config.status configure
config.guess config.sub install-sh missing mkinstalldirs ChangeLog
config.h.in stamp-h.in config.h libtool stamp-h build-stamp
intl

14
COPYING.README Normal file
View file

@ -0,0 +1,14 @@
The following applies to tinc:
This program is released under the GPL with the additional exemption that
compiling, linking, and/or using OpenSSL is allowed. You may provide binary
packages linked to the OpenSSL libraries, provided that all other requirements
of the GPL are met.
The following applies to the LZO library:
Hereby I grant a special exception to the tinc VPN project
(http://tinc.nl.linux.org/) to link the LZO library with the OpenSSL library
(http://www.openssl.org).
Markus F.X.J. Oberhumer

View file

@ -8,20 +8,11 @@ ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = config.rpath mkinstalldirs system.h COPYING.README depcomp
CVS_CREATED = ABOUT-NLS configure aclocal.m4 config.h.in config.guess \
config.sub install-sh ltconfig ltmain.sh missing mkinstalldirs \
stamp-h.in m4/Makefile.am ChangeLog po/Makefile.in.in \
po/tinc.pot po/*.sed po/*.header po/*.sin po/Rules-quot \
src/.libs intl depcomp
ChangeLog:
cvs2cl -U cvsusers --fsf
svn log > ChangeLog
cvs-clean: maintainer-clean
for f in $(CVS_CREATED) `find . -name Makefile.in` tinc-$(VERSION).tar.gz; do\
rm -Rf "$$f"; \
done
grep -l gettext `find m4 -type f` | xargs rm -f
svn-clean: maintainer-clean
svn status --no-ignore | sed -n 's/^[?I] \+//p' | tr '\012' '\0' | xargs -r0 rm -rf
deb:
dpkg-buildpackage -rfakeroot

15
NEWS
View file

@ -1,3 +1,18 @@
version 1.0.2 Nov 8 2003
* Fix address and hostname resolving under Windows.
* Remove warnings about non-existing scripts and unsupported address families.
* Use the event logger under Windows.
* Fix quoting of filenames and command line arguments under Windows.
* Strict checks for length incoming network packets and return values of
cryptographic functions,
* Fix a bug in metadata handling that made the tinc daemon abort.
version 1.0.1 Aug 14 2003
* Allow empty lines in config files.

12
README
View file

@ -1,4 +1,4 @@
This is the README file for tinc version 1.0.1. Installation
This is the README file for tinc version 1.0.2. Installation
instructions may be found in the INSTALL file.
tinc is Copyright (C) 1998-2003 by:
@ -31,6 +31,14 @@ launch a denial of service attack by replaying intercepted packets. The current
version adds sequence numbers and message authentication codes to prevent such
attacks.
On September the 15th of 2003, Peter Gutmann contacted us and showed us a
writeup describing various security issues in several VPN daemons. He showed
that tinc lacks perfect forward security, the connection authentication could
be done more properly, that the sequence number we use as an IV is not the best
practice and that the default length of the HMAC for packets is too short in
his opinion. We do not know of a way to exploit these weaknesses, but we will
address these issues in tinc 2.0.
Cryptography is a hard thing to get right. We cannot make any
guarantees. Time, review and feedback are the only things that can
prove the security of any cryptographic product. If you wish to review
@ -47,7 +55,7 @@ should be changed into "Device", and "Device" should be changed into
Compatibility
-------------
Version 1.0.1 is compatible with 1.0 and 1.0pre8 but not with older versions
Version 1.0.2 is compatible with 1.0.1, 1.0 and 1.0pre8 but not with older versions
of tinc.

13
TODO
View file

@ -1,14 +1,3 @@
TODO LIST
* Stop using UDP source address as the identifier of the remote tinc daemon.
Use a unique number sent along with ANS_KEY.
* Efficient multicast support.
* Check if caches using hash tables speed up route.c.
* Streamline the meta protocol. Use a binary format?
* Add (hooks for) a (graphical) frontend, like Pokey.
* Implement future goals as mentioned on the website.
* Think of new things to do.

View file

@ -1,157 +0,0 @@
#!/bin/sh
# Run this to generate all the initial makefiles,
# etc. just after a checkout.
DIE=0
if ${MAKE:-gmake} -q -C . autogen.sh 2> /dev/null
then
alias make=${MAKE:-gmake}
fi
srcdir="`/bin/pwd`"
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`autoconf' installed to compile tinc."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
(libtool --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`libtool' installed to compile tinc."
echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
}
grep "^AM_GNU_GETTEXT" $srcdir/configure.in >/dev/null && {
grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
(gettext --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`gettext' installed to compile tinc."
echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
}
grep "^AM_GNOME_GETTEXT" $srcdir/configure.in >/dev/null && {
grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
(gettext --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`gettext' installed to compile tinc."
echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`automake' installed to compile tinc."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
NO_AUTOMAKE=yes
}
# if no automake, don't bother testing for aclocal
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
echo "installed doesn't appear recent enough."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if test -z "$*"; then
echo "**Warning**: I am going to run \`configure' with no arguments."
echo "If you wish to pass any to it, please specify them on the"
echo \`$0\'" command line."
echo
fi
case $CC in
xlc )
am_opt=--include-deps;;
esac
for coin in `find $srcdir -name configure.in -print`
do
dr=`dirname $coin`
if test -f $dr/NO-AUTO-GEN; then
echo skipping $dr -- flagged as no auto-gen
else
echo processing $dr
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
( cd $dr
if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then
if grep "sed.*POTFILES" configure.in >/dev/null; then
: do nothing -- we still have an old unmodified configure.in
else
echo "Creating $dr/aclocal.m4 ..."
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
echo "Running autopoint..."
autopoint --force
echo "Making $dr/aclocal.m4 writable ..."
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
fi
fi
if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then
echo "Creating $dr/aclocal.m4 ..."
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
echo "Running autopoint..."
autopoint --force
echo "Making $dr/aclocal.m4 writable ..."
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
fi
if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
echo "Running libtoolize..."
libtoolize --force --copy
fi
aclocalinclude="$ACLOCAL_FLAGS"
for k in $macrodirs; do
if test -d $k; then
if test -f $k/Makefile.am.in; then
make -C $k -f Makefile.am.in Makefile.am
fi
aclocalinclude="$aclocalinclude -I $k"
##else
## echo "**Warning**: No such directory \`$k'. Ignored."
fi
done
touch ChangeLog
echo "Running aclocal $aclocalinclude ..."
aclocal $aclocalinclude
if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
echo "Running autoheader..."
autoheader
fi
echo "Running automake --gnu $am_opt ..."
automake --add-missing --gnu $am_opt
echo "Running autoconf ..."
autoconf
)
fi
done
conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
if test x$NOCONFIGURE = x; then
echo Running $srcdir/configure $conf_flags "$@" ...
$srcdir/configure $conf_flags "$@" \
&& echo Now type \`make\' to compile $PKG_NAME || exit 1
else
echo Skipping configure process.
fi

View file

@ -1,11 +1,12 @@
dnl Process this file with autoconf to produce a configure script.
dnl $Id: configure.in,v 1.21 2003/08/24 20:50:30 guus Exp $
dnl $Id: configure.in,v 1.13.2.86 2004/01/10 23:21:36 guus Exp $
AC_PREREQ(2.57)
AC_INIT(src/tincd.c)
AM_INIT_AUTOMAKE(tinc, 2.0-cvs)
AM_CONFIG_HEADER(config.h)
AC_PREREQ(2.59)
AC_INIT
AC_CONFIG_SRCDIR([src/tincd.c])
AM_INIT_AUTOMAKE(tinc, 1.0-cvs)
AC_CONFIG_HEADERS([config.h])
AM_MAINTAINER_MODE
dnl Include the macros from the m4/ directory
@ -197,7 +198,7 @@ AC_STRUCT_TM
tinc_ATTRIBUTE(__malloc__)
AC_CHECK_TYPES([socklen_t, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, struct in_addr, struct addrinfo, struct ip, struct icmp, struct in6_addr, struct sockaddr_in6, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
[#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@ -253,7 +254,7 @@ dnl Checks for library functions.
AC_FUNC_MEMCMP
AC_FUNC_ALLOCA
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([asprintf daemon fchmod fcloseall flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system unsetenv vsyslog])
AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system unsetenv vsyslog])
jm_FUNC_MALLOC
jm_FUNC_REALLOC
@ -284,13 +285,13 @@ tinc_LZO
dnl Check if support for jumbograms is requested
AC_ARG_ENABLE(jumbograms,
AC_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]),
AS_HELP_STRING([--enable-jumbograms], [enable support for jumbograms (packets up to 9000 bytes)]),
[ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]
)
dnl Check if checkpoint tracing has to be enabled
AC_ARG_ENABLE(tracing,
AC_HELP_STRING([--enable-tracing], [enable checkpoint tracing (debugging only)]),
AS_HELP_STRING([--enable-tracing], [enable checkpoint tracing (debugging only)]),
[ AC_DEFINE(ENABLE_TRACING, 1, [Checkpoint tracing]) ]
)

View file

@ -1,3 +0,0 @@
zarq:Ivo Timmermans <ivo@o2w.nl>
guus:Guus Sliepen <guus@sliepen.eu.org>
wsl:Wessel Dankers <wsl@nl.linux.org>

View file

@ -1 +0,0 @@
Makefile.in Makefile tinc.info sample-config.tar.gz

View file

@ -12,7 +12,7 @@ maintain a stable network.
provided that the entire resulting derived work is distributed
under the terms of a permission notice identical to this one.
$Id: CONNECTIVITY,v 1.3 2003/08/24 20:38:18 guus Exp $
$Id: CONNECTIVITY,v 1.1.2.11 2002/09/16 14:08:04 wsl Exp $
1. Synchronisation
==================

View file

@ -12,7 +12,7 @@ Network daemon.
provided that the entire resulting derived work is distributed
under the terms of a permission notice identical to this one.
$Id: NETWORKING,v 1.3 2003/08/24 20:38:18 guus Exp $
$Id: NETWORKING,v 1.1.2.3 2002/06/21 10:11:10 guus Exp $
1. Packet flow
==============

View file

@ -12,7 +12,7 @@ This is the protocol documentation for tinc, a Virtual Private Network daemon.
provided that the entire resulting derived work is distributed
under the terms of a permission notice identical to this one.
$Id: PROTOCOL,v 1.3 2003/08/24 20:38:18 guus Exp $
$Id: PROTOCOL,v 1.1.2.8 2002/09/15 22:19:37 guus Exp $
1. Protocols used in tinc

View file

@ -12,7 +12,7 @@ This is the security documentation for tinc, a Virtual Private Network daemon.
provided that the entire resulting derived work is distributed
under the terms of a permission notice identical to this one.
$Id: SECURITY2,v 1.3 2003/08/24 20:38:18 guus Exp $
$Id: SECURITY2,v 1.1.2.4 2002/09/15 22:19:37 guus Exp $
Proposed new authentication scheme
----------------------------------

View file

@ -1,79 +0,0 @@
This is the security documentation for tinc, a Virtual Private Network daemon.
Copyright 2001-2003 Guus Sliepen <guus@sliepen.eu.org>,
2001-2003 Wessel Dankers <wsl@nl.linux.org>
Permission is granted to make and distribute verbatim copies of
this documentation provided the copyright notice and this
permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of
this documentation under the conditions for verbatim copying,
provided that the entire resulting derived work is distributed
under the terms of a permission notice identical to this one.
$Id: SECURITY3,v 1.1 2003/10/01 09:43:01 guus Exp $
Proposed authentication scheme for tinc 2.0
-------------------------------------------
daemon message
--------------------------------------------------------------------------
A <attempts connection>
B <accepts connection>
A ID "A" <version> <cipher> <digest> <compression>
B ID "B" <version> <cipher> <digest> <compression>
A META_KEY <Diffie-Hellman public key> <nonce> <signature>
Where signature is that of the public key and nonce, using A's
private RSA key.
B META_KEY <Diffie-Hellman public key> <nonce> <signature>
Both sides now use Diffie-Hellman to compute the shared secret key. Because
only A and B can decrypt the respective public keys, only A and B can know this
shared key.
From the shared key the following things will be derived:
A's symmetric cipher key
A's symmetric cipher IV
A's HMAC key
A's verification data
B's symmetric cipher key
B's symmetric cipher IV
B's HMAC key
B's verification data
From now on:
- A will symmetrically encrypt outgoing traffic using A's symmetric cipher key
- B will symmetrically encrypt outgoing traffic using B's symmetric cipher key
A ACK <A's verification data> <port> <weight> <options>
B ACK <B's verification data> <port> <weight> <options>
After ACKs with the correct verification messages have been recieved, both ends have proved
their identity.
-------------------------------------------------------------------------
Changes from the protocol used in tinc 1.0pre5 up to 1.0.1:
Instead of directly sending the keys which will be used for symmetric
encryption, a Diffie-Hellman key exchange will be done. This prevents an
attacker from being able to send and use his own key if he can't read the key
that is sent to him. It also allows us to have perfect forward security, since
only public keys are exchanged in the Diffie-Hellman key exchange, so after the
RSA keys have been compromised it still is not possible to recover the shared
key from recorded authentications from the past.
The CHALLENGE/RESPONSE messages have been replaced by verification data in the
ACK message, which saves two round trips.
The ID messages will also contain information about the cipher and digest
algorithm and compression to use for encrypting the TCP connections.

View file

@ -219,6 +219,11 @@ Note that there must be exactly one of
or
.Va PrivateKeyFile
specified in the configuration file.
.It Va TunnelServer Li = yes | no Po no Pc Bq experimental
When this option is enabled tinc will no longer forward information between other tinc daemons,
and will only allow nodes and subnets on the VPN which are present in the
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
directory.
.El
.Sh HOST CONFIGURATION FILES
The host configuration files contain all information needed
@ -246,6 +251,7 @@ Any cipher supported by OpenSSL is recognised.
Furthermore, specifying
.Qq none
will turn off packet encryption.
It is best to use only those ciphers which support CBC mode.
.It Va Compression Li = Ar level Pq 0
This option sets the level of compression used for UDP packets.
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
@ -268,6 +274,11 @@ The length of the message authentication code used to authenticate UDP packets.
Can be anything from
.Qq 0
up to the length of the digest produced by the digest algorithm.
.It Va PMTU Li = Ar mtu Po 1514 Pc Bq experimental
This option controls the initial path MTU to this node.
.It Va PMTUDiscovery Li = yes | no Po no Pc Bq experimental
When this option is enabled, tinc will try to discover the path MTU to this node.
After the path MTU has been discovered, it will be enforced on the VPN.
.It Va Port Li = Ar port Pq 655
The port number on which this tinc daemon is listening for incoming connections.
.It Va PublicKey Li = Ar key Bq obsolete
@ -314,7 +325,7 @@ Setting this options also implicitly sets IndirectData.
.Sh SCRIPTS
Apart from reading the server and host configuration files,
tinc can also run scripts at certain moments.
On Windows (not Cygwin), the scripts should have the extension
Under Windows (not Cygwin), the scripts should have the extension
.Pa .bat .
.Bl -tag -width indent
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up

File diff suppressed because it is too large Load diff

View file

@ -67,6 +67,8 @@ Generate public/private RSA keypair and exit.
If
.Ar BITS
is omitted, the default length will be 1024 bits.
When saving keys to existing files, tinc will not delete the old keys,
you have to remove them manually.
.It Fl L, -mlock
Lock tinc into main memory.
This will prevent sensitive data like shared private keys to be written to the system swap files/partitions.
@ -130,7 +132,7 @@ Each level inherits all messages of the previous level:
This will log a message indicating
.Nm
has started along with a version number.
It will also any serious error.
It will also log any serious error.
.It 1
This will log all connections that are made with other tinc daemons.
.It 2

View file

@ -1 +0,0 @@
Makefile Makefile.in .deps

View file

@ -1,5 +1,5 @@
## Process this file with automake to produce Makefile.in
# $Id: Makefile.am,v 1.10 2003/08/24 20:38:20 guus Exp $
# $Id: Makefile.am,v 1.2.4.13 2003/07/18 12:16:23 guus Exp $
noinst_LIBRARIES = libvpn.a

View file

@ -29,7 +29,7 @@
library for inclusion into tinc (http://tinc.nl.linux.org/) by
Guus Sliepen <guus@sliepen.eu.org>.
$Id: avl_tree.c,v 1.3 2003/08/24 20:38:20 guus Exp $
$Id: avl_tree.c,v 1.1.2.19 2003/08/28 21:05:09 guus Exp $
*/
#include "system.h"
@ -280,7 +280,7 @@ void avl_free_tree(avl_tree_t *tree)
avl_node_t *avl_alloc_node(void)
{
return (avl_node_t *)xmalloc_and_zero(sizeof(avl_node_t));
return xmalloc_and_zero(sizeof(avl_node_t));
}
void avl_free_node(avl_tree_t *tree, avl_node_t *node)

View file

@ -29,7 +29,7 @@
library for inclusion into tinc (http://tinc.nl.linux.org/) by
Guus Sliepen <guus@sliepen.eu.org>.
$Id: avl_tree.h,v 1.3 2003/08/24 20:38:20 guus Exp $
$Id: avl_tree.h,v 1.1.2.10 2003/07/24 12:08:15 guus Exp $
*/

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: dropin.c,v 1.3 2003/08/24 20:38:20 guus Exp $
$Id: dropin.c,v 1.1.2.18 2003/07/29 22:59:00 guus Exp $
*/
#include "system.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: dropin.h,v 1.3 2003/08/24 20:38:20 guus Exp $
$Id: dropin.h,v 1.1.2.14 2003/07/29 22:59:00 guus Exp $
*/
#ifndef __DROPIN_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: ethernet.h,v 1.2 2003/08/24 20:38:20 guus Exp $
$Id: ethernet.h,v 1.1.2.5 2003/10/08 11:34:55 guus Exp $
*/
#ifndef __TINC_ETHERNET_H__
@ -27,26 +27,38 @@
#define ETH_ALEN 6
#endif
#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif
#ifndef ARPHRD_ETHER
#define ARPHRD_ETHER 1
#endif
#ifndef ETHERTYPE_IP
#define ETHERTYPE_IP 0x0800
#ifndef ETH_P_IP
#define ETH_P_IP 0x0800
#endif
#ifndef ETH_P_ARP
#define ETH_P_ARP 0x0806
#endif
#ifndef ETH_P_IPV6
#define ETH_P_IPV6 0x86DD
#endif
#ifndef HAVE_STRUCT_ETHER_HEADER
struct ether_header {
uint8_t ether_dhost[ETH_ALEN];
uint8_t ether_shost[ETH_ALEN];
uint16_t ether_type;
} __attribute__ ((__packed__));
#endif
#ifndef HAVE_STRUCT_ARPHDR
struct arphdr {
unsigned short int ar_hrd;
unsigned short int ar_pro;
unsigned char ar_hln;
unsigned char ar_pln;
unsigned short int ar_op;
};
uint16_t ar_hrd;
uint16_t ar_pro;
uint8_t ar_hln;
uint8_t ar_pln;
uint16_t ar_op;
} __attribute__ ((__packed__));
#define ARPOP_REQUEST 1
#define ARPOP_REPLY 2
@ -64,7 +76,7 @@ struct ether_arp {
uint8_t arp_spa[4];
uint8_t arp_tha[ETH_ALEN];
uint8_t arp_tpa[4];
};
} __attribute__ ((__packed__));
#define arp_hrd ea_hdr.ar_hrd
#define arp_pro ea_hdr.ar_pro
#define arp_hln ea_hdr.ar_hln

View file

@ -5,7 +5,7 @@
* See getaddrinfo.c and getnameinfo.c.
*/
/* $Id: fake-gai-errnos.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
/* $Id: fake-gai-errnos.h,v 1.1.2.3 2003/08/17 08:32:38 guus Exp $ */
/* for old netdb.h */
#ifndef EAI_NODATA

View file

@ -14,6 +14,7 @@
#include "ipv4.h"
#include "ipv6.h"
#include "fake-getaddrinfo.h"
#include "xalloc.h"
#ifndef HAVE_GAI_STRERROR
char *gai_strerror(int ecode)

View file

@ -1,4 +1,4 @@
/* $Id: fake-getaddrinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
/* $Id: fake-getaddrinfo.h,v 1.1.2.3 2003/07/17 15:06:25 guus Exp $ */
#ifndef _FAKE_GETADDRINFO_H
#define _FAKE_GETADDRINFO_H

View file

@ -1,4 +1,4 @@
/* $Id: fake-getnameinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
/* $Id: fake-getnameinfo.h,v 1.1.2.3 2003/07/17 15:06:25 guus Exp $ */
#ifndef _FAKE_GETNAMEINFO_H
#define _FAKE_GETNAMEINFO_H

View file

@ -1,120 +0,0 @@
/*
hooks.c -- hooks management
Copyright (C) 2002 Guus Sliepen <guus@sliepen.warande.net>,
2002 Ivo Timmermans <ivo@o2w.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: hooks.c,v 1.2 2002/05/02 11:50:07 zarq Exp $
*/
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <avl_tree.h>
#include <hooks.h>
#include <xalloc.h>
avl_tree_t *hooks_tree = NULL;
struct hooks_node {
const char *type;
avl_tree_t *hooks;
} hooks_node;
static int hook_type_compare(const void *a, const void *b)
{
return strcmp(((const struct hooks_node*)a)->type,
((const struct hooks_node*)b)->type);
}
static int hook_dummy_compare(const void *a, const void *b)
{
if(a < b)
return -1;
if(a > b)
return 1;
return 0;
}
void run_hooks(const char *type, ...)
{
avl_node_t *avlnode;
va_list args;
struct hooks_node *hn;
struct hooks_node target;
if(!hooks_tree)
return;
target.type = type;
hn = (struct hooks_node*)avl_search(hooks_tree, &target);
if(!hn || !(hn->hooks->head))
{
fprintf(stderr, "Warning, no hooks found for `%s'\n", type);
return;
}
va_start(args, type);
for(avlnode = hn->hooks->head; avlnode; avlnode = avlnode->next)
{
assert(avlnode->data);
((hook_function_t*)(avlnode->data))(type, args);
}
va_end(args);
}
void add_hook(const char *type, hook_function_t *hook)
{
struct hooks_node *hn;
struct hooks_node target;
if(!hooks_tree)
hooks_tree = avl_alloc_tree(hook_type_compare, NULL);
target.type = type;
hn = avl_search(hooks_tree, &target);
if(!hn)
{
avl_tree_t *t;
hn = xmalloc(sizeof(struct hooks_node));
t = avl_alloc_tree(hook_dummy_compare, NULL);
hn->type = type;
hn->hooks = t;
avl_insert(hooks_tree, (void*)hn);
}
avl_insert(hn->hooks, (void*)hook);
}
void del_hook(const char *type, hook_function_t *hook)
{
avl_tree_t *t;
struct hooks_node target;
if(!hooks_tree)
return;
target.type = type;
t = avl_search(hooks_tree, &target);
if(!t)
return;
avl_delete(t, (void*)hook);
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: ipv4.h,v 1.2 2003/08/24 20:38:20 guus Exp $
$Id: ipv4.h,v 1.1.2.5 2003/12/22 11:05:23 guus Exp $
*/
#ifndef __TINC_IPV4_H__
@ -35,6 +35,10 @@
#define ICMP_DEST_UNREACH 3
#endif
#ifndef ICMP_FRAG_NEEDED
#define ICMP_FRAG_NEEDED 4
#endif
#ifndef ICMP_NET_UNKNOWN
#define ICMP_NET_UNKNOWN 6
#endif
@ -68,7 +72,7 @@ struct ip {
uint8_t ip_p;
uint16_t ip_sum;
struct in_addr ip_src, ip_dst;
};
} __attribute__ ((__packed__));
#endif
#ifndef HAVE_STRUCT_ICMP
@ -126,7 +130,7 @@ struct icmp {
#define icmp_radv icmp_dun.id_radv
#define icmp_mask icmp_dun.id_mask
#define icmp_data icmp_dun.id_data
};
} __attribute__ ((__packed__));
#endif
#endif /* __TINC_IPV4_H__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: ipv6.h,v 1.2 2003/08/24 20:38:20 guus Exp $
$Id: ipv6.h,v 1.1.2.9 2003/12/22 11:05:23 guus Exp $
*/
#ifndef __TINC_IPV6_H__
@ -38,7 +38,7 @@ struct in6_addr {
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
};
} __attribute__ ((__packed__));
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
@ -51,7 +51,7 @@ struct sockaddr_in6 {
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
} __attribute__ ((__packed__));
#endif
#ifndef IN6_IS_ADDR_V4MAPPED
@ -74,7 +74,7 @@ struct ip6_hdr {
} ip6_ctlun;
struct in6_addr ip6_src;
struct in6_addr ip6_dst;
};
} __attribute__ ((__packed__));
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
@ -93,28 +93,37 @@ struct icmp6_hdr {
uint16_t icmp6_un_data16[2];
uint8_t icmp6_un_data8[4];
} icmp6_dataun;
};
} __attribute__ ((__packed__));
#define ICMP6_DST_UNREACH_NOROUTE 0
#define ICMP6_DST_UNREACH 1
#define ICMP6_PACKET_TOO_BIG 2
#define ICMP6_DST_UNREACH_ADDR 3
#define ND_NEIGHBOR_SOLICIT 135
#define ND_NEIGHBOR_ADVERT 136
#define icmp6_data32 icmp6_dataun.icmp6_un_data32
#define icmp6_data16 icmp6_dataun.icmp6_un_data16
#define icmp6_data8 icmp6_dataun.icmp6_un_data8
#define icmp6_mtu icmp6_data32[0]
#endif
#ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
struct nd_neighbor_solicit {
struct icmp6_hdr nd_ns_hdr;
struct in6_addr nd_ns_target;
};
} __attribute__ ((__packed__));
#define ND_OPT_SOURCE_LINKADDR 1
#define ND_OPT_TARGET_LINKADDR 2
#define nd_ns_type nd_ns_hdr.icmp6_type
#define nd_ns_code nd_ns_hdr.icmp6_code
#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
#endif
#ifndef HAVE_STRUCT_ND_OPT_HDR
struct nd_opt_hdr {
uint8_t nd_opt_type;
uint8_t nd_opt_len;
};
} __attribute__ ((__packed__));
#endif
#endif /* __TINC_IPV6_H__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: list.c,v 1.3 2003/08/24 20:38:20 guus Exp $
$Id: list.c,v 1.1.2.17 2003/08/28 21:05:09 guus Exp $
*/
#include "system.h"
@ -44,7 +44,7 @@ void list_free(list_t *list)
list_node_t *list_alloc_node(void)
{
return (list_node_t *)xmalloc_and_zero(sizeof(list_node_t));
return xmalloc_and_zero(sizeof(list_node_t));
}
void list_free_node(list_t *list, list_node_t *node)

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: list.h,v 1.3 2003/08/24 20:38:20 guus Exp $
$Id: list.h,v 1.1.2.11 2003/07/31 11:17:39 guus Exp $
*/
#ifndef __TINC_LIST_H__

View file

@ -34,14 +34,14 @@
* 0 is returned if either there's no pidfile, it's empty
* or no pid can be read.
*/
int read_pid (char *pidfile)
pid_t read_pid (char *pidfile)
{
FILE *f;
int pid;
long pid;
if (!(f=fopen(pidfile,"r")))
return 0;
fscanf(f,"%d", &pid);
fscanf(f,"%ld", &pid);
fclose(f);
return pid;
}
@ -50,11 +50,11 @@ int read_pid (char *pidfile)
*
* Reads the pid using read_pid and looks up the pid in the process
* table (using /proc) to determine if the process already exists. If
* so 1 is returned, otherwise 0.
* so the pid is returned, otherwise 0.
*/
int check_pid (char *pidfile)
pid_t check_pid (char *pidfile)
{
int pid = read_pid(pidfile);
pid_t pid = read_pid(pidfile);
/* Amazing ! _I_ am already holding the pid file... */
if ((!pid) || (pid == getpid ()))
@ -68,7 +68,7 @@ int check_pid (char *pidfile)
/* But... errno is usually changed only on error.. */
errno = 0;
if (kill(pid, 0) && errno == ESRCH)
return(0);
return 0;
return pid;
}
@ -78,30 +78,26 @@ int check_pid (char *pidfile)
* Writes the pid to the specified file. If that fails 0 is
* returned, otherwise the pid.
*/
int write_pid (char *pidfile)
pid_t write_pid (char *pidfile)
{
FILE *f;
int fd;
int pid;
pid_t pid;
if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
|| ((f = fdopen(fd, "r+")) == NULL) ) {
fprintf(stderr, "Can't open or create %s.\n", pidfile);
return 0;
}
#ifdef HAVE_FLOCK
if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
fscanf(f, "%d", &pid);
fclose(f);
printf("Can't lock, lock is held by pid %d.\n", pid);
return 0;
}
#endif
pid = getpid();
if (!fprintf(f,"%d\n", pid)) {
printf("Can't write pid , %s.\n", strerror(errno));
if (!fprintf(f,"%ld\n", (long)pid)) {
close(fd);
return 0;
}
@ -109,7 +105,6 @@ int write_pid (char *pidfile)
#ifdef HAVE_FLOCK
if (flock(fd, LOCK_UN) == -1) {
printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno));
close(fd);
return 0;
}

View file

@ -26,7 +26,7 @@
* 0 is returned if either there's no pidfile, it's empty
* or no pid can be read.
*/
int read_pid (char *pidfile);
pid_t read_pid (char *pidfile);
/* check_pid
*
@ -34,14 +34,14 @@ int read_pid (char *pidfile);
* table (using /proc) to determine if the process already exists. If
* so 1 is returned, otherwise 0.
*/
int check_pid (char *pidfile);
pid_t check_pid (char *pidfile);
/* write_pid
*
* Writes the pid to the specified file. If that fails 0 is
* returned, otherwise the pid.
*/
int write_pid (char *pidfile);
pid_t write_pid (char *pidfile);
/* remove_pid
*

View file

@ -1 +0,0 @@
Makefile.am Makefile.in Makefile

4
m4/Makefile.am Normal file
View file

@ -0,0 +1,4 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-
EXTRA_DIST = README *.m4

View file

@ -1,7 +1,7 @@
dnl Check to find out whether function attributes are supported.
dnl If they are not, #define them to be nothing.
AC_DEFUN(tinc_ATTRIBUTE,
AC_DEFUN([tinc_ATTRIBUTE],
[
AC_CACHE_CHECK([for working $1 attribute], tinc_cv_attribute_$1,
[

View file

@ -1,28 +1,24 @@
dnl Check to find the lzo headers/libraries
AC_DEFUN(tinc_LZO,
AC_DEFUN([tinc_LZO],
[
tinc_ac_save_CPPFLAGS="$CPPFLAGS"
AC_ARG_WITH(lzo,
AC_HELP_STRING([--with-lzo=DIR], [lzo base directory, or:]),
AS_HELP_STRING([--with-lzo=DIR], [lzo base directory, or:]),
[lzo="$withval"
CFLAGS="$CFLAGS -I$withval/include"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LIBS="$LIBS -L$withval/lib"]
LDFLAGS="$LDFLAGS -L$withval/lib"]
)
AC_ARG_WITH(lzo-include,
AC_HELP_STRING([--with-lzo-include=DIR], [lzo headers directory]),
AS_HELP_STRING([--with-lzo-include=DIR], [lzo headers directory]),
[lzo_include="$withval"
CFLAGS="$CFLAGS -I$withval"
CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(lzo-lib,
AC_HELP_STRING([--with-lzo-lib=DIR], [lzo library directory]),
AS_HELP_STRING([--with-lzo-lib=DIR], [lzo library directory]),
[lzo_lib="$withval"
LIBS="$LIBS -L$withval"]
LDFLAGS="$LDFLAGS -L$withval"]
)
AC_CHECK_HEADERS(lzo1x.h,
@ -30,8 +26,6 @@ AC_DEFUN(tinc_LZO,
[AC_MSG_ERROR("lzo header files not found."); break]
)
CPPFLAGS="$tinc_ac_save_CPPFLAGS"
AC_CHECK_LIB(lzo, lzo1x_1_compress,
[LIBS="$LIBS -llzo"],
[AC_MSG_ERROR("lzo libraries not found.")]

View file

@ -10,7 +10,7 @@ dnl /* Define to rpl_malloc if the replacement function should be used. */
dnl #undef malloc
dnl
AC_DEFUN(jm_FUNC_MALLOC,
AC_DEFUN([jm_FUNC_MALLOC],
[
if test x = y; then
dnl This code is deliberately never run via ./configure.
@ -23,21 +23,19 @@ AC_DEFUN(jm_FUNC_MALLOC,
AC_DEFINE(HAVE_DONE_WORKING_MALLOC_CHECK, 1, [Needed for xmalloc.c])
AC_CACHE_CHECK([for working malloc], jm_cv_func_working_malloc,
[AC_TRY_RUN([
[AC_RUN_IFELSE([AC_LANG_SOURCE([
char *malloc ();
int
main ()
{
exit (malloc (0) ? 0 : 1);
}
],
jm_cv_func_working_malloc=yes,
jm_cv_func_working_malloc=no,
dnl When crosscompiling, assume malloc is broken.
jm_cv_func_working_malloc=no)
])],
[jm_cv_func_working_malloc=yes],
[jm_cv_func_working_malloc=no],
[When crosscompiling])
])
if test $jm_cv_func_working_malloc = no; then
dnl This was: LIBOBJS="$LIBOBJS malloc.$ac_objext"
AC_LIBOBJ([malloc])
AC_DEFINE(malloc, rpl_malloc, [Replacement malloc()])
fi

View file

@ -1,28 +1,24 @@
dnl Check to find the OpenSSL headers/libraries
AC_DEFUN(tinc_OPENSSL,
AC_DEFUN([tinc_OPENSSL],
[
tinc_ac_save_CPPFLAGS="$CPPFLAGS"
AC_ARG_WITH(openssl,
AC_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]),
AS_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]),
[openssl="$withval"
CFLAGS="$CFLAGS -I$withval/include"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LIBS="$LIBS -L$withval/lib"]
LDFLAGS="$LDFLAGS -L$withval/lib"]
)
AC_ARG_WITH(openssl-include,
AC_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]),
AS_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]),
[openssl_include="$withval"
CFLAGS="$CFLAGS -I$withval"
CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(openssl-lib,
AC_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]),
AS_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]),
[openssl_lib="$withval"
LIBS="$LIBS -L$withval"]
LDFLAGS="$LDFLAGS -L$withval"]
)
AC_CHECK_HEADERS(openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h,
@ -30,8 +26,6 @@ AC_DEFUN(tinc_OPENSSL,
[AC_MSG_ERROR([OpenSSL header files not found.]); break]
)
CPPFLAGS="$tinc_ac_save_CPPFLAGS"
case $host_os in
*mingw*)
AC_CHECK_LIB(crypto, SHA1_version,

View file

@ -10,7 +10,7 @@ dnl /* Define to rpl_realloc if the replacement function should be used. */
dnl #undef realloc
dnl
AC_DEFUN(jm_FUNC_REALLOC,
AC_DEFUN([jm_FUNC_REALLOC],
[
if test x = y; then
dnl This code is deliberately never run via ./configure.
@ -23,21 +23,19 @@ AC_DEFUN(jm_FUNC_REALLOC,
AC_DEFINE(HAVE_DONE_WORKING_REALLOC_CHECK, 1, [Needed for xmalloc.c])
AC_CACHE_CHECK([for working realloc], jm_cv_func_working_realloc,
[AC_TRY_RUN([
[AC_RUN_IFELSE([AC_LANG_SOURCE([
char *realloc ();
int
main ()
{
exit (realloc (0, 0) ? 0 : 1);
}
],
jm_cv_func_working_realloc=yes,
jm_cv_func_working_realloc=no,
dnl When crosscompiling, assume realloc is broken.
jm_cv_func_working_realloc=no)
])],
[jm_cv_func_working_realloc=yes],
[jm_cv_func_working_realloc=no],
[When crosscompiling])
])
if test $jm_cv_func_working_realloc = no; then
dnl This was: LIBOBJS="$LIBOBJS realloc.$ac_objext"
AC_LIBOBJ([realloc])
AC_DEFINE(realloc, rpl_realloc, [Replacement realloc()])
fi

View file

@ -1,22 +1,28 @@
dnl Check to find out whether the running kernel has support for TUN/TAP
AC_DEFUN(tinc_TUNTAP,
AC_DEFUN([tinc_TUNTAP],
[
AC_ARG_WITH(kernel,
AC_HELP_STRING([--with-kernel=DIR], [give the directory with kernel sources (default: /usr/src/linux)]),
AS_HELP_STRING([--with-kernel=DIR], [give the directory with kernel sources (default: /usr/src/linux)]),
kerneldir="$withval",
kerneldir="/usr/src/linux"
)
AC_CACHE_CHECK([for linux/if_tun.h], tinc_cv_linux_if_tun_h,
[
AC_TRY_COMPILE([#include "$kerneldir/include/linux/if_tun.h"],
[int a = IFF_TAP;],
if_tun_h="\"$kerneldir/include/linux/if_tun.h\"",
[AC_TRY_COMPILE([#include <linux/if_tun.h>],
[int a = IFF_TAP;],
if_tun_h="default",
if_tun_h="no"
AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([
#include "$kerneldir/include/linux/if_tun.h"
int a = IFF_TAP;
]),
[if_tun_h="\"$kerneldir/include/linux/if_tun.h\""],
[AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([
#include <linux/if_tun.h>
int a = IFF_TAP;
]),
[if_tun_h="default"],
[if_tun_h="no"]
)]
)

View file

@ -1,28 +1,24 @@
dnl Check to find the zlib headers/libraries
AC_DEFUN(tinc_ZLIB,
AC_DEFUN([tinc_ZLIB],
[
tinc_ac_save_CPPFLAGS="$CPPFLAGS"
AC_ARG_WITH(zlib,
AC_HELP_STRING([--with-zlib=DIR], [zlib base directory, or:]),
AS_HELP_STRING([--with-zlib=DIR], [zlib base directory, or:]),
[zlib="$withval"
CFLAGS="$CFLAGS -I$withval/include"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LIBS="$LIBS -L$withval/lib"]
LDFLAGS="$LDFLAGS -L$withval/lib"]
)
AC_ARG_WITH(zlib-include,
AC_HELP_STRING([--with-zlib-include=DIR], [zlib headers directory]),
AS_HELP_STRING([--with-zlib-include=DIR], [zlib headers directory]),
[zlib_include="$withval"
CFLAGS="$CFLAGS -I$withval"
CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(zlib-lib,
AC_HELP_STRING([--with-zlib-lib=DIR], [zlib library directory]),
AS_HELP_STRING([--with-zlib-lib=DIR], [zlib library directory]),
[zlib_lib="$withval"
LIBS="$LIBS -L$withval"]
LDFLAGS="$LDFLAGS -L$withval"]
)
AC_CHECK_HEADERS(zlib.h,
@ -30,8 +26,6 @@ AC_DEFUN(tinc_ZLIB,
[AC_MSG_ERROR("zlib header files not found."); break]
)
CPPFLAGS="$tinc_ac_save_CPPFLAGS"
AC_CHECK_LIB(z, compress2,
[LIBS="$LIBS -lz"],
[AC_MSG_ERROR("zlib libraries not found.")]

View file

@ -1 +0,0 @@
Makefile.in.in POTFILES Makefile.in Makefile cat-id-tbl.c *.gmo stamp-cat-id *.pot

View file

@ -20,6 +20,22 @@ XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
# their copyright.
COPYRIGHT_HOLDER = Ivo Timmermans and Guus Sliepen
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
# in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
# understood.
# - Strings which make invalid assumptions about notation of date, time or
# money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS = tinc-devel@nl.linux.org
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
EXTRA_LOCALE_CATEGORIES =

693
po/nl.po

File diff suppressed because it is too large Load diff

1223
po/old/es.po Normal file

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
*.o .libs tincd Makefile.in Makefile .deps

View file

@ -1,5 +1,5 @@
## Produce this file with automake to get Makefile.in
# $Id: Makefile.am,v 1.13 2003/08/24 20:38:23 guus Exp $
# $Id: Makefile.am,v 1.4.4.33 2003/08/02 15:13:08 guus Exp $
sbin_PROGRAMS = tincd

View file

@ -19,7 +19,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: conf.c,v 1.14 2003/08/24 20:38:24 guus Exp $
$Id: conf.c,v 1.9.4.77 2003/12/12 19:52:24 guus Exp $
*/
#include "system.h"
@ -73,7 +73,7 @@ config_t *new_config(void)
{
cp();
return (config_t *) xmalloc_and_zero(sizeof(config_t));
return xmalloc_and_zero(sizeof(config_t));
}
void free_config(config_t *cfg)
@ -131,7 +131,7 @@ config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg)
if(node) {
if(node->next) {
found = (config_t *) node->next->data;
found = node->next->data;
if(!strcasecmp(found->variable, cfg->variable))
return found;
@ -214,16 +214,14 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result)
bool get_config_subnet(const config_t *cfg, subnet_t ** result)
{
subnet_t *subnet;
subnet_t subnet = {0};
cp();
if(!cfg)
return false;
subnet = str2net(cfg->value);
if(!subnet) {
if(!str2net(&subnet, cfg->value)) {
logger(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"),
cfg->variable, cfg->file, cfg->line);
return false;
@ -231,17 +229,16 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result)
/* Teach newbies what subnets are... */
if(((subnet->type == SUBNET_IPV4)
&& !maskcheck(&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t)))
|| ((subnet->type == SUBNET_IPV6)
&& !maskcheck(&subnet->net.ipv6.address, subnet->net.ipv6.prefixlength, sizeof(ipv6_t)))) {
if(((subnet.type == SUBNET_IPV4)
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t)))
|| ((subnet.type == SUBNET_IPV6)
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t)))) {
logger(LOG_ERR, _ ("Network address and prefix length do not match for configuration variable %s in %s line %d"),
cfg->variable, cfg->file, cfg->line);
free(subnet);
return false;
}
*result = subnet;
*(*result = new_subnet()) = subnet;
return true;
}
@ -324,7 +321,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
int err = -2; /* Parse error */
FILE *fp;
char *buffer, *line;
char *variable, *value;
char *variable, *value, *eol;
int lineno = 0;
int len;
bool ignore = false;
@ -375,6 +372,10 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
variable = value = line;
eol = line + strlen(line);
while(strchr("\t ", *--eol))
*eol = '\0';
len = strcspn(value, "\t =");
value += len;
value += strspn(value, "\t ");
@ -384,6 +385,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
}
variable[len] = '\0';
if(!*value) {
logger(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"),
variable, lineno, fname);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: conf.h,v 1.11 2003/08/24 20:38:24 guus Exp $
$Id: conf.h,v 1.6.4.43 2003/08/08 22:11:54 guus Exp $
*/
#ifndef __TINC_CONF_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: connection.c,v 1.4 2003/08/24 20:38:24 guus Exp $
$Id: connection.c,v 1.1.2.44 2003/08/28 21:05:10 guus Exp $
*/
#include "system.h"
@ -64,7 +64,7 @@ connection_t *new_connection(void)
cp();
c = (connection_t *) xmalloc_and_zero(sizeof(connection_t));
c = xmalloc_and_zero(sizeof(connection_t));
if(!c)
return NULL;
@ -120,7 +120,7 @@ void dump_connections(void)
logger(LOG_DEBUG, _("Connections:"));
for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *) node->data;
c = node->data;
logger(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
c->name, c->hostname, c->options, c->socket, *(uint32_t *)&c->status);
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: connection.h,v 1.4 2003/08/24 20:38:24 guus Exp $
$Id: connection.h,v 1.1.2.40 2003/12/20 21:25:17 guus Exp $
*/
#ifndef __TINC_CONNECTION_H__
@ -30,6 +30,7 @@
#define OPTION_INDIRECT 0x0001
#define OPTION_TCPONLY 0x0002
#define OPTION_PMTU_DISCOVERY 0x0004
typedef struct connection_status_t {
int pinged:1; /* sent ping */
@ -40,8 +41,8 @@ typedef struct connection_status_t {
int timeout:1; /* 1 if gotten timeout */
int encryptout:1; /* 1 if we can encrypt outgoing traffic */
int decryptin:1; /* 1 if we have to decrypt incoming traffic */
int mst:1; /* 1 if this connection is part of a minimum spanning tree */
int unused:18;
int mst:1; /* 1 if this connection is part of a minimum spanning tree */
int unused:23;
} connection_status_t;
#include "edge.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.3 2003/08/27 13:47:47 guus Exp $
$Id: device.c,v 1.1.2.17 2003/10/08 11:37:20 guus Exp $
*/
#include "system.h"
@ -59,7 +59,7 @@ int sp[2];
bool setup_device(void)
{
HKEY key, key2;
int i;
int i, err;
char regpath[1024];
char adapterid[1024];

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.3 2003/08/27 13:47:47 guus Exp $
$Id: device.c,v 1.1.2.10 2003/07/22 20:55:21 guus Exp $
*/
#include "system.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.h,v 1.3 2003/08/24 20:38:24 guus Exp $
$Id: device.h,v 1.1.2.11 2003/07/22 20:55:19 guus Exp $
*/
#ifndef __TINC_DEVICE_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: edge.c,v 1.4 2003/08/24 20:38:24 guus Exp $
$Id: edge.c,v 1.1.2.27 2003/08/28 21:05:10 guus Exp $
*/
#include "system.h"
@ -88,7 +88,7 @@ edge_t *new_edge(void)
{
cp();
return (edge_t *) xmalloc_and_zero(sizeof(edge_t));
return xmalloc_and_zero(sizeof(edge_t));
}
void free_edge(edge_t *e)
@ -148,9 +148,9 @@ void dump_edges(void)
logger(LOG_DEBUG, _("Edges:"));
for(node = node_tree->head; node; node = node->next) {
n = (node_t *) node->data;
n = node->data;
for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
e = (edge_t *) node2->data;
e = node2->data;
address = sockaddr2hostname(&e->address);
logger(LOG_DEBUG, _(" %s to %s at %s options %lx weight %d"),
e->from->name, e->to->name, address, e->options, e->weight);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: edge.h,v 1.4 2003/08/24 20:38:24 guus Exp $
$Id: edge.h,v 1.1.2.17 2003/07/30 21:52:41 guus Exp $
*/
#ifndef __TINC_EDGE_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: event.c,v 1.4 2003/08/24 20:38:24 guus Exp $
$Id: event.c,v 1.1.4.11 2003/08/28 21:05:10 guus Exp $
*/
#include "system.h"
@ -61,7 +61,7 @@ event_t *new_event(void)
{
cp();
return (event_t *) xmalloc_and_zero(sizeof(event_t));
return xmalloc_and_zero(sizeof(event_t));
}
void free_event(event_t *event)
@ -93,7 +93,7 @@ event_t *get_expired_event(void)
cp();
if(event_tree->head) {
event = (event_t *) event_tree->head->data;
event = event_tree->head->data;
if(event->time < now) {
avl_delete(event_tree, event);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: event.h,v 1.4 2003/08/24 20:38:24 guus Exp $
$Id: event.h,v 1.1.4.8 2003/07/30 21:52:41 guus Exp $
*/
#ifndef __TINC_EVENT_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.4 2003/08/27 13:47:48 guus Exp $
$Id: device.c,v 1.1.2.13 2003/07/22 20:55:21 guus Exp $
*/
#include "system.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: graph.c,v 1.6 2003/08/24 20:38:24 guus Exp $
$Id: graph.c,v 1.1.2.34 2003/12/22 11:04:16 guus Exp $
*/
/* We need to generate two trees from the graph:
@ -76,7 +76,7 @@ void mst_kruskal(void)
/* Clear MST status on connections */
for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *) node->data;
c = node->data;
c->status.mst = false;
}
@ -90,7 +90,7 @@ void mst_kruskal(void)
/* Clear visited status on nodes */
for(node = node_tree->head; node; node = node->next) {
n = (node_t *) node->data;
n = node->data;
n->status.visited = false;
nodes++;
}
@ -103,7 +103,7 @@ void mst_kruskal(void)
for(skipped = false, node = edge_weight_tree->head; node; node = next) {
next = node->next;
e = (edge_t *) node->data;
e = node->data;
if(!e->reverse || e->from->status.visited == e->to->status.visited) {
skipped = true;
@ -158,7 +158,7 @@ void sssp_bfs(void)
/* Clear visited status on nodes */
for(node = node_tree->head; node; node = node->next) {
n = (node_t *) node->data;
n = node->data;
n->status.visited = false;
n->status.indirect = true;
}
@ -178,22 +178,23 @@ void sssp_bfs(void)
while(todo_tree->head) {
for(from = todo_tree->head; from; from = next) { /* "from" is the node from which we start */
next = from->next;
n = (node_t *) from->data;
n = from->data;
for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */
e = (edge_t *) to->data;
e = to->data;
if(!e->reverse)
continue;
/* Situation:
/
/
------(n)-----(e->to)
\
\
/
/
----->(n)---e-->(e->to)
\
\
Where e is an edge, (n) and (e->to) are nodes.
n->address is set to the e->address of the edge left of n to n.
We are currently examining the edge e right of n from n:
@ -228,6 +229,14 @@ void sssp_bfs(void)
e->to->hostname = sockaddr2hostname(&e->to->address);
avl_insert_node(node_udp_tree, node);
if(e->to->options & OPTION_PMTU_DISCOVERY) {
e->to->mtuprobes = 0;
e->to->minmtu = 0;
e->to->maxmtu = MTU;
if(e->to->status.validkey)
send_mtu_probe(e->to);
}
}
node = avl_alloc_node();
@ -245,7 +254,7 @@ void sssp_bfs(void)
for(node = node_tree->head; node; node = next) {
next = node->next;
n = (node_t *) node->data;
n = node->data;
if(n->status.visited != n->status.reachable) {
n->status.reachable = !n->status.reachable;
@ -261,6 +270,10 @@ void sssp_bfs(void)
n->status.validkey = false;
n->status.waitingforkey = false;
n->maxmtu = MTU;
n->minmtu = 0;
n->mtuprobes = 0;
asprintf(&envp[0], "NETNAME=%s", netname ? : "");
asprintf(&envp[1], "DEVICE=%s", device ? : "");
asprintf(&envp[2], "INTERFACE=%s", iface ? : "");

View file

@ -17,9 +17,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: graph.h,v 1.4 2003/08/24 20:38:24 guus Exp $
$Id: graph.h,v 1.1.2.6 2003/09/03 16:20:33 guus Exp $
*/
#ifndef __TINC_GRAPH_H__
#define __TINC_GRAPH_H__
extern void graph(void);
extern void mst_kruskal(void);
extern void sssp_bfs(void);
#endif /* __TINC_GRAPH_H__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.4 2003/08/27 13:47:48 guus Exp $
$Id: device.c,v 1.1.2.21 2003/08/28 21:05:11 guus Exp $
*/
#include "system.h"
@ -94,10 +94,10 @@ bool setup_device(void)
if(iface)
strncpy(ifr.ifr_name, iface, IFNAMSIZ);
if(!ioctl(device_fd, TUNSETIFF, (void *) &ifr)) {
if(!ioctl(device_fd, TUNSETIFF, &ifr)) {
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
iface = ifrname;
} else if(!ioctl(device_fd, (('T' << 8) | 202), (void *) &ifr)) {
} else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) {
logger(LOG_WARNING, _("Old ioctl() request was needed for %s"), device);
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
iface = ifrname;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: logger.c,v 1.2 2003/08/24 20:38:24 guus Exp $
$Id: logger.c,v 1.1.2.12 2003/10/06 16:13:07 guus Exp $
*/
#include "system.h"
@ -78,7 +78,7 @@ void logger(int priority, const char *format, ...) {
fflush(stderr);
break;
case LOGMODE_FILE:
fprintf(logfile, "%ld %s[%d]: ", time(NULL), logident, logpid);
fprintf(logfile, "%ld %s[%ld]: ", time(NULL), logident, (long)logpid);
vfprintf(logfile, format, ap);
fprintf(logfile, "\n");
fflush(logfile);

View file

@ -17,11 +17,12 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: meta.c,v 1.5 2003/08/24 20:38:24 guus Exp $
$Id: meta.c,v 1.1.2.50 2003/11/17 15:30:17 guus Exp $
*/
#include "system.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include "avl_tree.h"
@ -46,7 +47,12 @@ bool send_meta(connection_t *c, const char *buffer, int length)
c->name, c->hostname);
if(c->status.encryptout) {
EVP_EncryptUpdate(c->outctx, outbuf, &outlen, buffer, length);
result = EVP_EncryptUpdate(c->outctx, outbuf, &outlen, buffer, length);
if(!result || outlen != length) {
logger(LOG_ERR, _("Error while encrypting metadata to %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
bufp = outbuf;
length = outlen;
} else
@ -80,7 +86,7 @@ void broadcast_meta(connection_t *from, const char *buffer, int length)
cp();
for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *) node->data;
c = node->data;
if(c != from && c->status.active)
send_meta(c, buffer, length);
@ -89,8 +95,8 @@ void broadcast_meta(connection_t *from, const char *buffer, int length)
bool receive_meta(connection_t *c)
{
int oldlen, i;
int lenin, reqlen;
int oldlen, i, result;
int lenin, lenout, reqlen;
bool decrypted = false;
char inbuf[MAXBUFSIZE];
@ -123,11 +129,16 @@ bool receive_meta(connection_t *c)
oldlen = c->buflen;
c->buflen += lenin;
while(lenin) {
while(lenin > 0) {
/* Decrypt */
if(c->status.decryptin && !decrypted) {
EVP_DecryptUpdate(c->inctx, inbuf, &lenin, c->buffer + oldlen, lenin);
result = EVP_DecryptUpdate(c->inctx, inbuf, &lenout, c->buffer + oldlen, lenin);
if(!result || lenout != lenin) {
logger(LOG_ERR, _("Error while decrypting metadata from %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
memcpy(c->buffer + oldlen, inbuf, lenin);
decrypted = true;
}
@ -139,7 +150,7 @@ bool receive_meta(connection_t *c)
receive_tcppacket(c, c->buffer, c->tcplen);
c->buflen -= c->tcplen;
lenin -= c->tcplen;
lenin -= c->tcplen - oldlen;
memmove(c->buffer, c->buffer + c->tcplen, c->buflen);
oldlen = 0;
c->tcplen = 0;
@ -167,7 +178,7 @@ bool receive_meta(connection_t *c)
return false;
c->buflen -= reqlen;
lenin -= reqlen;
lenin -= reqlen - oldlen;
memmove(c->buffer, c->buffer + reqlen, c->buflen);
oldlen = 0;
continue;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: meta.h,v 1.3 2003/08/24 20:38:24 guus Exp $
$Id: meta.h,v 1.1.2.11 2003/08/12 14:48:13 guus Exp $
*/
#ifndef __TINC_META_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.3 2003/08/27 13:47:49 guus Exp $
$Id: device.c,v 1.1.2.14 2003/10/08 11:37:53 guus Exp $
*/
#include "system.h"
@ -40,9 +40,15 @@
#define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD | 8000, request, method, FILE_ANY_ACCESS)
#define TAP_IOCTL_GET_LASTMAC TAP_CONTROL_CODE(0, METHOD_BUFFERED)
#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE(1, METHOD_BUFFERED)
#define TAP_IOCTL_SET_STATISTICS TAP_CONTROL_CODE(2, METHOD_BUFFERED)
#define TAP_IOCTL_GET_LASTMAC TAP_CONTROL_CODE(0, METHOD_BUFFERED)
#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE(1, METHOD_BUFFERED)
#define TAP_IOCTL_SET_STATISTICS TAP_CONTROL_CODE(2, METHOD_BUFFERED)
#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE(3, METHOD_BUFFERED)
#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE(4, METHOD_BUFFERED)
#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE(5, METHOD_BUFFERED)
#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE(6, METHOD_BUFFERED)
#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE(7, METHOD_BUFFERED)
int device_fd = 0;
HANDLE device_handle = INVALID_HANDLE_VALUE;
@ -131,6 +137,7 @@ bool setup_device(void)
char adaptername[1024];
char tapname[1024];
long len;
unsigned long status;
bool found = false;
@ -283,6 +290,11 @@ bool setup_device(void)
closesocket(sock);
/* Set media status for newer TAP-Win32 devices */
status = true;
DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL);
device_info = _("Windows tap device");
logger(LOG_INFO, _("%s (%s) is a %s"), device, iface, device_info);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net.c,v 1.40 2003/08/24 20:38:24 guus Exp $
$Id: net.c,v 1.35.4.203 2003/12/20 19:47:52 guus Exp $
*/
#include "system.h"
@ -63,7 +63,7 @@ static void purge(void)
for(nnode = node_tree->head; nnode; nnode = nnext) {
nnext = nnode->next;
n = (node_t *) nnode->data;
n = nnode->data;
if(!n->status.reachable) {
ifdebug(SCARY_THINGS) logger(LOG_DEBUG, _("Purging node %s (%s)"), n->name,
@ -71,15 +71,17 @@ static void purge(void)
for(snode = n->subnet_tree->head; snode; snode = snext) {
snext = snode->next;
s = (subnet_t *) snode->data;
send_del_subnet(broadcast, s);
s = snode->data;
if(!tunnelserver)
send_del_subnet(broadcast, s);
subnet_del(n, s);
}
for(enode = n->edge_tree->head; enode; enode = enext) {
enext = enode->next;
e = (edge_t *) enode->data;
send_del_edge(broadcast, e);
e = enode->data;
if(!tunnelserver)
send_del_edge(broadcast, e);
edge_del(e);
}
}
@ -89,12 +91,12 @@ static void purge(void)
for(nnode = node_tree->head; nnode; nnode = nnext) {
nnext = nnode->next;
n = (node_t *) nnode->data;
n = nnode->data;
if(!n->status.reachable) {
for(enode = edge_weight_tree->head; enode; enode = enext) {
enext = enode->next;
e = (edge_t *) enode->data;
e = enode->data;
if(e->to == n)
break;
@ -122,7 +124,7 @@ static int build_fdset(fd_set * fs)
for(node = connection_tree->head; node; node = next) {
next = node->next;
c = (connection_t *) node->data;
c = node->data;
if(c->status.remove) {
connection_del(c);
@ -178,7 +180,7 @@ void terminate_connection(connection_t *c, bool report)
closesocket(c->socket);
if(c->edge) {
if(report)
if(report && !tunnelserver)
send_del_edge(broadcast, c->edge);
edge_del(c->edge);
@ -186,6 +188,18 @@ void terminate_connection(connection_t *c, bool report)
/* Run MST and SSSP algorithms */
graph();
/* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
if(report && !c->node->status.reachable) {
edge_t *e;
e = lookup_edge(c->node, myself);
if(e) {
if(!tunnelserver)
send_del_edge(broadcast, e);
edge_del(e);
}
}
}
/* Check if this was our outgoing connection */
@ -213,7 +227,7 @@ static void check_dead_connections(void)
for(node = connection_tree->head; node; node = next) {
next = node->next;
c = (connection_t *) node->data;
c = node->data;
if(c->last_ping_time + pingtimeout < now) {
if(c->status.active) {
@ -256,11 +270,11 @@ static void check_network_activity(fd_set * f)
if(FD_ISSET(device_fd, f)) {
if(read_packet(&packet))
route_outgoing(&packet);
route(myself, &packet);
}
for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *) node->data;
c = node->data;
if(c->status.remove)
continue;
@ -320,7 +334,8 @@ int main_loop(void)
while(running) {
now = time(NULL);
tv.tv_sec = 1 + (rand() & 7); /* Approx. 5 seconds, randomized to prevent global synchronisation effects */
// tv.tv_sec = 1 + (rand() & 7); /* Approx. 5 seconds, randomized to prevent global synchronisation effects */
tv.tv_sec = 1;
tv.tv_usec = 0;
maxfd = build_fdset(&fset);
@ -353,7 +368,7 @@ int main_loop(void)
last_ping_check = now;
if(routing_mode == RMODE_SWITCH)
age_mac();
age_subnets();
age_past_requests();
@ -380,7 +395,7 @@ int main_loop(void)
logger(LOG_INFO, _("Flushing event queue"));
while(event_tree->head) {
event = (event_t *) event_tree->head->data;
event = event_tree->head->data;
event->handler(event->data);
event_del(event);
}
@ -408,7 +423,7 @@ int main_loop(void)
/* Close connections to hosts that have a changed or deleted host config file */
for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *) node->data;
c = node->data;
if(c->outgoing) {
free(c->outgoing->name);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net.h,v 1.13 2003/08/24 20:38:24 guus Exp $
$Id: net.h,v 1.9.4.73 2003/12/20 19:47:52 guus Exp $
*/
#ifndef __TINC_NET_H__
@ -54,7 +54,7 @@ typedef struct ipv6_t {
typedef short length_t;
#define AF_UNKNOWN 0xFFFF
#define AF_UNKNOWN 255
struct sockaddr_unknown {
uint16_t family;
@ -150,6 +150,7 @@ extern int main_loop(void);
extern void terminate_connection(struct connection_t *, bool);
extern void flush_queue(struct node_t *);
extern bool read_rsa_public_key(struct connection_t *);
extern void send_mtu_probe(struct node_t *);
#ifndef HAVE_MINGW
#define closesocket(s) close(s)

View file

@ -17,12 +17,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net_packet.c,v 1.5 2003/08/24 20:38:24 guus Exp $
$Id: net_packet.c,v 1.1.2.49 2003/12/27 16:32:52 guus Exp $
*/
#include "system.h"
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/hmac.h>
@ -34,6 +35,7 @@
#include "conf.h"
#include "connection.h"
#include "device.h"
#include "ethernet.h"
#include "event.h"
#include "graph.h"
#include "list.h"
@ -46,14 +48,73 @@
#include "utils.h"
#include "xalloc.h"
#ifdef WSAEMSGSIZE
#define EMSGSIZE WSAEMSGSIZE
#endif
int keylifetime = 0;
int keyexpires = 0;
EVP_CIPHER_CTX packet_ctx;
static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
static void send_udppacket(node_t *, vpn_packet_t *);
#define MAX_SEQNO 1073741824
void send_mtu_probe(node_t *n)
{
vpn_packet_t packet;
int len, i;
cp();
n->mtuprobes++;
n->mtuevent = NULL;
if(n->mtuprobes >= 10 && !n->minmtu) {
ifdebug(TRAFFIC) logger(LOG_INFO, _("No response to MTU probes from %s (%s)"), n->name, n->hostname);
return;
}
for(i = 0; i < 3; i++) {
if(n->mtuprobes >= 30 || n->minmtu >= n->maxmtu) {
n->mtu = n->minmtu;
ifdebug(TRAFFIC) logger(LOG_INFO, _("Fixing MTU of %s (%s) to %d after %d probes"), n->name, n->hostname, n->mtu, n->mtuprobes);
return;
}
len = n->minmtu + 1 + random() % (n->maxmtu - n->minmtu);
if(len < 64)
len = 64;
memset(packet.data, 0, 14);
RAND_pseudo_bytes(packet.data + 14, len - 14);
packet.len = len;
ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending MTU probe length %d to %s (%s)"), len, n->name, n->hostname);
send_udppacket(n, &packet);
}
n->mtuevent = xmalloc(sizeof(*n->mtuevent));
n->mtuevent->handler = (event_handler_t)send_mtu_probe;
n->mtuevent->data = n;
n->mtuevent->time = now + 1;
event_add(n->mtuevent);
}
void mtu_probe_h(node_t *n, vpn_packet_t *packet) {
ifdebug(TRAFFIC) logger(LOG_INFO, _("Got MTU probe length %d from %s (%s)"), packet->len, n->name, n->hostname);
if(!packet->data[0]) {
packet->data[0] = 1;
send_packet(n, packet);
} else {
if(n->minmtu < packet->len)
n->minmtu = packet->len;
}
}
static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level)
{
if(level == 10) {
@ -103,7 +164,7 @@ static void receive_packet(node_t *n, vpn_packet_t *packet)
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"),
packet->len, n->name, n->hostname);
route_incoming(n, packet);
route(n, packet);
}
static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
@ -118,6 +179,14 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
cp();
/* Check packet length */
if(inpkt->len < sizeof(inpkt->seqno) + myself->maclength) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got too short packet from %s (%s)"),
n->name, n->hostname);
return;
}
/* Check the message authentication code */
if(myself->digest && myself->maclength) {
@ -137,12 +206,14 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
if(myself->cipher) {
outpkt = pkt[nextpkt++];
// EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key,
// myself->key + myself->cipher->key_len);
EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL);
EVP_DecryptUpdate(&packet_ctx, (char *) &outpkt->seqno, &outlen,
(char *) &inpkt->seqno, inpkt->len);
EVP_DecryptFinal_ex(&packet_ctx, (char *) &outpkt->seqno + outlen, &outpad);
if(!EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL)
|| !EVP_DecryptUpdate(&packet_ctx, (char *) &outpkt->seqno, &outlen,
(char *) &inpkt->seqno, inpkt->len)
|| !EVP_DecryptFinal_ex(&packet_ctx, (char *) &outpkt->seqno + outlen, &outpad)) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Error decrypting packet from %s (%s): %s"),
n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
return;
}
outpkt->len = outlen + outpad;
inpkt = outpkt;
@ -181,15 +252,21 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
outpkt = pkt[nextpkt++];
if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, myself->compression)) < 0) {
logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
n->name, n->hostname);
ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
n->name, n->hostname);
return;
}
inpkt = outpkt;
}
receive_packet(n, inpkt);
if(n->connection)
n->connection->last_ping_time = now;
if(!inpkt->data[12] && !inpkt->data[13])
mtu_probe_h(n, inpkt);
else
receive_packet(n, inpkt);
}
void receive_tcppacket(connection_t *c, char *buffer, int len)
@ -228,8 +305,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
/* Since packet is on the stack of handle_tap_input(), we have to make a copy of it first. */
copy = xmalloc(sizeof(vpn_packet_t));
memcpy(copy, inpkt, sizeof(vpn_packet_t));
*(copy = xmalloc(sizeof(*copy))) = *inpkt;
list_insert_tail(n->queue, copy);
@ -253,7 +329,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
outpkt = pkt[nextpkt++];
if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->compression)) < 0) {
logger(LOG_ERR, _("Error while compressing packet to %s (%s)"),
ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while compressing packet to %s (%s)"),
n->name, n->hostname);
return;
}
@ -271,11 +347,14 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
if(n->cipher) {
outpkt = pkt[nextpkt++];
// EVP_EncryptInit_ex(&packet_ctx, n->cipher, NULL, n->key, n->key + n->cipher->key_len);
EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL);
EVP_EncryptUpdate(&n->packet_ctx, (char *) &outpkt->seqno, &outlen,
(char *) &inpkt->seqno, inpkt->len);
EVP_EncryptFinal_ex(&n->packet_ctx, (char *) &outpkt->seqno + outlen, &outpad);
if(!EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL)
|| !EVP_EncryptUpdate(&n->packet_ctx, (char *) &outpkt->seqno, &outlen,
(char *) &inpkt->seqno, inpkt->len)
|| !EVP_EncryptFinal_ex(&n->packet_ctx, (char *) &outpkt->seqno + outlen, &outpad)) {
ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while encrypting packet to %s (%s): %s"),
n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
goto end;
}
outpkt->len = outlen + outpad;
inpkt = outpkt;
@ -311,10 +390,16 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
#endif
if((sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa))) < 0) {
logger(LOG_ERR, _("Error sending packet to %s (%s): %s"), n->name, n->hostname, strerror(errno));
return;
if(errno == EMSGSIZE) {
if(n->maxmtu >= origlen)
n->maxmtu = origlen - 1;
if(n->mtu >= origlen)
n->mtu = origlen - 1;
} else
logger(LOG_ERR, _("Error sending packet to %s (%s): %s"), n->name, n->hostname, strerror(errno));
}
end:
inpkt->len = origlen;
}
@ -327,14 +412,16 @@ void send_packet(const node_t *n, vpn_packet_t *packet)
cp();
ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
packet->len, n->name, n->hostname);
if(n == myself) {
ifdebug(TRAFFIC) logger(LOG_NOTICE, _("Packet is looping back to us!"));
if(overwrite_mac)
memcpy(packet->data, mymac.x, ETH_ALEN);
write_packet(packet);
return;
}
ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
packet->len, n->name, n->hostname);
if(!n->status.reachable) {
ifdebug(TRAFFIC) logger(LOG_INFO, _("Node %s (%s) is not reachable"),
n->name, n->hostname);
@ -367,7 +454,7 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet)
packet->len, from->name, from->hostname);
for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *) node->data;
c = node->data;
if(c->status.active && c->status.mst && c != from->nexthop->connection)
send_packet(c->node, packet);
@ -384,7 +471,7 @@ void flush_queue(node_t *n)
for(node = n->queue->head; node; node = next) {
next = node->next;
send_udppacket(n, (vpn_packet_t *) node->data);
send_udppacket(n, node->data);
list_delete_node(n->queue, node);
}
}
@ -401,7 +488,7 @@ void handle_incoming_vpn_data(int sock)
pkt.len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
if(pkt.len <= 0) {
if(pkt.len < 0) {
logger(LOG_ERR, _("Receiving packet failed: %s"), strerror(errno));
return;
}
@ -418,8 +505,5 @@ void handle_incoming_vpn_data(int sock)
return;
}
if(n->connection)
n->connection->last_ping_time = now;
receive_udppacket(n, &pkt);
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net_setup.c,v 1.5 2003/08/24 20:38:24 guus Exp $
$Id: net_setup.c,v 1.1.2.50 2003/12/20 21:25:17 guus Exp $
*/
#include "system.h"
@ -25,6 +25,8 @@
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include "avl_tree.h"
#include "conf.h"
@ -148,17 +150,23 @@ bool read_rsa_public_key(connection_t *c)
bool read_rsa_private_key(void)
{
FILE *fp;
char *fname, *key;
char *fname, *key, *pubkey;
struct stat s;
cp();
if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
if(!get_config_string(lookup_config(myself->connection->config_tree, "PublicKey"), &pubkey)) {
logger(LOG_ERR, _("PrivateKey used but no PublicKey found!"));
return false;
}
myself->connection->rsa_key = RSA_new();
// RSA_blinding_on(myself->connection->rsa_key, NULL);
BN_hex2bn(&myself->connection->rsa_key->d, key);
BN_hex2bn(&myself->connection->rsa_key->n, pubkey);
BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
free(key);
free(pubkey);
return true;
}
@ -240,19 +248,15 @@ bool setup_myself(void)
myself->name = name;
myself->connection->name = xstrdup(name);
if(!read_rsa_private_key())
return false;
if(!read_connection_config(myself->connection)) {
logger(LOG_ERR, _("Cannot open host configuration file for myself!"));
return false;
}
if(!read_rsa_public_key(myself->connection))
if(!read_rsa_private_key())
return false;
if(!get_config_string
(lookup_config(myself->connection->config_tree, "Port"), &myport))
if(!get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport))
asprintf(&myport, "655");
/* Read in all the subnets specified in the host configuration file */
@ -270,25 +274,26 @@ bool setup_myself(void)
/* Check some options */
if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice))
if(choice)
myself->options |= OPTION_INDIRECT;
if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice)
myself->options |= OPTION_INDIRECT;
if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice))
if(choice)
myself->options |= OPTION_TCPONLY;
if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice)
myself->options |= OPTION_TCPONLY;
if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice))
if(choice)
myself->options |= OPTION_INDIRECT;
if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice) && choice)
myself->options |= OPTION_INDIRECT;
if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice))
if(choice)
myself->options |= OPTION_TCPONLY;
if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice) && choice)
myself->options |= OPTION_TCPONLY;
if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice)
myself->options |= OPTION_PMTU_DISCOVERY;
if(myself->options & OPTION_TCPONLY)
myself->options |= OPTION_INDIRECT;
get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
if(!strcasecmp(mode, "router"))
routing_mode = RMODE_ROUTER;
@ -314,7 +319,7 @@ bool setup_myself(void)
if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
macexpire = 600;
if(get_config_int(lookup_config(myself->connection->config_tree, "MaxTimeout"), &maxtimeout)) {
if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) {
if(maxtimeout <= 0) {
logger(LOG_ERR, _("Bogus maximum timeout!"));
return false;
@ -362,7 +367,7 @@ bool setup_myself(void)
myself->connection->outcipher = EVP_bf_ofb();
myself->key = (char *) xmalloc(myself->keylength);
myself->key = xmalloc(myself->keylength);
RAND_pseudo_bytes(myself->key, myself->keylength);
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
@ -372,7 +377,12 @@ bool setup_myself(void)
if(myself->cipher) {
EVP_CIPHER_CTX_init(&packet_ctx);
EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key, myself->key + myself->cipher->key_len);
if(!EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key, myself->key + myself->cipher->key_len)) {
logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
myself->name, myself->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
}
/* Check if we want to use message authentication codes... */
@ -549,7 +559,7 @@ void close_network_connections(void)
for(node = connection_tree->head; node; node = next) {
next = node->next;
c = (connection_t *) node->data;
c = node->data;
if(c->outgoing)
free(c->outgoing->name), free(c->outgoing), c->outgoing = NULL;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net_socket.c,v 1.4 2003/08/24 20:38:25 guus Exp $
$Id: net_socket.c,v 1.1.2.38 2003/12/22 11:04:16 guus Exp $
*/
#include "system.h"
@ -49,31 +49,30 @@ int listen_sockets;
int setup_listen_socket(const sockaddr_t *sa)
{
int nfd, flags;
int nfd;
char *addrstr;
int option;
char *iface;
#ifdef SO_BINDTODEVICE
struct ifreq ifr;
#endif
cp();
nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if(nfd < 0) {
logger(LOG_ERR, _("Creating metasocket failed: %s"), strerror(errno));
ifdebug(STATUS) logger(LOG_ERR, _("Creating metasocket failed: %s"), strerror(errno));
return -1;
}
#ifdef O_NONBLOCK
flags = fcntl(nfd, F_GETFL);
{
int flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
closesocket(nfd);
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
strerror(errno));
return -1;
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
closesocket(nfd);
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
strerror(errno));
return -1;
}
}
#endif
@ -94,6 +93,8 @@ int setup_listen_socket(const sockaddr_t *sa)
if(get_config_string
(lookup_config(config_tree, "BindToInterface"), &iface)) {
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
@ -129,13 +130,9 @@ int setup_listen_socket(const sockaddr_t *sa)
int setup_vpn_in_socket(const sockaddr_t *sa)
{
int nfd, flags;
int nfd;
char *addrstr;
int option;
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
char *iface;
struct ifreq ifr;
#endif
cp();
@ -147,29 +144,58 @@ int setup_vpn_in_socket(const sockaddr_t *sa)
}
#ifdef O_NONBLOCK
flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
closesocket(nfd);
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
strerror(errno));
return -1;
{
int flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
closesocket(nfd);
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
strerror(errno));
return -1;
}
}
#endif
option = 1;
setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
if(get_config_string
(lookup_config(config_tree, "BindToInterface"), &iface)) {
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
{
bool choice;
if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
closesocket(nfd);
logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
strerror(errno));
return -1;
if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
option = IP_PMTUDISC_DO;
setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option));
}
}
#endif
#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
{
bool choice;
if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
option = IPV6_PMTUDISC_DO;
setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option));
}
}
#endif
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
{
char *iface;
struct ifreq ifr;
if(get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) {
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
closesocket(nfd);
logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
strerror(errno));
return -1;
}
}
}
#endif
@ -255,8 +281,7 @@ begin:
goto begin;
}
memcpy(&c->address, c->outgoing->aip->ai_addr,
c->outgoing->aip->ai_addrlen);
memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen);
c->outgoing->aip = c->outgoing->aip->ai_next;
if(c->hostname)

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.4 2003/08/27 13:47:49 guus Exp $
$Id: device.c,v 1.1.2.13 2003/07/31 11:31:50 guus Exp $
*/
#include "system.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netutl.c,v 1.17 2003/08/24 20:38:25 guus Exp $
$Id: netutl.c,v 1.12.4.54 2003/08/22 15:03:59 guus Exp $
*/
#include "system.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netutl.h,v 1.6 2003/08/24 20:38:25 guus Exp $
$Id: netutl.h,v 1.2.4.19 2003/08/22 11:18:42 guus Exp $
*/
#ifndef __TINC_NETUTL_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: node.c,v 1.4 2003/08/24 20:38:25 guus Exp $
$Id: node.c,v 1.1.2.31 2003/12/22 11:04:16 guus Exp $
*/
#include "system.h"
@ -72,7 +72,7 @@ void exit_nodes(void)
node_t *new_node(void)
{
node_t *n = (node_t *) xmalloc_and_zero(sizeof(*n));
node_t *n = xmalloc_and_zero(sizeof(*n));
cp();
@ -80,6 +80,8 @@ node_t *new_node(void)
n->edge_tree = new_edge_tree();
n->queue = list_alloc((list_action_t) free);
EVP_CIPHER_CTX_init(&n->packet_ctx);
n->mtu = MTU;
n->maxmtu = MTU;
return n;
}
@ -109,6 +111,9 @@ void free_node(node_t *n)
sockaddrfree(&n->address);
EVP_CIPHER_CTX_cleanup(&n->packet_ctx);
if(n->mtuevent)
event_del(n->mtuevent);
free(n);
}
@ -131,13 +136,13 @@ void node_del(node_t *n)
for(node = n->subnet_tree->head; node; node = next) {
next = node->next;
s = (subnet_t *) node->data;
s = node->data;
subnet_del(n, s);
}
for(node = n->edge_tree->head; node; node = next) {
next = node->next;
e = (edge_t *) node->data;
e = node->data;
edge_del(e);
}
@ -178,12 +183,12 @@ void dump_nodes(void)
logger(LOG_DEBUG, _("Nodes:"));
for(node = node_tree->head; node; node = node->next) {
n = (node_t *) node->data;
logger(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
n = node->data;
logger(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s pmtu %d (min %d max %d)"),
n->name, n->hostname, n->cipher ? n->cipher->nid : 0,
n->digest ? n->digest->type : 0, n->maclength, n->compression,
n->options, *(uint32_t *)&n->status, n->nexthop ? n->nexthop->name : "-",
n->via ? n->via->name : "-");
n->via ? n->via->name : "-", n->mtu, n->minmtu, n->maxmtu);
}
logger(LOG_DEBUG, _("End of nodes."));

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: node.h,v 1.4 2003/08/24 20:38:25 guus Exp $
$Id: node.h,v 1.1.2.31 2003/12/22 11:04:16 guus Exp $
*/
#ifndef __TINC_NODE_H__
@ -25,13 +25,14 @@
#include "avl_tree.h"
#include "connection.h"
#include "event.h"
#include "list.h"
#include "subnet.h"
typedef struct node_status_t {
int active:1; /* 1 if active.. */
int validkey:1; /* 1 if we currently have a valid key for him */
int waitingforkey:1; /* 1 if we already sent out a request */
int waitingforkey:1; /* 1 if we already sent out a request */
int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
int reachable:1; /* 1 if this node is reachable in the graph */
int indirect:1; /* 1 if this node is not directly reachable by us */
@ -39,7 +40,7 @@ typedef struct node_status_t {
} node_status_t;
typedef struct node_t {
char *name; /* name of this node */
char *name; /* name of this node */
long int options; /* options turned on for this node */
sockaddr_t address; /* his real (internet) ip to send UDP packets to */
@ -47,30 +48,36 @@ typedef struct node_t {
node_status_t status;
const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
char *key; /* Cipher key and iv */
const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
char *key; /* Cipher key and iv */
int keylength; /* Cipher key and iv length */
EVP_CIPHER_CTX packet_ctx; /* Cipher context */
EVP_CIPHER_CTX packet_ctx; /* Cipher context */
const EVP_MD *digest; /* Digest type for MAC */
const EVP_MD *digest; /* Digest type for MAC */
int maclength; /* Length of MAC */
int compression; /* Compressionlevel, 0 = no compression */
list_t *queue; /* Queue for packets awaiting to be encrypted */
struct node_t *nexthop; /* nearest node from us to him */
struct node_t *nexthop; /* nearest node from us to him */
struct node_t *via; /* next hop for UDP packets */
avl_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */
avl_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */
avl_tree_t *edge_tree; /* Edges with this node as one of the endpoints */
avl_tree_t *edge_tree; /* Edges with this node as one of the endpoints */
struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
uint32_t sent_seqno; /* Sequence number last sent to this node */
uint32_t received_seqno; /* Sequence number last received from this node */
unsigned char late[16]; /* Bitfield marking late packets */
uint32_t sent_seqno; /* Sequence number last sent to this node */
uint32_t received_seqno; /* Sequence number last received from this node */
unsigned char late[16]; /* Bitfield marking late packets */
length_t mtu; /* Maximum size of packets to send to this node */
length_t minmtu; /* Probed minimum MTU */
length_t maxmtu; /* Probed maximum MTU */
int mtuprobes; /* Number of probes */
event_t *mtuevent; /* Probe event */
} node_t;
extern struct node_t *myself;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.4 2003/08/27 13:47:50 guus Exp $
$Id: device.c,v 1.1.2.19 2003/08/08 11:45:37 guus Exp $
*/
#include "system.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: process.c,v 1.5 2003/08/24 20:38:25 guus Exp $
$Id: process.c,v 1.1.2.78 2003/12/07 14:29:02 guus Exp $
*/
#include "system.h"
@ -58,19 +58,6 @@ static void memory_full(int size)
/* Some functions the less gifted operating systems might lack... */
#ifndef HAVE_FCLOSEALL
static int fcloseall(void)
{
fflush(stdin);
fflush(stdout);
fflush(stderr);
fclose(stdin);
fclose(stdout);
fclose(stderr);
return 0;
}
#endif
#ifdef HAVE_MINGW
extern char *identname;
extern char *program_name;
@ -254,7 +241,7 @@ bool init_service(void) {
*/
static bool write_pidfile(void)
{
int pid;
pid_t pid;
cp();
@ -262,16 +249,18 @@ static bool write_pidfile(void)
if(pid) {
if(netname)
fprintf(stderr, _("A tincd is already running for net `%s' with pid %d.\n"),
netname, pid);
fprintf(stderr, _("A tincd is already running for net `%s' with pid %ld.\n"),
netname, (long)pid);
else
fprintf(stderr, _("A tincd is already running with pid %d.\n"), pid);
fprintf(stderr, _("A tincd is already running with pid %ld.\n"), (long)pid);
return false;
}
/* if it's locked, write-protected, or whatever */
if(!write_pid(pidfilename))
if(!write_pid(pidfilename)) {
fprintf(stderr, _("Could write pid file %s: %s\n"), pidfilename, strerror(errno));
return false;
}
return true;
}
@ -283,7 +272,7 @@ static bool write_pidfile(void)
bool kill_other(int signal)
{
#ifndef HAVE_MINGW
int pid;
pid_t pid;
cp();
@ -348,8 +337,10 @@ bool detach(void)
/* Now UPDATE the pid in the pidfile, because we changed it... */
if(!write_pid(pidfilename))
if(!write_pid(pidfilename)) {
fprintf(stderr, _("Could not write pid file %s: %s\n"), pidfilename, strerror(errno));
return false;
}
#else
if(!statushandle)
exit(install_service());
@ -440,13 +431,19 @@ bool execute_script(const char *name, char **envp)
static RETSIGTYPE sigterm_handler(int a)
{
logger(LOG_NOTICE, _("Got %s signal"), "TERM");
running = false;
if(running)
running = false;
else
exit(1);
}
static RETSIGTYPE sigquit_handler(int a)
{
logger(LOG_NOTICE, _("Got %s signal"), "QUIT");
running = false;
if(running)
running = false;
else
exit(1);
}
static RETSIGTYPE fatal_signal_square(int a)

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: process.h,v 1.3 2003/08/24 20:38:27 guus Exp $
$Id: process.h,v 1.1.2.19 2003/08/02 20:50:38 guus Exp $
*/
#ifndef __TINC_PROCESS_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.c,v 1.32 2003/08/24 20:38:27 guus Exp $
$Id: protocol.c,v 1.28.4.148 2003/11/17 15:30:17 guus Exp $
*/
#include "system.h"
@ -30,6 +30,8 @@
#include "utils.h"
#include "xalloc.h"
bool tunnelserver = false;
/* Jumptable for the request handlers */
static bool (*request_handlers[])(connection_t *) = {
@ -219,7 +221,7 @@ bool seen_request(char *request)
ifdebug(SCARY_THINGS) logger(LOG_DEBUG, _("Already seen request"));
return true;
} else {
new = (past_request_t *) xmalloc(sizeof(*new));
new = xmalloc(sizeof(*new));
new->request = xstrdup(request);
new->firstseen = now;
avl_insert(past_request_tree, new);
@ -237,7 +239,7 @@ void age_past_requests(void)
for(node = past_request_tree->head; node; node = next) {
next = node->next;
p = (past_request_t *) node->data;
p = node->data;
if(p->firstseen + pingtimeout < now)
avl_delete_node(past_request_tree, node), deleted++;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.h,v 1.9 2003/08/24 20:38:27 guus Exp $
$Id: protocol.h,v 1.5.4.45 2003/11/17 15:30:18 guus Exp $
*/
#ifndef __TINC_PROTOCOL_H__
@ -54,6 +54,8 @@ typedef struct past_request_t {
time_t firstseen;
} past_request_t;
extern bool tunnelserver;
/* Maximum size of strings in a request */
#define MAX_STRING_SIZE 2048

View file

@ -17,13 +17,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_auth.c,v 1.5 2003/08/24 20:38:27 guus Exp $
$Id: protocol_auth.c,v 1.1.4.34 2003/12/22 11:04:16 guus Exp $
*/
#include "system.h"
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include "avl_tree.h"
@ -50,7 +51,6 @@ bool send_id(connection_t *c)
bool id_h(connection_t *c)
{
char name[MAX_STRING_SIZE];
bool choice;
cp();
@ -108,14 +108,6 @@ bool id_h(connection_t *c)
return false;
}
/* Check some options */
if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT)
c->options |= OPTION_INDIRECT;
if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY)
c->options |= OPTION_TCPONLY | OPTION_INDIRECT;
c->allow_request = METAKEY;
return send_metakey(c);
@ -141,7 +133,7 @@ bool send_metakey(connection_t *c)
cp();
/* Copy random data to the buffer */
RAND_bytes(c->outkey, len);
RAND_pseudo_bytes(c->outkey, len);
/* The message we send must be smaller than the modulus of the RSA key.
By definition, for a key of k bits, the following formula holds:
@ -190,10 +182,14 @@ bool send_metakey(connection_t *c)
/* Further outgoing requests are encrypted with the key we just generated */
if(c->outcipher) {
EVP_EncryptInit(c->outctx, c->outcipher,
c->outkey + len - c->outcipher->key_len,
c->outkey + len - c->outcipher->key_len -
c->outcipher->iv_len);
if(!EVP_EncryptInit(c->outctx, c->outcipher,
c->outkey + len - c->outcipher->key_len,
c->outkey + len - c->outcipher->key_len -
c->outcipher->iv_len)) {
logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
c->status.encryptout = true;
}
@ -262,10 +258,14 @@ bool metakey_h(connection_t *c)
return false;
}
EVP_DecryptInit(c->inctx, c->incipher,
c->inkey + len - c->incipher->key_len,
c->inkey + len - c->incipher->key_len -
c->incipher->iv_len);
if(!EVP_DecryptInit(c->inctx, c->incipher,
c->inkey + len - c->incipher->key_len,
c->inkey + len - c->incipher->key_len -
c->incipher->iv_len)) {
logger(LOG_ERR, _("Error during initialisation of cipher from %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
c->status.decryptin = true;
} else {
@ -315,7 +315,7 @@ bool send_challenge(connection_t *c)
/* Copy random data to the buffer */
RAND_bytes(c->hischallenge, len);
RAND_pseudo_bytes(c->hischallenge, len);
/* Convert to hex */
@ -375,10 +375,13 @@ bool send_chal_reply(connection_t *c)
/* Calculate the hash from the challenge we received */
EVP_DigestInit(&ctx, c->indigest);
EVP_DigestUpdate(&ctx, c->mychallenge,
RSA_size(myself->connection->rsa_key));
EVP_DigestFinal(&ctx, hash, NULL);
if(!EVP_DigestInit(&ctx, c->indigest)
|| !EVP_DigestUpdate(&ctx, c->mychallenge, RSA_size(myself->connection->rsa_key))
|| !EVP_DigestFinal(&ctx, hash, NULL)) {
logger(LOG_ERR, _("Error during calculation of response for %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
/* Convert the hash to a hexadecimal formatted string */
@ -418,9 +421,13 @@ bool chal_reply_h(connection_t *c)
/* Calculate the hash from the challenge we sent */
EVP_DigestInit(&ctx, c->outdigest);
EVP_DigestUpdate(&ctx, c->hischallenge, RSA_size(c->rsa_key));
EVP_DigestFinal(&ctx, myhash, NULL);
if(!EVP_DigestInit(&ctx, c->outdigest)
|| !EVP_DigestUpdate(&ctx, c->hischallenge, RSA_size(c->rsa_key))
|| !EVP_DigestFinal(&ctx, myhash, NULL)) {
logger(LOG_ERR, _("Error during calculation of response from %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
/* Verify the incoming hash with the calculated hash */
@ -452,6 +459,7 @@ bool send_ack(connection_t *c)
to create node_t and edge_t structures. */
struct timeval now;
bool choice;
cp();
@ -460,6 +468,19 @@ bool send_ack(connection_t *c)
gettimeofday(&now, NULL);
c->estimated_weight = (now.tv_sec - c->start.tv_sec) * 1000 + (now.tv_usec - c->start.tv_usec) / 1000;
/* Check some options */
if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT)
c->options |= OPTION_INDIRECT;
if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY)
c->options |= OPTION_TCPONLY | OPTION_INDIRECT;
if((get_config_bool(lookup_config(c->config_tree, "PMTUDiscovery"), &choice) && choice) || myself->options & OPTION_PMTU_DISCOVERY)
c->options |= OPTION_PMTU_DISCOVERY;
get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight);
return send_request(c, "%d %s %d %lx", ACK, myport, c->estimated_weight, c->options);
}
@ -472,16 +493,25 @@ static void send_everything(connection_t *c)
/* Send all known subnets and edges */
if(tunnelserver) {
for(node = myself->subnet_tree->head; node; node = node->next) {
s = node->data;
send_add_subnet(c, s);
}
return;
}
for(node = node_tree->head; node; node = node->next) {
n = (node_t *) node->data;
n = node->data;
for(node2 = n->subnet_tree->head; node2; node2 = node2->next) {
s = (subnet_t *) node2->data;
s = node2->data;
send_add_subnet(c, s);
}
for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
e = (edge_t *) node2->data;
e = node2->data;
send_add_edge(c, e);
}
}
@ -491,7 +521,7 @@ bool ack_h(connection_t *c)
{
char hisport[MAX_STRING_SIZE];
char *hisaddress, *dummy;
int weight;
int weight, mtu;
long int options;
node_t *n;
@ -526,6 +556,12 @@ bool ack_h(connection_t *c)
c->node = n;
c->options |= options;
if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu)
n->mtu = mtu;
if(get_config_int(lookup_config(myself->connection->config_tree, "PMTU"), &mtu) && mtu < n->mtu)
n->mtu = mtu;
/* Activate this connection */
c->allow_request = ALL;
@ -556,7 +592,10 @@ bool ack_h(connection_t *c)
/* Notify everyone of the new edge */
send_add_edge(broadcast, c->edge);
if(tunnelserver)
send_add_edge(c, c->edge);
else
send_add_edge(broadcast, c->edge);
/* Run MST and SSSP algorithms */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_edge.c,v 1.4 2003/08/24 20:38:27 guus Exp $
$Id: protocol_edge.c,v 1.1.4.23 2003/11/17 15:30:18 guus Exp $
*/
#include "system.h"
@ -110,6 +110,9 @@ bool add_edge_h(connection_t *c)
node_add(to);
}
if(tunnelserver && from != myself && from != c->node && to != myself && to != c->node)
return false;
/* Convert addresses */
address = str2sockaddr(to_address, to_port);
@ -154,7 +157,8 @@ bool add_edge_h(connection_t *c)
/* Tell the rest about the new edge */
forward_request(c);
if(!tunnelserver)
forward_request(c);
/* Run MST before or after we tell the rest? */
@ -221,6 +225,9 @@ bool del_edge_h(connection_t *c)
return true;
}
if(tunnelserver && from != myself && from != c->node && to != myself && to != c->node)
return false;
/* Check if edge exists */
e = lookup_edge(from, to);
@ -240,7 +247,8 @@ bool del_edge_h(connection_t *c)
/* Tell the rest about the deleted edge */
forward_request(c);
if(!tunnelserver)
forward_request(c);
/* Delete the edge */
@ -250,5 +258,16 @@ bool del_edge_h(connection_t *c)
graph();
/* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
if(!to->status.reachable) {
e = lookup_edge(to, myself);
if(e) {
if(!tunnelserver)
send_del_edge(broadcast, e);
edge_del(e);
}
}
return true;
}

View file

@ -17,11 +17,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_key.c,v 1.4 2003/08/24 20:38:27 guus Exp $
$Id: protocol_key.c,v 1.1.4.26 2003/12/20 21:25:17 guus Exp $
*/
#include "system.h"
#include <openssl/evp.h>
#include <openssl/err.h>
#include "avl_tree.h"
#include "connection.h"
#include "logger.h"
@ -77,7 +80,8 @@ bool key_changed_h(connection_t *c)
/* Tell the others */
forward_request(c);
if(!tunnelserver)
forward_request(c);
return true;
}
@ -127,6 +131,9 @@ bool req_key_h(connection_t *c)
memset(from->late, 0, sizeof(from->late));
send_ans_key(c, myself, from);
} else {
if(tunnelserver)
return false;
send_req_key(to->nexthop->connection, from, to);
}
@ -186,6 +193,9 @@ bool ans_key_h(connection_t *c)
/* Forward it if necessary */
if(to != myself) {
if(tunnelserver)
return false;
return send_request(to->nexthop->connection, "%s", c->buffer);
}
@ -251,7 +261,14 @@ bool ans_key_h(connection_t *c)
from->compression = compression;
if(from->cipher)
EVP_EncryptInit_ex(&from->packet_ctx, from->cipher, NULL, from->key, from->key + from->cipher->key_len);
if(!EVP_EncryptInit_ex(&from->packet_ctx, from->cipher, NULL, from->key, from->key + from->cipher->key_len)) {
logger(LOG_ERR, _("Error during initialisation of key from %s (%s): %s"),
from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
send_mtu_probe(from);
flush_queue(from);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_misc.c,v 1.4 2003/08/24 20:38:27 guus Exp $
$Id: protocol_misc.c,v 1.1.4.13 2003/07/24 12:08:16 guus Exp $
*/
#include "system.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_subnet.c,v 1.4 2003/08/24 20:38:27 guus Exp $
$Id: protocol_subnet.c,v 1.1.4.18 2003/12/12 19:52:25 guus Exp $
*/
#include "system.h"
@ -35,17 +35,14 @@
bool send_add_subnet(connection_t *c, const subnet_t *subnet)
{
bool x;
char *netstr;
char netstr[MAXNETSTR];
cp();
x = send_request(c, "%d %lx %s %s", ADD_SUBNET, random(),
subnet->owner->name, netstr = net2str(subnet));
if(!net2str(netstr, sizeof netstr, subnet))
return false;
free(netstr);
return x;
return send_request(c, "%d %lx %s %s", ADD_SUBNET, random(), subnet->owner->name, netstr);
}
bool add_subnet_h(connection_t *c)
@ -53,7 +50,7 @@ bool add_subnet_h(connection_t *c)
char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE];
node_t *owner;
subnet_t *s;
subnet_t s = {0}, *new;
cp();
@ -73,9 +70,7 @@ bool add_subnet_h(connection_t *c)
/* Check if subnet string is valid */
s = str2net(subnetstr);
if(!s) {
if(!str2net(&s, subnetstr)) {
logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
c->hostname, _("invalid subnet string"));
return false;
@ -94,48 +89,69 @@ bool add_subnet_h(connection_t *c)
node_add(owner);
}
if(tunnelserver && owner != myself && owner != c->node)
return false;
/* Check if we already know this subnet */
if(lookup_subnet(owner, s)) {
free_subnet(s);
if(lookup_subnet(owner, &s))
return true;
}
/* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */
if(owner == myself) {
ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for ourself"),
"ADD_SUBNET", c->name, c->hostname);
s->owner = myself;
send_del_subnet(c, s);
s.owner = myself;
send_del_subnet(c, &s);
return true;
}
/* In tunnel server mode, check if the subnet matches one in the config file of this node */
if(tunnelserver) {
config_t *cfg;
subnet_t *allowed;
for(cfg = lookup_config(c->config_tree, "Subnet"); cfg; cfg = lookup_config_next(c->config_tree, cfg)) {
if(!get_config_subnet(cfg, &allowed))
return false;
if(!subnet_compare(&s, allowed))
break;
free_subnet(allowed);
}
if(!cfg)
return false;
free_subnet(allowed);
}
/* If everything is correct, add the subnet to the list of the owner */
subnet_add(owner, s);
*(new = new_subnet()) = s;
subnet_add(owner, new);
/* Tell the rest */
forward_request(c);
if(!tunnelserver)
forward_request(c);
return true;
}
bool send_del_subnet(connection_t *c, const subnet_t *s)
{
bool x;
char *netstr;
char netstr[MAXNETSTR];
cp();
netstr = net2str(s);
if(!net2str(netstr, sizeof netstr, s))
return false;
x = send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
free(netstr);
return x;
return send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
}
bool del_subnet_h(connection_t *c)
@ -143,7 +159,7 @@ bool del_subnet_h(connection_t *c)
char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE];
node_t *owner;
subnet_t *s, *find;
subnet_t s = {0}, *find;
cp();
@ -171,11 +187,12 @@ bool del_subnet_h(connection_t *c)
return true;
}
if(tunnelserver && owner != myself && owner != c->node)
return false;
/* Check if subnet string is valid */
s = str2net(subnetstr);
if(!s) {
if(!str2net(&s, subnetstr)) {
logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
c->hostname, _("invalid subnet string"));
return false;
@ -186,11 +203,9 @@ bool del_subnet_h(connection_t *c)
/* If everything is correct, delete the subnet from the list of the owner */
s->owner = owner;
s.owner = owner;
find = lookup_subnet(owner, s);
free_subnet(s);
find = lookup_subnet(owner, &s);
if(!find) {
ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for %s which does not appear in his subnet tree"),
@ -209,7 +224,8 @@ bool del_subnet_h(connection_t *c)
/* Tell the rest */
forward_request(c);
if(!tunnelserver)
forward_request(c);
/* Finally, delete it. */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.3 2003/08/27 13:47:52 guus Exp $
$Id: device.c,v 1.1.2.9 2003/07/31 11:31:51 guus Exp $
*/
#include "config.h"

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: route.c,v 1.4 2003/08/24 20:38:28 guus Exp $
$Id: route.c,v 1.1.2.75 2003/12/24 10:48:15 guus Exp $
*/
#include "system.h"
@ -40,7 +40,6 @@
#include "avl_tree.h"
#include "connection.h"
#include "device.h"
#include "ethernet.h"
#include "ipv4.h"
#include "ipv6.h"
@ -57,9 +56,20 @@ int macexpire = 600;
bool overwrite_mac = false;
mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}};
/* Sizes of various headers */
static const size_t ether_size = sizeof(struct ether_header);
static const size_t arp_size = sizeof(struct ether_arp);
static const size_t ip_size = sizeof(struct ip);
static const size_t icmp_size = sizeof(struct icmp) - sizeof(struct ip);
static const size_t ip6_size = sizeof(struct ip6_hdr);
static const size_t icmp6_size = sizeof(struct icmp6_hdr);
static const size_t ns_size = sizeof(struct nd_neighbor_solicit);
static const size_t opt_size = sizeof(struct nd_opt_hdr);
/* RFC 1071 */
static uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
static __inline__ uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
{
uint16_t *p = data;
uint32_t checksum = prevsum ^ 0xFFFF;
@ -70,7 +80,7 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
}
if(len)
checksum += *(unsigned char *)p;
checksum += *(uint8_t *)p;
while(checksum >> 16)
checksum = (checksum & 0xFFFF) + (checksum >> 16);
@ -78,17 +88,30 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
return ~checksum;
}
static bool ratelimit(void) {
static __inline__ bool ratelimit(int frequency) {
static time_t lasttime = 0;
static int count = 0;
if(lasttime == now)
return true;
if(lasttime == now) {
if(++count > frequency)
return true;
} else {
lasttime = now;
count = 0;
}
lasttime = now;
return false;
}
static __inline__ bool checklength(node_t *source, vpn_packet_t *packet, length_t length) {
if(packet->len < length) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Got too short packet from %s (%s)"), source->name, source->hostname);
return false;
} else
return true;
}
static void learn_mac(mac_t *address)
static __inline__ void learn_mac(mac_t *address)
{
subnet_t *subnet;
avl_node_t *node;
@ -100,29 +123,31 @@ static void learn_mac(mac_t *address)
/* If we don't know this MAC address yet, store it */
if(!subnet || subnet->owner != myself) {
if(!subnet) {
ifdebug(TRAFFIC) logger(LOG_INFO, _("Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx"),
address->x[0], address->x[1], address->x[2], address->x[3],
address->x[4], address->x[5]);
subnet = new_subnet();
subnet->type = SUBNET_MAC;
memcpy(&subnet->net.mac.address, address, sizeof(mac_t));
subnet->expires = now + macexpire;
subnet->net.mac.address = *address;
subnet_add(myself, subnet);
/* And tell all other tinc daemons it's our MAC */
for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *) node->data;
c = node->data;
if(c->status.active)
send_add_subnet(c, subnet);
}
}
subnet->net.mac.lastseen = now;
if(subnet->expires)
subnet->expires = now + macexpire;
}
void age_mac(void)
void age_subnets(void)
{
subnet_t *s;
connection_t *c;
@ -132,15 +157,16 @@ void age_mac(void)
for(node = myself->subnet_tree->head; node; node = next) {
next = node->next;
s = (subnet_t *) node->data;
if(s->type == SUBNET_MAC && s->net.mac.lastseen && s->net.mac.lastseen + macexpire < now) {
ifdebug(TRAFFIC) logger(LOG_INFO, _("MAC address %hx:%hx:%hx:%hx:%hx:%hx expired"),
s->net.mac.address.x[0], s->net.mac.address.x[1],
s->net.mac.address.x[2], s->net.mac.address.x[3],
s->net.mac.address.x[4], s->net.mac.address.x[5]);
s = node->data;
if(s->expires && s->expires < now) {
ifdebug(TRAFFIC) {
char netstr[MAXNETSTR];
if(net2str(netstr, sizeof netstr, s))
logger(LOG_INFO, _("Subnet %s expired"), netstr);
}
for(node2 = connection_tree->head; node2; node2 = node2->next) {
c = (connection_t *) node2->data;
c = node2->data;
if(c->status.active)
send_del_subnet(c, s);
}
@ -150,7 +176,7 @@ void age_mac(void)
}
}
static node_t *route_mac(vpn_packet_t *packet)
static __inline__ void route_mac(node_t *source, vpn_packet_t *packet)
{
subnet_t *subnet;
@ -158,111 +184,215 @@ static node_t *route_mac(vpn_packet_t *packet)
/* Learn source address */
learn_mac((mac_t *)(&packet->data[6]));
if(source == myself)
learn_mac((mac_t *)(&packet->data[6]));
/* Lookup destination address */
subnet = lookup_subnet_mac((mac_t *)(&packet->data[0]));
if(subnet)
return subnet->owner;
else
return NULL;
if(!subnet) {
broadcast_packet(source, packet);
return;
}
if(subnet->owner == source) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Packet looping back to %s (%s)!"), source->name, source->hostname);
return;
}
send_packet(subnet->owner, packet);
}
/* RFC 792 */
static void route_ipv4_unreachable(vpn_packet_t *packet, uint8_t code)
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code)
{
struct ip *hdr;
struct icmp *icmp;
struct ip ip = {0};
struct icmp icmp = {0};
struct in_addr ip_src;
struct in_addr ip_dst;
uint32_t oldlen;
if(ratelimit())
if(ratelimit(3))
return;
cp();
hdr = (struct ip *)(packet->data + 14);
icmp = (struct icmp *)(packet->data + 14 + 20);
/* Copy headers from packet into properly aligned structs on the stack */
memcpy(&ip, packet->data + ether_size, ip_size);
/* Remember original source and destination */
memcpy(&ip_src, &hdr->ip_src, 4);
memcpy(&ip_dst, &hdr->ip_dst, 4);
oldlen = packet->len - 14;
if(oldlen >= IP_MSS - sizeof(*hdr) - sizeof(*icmp))
oldlen = IP_MSS - sizeof(*hdr) - sizeof(*icmp);
ip_src = ip.ip_src;
ip_dst = ip.ip_dst;
oldlen = packet->len - ether_size;
if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
icmp.icmp_nextmtu = htons(packet->len - ether_size);
if(oldlen >= IP_MSS - ip_size - icmp_size)
oldlen = IP_MSS - ip_size - icmp_size;
/* Copy first part of original contents to ICMP message */
memmove(&icmp->icmp_ip, hdr, oldlen);
memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen);
/* Fill in IPv4 header */
hdr->ip_v = 4;
hdr->ip_hl = sizeof(*hdr) / 4;
hdr->ip_tos = 0;
hdr->ip_len = htons(20 + 8 + oldlen);
hdr->ip_id = 0;
hdr->ip_off = 0;
hdr->ip_ttl = 255;
hdr->ip_p = IPPROTO_ICMP;
hdr->ip_sum = 0;
memcpy(&hdr->ip_src, &ip_dst, 4);
memcpy(&hdr->ip_dst, &ip_src, 4);
ip.ip_v = 4;
ip.ip_hl = ip_size / 4;
ip.ip_tos = 0;
ip.ip_len = htons(ip_size + icmp_size + oldlen);
ip.ip_id = 0;
ip.ip_off = 0;
ip.ip_ttl = 255;
ip.ip_p = IPPROTO_ICMP;
ip.ip_sum = 0;
ip.ip_src = ip_dst;
ip.ip_dst = ip_src;
hdr->ip_sum = inet_checksum(hdr, 20, ~0);
ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
/* Fill in ICMP header */
icmp->icmp_type = ICMP_DEST_UNREACH;
icmp->icmp_code = code;
icmp->icmp_cksum = 0;
icmp.icmp_type = type;
icmp.icmp_code = code;
icmp.icmp_cksum = 0;
icmp->icmp_cksum = inet_checksum(icmp, 8 + oldlen, ~0);
icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0);
icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum);
/* Copy structs on stack back to packet */
memcpy(packet->data + ether_size, &ip, ip_size);
memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size);
packet->len = 14 + 20 + 8 + oldlen;
write_packet(packet);
packet->len = ether_size + ip_size + icmp_size + oldlen;
send_packet(source, packet);
}
static node_t *route_ipv4(vpn_packet_t *packet)
/* RFC 791 */
static __inline__ void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) {
struct ip ip;
vpn_packet_t fragment;
int len, maxlen, todo;
uint8_t *offset;
uint16_t ip_off, origf;
cp();
memcpy(&ip, packet->data + ether_size, ip_size);
fragment.priority = packet->priority;
if(ip.ip_hl != ip_size / 4)
return;
todo = ntohs(ip.ip_len) - ip_size;
if(ether_size + ip_size + todo != packet->len) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Length of packet (%d) doesn't match length in IPv4 header (%d)"), packet->len, ether_size + ip_size + todo);
return;
}
ifdebug(TRAFFIC) logger(LOG_INFO, _("Fragmenting packet of %d bytes to %s (%s)"), packet->len, dest->name, dest->hostname);
offset = packet->data + ether_size + ip_size;
maxlen = (dest->mtu - ether_size - ip_size) & ~0x7;
ip_off = ntohs(ip.ip_off);
origf = ip_off & ~IP_OFFMASK;
ip_off &= IP_OFFMASK;
while(todo) {
len = todo > maxlen ? maxlen : todo;
memcpy(fragment.data + ether_size + ip_size, offset, len);
todo -= len;
offset += len;
ip.ip_len = htons(ip_size + len);
ip.ip_off = htons(ip_off | origf | (todo ? IP_MF : 0));
ip.ip_sum = 0;
ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
memcpy(fragment.data, packet->data, ether_size);
memcpy(fragment.data + ether_size, &ip, ip_size);
fragment.len = ether_size + ip_size + len;
send_packet(dest, &fragment);
ip_off += len / 8;
}
}
static __inline__ void route_ipv4_unicast(node_t *source, vpn_packet_t *packet)
{
subnet_t *subnet;
node_t *via;
cp();
subnet = lookup_subnet_ipv4((ipv4_t *) &packet->data[30]);
if(!subnet) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d"),
source->name, source->hostname,
packet->data[30],
packet->data[31],
packet->data[32],
packet->data[33]);
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
return;
}
if(subnet->owner == source) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Packet looping back to %s (%s)!"), source->name, source->hostname);
return;
}
if(!subnet->owner->status.reachable)
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
if(priorityinheritance)
packet->priority = packet->data[15];
subnet = lookup_subnet_ipv4((ipv4_t *) & packet->data[30]);
if(!subnet) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: unknown IPv4 destination address %d.%d.%d.%d"),
packet->data[30], packet->data[31], packet->data[32],
packet->data[33]);
route_ipv4_unreachable(packet, ICMP_NET_UNKNOWN);
return NULL;
}
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
if(!subnet->owner->status.reachable)
route_ipv4_unreachable(packet, ICMP_NET_UNREACH);
if(packet->len > via->mtu && via != myself) {
ifdebug(TRAFFIC) logger(LOG_INFO, _("Packet for %s (%s) length %d larger than MTU %d"), subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
if(packet->data[20] & 0x40) {
packet->len = via->mtu;
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
} else {
fragment_ipv4_packet(via, packet);
}
return subnet->owner;
return;
}
send_packet(subnet->owner, packet);
}
static __inline__ void route_ipv4(node_t *source, vpn_packet_t *packet)
{
cp();
if(!checklength(source, packet, ether_size + ip_size))
return;
route_ipv4_unicast(source, packet);
}
/* RFC 2463 */
static void route_ipv6_unreachable(vpn_packet_t *packet, uint8_t code)
static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code)
{
struct ip6_hdr *hdr;
struct icmp6_hdr *icmp;
struct ip6_hdr ip6;
struct icmp6_hdr icmp6 = {0};
uint16_t checksum;
struct {
@ -272,95 +402,122 @@ static void route_ipv6_unreachable(vpn_packet_t *packet, uint8_t code)
uint32_t next;
} pseudo;
if(ratelimit())
if(ratelimit(3))
return;
cp();
hdr = (struct ip6_hdr *)(packet->data + 14);
icmp = (struct icmp6_hdr *)(packet->data + 14 + sizeof(*hdr));
/* Copy headers from packet to structs on the stack */
memcpy(&ip6, packet->data + ether_size, ip6_size);
/* Remember original source and destination */
memcpy(&pseudo.ip6_src, &hdr->ip6_dst, 16);
memcpy(&pseudo.ip6_dst, &hdr->ip6_src, 16);
pseudo.length = ntohs(hdr->ip6_plen) + sizeof(*hdr);
if(pseudo.length >= IP_MSS - sizeof(*hdr) - sizeof(*icmp))
pseudo.length = IP_MSS - sizeof(*hdr) - sizeof(*icmp);
pseudo.ip6_src = ip6.ip6_dst;
pseudo.ip6_dst = ip6.ip6_src;
pseudo.length = packet->len - ether_size;
if(type == ICMP6_PACKET_TOO_BIG)
icmp6.icmp6_mtu = htonl(pseudo.length);
if(pseudo.length >= IP_MSS - ip6_size - icmp6_size)
pseudo.length = IP_MSS - ip6_size - icmp6_size;
/* Copy first part of original contents to ICMP message */
memmove(((char *)icmp) + sizeof(*icmp), hdr, pseudo.length);
memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length);
/* Fill in IPv6 header */
hdr->ip6_flow = htonl(0x60000000UL);
hdr->ip6_plen = htons(sizeof(*icmp) + pseudo.length);
hdr->ip6_nxt = IPPROTO_ICMPV6;
hdr->ip6_hlim = 255;
memcpy(&hdr->ip6_dst, &pseudo.ip6_dst, 16);
memcpy(&hdr->ip6_src, &pseudo.ip6_src, 16);
ip6.ip6_flow = htonl(0x60000000UL);
ip6.ip6_plen = htons(icmp6_size + pseudo.length);
ip6.ip6_nxt = IPPROTO_ICMPV6;
ip6.ip6_hlim = 255;
ip6.ip6_src = pseudo.ip6_src;
ip6.ip6_dst = pseudo.ip6_dst;
/* Fill in ICMP header */
icmp->icmp6_type = ICMP6_DST_UNREACH;
icmp->icmp6_code = code;
icmp->icmp6_cksum = 0;
icmp6.icmp6_type = type;
icmp6.icmp6_code = code;
icmp6.icmp6_cksum = 0;
/* Create pseudo header */
pseudo.length = htonl(sizeof(*icmp) + pseudo.length);
pseudo.length = htonl(icmp6_size + pseudo.length);
pseudo.next = htonl(IPPROTO_ICMPV6);
/* Generate checksum */
checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
checksum = inet_checksum(icmp, ntohl(pseudo.length), checksum);
checksum = inet_checksum(&icmp6, icmp6_size, checksum);
checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum);
icmp->icmp6_cksum = checksum;
icmp6.icmp6_cksum = checksum;
/* Copy structs on stack back to packet */
memcpy(packet->data + ether_size, &ip6, ip6_size);
memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size);
packet->len = 14 + sizeof(*hdr) + ntohl(pseudo.length);
packet->len = ether_size + ip6_size + ntohl(pseudo.length);
write_packet(packet);
send_packet(source, packet);
}
static node_t *route_ipv6(vpn_packet_t *packet)
static __inline__ void route_ipv6_unicast(node_t *source, vpn_packet_t *packet)
{
subnet_t *subnet;
node_t *via;
cp();
subnet = lookup_subnet_ipv6((ipv6_t *) & packet->data[38]);
subnet = lookup_subnet_ipv6((ipv6_t *) &packet->data[38]);
if(!subnet) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
ntohs(*(uint16_t *) & packet->data[38]),
ntohs(*(uint16_t *) & packet->data[40]),
ntohs(*(uint16_t *) & packet->data[42]),
ntohs(*(uint16_t *) & packet->data[44]),
ntohs(*(uint16_t *) & packet->data[46]),
ntohs(*(uint16_t *) & packet->data[48]),
ntohs(*(uint16_t *) & packet->data[50]),
ntohs(*(uint16_t *) & packet->data[52]));
route_ipv6_unreachable(packet, ICMP6_DST_UNREACH_ADDR);
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
source->name, source->hostname,
ntohs(*(uint16_t *) &packet->data[38]),
ntohs(*(uint16_t *) &packet->data[40]),
ntohs(*(uint16_t *) &packet->data[42]),
ntohs(*(uint16_t *) &packet->data[44]),
ntohs(*(uint16_t *) &packet->data[46]),
ntohs(*(uint16_t *) &packet->data[48]),
ntohs(*(uint16_t *) &packet->data[50]),
ntohs(*(uint16_t *) &packet->data[52]));
return NULL;
route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
return;
}
if(subnet->owner == source) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Packet looping back to %s (%s)!"), source->name, source->hostname);
return;
}
if(!subnet->owner->status.reachable)
route_ipv6_unreachable(packet, ICMP6_DST_UNREACH_NOROUTE);
route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
return subnet->owner;
if(packet->len > via->mtu && via != myself) {
ifdebug(TRAFFIC) logger(LOG_INFO, _("Packet for %s (%s) length %d larger than MTU %d"), subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
packet->len = via->mtu;
route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
return;
}
send_packet(subnet->owner, packet);
}
/* RFC 2461 */
static void route_neighborsol(vpn_packet_t *packet)
static void route_neighborsol(node_t *source, vpn_packet_t *packet)
{
struct ip6_hdr *hdr;
struct nd_neighbor_solicit *ns;
struct nd_opt_hdr *opt;
struct ip6_hdr ip6;
struct nd_neighbor_solicit ns;
struct nd_opt_hdr opt;
subnet_t *subnet;
uint16_t checksum;
@ -373,34 +530,46 @@ static void route_neighborsol(vpn_packet_t *packet)
cp();
hdr = (struct ip6_hdr *)(packet->data + 14);
ns = (struct nd_neighbor_solicit *)(packet->data + 14 + sizeof(*hdr));
opt = (struct nd_opt_hdr *)(packet->data + 14 + sizeof(*hdr) + sizeof(*ns));
if(!checklength(source, packet, ether_size + ip6_size + ns_size + opt_size + ETH_ALEN))
return;
if(source != myself) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Got neighbor solicitation request from %s (%s) while in router mode!"), source->name, source->hostname);
return;
}
/* Copy headers from packet to structs on the stack */
memcpy(&ip6, packet->data + ether_size, ip6_size);
memcpy(&ns, packet->data + ether_size + ip6_size, ns_size);
memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size);
/* First, snatch the source address from the neighbor solicitation packet */
if(overwrite_mac)
memcpy(mymac.x, packet->data + 6, 6);
memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN);
/* Check if this is a valid neighbor solicitation request */
if(ns->nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
opt->nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type neighbor solicitation request"));
return;
}
/* Create pseudo header */
memcpy(&pseudo.ip6_src, &hdr->ip6_src, 16);
memcpy(&pseudo.ip6_dst, &hdr->ip6_dst, 16);
pseudo.length = htonl(sizeof(*ns) + sizeof(*opt) + 6);
pseudo.ip6_src = ip6.ip6_src;
pseudo.ip6_dst = ip6.ip6_dst;
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
pseudo.next = htonl(IPPROTO_ICMPV6);
/* Generate checksum */
checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
checksum = inet_checksum(ns, sizeof(*ns) + 8, checksum);
checksum = inet_checksum(&ns, ns_size, checksum);
checksum = inet_checksum(&opt, opt_size, checksum);
checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum);
if(checksum) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: checksum error for neighbor solicitation request"));
@ -409,18 +578,18 @@ static void route_neighborsol(vpn_packet_t *packet)
/* Check if the IPv6 address exists on the VPN */
subnet = lookup_subnet_ipv6((ipv6_t *) & ns->nd_ns_target);
subnet = lookup_subnet_ipv6((ipv6_t *) &ns.nd_ns_target);
if(!subnet) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
ntohs(((uint16_t *) & ns->nd_ns_target)[0]),
ntohs(((uint16_t *) & ns->nd_ns_target)[1]),
ntohs(((uint16_t *) & ns->nd_ns_target)[2]),
ntohs(((uint16_t *) & ns->nd_ns_target)[3]),
ntohs(((uint16_t *) & ns->nd_ns_target)[4]),
ntohs(((uint16_t *) & ns->nd_ns_target)[5]),
ntohs(((uint16_t *) & ns->nd_ns_target)[6]),
ntohs(((uint16_t *) & ns->nd_ns_target)[7]));
ntohs(((uint16_t *) &ns.nd_ns_target)[0]),
ntohs(((uint16_t *) &ns.nd_ns_target)[1]),
ntohs(((uint16_t *) &ns.nd_ns_target)[2]),
ntohs(((uint16_t *) &ns.nd_ns_target)[3]),
ntohs(((uint16_t *) &ns.nd_ns_target)[4]),
ntohs(((uint16_t *) &ns.nd_ns_target)[5]),
ntohs(((uint16_t *) &ns.nd_ns_target)[6]),
ntohs(((uint16_t *) &ns.nd_ns_target)[7]));
return;
}
@ -432,77 +601,102 @@ static void route_neighborsol(vpn_packet_t *packet)
/* Create neighbor advertation reply */
memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */
packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
memcpy(&hdr->ip6_dst, &hdr->ip6_src, 16); /* swap destination and source protocol address */
memcpy(&hdr->ip6_src, &ns->nd_ns_target, 16); /* ... */
ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */
ip6.ip6_src = ns.nd_ns_target;
memcpy((char *) opt + sizeof(*opt), packet->data + ETHER_ADDR_LEN, 6); /* add fake source hard addr */
memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
ns->nd_ns_hdr.icmp6_cksum = 0;
ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[0] = 0x40; /* Set solicited flag */
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[1] =
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[2] =
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[3] = 0;
opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
ns.nd_ns_cksum = 0;
ns.nd_ns_type = ND_NEIGHBOR_ADVERT;
ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */
opt.nd_opt_type = ND_OPT_TARGET_LINKADDR;
/* Create pseudo header */
memcpy(&pseudo.ip6_src, &hdr->ip6_src, 16);
memcpy(&pseudo.ip6_dst, &hdr->ip6_dst, 16);
pseudo.length = htonl(sizeof(*ns) + sizeof(*opt) + 6);
pseudo.ip6_src = ip6.ip6_src;
pseudo.ip6_dst = ip6.ip6_dst;
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
pseudo.next = htonl(IPPROTO_ICMPV6);
/* Generate checksum */
checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
checksum = inet_checksum(ns, sizeof(*ns) + 8, checksum);
checksum = inet_checksum(&ns, ns_size, checksum);
checksum = inet_checksum(&opt, opt_size, checksum);
checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum);
ns->nd_ns_hdr.icmp6_cksum = checksum;
ns.nd_ns_hdr.icmp6_cksum = checksum;
write_packet(packet);
/* Copy structs on stack back to packet */
memcpy(packet->data + ether_size, &ip6, ip6_size);
memcpy(packet->data + ether_size + ip6_size, &ns, ns_size);
memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size);
send_packet(source, packet);
}
static __inline__ void route_ipv6(node_t *source, vpn_packet_t *packet)
{
cp();
if(!checklength(source, packet, ether_size + ip6_size))
return;
if(packet->data[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && packet->data[54] == ND_NEIGHBOR_SOLICIT) {
route_neighborsol(source, packet);
return;
}
route_ipv6_unicast(source, packet);
}
/* RFC 826 */
static void route_arp(vpn_packet_t *packet)
static void route_arp(node_t *source, vpn_packet_t *packet)
{
struct ether_arp *arp;
struct ether_arp arp;
subnet_t *subnet;
uint8_t ipbuf[4];
struct in_addr addr;
cp();
if(!checklength(source, packet, ether_size + arp_size))
return;
if(source != myself) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Got ARP request from %s (%s) while in router mode!"), source->name, source->hostname);
return;
}
/* First, snatch the source address from the ARP packet */
if(overwrite_mac)
memcpy(mymac.x, packet->data + 6, 6);
memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN);
/* This routine generates replies to ARP requests.
You don't need to set NOARP flag on the interface anymore (which is broken on FreeBSD).
Most of the code here is taken from choparp.c by Takamichi Tateoka (tree@mma.club.uec.ac.jp)
*/
/* Copy headers from packet to structs on the stack */
arp = (struct ether_arp *)(packet->data + 14);
memcpy(&arp, packet->data + ether_size, arp_size);
/* Check if this is a valid ARP request */
if(ntohs(arp->arp_hrd) != ARPHRD_ETHER || ntohs(arp->arp_pro) != ETHERTYPE_IP ||
arp->arp_hln != ETHER_ADDR_LEN || arp->arp_pln != 4 || ntohs(arp->arp_op) != ARPOP_REQUEST) {
if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP ||
arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof(addr) || ntohs(arp.arp_op) != ARPOP_REQUEST) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type ARP request"));
return;
}
/* Check if the IPv4 address exists on the VPN */
subnet = lookup_subnet_ipv4((ipv4_t *) arp->arp_tpa);
subnet = lookup_subnet_ipv4((ipv4_t *) &arp.arp_tpa);
if(!subnet) {
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: ARP request for unknown address %d.%d.%d.%d"),
arp->arp_tpa[0], arp->arp_tpa[1], arp->arp_tpa[2],
arp->arp_tpa[3]);
arp.arp_tpa[0], arp.arp_tpa[1], arp.arp_tpa[2],
arp.arp_tpa[3]);
return;
}
@ -511,126 +705,63 @@ static void route_arp(vpn_packet_t *packet)
if(subnet->owner == myself)
return; /* silently ignore */
memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */
packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
memcpy(ipbuf, arp->arp_tpa, 4); /* save protocol addr */
memcpy(arp->arp_tpa, arp->arp_spa, 4); /* swap destination and source protocol address */
memcpy(arp->arp_spa, ipbuf, 4); /* ... */
memcpy(&addr, arp.arp_tpa, sizeof(addr)); /* save protocol addr */
memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */
memcpy(arp.arp_spa, &addr, sizeof(addr)); /* ... */
memcpy(arp->arp_tha, arp->arp_sha, 10); /* set target hard/proto addr */
memcpy(arp->arp_sha, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* add fake source hard addr */
arp->arp_op = htons(ARPOP_REPLY);
memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */
memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
arp.arp_op = htons(ARPOP_REPLY);
write_packet(packet);
/* Copy structs on stack back to packet */
memcpy(packet->data + ether_size, &arp, arp_size);
send_packet(source, packet);
}
void route_outgoing(vpn_packet_t *packet)
void route(node_t *source, vpn_packet_t *packet)
{
uint16_t type;
node_t *n = NULL;
cp();
/* FIXME: multicast? */
if(!checklength(source, packet, ether_size))
return;
switch (routing_mode) {
case RMODE_ROUTER:
type = ntohs(*((uint16_t *)(&packet->data[12])));
switch (type) {
case 0x0800:
n = route_ipv4(packet);
break;
case 0x86DD:
if(packet->data[20] == IPPROTO_ICMPV6 && packet->data[54] == ND_NEIGHBOR_SOLICIT) {
route_neighborsol(packet);
return;
}
n = route_ipv6(packet);
break;
case 0x0806:
route_arp(packet);
return;
default:
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type);
return;
}
if(n)
send_packet(n, packet);
break;
case RMODE_SWITCH:
n = route_mac(packet);
if(n)
send_packet(n, packet);
else
broadcast_packet(myself, packet);
break;
case RMODE_HUB:
broadcast_packet(myself, packet);
break;
}
}
void route_incoming(node_t *source, vpn_packet_t *packet)
{
switch (routing_mode) {
case RMODE_ROUTER:
{
node_t *n = NULL;
uint16_t type;
type = ntohs(*((uint16_t *)(&packet->data[12])));
switch (type) {
case 0x0800:
n = route_ipv4(packet);
case ETH_P_ARP:
route_arp(source, packet);
break;
case 0x86DD:
n = route_ipv6(packet);
case ETH_P_IP:
route_ipv4(source, packet);
break;
case ETH_P_IPV6:
route_ipv6(source, packet);
break;
default:
n = myself;
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown type %hx"), source->name, source->hostname, type);
break;
}
if(n) {
if(n == myself) {
if(overwrite_mac)
memcpy(packet->data, mymac.x, 6);
write_packet(packet);
} else
send_packet(n, packet);
}
}
break;
case RMODE_SWITCH:
{
subnet_t *subnet;
subnet = lookup_subnet_mac((mac_t *)(&packet->data[0]));
if(subnet) {
if(subnet->owner == myself)
write_packet(packet);
else
send_packet(subnet->owner, packet);
} else {
broadcast_packet(source, packet);
write_packet(packet);
}
}
route_mac(source, packet);
break;
case RMODE_HUB:
broadcast_packet(source, packet); /* Spread it on */
write_packet(packet);
broadcast_packet(source, packet);
break;
}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: route.h,v 1.3 2003/08/24 20:38:28 guus Exp $
$Id: route.h,v 1.1.2.14 2003/12/12 19:52:25 guus Exp $
*/
#ifndef __TINC_ROUTE_H__
@ -39,8 +39,7 @@ extern int macexpire;
extern mac_t mymac;
extern void age_mac(void);
extern void route_incoming(struct node_t *, struct vpn_packet_t *);
extern void route_outgoing(struct vpn_packet_t *);
extern void age_subnets(void);
extern void route(struct node_t *, struct vpn_packet_t *);
#endif /* __TINC_ROUTE_H__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.4 2003/08/27 13:47:52 guus Exp $
$Id: device.c,v 1.1.2.17 2003/07/31 11:20:32 guus Exp $
*/

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: subnet.c,v 1.4 2003/08/24 20:38:28 guus Exp $
$Id: subnet.c,v 1.1.2.52 2003/12/12 19:52:25 guus Exp $
*/
#include "system.h"
@ -83,7 +83,7 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b)
return strcmp(a->owner->name, b->owner->name);
}
static int subnet_compare(const subnet_t *a, const subnet_t *b)
int subnet_compare(const subnet_t *a, const subnet_t *b)
{
int result;
@ -145,7 +145,7 @@ subnet_t *new_subnet(void)
{
cp();
return (subnet_t *) xmalloc_and_zero(sizeof(subnet_t));
return xmalloc_and_zero(sizeof(subnet_t));
}
void free_subnet(subnet_t *subnet)
@ -177,16 +177,13 @@ void subnet_del(node_t *n, subnet_t *subnet)
/* Ascii representation of subnets */
subnet_t *str2net(const char *subnetstr)
bool str2net(subnet_t *subnet, const char *subnetstr)
{
int i, l;
subnet_t *subnet;
uint16_t x[8];
cp();
subnet = new_subnet();
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
&x[0], &x[1], &x[2], &x[3], &l) == 5) {
subnet->type = SUBNET_IPV4;
@ -195,7 +192,7 @@ subnet_t *str2net(const char *subnetstr)
for(i = 0; i < 4; i++)
subnet->net.ipv4.address.x[i] = x[i];
return subnet;
return true;
}
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
@ -207,7 +204,7 @@ subnet_t *str2net(const char *subnetstr)
for(i = 0; i < 8; i++)
subnet->net.ipv6.address.x[i] = htons(x[i]);
return subnet;
return true;
}
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu", &x[0], &x[1], &x[2], &x[3]) == 4) {
@ -217,7 +214,7 @@ subnet_t *str2net(const char *subnetstr)
for(i = 0; i < 4; i++)
subnet->net.ipv4.address.x[i] = x[i];
return subnet;
return true;
}
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
@ -228,7 +225,7 @@ subnet_t *str2net(const char *subnetstr)
for(i = 0; i < 8; i++)
subnet->net.ipv6.address.x[i] = htons(x[i]);
return subnet;
return true;
}
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx",
@ -238,23 +235,19 @@ subnet_t *str2net(const char *subnetstr)
for(i = 0; i < 6; i++)
subnet->net.mac.address.x[i] = x[i];
return subnet;
return true;
}
free(subnet);
return NULL;
return false;
}
char *net2str(const subnet_t *subnet)
bool net2str(char *netstr, int len, const subnet_t *subnet)
{
char *netstr;
cp();
switch (subnet->type) {
case SUBNET_MAC:
asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx",
snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx",
subnet->net.mac.address.x[0],
subnet->net.mac.address.x[1],
subnet->net.mac.address.x[2],
@ -263,7 +256,7 @@ char *net2str(const subnet_t *subnet)
break;
case SUBNET_IPV4:
asprintf(&netstr, "%hu.%hu.%hu.%hu/%d",
snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d",
subnet->net.ipv4.address.x[0],
subnet->net.ipv4.address.x[1],
subnet->net.ipv4.address.x[2],
@ -271,7 +264,7 @@ char *net2str(const subnet_t *subnet)
break;
case SUBNET_IPV6:
asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
ntohs(subnet->net.ipv6.address.x[0]),
ntohs(subnet->net.ipv6.address.x[1]),
ntohs(subnet->net.ipv6.address.x[2]),
@ -313,7 +306,7 @@ subnet_t *lookup_subnet_mac(const mac_t *address)
subnet.net.mac.address = *address;
subnet.owner = NULL;
p = (subnet_t *) avl_search(subnet_tree, &subnet);
p = avl_search(subnet_tree, &subnet);
return p;
}
@ -332,7 +325,7 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address)
do {
/* Go find subnet */
p = (subnet_t *) avl_search_closest_smaller(subnet_tree, &subnet);
p = avl_search_closest_smaller(subnet_tree, &subnet);
/* Check if the found subnet REALLY matches */
@ -370,7 +363,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address)
do {
/* Go find subnet */
p = (subnet_t *) avl_search_closest_smaller(subnet_tree, &subnet);
p = avl_search_closest_smaller(subnet_tree, &subnet);
/* Check if the found subnet REALLY matches */
@ -394,7 +387,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address)
void dump_subnets(void)
{
char *netstr;
char netstr[MAXNETSTR];
subnet_t *subnet;
avl_node_t *node;
@ -403,10 +396,10 @@ void dump_subnets(void)
logger(LOG_DEBUG, _("Subnet list:"));
for(node = subnet_tree->head; node; node = node->next) {
subnet = (subnet_t *) node->data;
netstr = net2str(subnet);
subnet = node->data;
if(!net2str(netstr, sizeof netstr, subnet))
continue;
logger(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
free(netstr);
}
logger(LOG_DEBUG, _("End of subnet list."));

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: subnet.h,v 1.4 2003/08/24 20:38:28 guus Exp $
$Id: subnet.h,v 1.1.2.27 2003/12/12 19:52:25 guus Exp $
*/
#ifndef __TINC_SUBNET_H__
@ -34,7 +34,6 @@ typedef enum subnet_type_t {
typedef struct subnet_mac_t {
mac_t address;
time_t lastseen;
} subnet_mac_t;
typedef struct subnet_ipv4_t {
@ -51,9 +50,9 @@ typedef struct subnet_ipv6_t {
typedef struct subnet_t {
struct node_t *owner; /* the owner of this subnet */
struct node_t *uplink; /* the uplink which we should send packets to for this subnet */
subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
time_t expires; /* expiry time */
/* And now for the actual subnet: */
@ -64,6 +63,9 @@ typedef struct subnet_t {
} net;
} subnet_t;
#define MAXNETSTR 64
extern int subnet_compare(const struct subnet_t *, const struct subnet_t *);
extern subnet_t *new_subnet(void) __attribute__ ((__malloc__));
extern void free_subnet(subnet_t *);
extern void init_subnets(void);
@ -72,8 +74,8 @@ extern avl_tree_t *new_subnet_tree(void) __attribute__ ((__malloc__));
extern void free_subnet_tree(avl_tree_t *);
extern void subnet_add(struct node_t *, subnet_t *);
extern void subnet_del(struct node_t *, subnet_t *);
extern char *net2str(const subnet_t *);
extern subnet_t *str2net(const char *);
extern bool net2str(char *, int, const subnet_t *);
extern bool str2net(subnet_t *, const char *);
extern subnet_t *lookup_subnet(const struct node_t *, const subnet_t *);
extern subnet_t *lookup_subnet_mac(const mac_t *);
extern subnet_t *lookup_subnet_ipv4(const ipv4_t *);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: tincd.c,v 1.17 2003/08/24 20:38:29 guus Exp $
$Id: tincd.c,v 1.10.4.90 2003/12/07 14:31:09 guus Exp $
*/
#include "system.h"
@ -39,6 +39,7 @@
#include <lzo1x.h>
#include <getopt.h>
#include <pidfile.h>
#include "conf.h"
#include "device.h"
@ -291,7 +292,7 @@ static bool keygen(int bits)
char *filename;
fprintf(stderr, _("Generating %d bits keys:\n"), bits);
rsa_key = RSA_generate_key(bits, 0xFFFF, indicator, NULL);
rsa_key = RSA_generate_key(bits, 0x10001, indicator, NULL);
if(!rsa_key) {
fprintf(stderr, _("Error during key generation!\n"));
@ -482,17 +483,10 @@ int main2(int argc, char **argv)
return 1;
/* Setup sockets and open device. If it doesn't work, don't give up but try again. */
/* Setup sockets and open device. */
while(!setup_network_connections()) {
if(do_detach) {
logger(LOG_NOTICE, _("Restarting in %d seconds!"), maxtimeout);
sleep(maxtimeout);
} else {
logger(LOG_ERR, _("Not restarting."));
return 1;
}
}
if(!setup_network_connections())
goto end;
/* Start main loop. It only exits when tinc is killed. */
@ -505,6 +499,12 @@ int main2(int argc, char **argv)
ifdebug(CONNECTIONS)
dump_device_stats();
end:
logger(LOG_NOTICE, _("Terminating"));
#ifndef HAVE_MINGW
remove_pid(pidfilename);
#endif
return status;
}