Move CABAL branch to its rightful place: the trunk.
This commit is contained in:
commit
42e01abd54
97 changed files with 3300 additions and 1616 deletions
|
@ -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
14
COPYING.README
Normal 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
|
15
Makefile.am
15
Makefile.am
|
@ -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
15
NEWS
|
@ -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
12
README
|
@ -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
13
TODO
|
@ -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.
|
||||
|
|
157
autogen.sh
157
autogen.sh
|
@ -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
|
19
configure.in
19
configure.in
|
@ -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]) ]
|
||||
)
|
||||
|
||||
|
|
3
cvsusers
3
cvsusers
|
@ -1,3 +0,0 @@
|
|||
zarq:Ivo Timmermans <ivo@o2w.nl>
|
||||
guus:Guus Sliepen <guus@sliepen.eu.org>
|
||||
wsl:Wessel Dankers <wsl@nl.linux.org>
|
|
@ -1 +0,0 @@
|
|||
Makefile.in Makefile tinc.info sample-config.tar.gz
|
|
@ -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
|
||||
==================
|
||||
|
|
|
@ -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
|
||||
==============
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
----------------------------------
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
622
doc/tinc.texi
622
doc/tinc.texi
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Makefile Makefile.in .deps
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 $
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
120
lib/hooks.c
120
lib/hooks.c
|
@ -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);
|
||||
}
|
10
lib/ipv4.h
10
lib/ipv4.h
|
@ -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__ */
|
||||
|
|
23
lib/ipv6.h
23
lib/ipv6.h
|
@ -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__ */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Makefile.am Makefile.in Makefile
|
4
m4/Makefile.am
Normal file
4
m4/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
|||
## Process this file with automake to produce Makefile.in -*-Makefile-*-
|
||||
|
||||
EXTRA_DIST = README *.m4
|
||||
|
|
@ -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,
|
||||
[
|
||||
|
|
18
m4/lzo.m4
18
m4/lzo.m4
|
@ -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.")]
|
||||
|
|
14
m4/malloc.m4
14
m4/malloc.m4
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
24
m4/tuntap.m4
24
m4/tuntap.m4
|
@ -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"]
|
||||
)]
|
||||
)
|
||||
|
||||
|
|
18
m4/zlib.m4
18
m4/zlib.m4
|
@ -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.")]
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Makefile.in.in POTFILES Makefile.in Makefile cat-id-tbl.c *.gmo stamp-cat-id *.pot
|
16
po/Makevars
16
po/Makevars
|
@ -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 =
|
||||
|
|
1223
po/old/es.po
Normal file
1223
po/old/es.po
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1 +0,0 @@
|
|||
*.o .libs tincd Makefile.in Makefile .deps
|
|
@ -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
|
||||
|
||||
|
|
30
src/conf.c
30
src/conf.c
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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"
|
||||
|
|
39
src/graph.c
39
src/graph.c
|
@ -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 ? : "");
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
29
src/meta.c
29
src/meta.c
|
@ -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;
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
49
src/net.c
49
src/net.c
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
146
src/net_packet.c
146
src/net_packet.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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__
|
||||
|
|
19
src/node.c
19
src/node.c
|
@ -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."));
|
||||
|
|
33
src/node.h
33
src/node.h
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
651
src/route.c
651
src/route.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 $
|
||||
*/
|
||||
|
||||
|
||||
|
|
49
src/subnet.c
49
src/subnet.c
|
@ -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."));
|
||||
|
|
12
src/subnet.h
12
src/subnet.h
|
@ -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 *);
|
||||
|
|
24
src/tincd.c
24
src/tincd.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue