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
|
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:
|
ChangeLog:
|
||||||
cvs2cl -U cvsusers --fsf
|
svn log > ChangeLog
|
||||||
|
|
||||||
cvs-clean: maintainer-clean
|
svn-clean: maintainer-clean
|
||||||
for f in $(CVS_CREATED) `find . -name Makefile.in` tinc-$(VERSION).tar.gz; do\
|
svn status --no-ignore | sed -n 's/^[?I] \+//p' | tr '\012' '\0' | xargs -r0 rm -rf
|
||||||
rm -Rf "$$f"; \
|
|
||||||
done
|
|
||||||
grep -l gettext `find m4 -type f` | xargs rm -f
|
|
||||||
|
|
||||||
deb:
|
deb:
|
||||||
dpkg-buildpackage -rfakeroot
|
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
|
version 1.0.1 Aug 14 2003
|
||||||
|
|
||||||
* Allow empty lines in config files.
|
* 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.
|
instructions may be found in the INSTALL file.
|
||||||
|
|
||||||
tinc is Copyright (C) 1998-2003 by:
|
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
|
version adds sequence numbers and message authentication codes to prevent such
|
||||||
attacks.
|
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
|
Cryptography is a hard thing to get right. We cannot make any
|
||||||
guarantees. Time, review and feedback are the only things that can
|
guarantees. Time, review and feedback are the only things that can
|
||||||
prove the security of any cryptographic product. If you wish to review
|
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
|
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.
|
of tinc.
|
||||||
|
|
||||||
|
|
||||||
|
|
13
TODO
13
TODO
|
@ -1,14 +1,3 @@
|
||||||
TODO LIST
|
TODO LIST
|
||||||
|
|
||||||
* Stop using UDP source address as the identifier of the remote tinc daemon.
|
* Think of new things to do.
|
||||||
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.
|
|
||||||
|
|
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 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_PREREQ(2.59)
|
||||||
AC_INIT(src/tincd.c)
|
AC_INIT
|
||||||
AM_INIT_AUTOMAKE(tinc, 2.0-cvs)
|
AC_CONFIG_SRCDIR([src/tincd.c])
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_INIT_AUTOMAKE(tinc, 1.0-cvs)
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
dnl Include the macros from the m4/ directory
|
dnl Include the macros from the m4/ directory
|
||||||
|
@ -197,7 +198,7 @@ AC_STRUCT_TM
|
||||||
|
|
||||||
tinc_ATTRIBUTE(__malloc__)
|
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
|
[#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -253,7 +254,7 @@ dnl Checks for library functions.
|
||||||
AC_FUNC_MEMCMP
|
AC_FUNC_MEMCMP
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
AC_TYPE_SIGNAL
|
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_MALLOC
|
||||||
jm_FUNC_REALLOC
|
jm_FUNC_REALLOC
|
||||||
|
|
||||||
|
@ -284,13 +285,13 @@ tinc_LZO
|
||||||
|
|
||||||
dnl Check if support for jumbograms is requested
|
dnl Check if support for jumbograms is requested
|
||||||
AC_ARG_ENABLE(jumbograms,
|
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)]) ]
|
[ AC_DEFINE(ENABLE_JUMBOGRAMS, 1, [Support for jumbograms (packets up to 9000 bytes)]) ]
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl Check if checkpoint tracing has to be enabled
|
dnl Check if checkpoint tracing has to be enabled
|
||||||
AC_ARG_ENABLE(tracing,
|
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]) ]
|
[ 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
|
provided that the entire resulting derived work is distributed
|
||||||
under the terms of a permission notice identical to this one.
|
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
|
1. Synchronisation
|
||||||
==================
|
==================
|
||||||
|
|
|
@ -12,7 +12,7 @@ Network daemon.
|
||||||
provided that the entire resulting derived work is distributed
|
provided that the entire resulting derived work is distributed
|
||||||
under the terms of a permission notice identical to this one.
|
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
|
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
|
provided that the entire resulting derived work is distributed
|
||||||
under the terms of a permission notice identical to this one.
|
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
|
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
|
provided that the entire resulting derived work is distributed
|
||||||
under the terms of a permission notice identical to this one.
|
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
|
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
|
or
|
||||||
.Va PrivateKeyFile
|
.Va PrivateKeyFile
|
||||||
specified in the configuration file.
|
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
|
.El
|
||||||
.Sh HOST CONFIGURATION FILES
|
.Sh HOST CONFIGURATION FILES
|
||||||
The host configuration files contain all information needed
|
The host configuration files contain all information needed
|
||||||
|
@ -246,6 +251,7 @@ Any cipher supported by OpenSSL is recognised.
|
||||||
Furthermore, specifying
|
Furthermore, specifying
|
||||||
.Qq none
|
.Qq none
|
||||||
will turn off packet encryption.
|
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
|
.It Va Compression Li = Ar level Pq 0
|
||||||
This option sets the level of compression used for UDP packets.
|
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),
|
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
|
Can be anything from
|
||||||
.Qq 0
|
.Qq 0
|
||||||
up to the length of the digest produced by the digest algorithm.
|
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
|
.It Va Port Li = Ar port Pq 655
|
||||||
The port number on which this tinc daemon is listening for incoming connections.
|
The port number on which this tinc daemon is listening for incoming connections.
|
||||||
.It Va PublicKey Li = Ar key Bq obsolete
|
.It Va PublicKey Li = Ar key Bq obsolete
|
||||||
|
@ -314,7 +325,7 @@ Setting this options also implicitly sets IndirectData.
|
||||||
.Sh SCRIPTS
|
.Sh SCRIPTS
|
||||||
Apart from reading the server and host configuration files,
|
Apart from reading the server and host configuration files,
|
||||||
tinc can also run scripts at certain moments.
|
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 .
|
.Pa .bat .
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
.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
|
If
|
||||||
.Ar BITS
|
.Ar BITS
|
||||||
is omitted, the default length will be 1024 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
|
.It Fl L, -mlock
|
||||||
Lock tinc into main memory.
|
Lock tinc into main memory.
|
||||||
This will prevent sensitive data like shared private keys to be written to the system swap files/partitions.
|
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
|
This will log a message indicating
|
||||||
.Nm
|
.Nm
|
||||||
has started along with a version number.
|
has started along with a version number.
|
||||||
It will also any serious error.
|
It will also log any serious error.
|
||||||
.It 1
|
.It 1
|
||||||
This will log all connections that are made with other tinc daemons.
|
This will log all connections that are made with other tinc daemons.
|
||||||
.It 2
|
.It 2
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Makefile Makefile.in .deps
|
|
|
@ -1,5 +1,5 @@
|
||||||
## Process this file with automake to produce Makefile.in
|
## 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
|
noinst_LIBRARIES = libvpn.a
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
library for inclusion into tinc (http://tinc.nl.linux.org/) by
|
library for inclusion into tinc (http://tinc.nl.linux.org/) by
|
||||||
Guus Sliepen <guus@sliepen.eu.org>.
|
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"
|
#include "system.h"
|
||||||
|
@ -280,7 +280,7 @@ void avl_free_tree(avl_tree_t *tree)
|
||||||
|
|
||||||
avl_node_t *avl_alloc_node(void)
|
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)
|
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
|
library for inclusion into tinc (http://tinc.nl.linux.org/) by
|
||||||
Guus Sliepen <guus@sliepen.eu.org>.
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __DROPIN_H__
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_ETHERNET_H__
|
||||||
|
@ -27,26 +27,38 @@
|
||||||
#define ETH_ALEN 6
|
#define ETH_ALEN 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ETHER_ADDR_LEN
|
|
||||||
#define ETHER_ADDR_LEN 6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ARPHRD_ETHER
|
#ifndef ARPHRD_ETHER
|
||||||
#define ARPHRD_ETHER 1
|
#define ARPHRD_ETHER 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ETHERTYPE_IP
|
#ifndef ETH_P_IP
|
||||||
#define ETHERTYPE_IP 0x0800
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_ARPHDR
|
#ifndef HAVE_STRUCT_ARPHDR
|
||||||
struct arphdr {
|
struct arphdr {
|
||||||
unsigned short int ar_hrd;
|
uint16_t ar_hrd;
|
||||||
unsigned short int ar_pro;
|
uint16_t ar_pro;
|
||||||
unsigned char ar_hln;
|
uint8_t ar_hln;
|
||||||
unsigned char ar_pln;
|
uint8_t ar_pln;
|
||||||
unsigned short int ar_op;
|
uint16_t ar_op;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
|
|
||||||
#define ARPOP_REQUEST 1
|
#define ARPOP_REQUEST 1
|
||||||
#define ARPOP_REPLY 2
|
#define ARPOP_REPLY 2
|
||||||
|
@ -64,7 +76,7 @@ struct ether_arp {
|
||||||
uint8_t arp_spa[4];
|
uint8_t arp_spa[4];
|
||||||
uint8_t arp_tha[ETH_ALEN];
|
uint8_t arp_tha[ETH_ALEN];
|
||||||
uint8_t arp_tpa[4];
|
uint8_t arp_tpa[4];
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#define arp_hrd ea_hdr.ar_hrd
|
#define arp_hrd ea_hdr.ar_hrd
|
||||||
#define arp_pro ea_hdr.ar_pro
|
#define arp_pro ea_hdr.ar_pro
|
||||||
#define arp_hln ea_hdr.ar_hln
|
#define arp_hln ea_hdr.ar_hln
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* See getaddrinfo.c and getnameinfo.c.
|
* 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 */
|
/* for old netdb.h */
|
||||||
#ifndef EAI_NODATA
|
#ifndef EAI_NODATA
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "ipv4.h"
|
#include "ipv4.h"
|
||||||
#include "ipv6.h"
|
#include "ipv6.h"
|
||||||
#include "fake-getaddrinfo.h"
|
#include "fake-getaddrinfo.h"
|
||||||
|
#include "xalloc.h"
|
||||||
|
|
||||||
#ifndef HAVE_GAI_STRERROR
|
#ifndef HAVE_GAI_STRERROR
|
||||||
char *gai_strerror(int ecode)
|
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
|
#ifndef _FAKE_GETADDRINFO_H
|
||||||
#define _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
|
#ifndef _FAKE_GETNAMEINFO_H
|
||||||
#define _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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_IPV4_H__
|
||||||
|
@ -35,6 +35,10 @@
|
||||||
#define ICMP_DEST_UNREACH 3
|
#define ICMP_DEST_UNREACH 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ICMP_FRAG_NEEDED
|
||||||
|
#define ICMP_FRAG_NEEDED 4
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ICMP_NET_UNKNOWN
|
#ifndef ICMP_NET_UNKNOWN
|
||||||
#define ICMP_NET_UNKNOWN 6
|
#define ICMP_NET_UNKNOWN 6
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,7 +72,7 @@ struct ip {
|
||||||
uint8_t ip_p;
|
uint8_t ip_p;
|
||||||
uint16_t ip_sum;
|
uint16_t ip_sum;
|
||||||
struct in_addr ip_src, ip_dst;
|
struct in_addr ip_src, ip_dst;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_ICMP
|
#ifndef HAVE_STRUCT_ICMP
|
||||||
|
@ -126,7 +130,7 @@ struct icmp {
|
||||||
#define icmp_radv icmp_dun.id_radv
|
#define icmp_radv icmp_dun.id_radv
|
||||||
#define icmp_mask icmp_dun.id_mask
|
#define icmp_mask icmp_dun.id_mask
|
||||||
#define icmp_data icmp_dun.id_data
|
#define icmp_data icmp_dun.id_data
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __TINC_IPV4_H__ */
|
#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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_IPV6_H__
|
||||||
|
@ -38,7 +38,7 @@ struct in6_addr {
|
||||||
uint16_t u6_addr16[8];
|
uint16_t u6_addr16[8];
|
||||||
uint32_t u6_addr32[4];
|
uint32_t u6_addr32[4];
|
||||||
} in6_u;
|
} in6_u;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#define s6_addr in6_u.u6_addr8
|
#define s6_addr in6_u.u6_addr8
|
||||||
#define s6_addr16 in6_u.u6_addr16
|
#define s6_addr16 in6_u.u6_addr16
|
||||||
#define s6_addr32 in6_u.u6_addr32
|
#define s6_addr32 in6_u.u6_addr32
|
||||||
|
@ -51,7 +51,7 @@ struct sockaddr_in6 {
|
||||||
uint32_t sin6_flowinfo;
|
uint32_t sin6_flowinfo;
|
||||||
struct in6_addr sin6_addr;
|
struct in6_addr sin6_addr;
|
||||||
uint32_t sin6_scope_id;
|
uint32_t sin6_scope_id;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef IN6_IS_ADDR_V4MAPPED
|
#ifndef IN6_IS_ADDR_V4MAPPED
|
||||||
|
@ -74,7 +74,7 @@ struct ip6_hdr {
|
||||||
} ip6_ctlun;
|
} ip6_ctlun;
|
||||||
struct in6_addr ip6_src;
|
struct in6_addr ip6_src;
|
||||||
struct in6_addr ip6_dst;
|
struct in6_addr ip6_dst;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
|
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
|
||||||
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
|
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
|
||||||
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
|
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
|
||||||
|
@ -93,28 +93,37 @@ struct icmp6_hdr {
|
||||||
uint16_t icmp6_un_data16[2];
|
uint16_t icmp6_un_data16[2];
|
||||||
uint8_t icmp6_un_data8[4];
|
uint8_t icmp6_un_data8[4];
|
||||||
} icmp6_dataun;
|
} icmp6_dataun;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#define ICMP6_DST_UNREACH_NOROUTE 0
|
#define ICMP6_DST_UNREACH_NOROUTE 0
|
||||||
#define ICMP6_DST_UNREACH 1
|
#define ICMP6_DST_UNREACH 1
|
||||||
|
#define ICMP6_PACKET_TOO_BIG 2
|
||||||
#define ICMP6_DST_UNREACH_ADDR 3
|
#define ICMP6_DST_UNREACH_ADDR 3
|
||||||
#define ND_NEIGHBOR_SOLICIT 135
|
#define ND_NEIGHBOR_SOLICIT 135
|
||||||
#define ND_NEIGHBOR_ADVERT 136
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
|
#ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
|
||||||
struct nd_neighbor_solicit {
|
struct nd_neighbor_solicit {
|
||||||
struct icmp6_hdr nd_ns_hdr;
|
struct icmp6_hdr nd_ns_hdr;
|
||||||
struct in6_addr nd_ns_target;
|
struct in6_addr nd_ns_target;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#define ND_OPT_SOURCE_LINKADDR 1
|
#define ND_OPT_SOURCE_LINKADDR 1
|
||||||
#define ND_OPT_TARGET_LINKADDR 2
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_ND_OPT_HDR
|
#ifndef HAVE_STRUCT_ND_OPT_HDR
|
||||||
struct nd_opt_hdr {
|
struct nd_opt_hdr {
|
||||||
uint8_t nd_opt_type;
|
uint8_t nd_opt_type;
|
||||||
uint8_t nd_opt_len;
|
uint8_t nd_opt_len;
|
||||||
};
|
} __attribute__ ((__packed__));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __TINC_IPV6_H__ */
|
#endif /* __TINC_IPV6_H__ */
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -44,7 +44,7 @@ void list_free(list_t *list)
|
||||||
|
|
||||||
list_node_t *list_alloc_node(void)
|
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)
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_LIST_H__
|
||||||
|
|
|
@ -34,14 +34,14 @@
|
||||||
* 0 is returned if either there's no pidfile, it's empty
|
* 0 is returned if either there's no pidfile, it's empty
|
||||||
* or no pid can be read.
|
* or no pid can be read.
|
||||||
*/
|
*/
|
||||||
int read_pid (char *pidfile)
|
pid_t read_pid (char *pidfile)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int pid;
|
long pid;
|
||||||
|
|
||||||
if (!(f=fopen(pidfile,"r")))
|
if (!(f=fopen(pidfile,"r")))
|
||||||
return 0;
|
return 0;
|
||||||
fscanf(f,"%d", &pid);
|
fscanf(f,"%ld", &pid);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return pid;
|
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
|
* 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
|
* 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... */
|
/* Amazing ! _I_ am already holding the pid file... */
|
||||||
if ((!pid) || (pid == getpid ()))
|
if ((!pid) || (pid == getpid ()))
|
||||||
|
@ -68,7 +68,7 @@ int check_pid (char *pidfile)
|
||||||
/* But... errno is usually changed only on error.. */
|
/* But... errno is usually changed only on error.. */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (kill(pid, 0) && errno == ESRCH)
|
if (kill(pid, 0) && errno == ESRCH)
|
||||||
return(0);
|
return 0;
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
@ -78,30 +78,26 @@ int check_pid (char *pidfile)
|
||||||
* Writes the pid to the specified file. If that fails 0 is
|
* Writes the pid to the specified file. If that fails 0 is
|
||||||
* returned, otherwise the pid.
|
* returned, otherwise the pid.
|
||||||
*/
|
*/
|
||||||
int write_pid (char *pidfile)
|
pid_t write_pid (char *pidfile)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int fd;
|
int fd;
|
||||||
int pid;
|
pid_t pid;
|
||||||
|
|
||||||
if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
|
if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
|
||||||
|| ((f = fdopen(fd, "r+")) == NULL) ) {
|
|| ((f = fdopen(fd, "r+")) == NULL) ) {
|
||||||
fprintf(stderr, "Can't open or create %s.\n", pidfile);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_FLOCK
|
#ifdef HAVE_FLOCK
|
||||||
if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
|
if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
|
||||||
fscanf(f, "%d", &pid);
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
printf("Can't lock, lock is held by pid %d.\n", pid);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
if (!fprintf(f,"%d\n", pid)) {
|
if (!fprintf(f,"%ld\n", (long)pid)) {
|
||||||
printf("Can't write pid , %s.\n", strerror(errno));
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +105,6 @@ int write_pid (char *pidfile)
|
||||||
|
|
||||||
#ifdef HAVE_FLOCK
|
#ifdef HAVE_FLOCK
|
||||||
if (flock(fd, LOCK_UN) == -1) {
|
if (flock(fd, LOCK_UN) == -1) {
|
||||||
printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno));
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* 0 is returned if either there's no pidfile, it's empty
|
* 0 is returned if either there's no pidfile, it's empty
|
||||||
* or no pid can be read.
|
* or no pid can be read.
|
||||||
*/
|
*/
|
||||||
int read_pid (char *pidfile);
|
pid_t read_pid (char *pidfile);
|
||||||
|
|
||||||
/* check_pid
|
/* check_pid
|
||||||
*
|
*
|
||||||
|
@ -34,14 +34,14 @@ int read_pid (char *pidfile);
|
||||||
* table (using /proc) to determine if the process already exists. If
|
* table (using /proc) to determine if the process already exists. If
|
||||||
* so 1 is returned, otherwise 0.
|
* so 1 is returned, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int check_pid (char *pidfile);
|
pid_t check_pid (char *pidfile);
|
||||||
|
|
||||||
/* write_pid
|
/* write_pid
|
||||||
*
|
*
|
||||||
* Writes the pid to the specified file. If that fails 0 is
|
* Writes the pid to the specified file. If that fails 0 is
|
||||||
* returned, otherwise the pid.
|
* returned, otherwise the pid.
|
||||||
*/
|
*/
|
||||||
int write_pid (char *pidfile);
|
pid_t write_pid (char *pidfile);
|
||||||
|
|
||||||
/* remove_pid
|
/* 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 Check to find out whether function attributes are supported.
|
||||||
dnl If they are not, #define them to be nothing.
|
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,
|
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
|
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_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"
|
[lzo="$withval"
|
||||||
CFLAGS="$CFLAGS -I$withval/include"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
||||||
LIBS="$LIBS -L$withval/lib"]
|
LDFLAGS="$LDFLAGS -L$withval/lib"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_WITH(lzo-include,
|
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"
|
[lzo_include="$withval"
|
||||||
CFLAGS="$CFLAGS -I$withval"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval"]
|
CPPFLAGS="$CPPFLAGS -I$withval"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_WITH(lzo-lib,
|
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"
|
[lzo_lib="$withval"
|
||||||
LIBS="$LIBS -L$withval"]
|
LDFLAGS="$LDFLAGS -L$withval"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_CHECK_HEADERS(lzo1x.h,
|
AC_CHECK_HEADERS(lzo1x.h,
|
||||||
|
@ -30,8 +26,6 @@ AC_DEFUN(tinc_LZO,
|
||||||
[AC_MSG_ERROR("lzo header files not found."); break]
|
[AC_MSG_ERROR("lzo header files not found."); break]
|
||||||
)
|
)
|
||||||
|
|
||||||
CPPFLAGS="$tinc_ac_save_CPPFLAGS"
|
|
||||||
|
|
||||||
AC_CHECK_LIB(lzo, lzo1x_1_compress,
|
AC_CHECK_LIB(lzo, lzo1x_1_compress,
|
||||||
[LIBS="$LIBS -llzo"],
|
[LIBS="$LIBS -llzo"],
|
||||||
[AC_MSG_ERROR("lzo libraries not found.")]
|
[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 #undef malloc
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
AC_DEFUN(jm_FUNC_MALLOC,
|
AC_DEFUN([jm_FUNC_MALLOC],
|
||||||
[
|
[
|
||||||
if test x = y; then
|
if test x = y; then
|
||||||
dnl This code is deliberately never run via ./configure.
|
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_DEFINE(HAVE_DONE_WORKING_MALLOC_CHECK, 1, [Needed for xmalloc.c])
|
||||||
|
|
||||||
AC_CACHE_CHECK([for working malloc], jm_cv_func_working_malloc,
|
AC_CACHE_CHECK([for working malloc], jm_cv_func_working_malloc,
|
||||||
[AC_TRY_RUN([
|
[AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||||
char *malloc ();
|
char *malloc ();
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
exit (malloc (0) ? 0 : 1);
|
exit (malloc (0) ? 0 : 1);
|
||||||
}
|
}
|
||||||
],
|
])],
|
||||||
jm_cv_func_working_malloc=yes,
|
[jm_cv_func_working_malloc=yes],
|
||||||
jm_cv_func_working_malloc=no,
|
[jm_cv_func_working_malloc=no],
|
||||||
dnl When crosscompiling, assume malloc is broken.
|
[When crosscompiling])
|
||||||
jm_cv_func_working_malloc=no)
|
|
||||||
])
|
])
|
||||||
if test $jm_cv_func_working_malloc = no; then
|
if test $jm_cv_func_working_malloc = no; then
|
||||||
dnl This was: LIBOBJS="$LIBOBJS malloc.$ac_objext"
|
|
||||||
AC_LIBOBJ([malloc])
|
AC_LIBOBJ([malloc])
|
||||||
AC_DEFINE(malloc, rpl_malloc, [Replacement malloc()])
|
AC_DEFINE(malloc, rpl_malloc, [Replacement malloc()])
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,28 +1,24 @@
|
||||||
dnl Check to find the OpenSSL headers/libraries
|
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_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"
|
[openssl="$withval"
|
||||||
CFLAGS="$CFLAGS -I$withval/include"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
||||||
LIBS="$LIBS -L$withval/lib"]
|
LDFLAGS="$LDFLAGS -L$withval/lib"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_WITH(openssl-include,
|
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"
|
[openssl_include="$withval"
|
||||||
CFLAGS="$CFLAGS -I$withval"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval"]
|
CPPFLAGS="$CPPFLAGS -I$withval"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_WITH(openssl-lib,
|
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"
|
[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,
|
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]
|
[AC_MSG_ERROR([OpenSSL header files not found.]); break]
|
||||||
)
|
)
|
||||||
|
|
||||||
CPPFLAGS="$tinc_ac_save_CPPFLAGS"
|
|
||||||
|
|
||||||
case $host_os in
|
case $host_os in
|
||||||
*mingw*)
|
*mingw*)
|
||||||
AC_CHECK_LIB(crypto, SHA1_version,
|
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 #undef realloc
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
AC_DEFUN(jm_FUNC_REALLOC,
|
AC_DEFUN([jm_FUNC_REALLOC],
|
||||||
[
|
[
|
||||||
if test x = y; then
|
if test x = y; then
|
||||||
dnl This code is deliberately never run via ./configure.
|
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_DEFINE(HAVE_DONE_WORKING_REALLOC_CHECK, 1, [Needed for xmalloc.c])
|
||||||
|
|
||||||
AC_CACHE_CHECK([for working realloc], jm_cv_func_working_realloc,
|
AC_CACHE_CHECK([for working realloc], jm_cv_func_working_realloc,
|
||||||
[AC_TRY_RUN([
|
[AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||||
char *realloc ();
|
char *realloc ();
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
exit (realloc (0, 0) ? 0 : 1);
|
exit (realloc (0, 0) ? 0 : 1);
|
||||||
}
|
}
|
||||||
],
|
])],
|
||||||
jm_cv_func_working_realloc=yes,
|
[jm_cv_func_working_realloc=yes],
|
||||||
jm_cv_func_working_realloc=no,
|
[jm_cv_func_working_realloc=no],
|
||||||
dnl When crosscompiling, assume realloc is broken.
|
[When crosscompiling])
|
||||||
jm_cv_func_working_realloc=no)
|
|
||||||
])
|
])
|
||||||
if test $jm_cv_func_working_realloc = no; then
|
if test $jm_cv_func_working_realloc = no; then
|
||||||
dnl This was: LIBOBJS="$LIBOBJS realloc.$ac_objext"
|
|
||||||
AC_LIBOBJ([realloc])
|
AC_LIBOBJ([realloc])
|
||||||
AC_DEFINE(realloc, rpl_realloc, [Replacement realloc()])
|
AC_DEFINE(realloc, rpl_realloc, [Replacement realloc()])
|
||||||
fi
|
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
|
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_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="$withval",
|
||||||
kerneldir="/usr/src/linux"
|
kerneldir="/usr/src/linux"
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_CACHE_CHECK([for linux/if_tun.h], tinc_cv_linux_if_tun_h,
|
AC_CACHE_CHECK([for linux/if_tun.h], tinc_cv_linux_if_tun_h,
|
||||||
[
|
[
|
||||||
AC_TRY_COMPILE([#include "$kerneldir/include/linux/if_tun.h"],
|
AC_COMPILE_IFELSE(
|
||||||
[int a = IFF_TAP;],
|
AC_LANG_PROGRAM([
|
||||||
if_tun_h="\"$kerneldir/include/linux/if_tun.h\"",
|
#include "$kerneldir/include/linux/if_tun.h"
|
||||||
[AC_TRY_COMPILE([#include <linux/if_tun.h>],
|
int a = IFF_TAP;
|
||||||
[int a = IFF_TAP;],
|
]),
|
||||||
if_tun_h="default",
|
[if_tun_h="\"$kerneldir/include/linux/if_tun.h\""],
|
||||||
if_tun_h="no"
|
[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
|
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_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"
|
[zlib="$withval"
|
||||||
CFLAGS="$CFLAGS -I$withval/include"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
||||||
LIBS="$LIBS -L$withval/lib"]
|
LDFLAGS="$LDFLAGS -L$withval/lib"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_WITH(zlib-include,
|
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"
|
[zlib_include="$withval"
|
||||||
CFLAGS="$CFLAGS -I$withval"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$withval"]
|
CPPFLAGS="$CPPFLAGS -I$withval"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_WITH(zlib-lib,
|
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"
|
[zlib_lib="$withval"
|
||||||
LIBS="$LIBS -L$withval"]
|
LDFLAGS="$LDFLAGS -L$withval"]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_CHECK_HEADERS(zlib.h,
|
AC_CHECK_HEADERS(zlib.h,
|
||||||
|
@ -30,8 +26,6 @@ AC_DEFUN(tinc_ZLIB,
|
||||||
[AC_MSG_ERROR("zlib header files not found."); break]
|
[AC_MSG_ERROR("zlib header files not found."); break]
|
||||||
)
|
)
|
||||||
|
|
||||||
CPPFLAGS="$tinc_ac_save_CPPFLAGS"
|
|
||||||
|
|
||||||
AC_CHECK_LIB(z, compress2,
|
AC_CHECK_LIB(z, compress2,
|
||||||
[LIBS="$LIBS -lz"],
|
[LIBS="$LIBS -lz"],
|
||||||
[AC_MSG_ERROR("zlib libraries not found.")]
|
[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.
|
# their copyright.
|
||||||
COPYRIGHT_HOLDER = Ivo Timmermans and Guus Sliepen
|
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
|
# This is the list of locale categories, beyond LC_MESSAGES, for which the
|
||||||
# message catalogs shall be used. It is usually empty.
|
# message catalogs shall be used. It is usually empty.
|
||||||
EXTRA_LOCALE_CATEGORIES =
|
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
|
## 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
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -73,7 +73,7 @@ config_t *new_config(void)
|
||||||
{
|
{
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
return (config_t *) xmalloc_and_zero(sizeof(config_t));
|
return xmalloc_and_zero(sizeof(config_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_config(config_t *cfg)
|
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) {
|
||||||
if(node->next) {
|
if(node->next) {
|
||||||
found = (config_t *) node->next->data;
|
found = node->next->data;
|
||||||
|
|
||||||
if(!strcasecmp(found->variable, cfg->variable))
|
if(!strcasecmp(found->variable, cfg->variable))
|
||||||
return found;
|
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)
|
bool get_config_subnet(const config_t *cfg, subnet_t ** result)
|
||||||
{
|
{
|
||||||
subnet_t *subnet;
|
subnet_t subnet = {0};
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
if(!cfg)
|
if(!cfg)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
subnet = str2net(cfg->value);
|
if(!str2net(&subnet, cfg->value)) {
|
||||||
|
|
||||||
if(!subnet) {
|
|
||||||
logger(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"),
|
logger(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"),
|
||||||
cfg->variable, cfg->file, cfg->line);
|
cfg->variable, cfg->file, cfg->line);
|
||||||
return false;
|
return false;
|
||||||
|
@ -231,17 +229,16 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result)
|
||||||
|
|
||||||
/* Teach newbies what subnets are... */
|
/* Teach newbies what subnets are... */
|
||||||
|
|
||||||
if(((subnet->type == SUBNET_IPV4)
|
if(((subnet.type == SUBNET_IPV4)
|
||||||
&& !maskcheck(&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t)))
|
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t)))
|
||||||
|| ((subnet->type == SUBNET_IPV6)
|
|| ((subnet.type == SUBNET_IPV6)
|
||||||
&& !maskcheck(&subnet->net.ipv6.address, subnet->net.ipv6.prefixlength, sizeof(ipv6_t)))) {
|
&& !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"),
|
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);
|
cfg->variable, cfg->file, cfg->line);
|
||||||
free(subnet);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = subnet;
|
*(*result = new_subnet()) = subnet;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -324,7 +321,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
|
||||||
int err = -2; /* Parse error */
|
int err = -2; /* Parse error */
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buffer, *line;
|
char *buffer, *line;
|
||||||
char *variable, *value;
|
char *variable, *value, *eol;
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
int len;
|
int len;
|
||||||
bool ignore = false;
|
bool ignore = false;
|
||||||
|
@ -375,6 +372,10 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
|
||||||
|
|
||||||
variable = value = line;
|
variable = value = line;
|
||||||
|
|
||||||
|
eol = line + strlen(line);
|
||||||
|
while(strchr("\t ", *--eol))
|
||||||
|
*eol = '\0';
|
||||||
|
|
||||||
len = strcspn(value, "\t =");
|
len = strcspn(value, "\t =");
|
||||||
value += len;
|
value += len;
|
||||||
value += strspn(value, "\t ");
|
value += strspn(value, "\t ");
|
||||||
|
@ -384,6 +385,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
|
||||||
}
|
}
|
||||||
variable[len] = '\0';
|
variable[len] = '\0';
|
||||||
|
|
||||||
|
|
||||||
if(!*value) {
|
if(!*value) {
|
||||||
logger(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"),
|
logger(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"),
|
||||||
variable, lineno, fname);
|
variable, lineno, fname);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_CONF_H__
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -64,7 +64,7 @@ connection_t *new_connection(void)
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
c = (connection_t *) xmalloc_and_zero(sizeof(connection_t));
|
c = xmalloc_and_zero(sizeof(connection_t));
|
||||||
|
|
||||||
if(!c)
|
if(!c)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -120,7 +120,7 @@ void dump_connections(void)
|
||||||
logger(LOG_DEBUG, _("Connections:"));
|
logger(LOG_DEBUG, _("Connections:"));
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
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"),
|
logger(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
|
||||||
c->name, c->hostname, c->options, c->socket, *(uint32_t *)&c->status);
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_CONNECTION_H__
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#define OPTION_INDIRECT 0x0001
|
#define OPTION_INDIRECT 0x0001
|
||||||
#define OPTION_TCPONLY 0x0002
|
#define OPTION_TCPONLY 0x0002
|
||||||
|
#define OPTION_PMTU_DISCOVERY 0x0004
|
||||||
|
|
||||||
typedef struct connection_status_t {
|
typedef struct connection_status_t {
|
||||||
int pinged:1; /* sent ping */
|
int pinged:1; /* sent ping */
|
||||||
|
@ -40,8 +41,8 @@ typedef struct connection_status_t {
|
||||||
int timeout:1; /* 1 if gotten timeout */
|
int timeout:1; /* 1 if gotten timeout */
|
||||||
int encryptout:1; /* 1 if we can encrypt outgoing traffic */
|
int encryptout:1; /* 1 if we can encrypt outgoing traffic */
|
||||||
int decryptin:1; /* 1 if we have to decrypt incoming 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 mst:1; /* 1 if this connection is part of a minimum spanning tree */
|
||||||
int unused:18;
|
int unused:23;
|
||||||
} connection_status_t;
|
} connection_status_t;
|
||||||
|
|
||||||
#include "edge.h"
|
#include "edge.h"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -59,7 +59,7 @@ int sp[2];
|
||||||
bool setup_device(void)
|
bool setup_device(void)
|
||||||
{
|
{
|
||||||
HKEY key, key2;
|
HKEY key, key2;
|
||||||
int i;
|
int i, err;
|
||||||
|
|
||||||
char regpath[1024];
|
char regpath[1024];
|
||||||
char adapterid[1024];
|
char adapterid[1024];
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_DEVICE_H__
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -88,7 +88,7 @@ edge_t *new_edge(void)
|
||||||
{
|
{
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
return (edge_t *) xmalloc_and_zero(sizeof(edge_t));
|
return xmalloc_and_zero(sizeof(edge_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_edge(edge_t *e)
|
void free_edge(edge_t *e)
|
||||||
|
@ -148,9 +148,9 @@ void dump_edges(void)
|
||||||
logger(LOG_DEBUG, _("Edges:"));
|
logger(LOG_DEBUG, _("Edges:"));
|
||||||
|
|
||||||
for(node = node_tree->head; node; node = node->next) {
|
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) {
|
for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
|
||||||
e = (edge_t *) node2->data;
|
e = node2->data;
|
||||||
address = sockaddr2hostname(&e->address);
|
address = sockaddr2hostname(&e->address);
|
||||||
logger(LOG_DEBUG, _(" %s to %s at %s options %lx weight %d"),
|
logger(LOG_DEBUG, _(" %s to %s at %s options %lx weight %d"),
|
||||||
e->from->name, e->to->name, address, e->options, e->weight);
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_EDGE_H__
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -61,7 +61,7 @@ event_t *new_event(void)
|
||||||
{
|
{
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
return (event_t *) xmalloc_and_zero(sizeof(event_t));
|
return xmalloc_and_zero(sizeof(event_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_event(event_t *event)
|
void free_event(event_t *event)
|
||||||
|
@ -93,7 +93,7 @@ event_t *get_expired_event(void)
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
if(event_tree->head) {
|
if(event_tree->head) {
|
||||||
event = (event_t *) event_tree->head->data;
|
event = event_tree->head->data;
|
||||||
|
|
||||||
if(event->time < now) {
|
if(event->time < now) {
|
||||||
avl_delete(event_tree, event);
|
avl_delete(event_tree, event);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_EVENT_H__
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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:
|
/* We need to generate two trees from the graph:
|
||||||
|
@ -76,7 +76,7 @@ void mst_kruskal(void)
|
||||||
/* Clear MST status on connections */
|
/* Clear MST status on connections */
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
for(node = connection_tree->head; node; node = node->next) {
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
c->status.mst = false;
|
c->status.mst = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ void mst_kruskal(void)
|
||||||
/* Clear visited status on nodes */
|
/* Clear visited status on nodes */
|
||||||
|
|
||||||
for(node = node_tree->head; node; node = node->next) {
|
for(node = node_tree->head; node; node = node->next) {
|
||||||
n = (node_t *) node->data;
|
n = node->data;
|
||||||
n->status.visited = false;
|
n->status.visited = false;
|
||||||
nodes++;
|
nodes++;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ void mst_kruskal(void)
|
||||||
|
|
||||||
for(skipped = false, node = edge_weight_tree->head; node; node = next) {
|
for(skipped = false, node = edge_weight_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
e = (edge_t *) node->data;
|
e = node->data;
|
||||||
|
|
||||||
if(!e->reverse || e->from->status.visited == e->to->status.visited) {
|
if(!e->reverse || e->from->status.visited == e->to->status.visited) {
|
||||||
skipped = true;
|
skipped = true;
|
||||||
|
@ -158,7 +158,7 @@ void sssp_bfs(void)
|
||||||
/* Clear visited status on nodes */
|
/* Clear visited status on nodes */
|
||||||
|
|
||||||
for(node = node_tree->head; node; node = node->next) {
|
for(node = node_tree->head; node; node = node->next) {
|
||||||
n = (node_t *) node->data;
|
n = node->data;
|
||||||
n->status.visited = false;
|
n->status.visited = false;
|
||||||
n->status.indirect = true;
|
n->status.indirect = true;
|
||||||
}
|
}
|
||||||
|
@ -178,22 +178,23 @@ void sssp_bfs(void)
|
||||||
while(todo_tree->head) {
|
while(todo_tree->head) {
|
||||||
for(from = todo_tree->head; from; from = next) { /* "from" is the node from which we start */
|
for(from = todo_tree->head; from; from = next) { /* "from" is the node from which we start */
|
||||||
next = from->next;
|
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" */
|
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)
|
if(!e->reverse)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Situation:
|
/* 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.
|
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:
|
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);
|
e->to->hostname = sockaddr2hostname(&e->to->address);
|
||||||
avl_insert_node(node_udp_tree, node);
|
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();
|
node = avl_alloc_node();
|
||||||
|
@ -245,7 +254,7 @@ void sssp_bfs(void)
|
||||||
|
|
||||||
for(node = node_tree->head; node; node = next) {
|
for(node = node_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
n = (node_t *) node->data;
|
n = node->data;
|
||||||
|
|
||||||
if(n->status.visited != n->status.reachable) {
|
if(n->status.visited != n->status.reachable) {
|
||||||
n->status.reachable = !n->status.reachable;
|
n->status.reachable = !n->status.reachable;
|
||||||
|
@ -261,6 +270,10 @@ void sssp_bfs(void)
|
||||||
n->status.validkey = false;
|
n->status.validkey = false;
|
||||||
n->status.waitingforkey = false;
|
n->status.waitingforkey = false;
|
||||||
|
|
||||||
|
n->maxmtu = MTU;
|
||||||
|
n->minmtu = 0;
|
||||||
|
n->mtuprobes = 0;
|
||||||
|
|
||||||
asprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
asprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||||
asprintf(&envp[1], "DEVICE=%s", device ? : "");
|
asprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||||
asprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
asprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||||
|
|
|
@ -17,9 +17,14 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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 graph(void);
|
||||||
extern void mst_kruskal(void);
|
extern void mst_kruskal(void);
|
||||||
extern void sssp_bfs(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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -94,10 +94,10 @@ bool setup_device(void)
|
||||||
if(iface)
|
if(iface)
|
||||||
strncpy(ifr.ifr_name, iface, IFNAMSIZ);
|
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);
|
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
|
||||||
iface = ifrname;
|
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);
|
logger(LOG_WARNING, _("Old ioctl() request was needed for %s"), device);
|
||||||
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
|
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
|
||||||
iface = ifrname;
|
iface = ifrname;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -78,7 +78,7 @@ void logger(int priority, const char *format, ...) {
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
break;
|
break;
|
||||||
case LOGMODE_FILE:
|
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);
|
vfprintf(logfile, format, ap);
|
||||||
fprintf(logfile, "\n");
|
fprintf(logfile, "\n");
|
||||||
fflush(logfile);
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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 "system.h"
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
#include "avl_tree.h"
|
#include "avl_tree.h"
|
||||||
|
@ -46,7 +47,12 @@ bool send_meta(connection_t *c, const char *buffer, int length)
|
||||||
c->name, c->hostname);
|
c->name, c->hostname);
|
||||||
|
|
||||||
if(c->status.encryptout) {
|
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;
|
bufp = outbuf;
|
||||||
length = outlen;
|
length = outlen;
|
||||||
} else
|
} else
|
||||||
|
@ -80,7 +86,7 @@ void broadcast_meta(connection_t *from, const char *buffer, int length)
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
for(node = connection_tree->head; node; node = node->next) {
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
|
|
||||||
if(c != from && c->status.active)
|
if(c != from && c->status.active)
|
||||||
send_meta(c, buffer, length);
|
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)
|
bool receive_meta(connection_t *c)
|
||||||
{
|
{
|
||||||
int oldlen, i;
|
int oldlen, i, result;
|
||||||
int lenin, reqlen;
|
int lenin, lenout, reqlen;
|
||||||
bool decrypted = false;
|
bool decrypted = false;
|
||||||
char inbuf[MAXBUFSIZE];
|
char inbuf[MAXBUFSIZE];
|
||||||
|
|
||||||
|
@ -123,11 +129,16 @@ bool receive_meta(connection_t *c)
|
||||||
oldlen = c->buflen;
|
oldlen = c->buflen;
|
||||||
c->buflen += lenin;
|
c->buflen += lenin;
|
||||||
|
|
||||||
while(lenin) {
|
while(lenin > 0) {
|
||||||
/* Decrypt */
|
/* Decrypt */
|
||||||
|
|
||||||
if(c->status.decryptin && !decrypted) {
|
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);
|
memcpy(c->buffer + oldlen, inbuf, lenin);
|
||||||
decrypted = true;
|
decrypted = true;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +150,7 @@ bool receive_meta(connection_t *c)
|
||||||
receive_tcppacket(c, c->buffer, c->tcplen);
|
receive_tcppacket(c, c->buffer, c->tcplen);
|
||||||
|
|
||||||
c->buflen -= c->tcplen;
|
c->buflen -= c->tcplen;
|
||||||
lenin -= c->tcplen;
|
lenin -= c->tcplen - oldlen;
|
||||||
memmove(c->buffer, c->buffer + c->tcplen, c->buflen);
|
memmove(c->buffer, c->buffer + c->tcplen, c->buflen);
|
||||||
oldlen = 0;
|
oldlen = 0;
|
||||||
c->tcplen = 0;
|
c->tcplen = 0;
|
||||||
|
@ -167,7 +178,7 @@ bool receive_meta(connection_t *c)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
c->buflen -= reqlen;
|
c->buflen -= reqlen;
|
||||||
lenin -= reqlen;
|
lenin -= reqlen - oldlen;
|
||||||
memmove(c->buffer, c->buffer + reqlen, c->buflen);
|
memmove(c->buffer, c->buffer + reqlen, c->buflen);
|
||||||
oldlen = 0;
|
oldlen = 0;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_META_H__
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#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_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_LASTMAC TAP_CONTROL_CODE(0, METHOD_BUFFERED)
|
||||||
#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE(1, 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_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;
|
int device_fd = 0;
|
||||||
HANDLE device_handle = INVALID_HANDLE_VALUE;
|
HANDLE device_handle = INVALID_HANDLE_VALUE;
|
||||||
|
@ -131,6 +137,7 @@ bool setup_device(void)
|
||||||
char adaptername[1024];
|
char adaptername[1024];
|
||||||
char tapname[1024];
|
char tapname[1024];
|
||||||
long len;
|
long len;
|
||||||
|
unsigned long status;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
|
@ -283,6 +290,11 @@ bool setup_device(void)
|
||||||
|
|
||||||
closesocket(sock);
|
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");
|
device_info = _("Windows tap device");
|
||||||
|
|
||||||
logger(LOG_INFO, _("%s (%s) is a %s"), device, iface, device_info);
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -63,7 +63,7 @@ static void purge(void)
|
||||||
|
|
||||||
for(nnode = node_tree->head; nnode; nnode = nnext) {
|
for(nnode = node_tree->head; nnode; nnode = nnext) {
|
||||||
nnext = nnode->next;
|
nnext = nnode->next;
|
||||||
n = (node_t *) nnode->data;
|
n = nnode->data;
|
||||||
|
|
||||||
if(!n->status.reachable) {
|
if(!n->status.reachable) {
|
||||||
ifdebug(SCARY_THINGS) logger(LOG_DEBUG, _("Purging node %s (%s)"), n->name,
|
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) {
|
for(snode = n->subnet_tree->head; snode; snode = snext) {
|
||||||
snext = snode->next;
|
snext = snode->next;
|
||||||
s = (subnet_t *) snode->data;
|
s = snode->data;
|
||||||
send_del_subnet(broadcast, s);
|
if(!tunnelserver)
|
||||||
|
send_del_subnet(broadcast, s);
|
||||||
subnet_del(n, s);
|
subnet_del(n, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(enode = n->edge_tree->head; enode; enode = enext) {
|
for(enode = n->edge_tree->head; enode; enode = enext) {
|
||||||
enext = enode->next;
|
enext = enode->next;
|
||||||
e = (edge_t *) enode->data;
|
e = enode->data;
|
||||||
send_del_edge(broadcast, e);
|
if(!tunnelserver)
|
||||||
|
send_del_edge(broadcast, e);
|
||||||
edge_del(e);
|
edge_del(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,12 +91,12 @@ static void purge(void)
|
||||||
|
|
||||||
for(nnode = node_tree->head; nnode; nnode = nnext) {
|
for(nnode = node_tree->head; nnode; nnode = nnext) {
|
||||||
nnext = nnode->next;
|
nnext = nnode->next;
|
||||||
n = (node_t *) nnode->data;
|
n = nnode->data;
|
||||||
|
|
||||||
if(!n->status.reachable) {
|
if(!n->status.reachable) {
|
||||||
for(enode = edge_weight_tree->head; enode; enode = enext) {
|
for(enode = edge_weight_tree->head; enode; enode = enext) {
|
||||||
enext = enode->next;
|
enext = enode->next;
|
||||||
e = (edge_t *) enode->data;
|
e = enode->data;
|
||||||
|
|
||||||
if(e->to == n)
|
if(e->to == n)
|
||||||
break;
|
break;
|
||||||
|
@ -122,7 +124,7 @@ static int build_fdset(fd_set * fs)
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = next) {
|
for(node = connection_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
|
|
||||||
if(c->status.remove) {
|
if(c->status.remove) {
|
||||||
connection_del(c);
|
connection_del(c);
|
||||||
|
@ -178,7 +180,7 @@ void terminate_connection(connection_t *c, bool report)
|
||||||
closesocket(c->socket);
|
closesocket(c->socket);
|
||||||
|
|
||||||
if(c->edge) {
|
if(c->edge) {
|
||||||
if(report)
|
if(report && !tunnelserver)
|
||||||
send_del_edge(broadcast, c->edge);
|
send_del_edge(broadcast, c->edge);
|
||||||
|
|
||||||
edge_del(c->edge);
|
edge_del(c->edge);
|
||||||
|
@ -186,6 +188,18 @@ void terminate_connection(connection_t *c, bool report)
|
||||||
/* Run MST and SSSP algorithms */
|
/* Run MST and SSSP algorithms */
|
||||||
|
|
||||||
graph();
|
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 */
|
/* 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) {
|
for(node = connection_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
|
|
||||||
if(c->last_ping_time + pingtimeout < now) {
|
if(c->last_ping_time + pingtimeout < now) {
|
||||||
if(c->status.active) {
|
if(c->status.active) {
|
||||||
|
@ -256,11 +270,11 @@ static void check_network_activity(fd_set * f)
|
||||||
|
|
||||||
if(FD_ISSET(device_fd, f)) {
|
if(FD_ISSET(device_fd, f)) {
|
||||||
if(read_packet(&packet))
|
if(read_packet(&packet))
|
||||||
route_outgoing(&packet);
|
route(myself, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
for(node = connection_tree->head; node; node = node->next) {
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
|
|
||||||
if(c->status.remove)
|
if(c->status.remove)
|
||||||
continue;
|
continue;
|
||||||
|
@ -320,7 +334,8 @@ int main_loop(void)
|
||||||
while(running) {
|
while(running) {
|
||||||
now = time(NULL);
|
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;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
maxfd = build_fdset(&fset);
|
maxfd = build_fdset(&fset);
|
||||||
|
@ -353,7 +368,7 @@ int main_loop(void)
|
||||||
last_ping_check = now;
|
last_ping_check = now;
|
||||||
|
|
||||||
if(routing_mode == RMODE_SWITCH)
|
if(routing_mode == RMODE_SWITCH)
|
||||||
age_mac();
|
age_subnets();
|
||||||
|
|
||||||
age_past_requests();
|
age_past_requests();
|
||||||
|
|
||||||
|
@ -380,7 +395,7 @@ int main_loop(void)
|
||||||
logger(LOG_INFO, _("Flushing event queue"));
|
logger(LOG_INFO, _("Flushing event queue"));
|
||||||
|
|
||||||
while(event_tree->head) {
|
while(event_tree->head) {
|
||||||
event = (event_t *) event_tree->head->data;
|
event = event_tree->head->data;
|
||||||
event->handler(event->data);
|
event->handler(event->data);
|
||||||
event_del(event);
|
event_del(event);
|
||||||
}
|
}
|
||||||
|
@ -408,7 +423,7 @@ int main_loop(void)
|
||||||
/* Close connections to hosts that have a changed or deleted host config file */
|
/* Close connections to hosts that have a changed or deleted host config file */
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
for(node = connection_tree->head; node; node = node->next) {
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
|
|
||||||
if(c->outgoing) {
|
if(c->outgoing) {
|
||||||
free(c->outgoing->name);
|
free(c->outgoing->name);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_NET_H__
|
||||||
|
@ -54,7 +54,7 @@ typedef struct ipv6_t {
|
||||||
|
|
||||||
typedef short length_t;
|
typedef short length_t;
|
||||||
|
|
||||||
#define AF_UNKNOWN 0xFFFF
|
#define AF_UNKNOWN 255
|
||||||
|
|
||||||
struct sockaddr_unknown {
|
struct sockaddr_unknown {
|
||||||
uint16_t family;
|
uint16_t family;
|
||||||
|
@ -150,6 +150,7 @@ extern int main_loop(void);
|
||||||
extern void terminate_connection(struct connection_t *, bool);
|
extern void terminate_connection(struct connection_t *, bool);
|
||||||
extern void flush_queue(struct node_t *);
|
extern void flush_queue(struct node_t *);
|
||||||
extern bool read_rsa_public_key(struct connection_t *);
|
extern bool read_rsa_public_key(struct connection_t *);
|
||||||
|
extern void send_mtu_probe(struct node_t *);
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
#define closesocket(s) close(s)
|
#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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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 "system.h"
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "ethernet.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
@ -46,14 +48,73 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
|
#ifdef WSAEMSGSIZE
|
||||||
|
#define EMSGSIZE WSAEMSGSIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
int keylifetime = 0;
|
int keylifetime = 0;
|
||||||
int keyexpires = 0;
|
int keyexpires = 0;
|
||||||
EVP_CIPHER_CTX packet_ctx;
|
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 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
|
#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)
|
static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level)
|
||||||
{
|
{
|
||||||
if(level == 10) {
|
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)"),
|
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"),
|
||||||
packet->len, n->name, n->hostname);
|
packet->len, n->name, n->hostname);
|
||||||
|
|
||||||
route_incoming(n, packet);
|
route(n, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
|
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();
|
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 */
|
/* Check the message authentication code */
|
||||||
|
|
||||||
if(myself->digest && myself->maclength) {
|
if(myself->digest && myself->maclength) {
|
||||||
|
@ -137,12 +206,14 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
|
||||||
if(myself->cipher) {
|
if(myself->cipher) {
|
||||||
outpkt = pkt[nextpkt++];
|
outpkt = pkt[nextpkt++];
|
||||||
|
|
||||||
// EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key,
|
if(!EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL)
|
||||||
// myself->key + myself->cipher->key_len);
|
|| !EVP_DecryptUpdate(&packet_ctx, (char *) &outpkt->seqno, &outlen,
|
||||||
EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL);
|
(char *) &inpkt->seqno, inpkt->len)
|
||||||
EVP_DecryptUpdate(&packet_ctx, (char *) &outpkt->seqno, &outlen,
|
|| !EVP_DecryptFinal_ex(&packet_ctx, (char *) &outpkt->seqno + outlen, &outpad)) {
|
||||||
(char *) &inpkt->seqno, inpkt->len);
|
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Error decrypting packet from %s (%s): %s"),
|
||||||
EVP_DecryptFinal_ex(&packet_ctx, (char *) &outpkt->seqno + outlen, &outpad);
|
n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
outpkt->len = outlen + outpad;
|
outpkt->len = outlen + outpad;
|
||||||
inpkt = outpkt;
|
inpkt = outpkt;
|
||||||
|
@ -181,15 +252,21 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
|
||||||
outpkt = pkt[nextpkt++];
|
outpkt = pkt[nextpkt++];
|
||||||
|
|
||||||
if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, myself->compression)) < 0) {
|
if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, myself->compression)) < 0) {
|
||||||
logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
|
ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
|
||||||
n->name, n->hostname);
|
n->name, n->hostname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inpkt = outpkt;
|
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)
|
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. */
|
/* 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));
|
*(copy = xmalloc(sizeof(*copy))) = *inpkt;
|
||||||
memcpy(copy, inpkt, sizeof(vpn_packet_t));
|
|
||||||
|
|
||||||
list_insert_tail(n->queue, copy);
|
list_insert_tail(n->queue, copy);
|
||||||
|
|
||||||
|
@ -253,7 +329,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
|
||||||
outpkt = pkt[nextpkt++];
|
outpkt = pkt[nextpkt++];
|
||||||
|
|
||||||
if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->compression)) < 0) {
|
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);
|
n->name, n->hostname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -271,11 +347,14 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
|
||||||
if(n->cipher) {
|
if(n->cipher) {
|
||||||
outpkt = pkt[nextpkt++];
|
outpkt = pkt[nextpkt++];
|
||||||
|
|
||||||
// EVP_EncryptInit_ex(&packet_ctx, n->cipher, NULL, n->key, n->key + n->cipher->key_len);
|
if(!EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL)
|
||||||
EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL);
|
|| !EVP_EncryptUpdate(&n->packet_ctx, (char *) &outpkt->seqno, &outlen,
|
||||||
EVP_EncryptUpdate(&n->packet_ctx, (char *) &outpkt->seqno, &outlen,
|
(char *) &inpkt->seqno, inpkt->len)
|
||||||
(char *) &inpkt->seqno, inpkt->len);
|
|| !EVP_EncryptFinal_ex(&n->packet_ctx, (char *) &outpkt->seqno + outlen, &outpad)) {
|
||||||
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;
|
outpkt->len = outlen + outpad;
|
||||||
inpkt = outpkt;
|
inpkt = outpkt;
|
||||||
|
@ -311,10 +390,16 @@ static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if((sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa))) < 0) {
|
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));
|
if(errno == EMSGSIZE) {
|
||||||
return;
|
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;
|
inpkt->len = origlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,14 +412,16 @@ void send_packet(const node_t *n, vpn_packet_t *packet)
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
|
|
||||||
packet->len, n->name, n->hostname);
|
|
||||||
|
|
||||||
if(n == myself) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
|
||||||
|
packet->len, n->name, n->hostname);
|
||||||
|
|
||||||
if(!n->status.reachable) {
|
if(!n->status.reachable) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_INFO, _("Node %s (%s) is not reachable"),
|
ifdebug(TRAFFIC) logger(LOG_INFO, _("Node %s (%s) is not reachable"),
|
||||||
n->name, n->hostname);
|
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);
|
packet->len, from->name, from->hostname);
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
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)
|
if(c->status.active && c->status.mst && c != from->nexthop->connection)
|
||||||
send_packet(c->node, packet);
|
send_packet(c->node, packet);
|
||||||
|
@ -384,7 +471,7 @@ void flush_queue(node_t *n)
|
||||||
|
|
||||||
for(node = n->queue->head; node; node = next) {
|
for(node = n->queue->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
send_udppacket(n, (vpn_packet_t *) node->data);
|
send_udppacket(n, node->data);
|
||||||
list_delete_node(n->queue, node);
|
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);
|
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));
|
logger(LOG_ERR, _("Receiving packet failed: %s"), strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -418,8 +505,5 @@ void handle_incoming_vpn_data(int sock)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n->connection)
|
|
||||||
n->connection->last_ping_time = now;
|
|
||||||
|
|
||||||
receive_udppacket(n, &pkt);
|
receive_udppacket(n, &pkt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -25,6 +25,8 @@
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
#include "avl_tree.h"
|
#include "avl_tree.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
@ -148,17 +150,23 @@ bool read_rsa_public_key(connection_t *c)
|
||||||
bool read_rsa_private_key(void)
|
bool read_rsa_private_key(void)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *fname, *key;
|
char *fname, *key, *pubkey;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
|
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();
|
myself->connection->rsa_key = RSA_new();
|
||||||
// RSA_blinding_on(myself->connection->rsa_key, NULL);
|
// RSA_blinding_on(myself->connection->rsa_key, NULL);
|
||||||
BN_hex2bn(&myself->connection->rsa_key->d, key);
|
BN_hex2bn(&myself->connection->rsa_key->d, key);
|
||||||
|
BN_hex2bn(&myself->connection->rsa_key->n, pubkey);
|
||||||
BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
|
BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
|
||||||
free(key);
|
free(key);
|
||||||
|
free(pubkey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,19 +248,15 @@ bool setup_myself(void)
|
||||||
myself->name = name;
|
myself->name = name;
|
||||||
myself->connection->name = xstrdup(name);
|
myself->connection->name = xstrdup(name);
|
||||||
|
|
||||||
if(!read_rsa_private_key())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!read_connection_config(myself->connection)) {
|
if(!read_connection_config(myself->connection)) {
|
||||||
logger(LOG_ERR, _("Cannot open host configuration file for myself!"));
|
logger(LOG_ERR, _("Cannot open host configuration file for myself!"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!read_rsa_public_key(myself->connection))
|
if(!read_rsa_private_key())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!get_config_string
|
if(!get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport))
|
||||||
(lookup_config(myself->connection->config_tree, "Port"), &myport))
|
|
||||||
asprintf(&myport, "655");
|
asprintf(&myport, "655");
|
||||||
|
|
||||||
/* Read in all the subnets specified in the host configuration file */
|
/* Read in all the subnets specified in the host configuration file */
|
||||||
|
@ -270,25 +274,26 @@ bool setup_myself(void)
|
||||||
|
|
||||||
/* Check some options */
|
/* Check some options */
|
||||||
|
|
||||||
if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice))
|
if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice)
|
||||||
if(choice)
|
myself->options |= OPTION_INDIRECT;
|
||||||
myself->options |= OPTION_INDIRECT;
|
|
||||||
|
|
||||||
if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice))
|
if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice)
|
||||||
if(choice)
|
myself->options |= OPTION_TCPONLY;
|
||||||
myself->options |= OPTION_TCPONLY;
|
|
||||||
|
|
||||||
if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice))
|
if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice) && choice)
|
||||||
if(choice)
|
myself->options |= OPTION_INDIRECT;
|
||||||
myself->options |= OPTION_INDIRECT;
|
|
||||||
|
|
||||||
if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice))
|
if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice) && choice)
|
||||||
if(choice)
|
myself->options |= OPTION_TCPONLY;
|
||||||
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)
|
if(myself->options & OPTION_TCPONLY)
|
||||||
myself->options |= OPTION_INDIRECT;
|
myself->options |= OPTION_INDIRECT;
|
||||||
|
|
||||||
|
get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
|
||||||
|
|
||||||
if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
|
if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
|
||||||
if(!strcasecmp(mode, "router"))
|
if(!strcasecmp(mode, "router"))
|
||||||
routing_mode = RMODE_ROUTER;
|
routing_mode = RMODE_ROUTER;
|
||||||
|
@ -314,7 +319,7 @@ bool setup_myself(void)
|
||||||
if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
|
if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
|
||||||
macexpire = 600;
|
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) {
|
if(maxtimeout <= 0) {
|
||||||
logger(LOG_ERR, _("Bogus maximum timeout!"));
|
logger(LOG_ERR, _("Bogus maximum timeout!"));
|
||||||
return false;
|
return false;
|
||||||
|
@ -362,7 +367,7 @@ bool setup_myself(void)
|
||||||
|
|
||||||
myself->connection->outcipher = EVP_bf_ofb();
|
myself->connection->outcipher = EVP_bf_ofb();
|
||||||
|
|
||||||
myself->key = (char *) xmalloc(myself->keylength);
|
myself->key = xmalloc(myself->keylength);
|
||||||
RAND_pseudo_bytes(myself->key, myself->keylength);
|
RAND_pseudo_bytes(myself->key, myself->keylength);
|
||||||
|
|
||||||
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
|
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
|
||||||
|
@ -372,7 +377,12 @@ bool setup_myself(void)
|
||||||
|
|
||||||
if(myself->cipher) {
|
if(myself->cipher) {
|
||||||
EVP_CIPHER_CTX_init(&packet_ctx);
|
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... */
|
/* 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) {
|
for(node = connection_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
|
|
||||||
if(c->outgoing)
|
if(c->outgoing)
|
||||||
free(c->outgoing->name), free(c->outgoing), c->outgoing = NULL;
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -49,31 +49,30 @@ int listen_sockets;
|
||||||
|
|
||||||
int setup_listen_socket(const sockaddr_t *sa)
|
int setup_listen_socket(const sockaddr_t *sa)
|
||||||
{
|
{
|
||||||
int nfd, flags;
|
int nfd;
|
||||||
char *addrstr;
|
char *addrstr;
|
||||||
int option;
|
int option;
|
||||||
char *iface;
|
char *iface;
|
||||||
#ifdef SO_BINDTODEVICE
|
|
||||||
struct ifreq ifr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
|
nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
if(nfd < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef O_NONBLOCK
|
#ifdef O_NONBLOCK
|
||||||
flags = fcntl(nfd, F_GETFL);
|
{
|
||||||
|
int flags = fcntl(nfd, F_GETFL);
|
||||||
|
|
||||||
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||||
closesocket(nfd);
|
closesocket(nfd);
|
||||||
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
|
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -94,6 +93,8 @@ int setup_listen_socket(const sockaddr_t *sa)
|
||||||
if(get_config_string
|
if(get_config_string
|
||||||
(lookup_config(config_tree, "BindToInterface"), &iface)) {
|
(lookup_config(config_tree, "BindToInterface"), &iface)) {
|
||||||
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
|
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
|
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 setup_vpn_in_socket(const sockaddr_t *sa)
|
||||||
{
|
{
|
||||||
int nfd, flags;
|
int nfd;
|
||||||
char *addrstr;
|
char *addrstr;
|
||||||
int option;
|
int option;
|
||||||
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
|
|
||||||
char *iface;
|
|
||||||
struct ifreq ifr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
|
@ -147,29 +144,58 @@ int setup_vpn_in_socket(const sockaddr_t *sa)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef O_NONBLOCK
|
#ifdef O_NONBLOCK
|
||||||
flags = fcntl(nfd, F_GETFL);
|
{
|
||||||
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
int flags = fcntl(nfd, F_GETFL);
|
||||||
closesocket(nfd);
|
|
||||||
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
|
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||||
strerror(errno));
|
closesocket(nfd);
|
||||||
return -1;
|
logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
option = 1;
|
option = 1;
|
||||||
setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
|
setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
|
||||||
|
|
||||||
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
|
#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
|
||||||
if(get_config_string
|
{
|
||||||
(lookup_config(config_tree, "BindToInterface"), &iface)) {
|
bool choice;
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
|
||||||
strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
|
|
||||||
|
|
||||||
if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
|
if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
|
||||||
closesocket(nfd);
|
option = IP_PMTUDISC_DO;
|
||||||
logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
|
setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option));
|
||||||
strerror(errno));
|
}
|
||||||
return -1;
|
}
|
||||||
|
#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
|
#endif
|
||||||
|
@ -255,8 +281,7 @@ begin:
|
||||||
goto begin;
|
goto begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&c->address, c->outgoing->aip->ai_addr,
|
memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen);
|
||||||
c->outgoing->aip->ai_addrlen);
|
|
||||||
c->outgoing->aip = c->outgoing->aip->ai_next;
|
c->outgoing->aip = c->outgoing->aip->ai_next;
|
||||||
|
|
||||||
if(c->hostname)
|
if(c->hostname)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -72,7 +72,7 @@ void exit_nodes(void)
|
||||||
|
|
||||||
node_t *new_node(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();
|
cp();
|
||||||
|
|
||||||
|
@ -80,6 +80,8 @@ node_t *new_node(void)
|
||||||
n->edge_tree = new_edge_tree();
|
n->edge_tree = new_edge_tree();
|
||||||
n->queue = list_alloc((list_action_t) free);
|
n->queue = list_alloc((list_action_t) free);
|
||||||
EVP_CIPHER_CTX_init(&n->packet_ctx);
|
EVP_CIPHER_CTX_init(&n->packet_ctx);
|
||||||
|
n->mtu = MTU;
|
||||||
|
n->maxmtu = MTU;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +111,9 @@ void free_node(node_t *n)
|
||||||
sockaddrfree(&n->address);
|
sockaddrfree(&n->address);
|
||||||
|
|
||||||
EVP_CIPHER_CTX_cleanup(&n->packet_ctx);
|
EVP_CIPHER_CTX_cleanup(&n->packet_ctx);
|
||||||
|
|
||||||
|
if(n->mtuevent)
|
||||||
|
event_del(n->mtuevent);
|
||||||
|
|
||||||
free(n);
|
free(n);
|
||||||
}
|
}
|
||||||
|
@ -131,13 +136,13 @@ void node_del(node_t *n)
|
||||||
|
|
||||||
for(node = n->subnet_tree->head; node; node = next) {
|
for(node = n->subnet_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
s = (subnet_t *) node->data;
|
s = node->data;
|
||||||
subnet_del(n, s);
|
subnet_del(n, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(node = n->edge_tree->head; node; node = next) {
|
for(node = n->edge_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
e = (edge_t *) node->data;
|
e = node->data;
|
||||||
edge_del(e);
|
edge_del(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,12 +183,12 @@ void dump_nodes(void)
|
||||||
logger(LOG_DEBUG, _("Nodes:"));
|
logger(LOG_DEBUG, _("Nodes:"));
|
||||||
|
|
||||||
for(node = node_tree->head; node; node = node->next) {
|
for(node = node_tree->head; node; node = node->next) {
|
||||||
n = (node_t *) node->data;
|
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"),
|
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->name, n->hostname, n->cipher ? n->cipher->nid : 0,
|
||||||
n->digest ? n->digest->type : 0, n->maclength, n->compression,
|
n->digest ? n->digest->type : 0, n->maclength, n->compression,
|
||||||
n->options, *(uint32_t *)&n->status, n->nexthop ? n->nexthop->name : "-",
|
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."));
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_NODE_H__
|
||||||
|
@ -25,13 +25,14 @@
|
||||||
|
|
||||||
#include "avl_tree.h"
|
#include "avl_tree.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "event.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "subnet.h"
|
#include "subnet.h"
|
||||||
|
|
||||||
typedef struct node_status_t {
|
typedef struct node_status_t {
|
||||||
int active:1; /* 1 if active.. */
|
int active:1; /* 1 if active.. */
|
||||||
int validkey:1; /* 1 if we currently have a valid key for him */
|
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 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 reachable:1; /* 1 if this node is reachable in the graph */
|
||||||
int indirect:1; /* 1 if this node is not directly reachable by us */
|
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;
|
} node_status_t;
|
||||||
|
|
||||||
typedef struct node_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 */
|
long int options; /* options turned on for this node */
|
||||||
|
|
||||||
sockaddr_t address; /* his real (internet) ip to send UDP packets to */
|
sockaddr_t address; /* his real (internet) ip to send UDP packets to */
|
||||||
|
@ -47,30 +48,36 @@ typedef struct node_t {
|
||||||
|
|
||||||
node_status_t status;
|
node_status_t status;
|
||||||
|
|
||||||
const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
|
const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
|
||||||
char *key; /* Cipher key and iv */
|
char *key; /* Cipher key and iv */
|
||||||
int keylength; /* Cipher key and iv length */
|
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 maclength; /* Length of MAC */
|
||||||
|
|
||||||
int compression; /* Compressionlevel, 0 = no compression */
|
int compression; /* Compressionlevel, 0 = no compression */
|
||||||
|
|
||||||
list_t *queue; /* Queue for packets awaiting to be encrypted */
|
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 */
|
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) */
|
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 sent_seqno; /* Sequence number last sent to this node */
|
||||||
uint32_t received_seqno; /* Sequence number last received from this node */
|
uint32_t received_seqno; /* Sequence number last received from this node */
|
||||||
unsigned char late[16]; /* Bitfield marking late packets */
|
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;
|
} node_t;
|
||||||
|
|
||||||
extern struct node_t *myself;
|
extern struct node_t *myself;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -58,19 +58,6 @@ static void memory_full(int size)
|
||||||
|
|
||||||
/* Some functions the less gifted operating systems might lack... */
|
/* 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
|
#ifdef HAVE_MINGW
|
||||||
extern char *identname;
|
extern char *identname;
|
||||||
extern char *program_name;
|
extern char *program_name;
|
||||||
|
@ -254,7 +241,7 @@ bool init_service(void) {
|
||||||
*/
|
*/
|
||||||
static bool write_pidfile(void)
|
static bool write_pidfile(void)
|
||||||
{
|
{
|
||||||
int pid;
|
pid_t pid;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
|
@ -262,16 +249,18 @@ static bool write_pidfile(void)
|
||||||
|
|
||||||
if(pid) {
|
if(pid) {
|
||||||
if(netname)
|
if(netname)
|
||||||
fprintf(stderr, _("A tincd is already running for net `%s' with pid %d.\n"),
|
fprintf(stderr, _("A tincd is already running for net `%s' with pid %ld.\n"),
|
||||||
netname, pid);
|
netname, (long)pid);
|
||||||
else
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if it's locked, write-protected, or whatever */
|
/* 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 false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +272,7 @@ static bool write_pidfile(void)
|
||||||
bool kill_other(int signal)
|
bool kill_other(int signal)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
int pid;
|
pid_t pid;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
|
@ -348,8 +337,10 @@ bool detach(void)
|
||||||
|
|
||||||
/* Now UPDATE the pid in the pidfile, because we changed it... */
|
/* 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;
|
return false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if(!statushandle)
|
if(!statushandle)
|
||||||
exit(install_service());
|
exit(install_service());
|
||||||
|
@ -440,13 +431,19 @@ bool execute_script(const char *name, char **envp)
|
||||||
static RETSIGTYPE sigterm_handler(int a)
|
static RETSIGTYPE sigterm_handler(int a)
|
||||||
{
|
{
|
||||||
logger(LOG_NOTICE, _("Got %s signal"), "TERM");
|
logger(LOG_NOTICE, _("Got %s signal"), "TERM");
|
||||||
running = false;
|
if(running)
|
||||||
|
running = false;
|
||||||
|
else
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RETSIGTYPE sigquit_handler(int a)
|
static RETSIGTYPE sigquit_handler(int a)
|
||||||
{
|
{
|
||||||
logger(LOG_NOTICE, _("Got %s signal"), "QUIT");
|
logger(LOG_NOTICE, _("Got %s signal"), "QUIT");
|
||||||
running = false;
|
if(running)
|
||||||
|
running = false;
|
||||||
|
else
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RETSIGTYPE fatal_signal_square(int a)
|
static RETSIGTYPE fatal_signal_square(int a)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_PROCESS_H__
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -30,6 +30,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
|
bool tunnelserver = false;
|
||||||
|
|
||||||
/* Jumptable for the request handlers */
|
/* Jumptable for the request handlers */
|
||||||
|
|
||||||
static bool (*request_handlers[])(connection_t *) = {
|
static bool (*request_handlers[])(connection_t *) = {
|
||||||
|
@ -219,7 +221,7 @@ bool seen_request(char *request)
|
||||||
ifdebug(SCARY_THINGS) logger(LOG_DEBUG, _("Already seen request"));
|
ifdebug(SCARY_THINGS) logger(LOG_DEBUG, _("Already seen request"));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
new = (past_request_t *) xmalloc(sizeof(*new));
|
new = xmalloc(sizeof(*new));
|
||||||
new->request = xstrdup(request);
|
new->request = xstrdup(request);
|
||||||
new->firstseen = now;
|
new->firstseen = now;
|
||||||
avl_insert(past_request_tree, new);
|
avl_insert(past_request_tree, new);
|
||||||
|
@ -237,7 +239,7 @@ void age_past_requests(void)
|
||||||
|
|
||||||
for(node = past_request_tree->head; node; node = next) {
|
for(node = past_request_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
p = (past_request_t *) node->data;
|
p = node->data;
|
||||||
|
|
||||||
if(p->firstseen + pingtimeout < now)
|
if(p->firstseen + pingtimeout < now)
|
||||||
avl_delete_node(past_request_tree, node), deleted++;
|
avl_delete_node(past_request_tree, node), deleted++;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_PROTOCOL_H__
|
||||||
|
@ -54,6 +54,8 @@ typedef struct past_request_t {
|
||||||
time_t firstseen;
|
time_t firstseen;
|
||||||
} past_request_t;
|
} past_request_t;
|
||||||
|
|
||||||
|
extern bool tunnelserver;
|
||||||
|
|
||||||
/* Maximum size of strings in a request */
|
/* Maximum size of strings in a request */
|
||||||
|
|
||||||
#define MAX_STRING_SIZE 2048
|
#define MAX_STRING_SIZE 2048
|
||||||
|
|
|
@ -17,13 +17,14 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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 "system.h"
|
||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
#include "avl_tree.h"
|
#include "avl_tree.h"
|
||||||
|
@ -50,7 +51,6 @@ bool send_id(connection_t *c)
|
||||||
bool id_h(connection_t *c)
|
bool id_h(connection_t *c)
|
||||||
{
|
{
|
||||||
char name[MAX_STRING_SIZE];
|
char name[MAX_STRING_SIZE];
|
||||||
bool choice;
|
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
|
@ -108,14 +108,6 @@ bool id_h(connection_t *c)
|
||||||
return false;
|
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;
|
c->allow_request = METAKEY;
|
||||||
|
|
||||||
return send_metakey(c);
|
return send_metakey(c);
|
||||||
|
@ -141,7 +133,7 @@ bool send_metakey(connection_t *c)
|
||||||
cp();
|
cp();
|
||||||
/* Copy random data to the buffer */
|
/* 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.
|
/* 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:
|
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 */
|
/* Further outgoing requests are encrypted with the key we just generated */
|
||||||
|
|
||||||
if(c->outcipher) {
|
if(c->outcipher) {
|
||||||
EVP_EncryptInit(c->outctx, c->outcipher,
|
if(!EVP_EncryptInit(c->outctx, c->outcipher,
|
||||||
c->outkey + len - c->outcipher->key_len,
|
c->outkey + len - c->outcipher->key_len,
|
||||||
c->outkey + len - c->outcipher->key_len -
|
c->outkey + len - c->outcipher->key_len -
|
||||||
c->outcipher->iv_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;
|
c->status.encryptout = true;
|
||||||
}
|
}
|
||||||
|
@ -262,10 +258,14 @@ bool metakey_h(connection_t *c)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_DecryptInit(c->inctx, c->incipher,
|
if(!EVP_DecryptInit(c->inctx, c->incipher,
|
||||||
c->inkey + len - c->incipher->key_len,
|
c->inkey + len - c->incipher->key_len,
|
||||||
c->inkey + len - c->incipher->key_len -
|
c->inkey + len - c->incipher->key_len -
|
||||||
c->incipher->iv_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;
|
c->status.decryptin = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -315,7 +315,7 @@ bool send_challenge(connection_t *c)
|
||||||
|
|
||||||
/* Copy random data to the buffer */
|
/* Copy random data to the buffer */
|
||||||
|
|
||||||
RAND_bytes(c->hischallenge, len);
|
RAND_pseudo_bytes(c->hischallenge, len);
|
||||||
|
|
||||||
/* Convert to hex */
|
/* Convert to hex */
|
||||||
|
|
||||||
|
@ -375,10 +375,13 @@ bool send_chal_reply(connection_t *c)
|
||||||
|
|
||||||
/* Calculate the hash from the challenge we received */
|
/* Calculate the hash from the challenge we received */
|
||||||
|
|
||||||
EVP_DigestInit(&ctx, c->indigest);
|
if(!EVP_DigestInit(&ctx, c->indigest)
|
||||||
EVP_DigestUpdate(&ctx, c->mychallenge,
|
|| !EVP_DigestUpdate(&ctx, c->mychallenge, RSA_size(myself->connection->rsa_key))
|
||||||
RSA_size(myself->connection->rsa_key));
|
|| !EVP_DigestFinal(&ctx, hash, NULL)) {
|
||||||
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 */
|
/* 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 */
|
/* Calculate the hash from the challenge we sent */
|
||||||
|
|
||||||
EVP_DigestInit(&ctx, c->outdigest);
|
if(!EVP_DigestInit(&ctx, c->outdigest)
|
||||||
EVP_DigestUpdate(&ctx, c->hischallenge, RSA_size(c->rsa_key));
|
|| !EVP_DigestUpdate(&ctx, c->hischallenge, RSA_size(c->rsa_key))
|
||||||
EVP_DigestFinal(&ctx, myhash, NULL);
|
|| !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 */
|
/* 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. */
|
to create node_t and edge_t structures. */
|
||||||
|
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
bool choice;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
|
@ -460,6 +468,19 @@ bool send_ack(connection_t *c)
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
c->estimated_weight = (now.tv_sec - c->start.tv_sec) * 1000 + (now.tv_usec - c->start.tv_usec) / 1000;
|
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);
|
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 */
|
/* 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) {
|
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) {
|
for(node2 = n->subnet_tree->head; node2; node2 = node2->next) {
|
||||||
s = (subnet_t *) node2->data;
|
s = node2->data;
|
||||||
send_add_subnet(c, s);
|
send_add_subnet(c, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
|
for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
|
||||||
e = (edge_t *) node2->data;
|
e = node2->data;
|
||||||
send_add_edge(c, e);
|
send_add_edge(c, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,7 +521,7 @@ bool ack_h(connection_t *c)
|
||||||
{
|
{
|
||||||
char hisport[MAX_STRING_SIZE];
|
char hisport[MAX_STRING_SIZE];
|
||||||
char *hisaddress, *dummy;
|
char *hisaddress, *dummy;
|
||||||
int weight;
|
int weight, mtu;
|
||||||
long int options;
|
long int options;
|
||||||
node_t *n;
|
node_t *n;
|
||||||
|
|
||||||
|
@ -526,6 +556,12 @@ bool ack_h(connection_t *c)
|
||||||
c->node = n;
|
c->node = n;
|
||||||
c->options |= options;
|
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 */
|
/* Activate this connection */
|
||||||
|
|
||||||
c->allow_request = ALL;
|
c->allow_request = ALL;
|
||||||
|
@ -556,7 +592,10 @@ bool ack_h(connection_t *c)
|
||||||
|
|
||||||
/* Notify everyone of the new edge */
|
/* 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 */
|
/* Run MST and SSSP algorithms */
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -110,6 +110,9 @@ bool add_edge_h(connection_t *c)
|
||||||
node_add(to);
|
node_add(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tunnelserver && from != myself && from != c->node && to != myself && to != c->node)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Convert addresses */
|
/* Convert addresses */
|
||||||
|
|
||||||
address = str2sockaddr(to_address, to_port);
|
address = str2sockaddr(to_address, to_port);
|
||||||
|
@ -154,7 +157,8 @@ bool add_edge_h(connection_t *c)
|
||||||
|
|
||||||
/* Tell the rest about the new edge */
|
/* Tell the rest about the new edge */
|
||||||
|
|
||||||
forward_request(c);
|
if(!tunnelserver)
|
||||||
|
forward_request(c);
|
||||||
|
|
||||||
/* Run MST before or after we tell the rest? */
|
/* Run MST before or after we tell the rest? */
|
||||||
|
|
||||||
|
@ -221,6 +225,9 @@ bool del_edge_h(connection_t *c)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tunnelserver && from != myself && from != c->node && to != myself && to != c->node)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Check if edge exists */
|
/* Check if edge exists */
|
||||||
|
|
||||||
e = lookup_edge(from, to);
|
e = lookup_edge(from, to);
|
||||||
|
@ -240,7 +247,8 @@ bool del_edge_h(connection_t *c)
|
||||||
|
|
||||||
/* Tell the rest about the deleted edge */
|
/* Tell the rest about the deleted edge */
|
||||||
|
|
||||||
forward_request(c);
|
if(!tunnelserver)
|
||||||
|
forward_request(c);
|
||||||
|
|
||||||
/* Delete the edge */
|
/* Delete the edge */
|
||||||
|
|
||||||
|
@ -250,5 +258,16 @@ bool del_edge_h(connection_t *c)
|
||||||
|
|
||||||
graph();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,14 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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 "system.h"
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
#include "avl_tree.h"
|
#include "avl_tree.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
@ -77,7 +80,8 @@ bool key_changed_h(connection_t *c)
|
||||||
|
|
||||||
/* Tell the others */
|
/* Tell the others */
|
||||||
|
|
||||||
forward_request(c);
|
if(!tunnelserver)
|
||||||
|
forward_request(c);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -127,6 +131,9 @@ bool req_key_h(connection_t *c)
|
||||||
memset(from->late, 0, sizeof(from->late));
|
memset(from->late, 0, sizeof(from->late));
|
||||||
send_ans_key(c, myself, from);
|
send_ans_key(c, myself, from);
|
||||||
} else {
|
} else {
|
||||||
|
if(tunnelserver)
|
||||||
|
return false;
|
||||||
|
|
||||||
send_req_key(to->nexthop->connection, from, to);
|
send_req_key(to->nexthop->connection, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +193,9 @@ bool ans_key_h(connection_t *c)
|
||||||
/* Forward it if necessary */
|
/* Forward it if necessary */
|
||||||
|
|
||||||
if(to != myself) {
|
if(to != myself) {
|
||||||
|
if(tunnelserver)
|
||||||
|
return false;
|
||||||
|
|
||||||
return send_request(to->nexthop->connection, "%s", c->buffer);
|
return send_request(to->nexthop->connection, "%s", c->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +261,14 @@ bool ans_key_h(connection_t *c)
|
||||||
from->compression = compression;
|
from->compression = compression;
|
||||||
|
|
||||||
if(from->cipher)
|
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);
|
flush_queue(from);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -35,17 +35,14 @@
|
||||||
|
|
||||||
bool send_add_subnet(connection_t *c, const subnet_t *subnet)
|
bool send_add_subnet(connection_t *c, const subnet_t *subnet)
|
||||||
{
|
{
|
||||||
bool x;
|
char netstr[MAXNETSTR];
|
||||||
char *netstr;
|
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
x = send_request(c, "%d %lx %s %s", ADD_SUBNET, random(),
|
if(!net2str(netstr, sizeof netstr, subnet))
|
||||||
subnet->owner->name, netstr = net2str(subnet));
|
return false;
|
||||||
|
|
||||||
free(netstr);
|
return send_request(c, "%d %lx %s %s", ADD_SUBNET, random(), subnet->owner->name, netstr);
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool add_subnet_h(connection_t *c)
|
bool add_subnet_h(connection_t *c)
|
||||||
|
@ -53,7 +50,7 @@ bool add_subnet_h(connection_t *c)
|
||||||
char subnetstr[MAX_STRING_SIZE];
|
char subnetstr[MAX_STRING_SIZE];
|
||||||
char name[MAX_STRING_SIZE];
|
char name[MAX_STRING_SIZE];
|
||||||
node_t *owner;
|
node_t *owner;
|
||||||
subnet_t *s;
|
subnet_t s = {0}, *new;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
|
@ -73,9 +70,7 @@ bool add_subnet_h(connection_t *c)
|
||||||
|
|
||||||
/* Check if subnet string is valid */
|
/* Check if subnet string is valid */
|
||||||
|
|
||||||
s = str2net(subnetstr);
|
if(!str2net(&s, subnetstr)) {
|
||||||
|
|
||||||
if(!s) {
|
|
||||||
logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
|
logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
|
||||||
c->hostname, _("invalid subnet string"));
|
c->hostname, _("invalid subnet string"));
|
||||||
return false;
|
return false;
|
||||||
|
@ -94,48 +89,69 @@ bool add_subnet_h(connection_t *c)
|
||||||
node_add(owner);
|
node_add(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tunnelserver && owner != myself && owner != c->node)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Check if we already know this subnet */
|
/* Check if we already know this subnet */
|
||||||
|
|
||||||
if(lookup_subnet(owner, s)) {
|
if(lookup_subnet(owner, &s))
|
||||||
free_subnet(s);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */
|
/* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */
|
||||||
|
|
||||||
if(owner == myself) {
|
if(owner == myself) {
|
||||||
ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for ourself"),
|
ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for ourself"),
|
||||||
"ADD_SUBNET", c->name, c->hostname);
|
"ADD_SUBNET", c->name, c->hostname);
|
||||||
s->owner = myself;
|
s.owner = myself;
|
||||||
send_del_subnet(c, s);
|
send_del_subnet(c, &s);
|
||||||
return true;
|
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 */
|
/* 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 */
|
/* Tell the rest */
|
||||||
|
|
||||||
forward_request(c);
|
if(!tunnelserver)
|
||||||
|
forward_request(c);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool send_del_subnet(connection_t *c, const subnet_t *s)
|
bool send_del_subnet(connection_t *c, const subnet_t *s)
|
||||||
{
|
{
|
||||||
bool x;
|
char netstr[MAXNETSTR];
|
||||||
char *netstr;
|
|
||||||
|
|
||||||
cp();
|
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);
|
return send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
|
||||||
|
|
||||||
free(netstr);
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool del_subnet_h(connection_t *c)
|
bool del_subnet_h(connection_t *c)
|
||||||
|
@ -143,7 +159,7 @@ bool del_subnet_h(connection_t *c)
|
||||||
char subnetstr[MAX_STRING_SIZE];
|
char subnetstr[MAX_STRING_SIZE];
|
||||||
char name[MAX_STRING_SIZE];
|
char name[MAX_STRING_SIZE];
|
||||||
node_t *owner;
|
node_t *owner;
|
||||||
subnet_t *s, *find;
|
subnet_t s = {0}, *find;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
|
@ -171,11 +187,12 @@ bool del_subnet_h(connection_t *c)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tunnelserver && owner != myself && owner != c->node)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Check if subnet string is valid */
|
/* Check if subnet string is valid */
|
||||||
|
|
||||||
s = str2net(subnetstr);
|
if(!str2net(&s, subnetstr)) {
|
||||||
|
|
||||||
if(!s) {
|
|
||||||
logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
|
logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
|
||||||
c->hostname, _("invalid subnet string"));
|
c->hostname, _("invalid subnet string"));
|
||||||
return false;
|
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 */
|
/* If everything is correct, delete the subnet from the list of the owner */
|
||||||
|
|
||||||
s->owner = owner;
|
s.owner = owner;
|
||||||
|
|
||||||
find = lookup_subnet(owner, s);
|
find = lookup_subnet(owner, &s);
|
||||||
|
|
||||||
free_subnet(s);
|
|
||||||
|
|
||||||
if(!find) {
|
if(!find) {
|
||||||
ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for %s which does not appear in his subnet tree"),
|
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 */
|
/* Tell the rest */
|
||||||
|
|
||||||
forward_request(c);
|
if(!tunnelserver)
|
||||||
|
forward_request(c);
|
||||||
|
|
||||||
/* Finally, delete it. */
|
/* Finally, delete it. */
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -40,7 +40,6 @@
|
||||||
|
|
||||||
#include "avl_tree.h"
|
#include "avl_tree.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "device.h"
|
|
||||||
#include "ethernet.h"
|
#include "ethernet.h"
|
||||||
#include "ipv4.h"
|
#include "ipv4.h"
|
||||||
#include "ipv6.h"
|
#include "ipv6.h"
|
||||||
|
@ -57,9 +56,20 @@ int macexpire = 600;
|
||||||
bool overwrite_mac = false;
|
bool overwrite_mac = false;
|
||||||
mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}};
|
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 */
|
/* 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;
|
uint16_t *p = data;
|
||||||
uint32_t checksum = prevsum ^ 0xFFFF;
|
uint32_t checksum = prevsum ^ 0xFFFF;
|
||||||
|
@ -70,7 +80,7 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(len)
|
if(len)
|
||||||
checksum += *(unsigned char *)p;
|
checksum += *(uint8_t *)p;
|
||||||
|
|
||||||
while(checksum >> 16)
|
while(checksum >> 16)
|
||||||
checksum = (checksum & 0xFFFF) + (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;
|
return ~checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ratelimit(void) {
|
static __inline__ bool ratelimit(int frequency) {
|
||||||
static time_t lasttime = 0;
|
static time_t lasttime = 0;
|
||||||
|
static int count = 0;
|
||||||
|
|
||||||
if(lasttime == now)
|
if(lasttime == now) {
|
||||||
return true;
|
if(++count > frequency)
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
lasttime = now;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
lasttime = now;
|
|
||||||
return false;
|
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;
|
subnet_t *subnet;
|
||||||
avl_node_t *node;
|
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 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"),
|
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[0], address->x[1], address->x[2], address->x[3],
|
||||||
address->x[4], address->x[5]);
|
address->x[4], address->x[5]);
|
||||||
|
|
||||||
subnet = new_subnet();
|
subnet = new_subnet();
|
||||||
subnet->type = SUBNET_MAC;
|
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);
|
subnet_add(myself, subnet);
|
||||||
|
|
||||||
/* And tell all other tinc daemons it's our MAC */
|
/* And tell all other tinc daemons it's our MAC */
|
||||||
|
|
||||||
for(node = connection_tree->head; node; node = node->next) {
|
for(node = connection_tree->head; node; node = node->next) {
|
||||||
c = (connection_t *) node->data;
|
c = node->data;
|
||||||
if(c->status.active)
|
if(c->status.active)
|
||||||
send_add_subnet(c, subnet);
|
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;
|
subnet_t *s;
|
||||||
connection_t *c;
|
connection_t *c;
|
||||||
|
@ -132,15 +157,16 @@ void age_mac(void)
|
||||||
|
|
||||||
for(node = myself->subnet_tree->head; node; node = next) {
|
for(node = myself->subnet_tree->head; node; node = next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
s = (subnet_t *) node->data;
|
s = node->data;
|
||||||
if(s->type == SUBNET_MAC && s->net.mac.lastseen && s->net.mac.lastseen + macexpire < now) {
|
if(s->expires && s->expires < now) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_INFO, _("MAC address %hx:%hx:%hx:%hx:%hx:%hx expired"),
|
ifdebug(TRAFFIC) {
|
||||||
s->net.mac.address.x[0], s->net.mac.address.x[1],
|
char netstr[MAXNETSTR];
|
||||||
s->net.mac.address.x[2], s->net.mac.address.x[3],
|
if(net2str(netstr, sizeof netstr, s))
|
||||||
s->net.mac.address.x[4], s->net.mac.address.x[5]);
|
logger(LOG_INFO, _("Subnet %s expired"), netstr);
|
||||||
|
}
|
||||||
|
|
||||||
for(node2 = connection_tree->head; node2; node2 = node2->next) {
|
for(node2 = connection_tree->head; node2; node2 = node2->next) {
|
||||||
c = (connection_t *) node2->data;
|
c = node2->data;
|
||||||
if(c->status.active)
|
if(c->status.active)
|
||||||
send_del_subnet(c, s);
|
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;
|
subnet_t *subnet;
|
||||||
|
|
||||||
|
@ -158,111 +184,215 @@ static node_t *route_mac(vpn_packet_t *packet)
|
||||||
|
|
||||||
/* Learn source address */
|
/* Learn source address */
|
||||||
|
|
||||||
learn_mac((mac_t *)(&packet->data[6]));
|
if(source == myself)
|
||||||
|
learn_mac((mac_t *)(&packet->data[6]));
|
||||||
|
|
||||||
/* Lookup destination address */
|
/* Lookup destination address */
|
||||||
|
|
||||||
subnet = lookup_subnet_mac((mac_t *)(&packet->data[0]));
|
subnet = lookup_subnet_mac((mac_t *)(&packet->data[0]));
|
||||||
|
|
||||||
if(subnet)
|
if(!subnet) {
|
||||||
return subnet->owner;
|
broadcast_packet(source, packet);
|
||||||
else
|
return;
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
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 */
|
/* 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 ip ip = {0};
|
||||||
struct icmp *icmp;
|
struct icmp icmp = {0};
|
||||||
|
|
||||||
struct in_addr ip_src;
|
struct in_addr ip_src;
|
||||||
struct in_addr ip_dst;
|
struct in_addr ip_dst;
|
||||||
uint32_t oldlen;
|
uint32_t oldlen;
|
||||||
|
|
||||||
if(ratelimit())
|
if(ratelimit(3))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
hdr = (struct ip *)(packet->data + 14);
|
/* Copy headers from packet into properly aligned structs on the stack */
|
||||||
icmp = (struct icmp *)(packet->data + 14 + 20);
|
|
||||||
|
memcpy(&ip, packet->data + ether_size, ip_size);
|
||||||
|
|
||||||
/* Remember original source and destination */
|
/* 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))
|
ip_src = ip.ip_src;
|
||||||
oldlen = IP_MSS - sizeof(*hdr) - sizeof(*icmp);
|
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 */
|
/* 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 */
|
/* Fill in IPv4 header */
|
||||||
|
|
||||||
hdr->ip_v = 4;
|
ip.ip_v = 4;
|
||||||
hdr->ip_hl = sizeof(*hdr) / 4;
|
ip.ip_hl = ip_size / 4;
|
||||||
hdr->ip_tos = 0;
|
ip.ip_tos = 0;
|
||||||
hdr->ip_len = htons(20 + 8 + oldlen);
|
ip.ip_len = htons(ip_size + icmp_size + oldlen);
|
||||||
hdr->ip_id = 0;
|
ip.ip_id = 0;
|
||||||
hdr->ip_off = 0;
|
ip.ip_off = 0;
|
||||||
hdr->ip_ttl = 255;
|
ip.ip_ttl = 255;
|
||||||
hdr->ip_p = IPPROTO_ICMP;
|
ip.ip_p = IPPROTO_ICMP;
|
||||||
hdr->ip_sum = 0;
|
ip.ip_sum = 0;
|
||||||
memcpy(&hdr->ip_src, &ip_dst, 4);
|
ip.ip_src = ip_dst;
|
||||||
memcpy(&hdr->ip_dst, &ip_src, 4);
|
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 */
|
/* Fill in ICMP header */
|
||||||
|
|
||||||
icmp->icmp_type = ICMP_DEST_UNREACH;
|
icmp.icmp_type = type;
|
||||||
icmp->icmp_code = code;
|
icmp.icmp_code = code;
|
||||||
icmp->icmp_cksum = 0;
|
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;
|
packet->len = ether_size + ip_size + icmp_size + oldlen;
|
||||||
|
|
||||||
write_packet(packet);
|
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;
|
subnet_t *subnet;
|
||||||
|
node_t *via;
|
||||||
|
|
||||||
cp();
|
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)
|
if(priorityinheritance)
|
||||||
packet->priority = packet->data[15];
|
packet->priority = packet->data[15];
|
||||||
|
|
||||||
subnet = lookup_subnet_ipv4((ipv4_t *) & packet->data[30]);
|
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!subnet->owner->status.reachable)
|
if(packet->len > via->mtu && via != myself) {
|
||||||
route_ipv4_unreachable(packet, ICMP_NET_UNREACH);
|
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 */
|
/* 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 ip6_hdr ip6;
|
||||||
struct icmp6_hdr *icmp;
|
struct icmp6_hdr icmp6 = {0};
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -272,95 +402,122 @@ static void route_ipv6_unreachable(vpn_packet_t *packet, uint8_t code)
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
} pseudo;
|
} pseudo;
|
||||||
|
|
||||||
if(ratelimit())
|
if(ratelimit(3))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
hdr = (struct ip6_hdr *)(packet->data + 14);
|
/* Copy headers from packet to structs on the stack */
|
||||||
icmp = (struct icmp6_hdr *)(packet->data + 14 + sizeof(*hdr));
|
|
||||||
|
memcpy(&ip6, packet->data + ether_size, ip6_size);
|
||||||
|
|
||||||
/* Remember original source and destination */
|
/* 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.ip6_src = ip6.ip6_dst;
|
||||||
pseudo.length = IP_MSS - sizeof(*hdr) - sizeof(*icmp);
|
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 */
|
/* 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 */
|
/* Fill in IPv6 header */
|
||||||
|
|
||||||
hdr->ip6_flow = htonl(0x60000000UL);
|
ip6.ip6_flow = htonl(0x60000000UL);
|
||||||
hdr->ip6_plen = htons(sizeof(*icmp) + pseudo.length);
|
ip6.ip6_plen = htons(icmp6_size + pseudo.length);
|
||||||
hdr->ip6_nxt = IPPROTO_ICMPV6;
|
ip6.ip6_nxt = IPPROTO_ICMPV6;
|
||||||
hdr->ip6_hlim = 255;
|
ip6.ip6_hlim = 255;
|
||||||
memcpy(&hdr->ip6_dst, &pseudo.ip6_dst, 16);
|
ip6.ip6_src = pseudo.ip6_src;
|
||||||
memcpy(&hdr->ip6_src, &pseudo.ip6_src, 16);
|
ip6.ip6_dst = pseudo.ip6_dst;
|
||||||
|
|
||||||
/* Fill in ICMP header */
|
/* Fill in ICMP header */
|
||||||
|
|
||||||
icmp->icmp6_type = ICMP6_DST_UNREACH;
|
icmp6.icmp6_type = type;
|
||||||
icmp->icmp6_code = code;
|
icmp6.icmp6_code = code;
|
||||||
icmp->icmp6_cksum = 0;
|
icmp6.icmp6_cksum = 0;
|
||||||
|
|
||||||
/* Create pseudo header */
|
/* Create pseudo header */
|
||||||
|
|
||||||
pseudo.length = htonl(sizeof(*icmp) + pseudo.length);
|
pseudo.length = htonl(icmp6_size + pseudo.length);
|
||||||
pseudo.next = htonl(IPPROTO_ICMPV6);
|
pseudo.next = htonl(IPPROTO_ICMPV6);
|
||||||
|
|
||||||
/* Generate checksum */
|
/* Generate checksum */
|
||||||
|
|
||||||
checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
|
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;
|
subnet_t *subnet;
|
||||||
|
node_t *via;
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
subnet = lookup_subnet_ipv6((ipv6_t *) & packet->data[38]);
|
subnet = lookup_subnet_ipv6((ipv6_t *) &packet->data[38]);
|
||||||
|
|
||||||
if(!subnet) {
|
if(!subnet) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
|
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
|
||||||
ntohs(*(uint16_t *) & packet->data[38]),
|
source->name, source->hostname,
|
||||||
ntohs(*(uint16_t *) & packet->data[40]),
|
ntohs(*(uint16_t *) &packet->data[38]),
|
||||||
ntohs(*(uint16_t *) & packet->data[42]),
|
ntohs(*(uint16_t *) &packet->data[40]),
|
||||||
ntohs(*(uint16_t *) & packet->data[44]),
|
ntohs(*(uint16_t *) &packet->data[42]),
|
||||||
ntohs(*(uint16_t *) & packet->data[46]),
|
ntohs(*(uint16_t *) &packet->data[44]),
|
||||||
ntohs(*(uint16_t *) & packet->data[48]),
|
ntohs(*(uint16_t *) &packet->data[46]),
|
||||||
ntohs(*(uint16_t *) & packet->data[50]),
|
ntohs(*(uint16_t *) &packet->data[48]),
|
||||||
ntohs(*(uint16_t *) & packet->data[52]));
|
ntohs(*(uint16_t *) &packet->data[50]),
|
||||||
route_ipv6_unreachable(packet, ICMP6_DST_UNREACH_ADDR);
|
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)
|
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 */
|
/* 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 ip6_hdr ip6;
|
||||||
struct nd_neighbor_solicit *ns;
|
struct nd_neighbor_solicit ns;
|
||||||
struct nd_opt_hdr *opt;
|
struct nd_opt_hdr opt;
|
||||||
subnet_t *subnet;
|
subnet_t *subnet;
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
|
|
||||||
|
@ -373,34 +530,46 @@ static void route_neighborsol(vpn_packet_t *packet)
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
hdr = (struct ip6_hdr *)(packet->data + 14);
|
if(!checklength(source, packet, ether_size + ip6_size + ns_size + opt_size + ETH_ALEN))
|
||||||
ns = (struct nd_neighbor_solicit *)(packet->data + 14 + sizeof(*hdr));
|
return;
|
||||||
opt = (struct nd_opt_hdr *)(packet->data + 14 + sizeof(*hdr) + sizeof(*ns));
|
|
||||||
|
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 */
|
/* First, snatch the source address from the neighbor solicitation packet */
|
||||||
|
|
||||||
if(overwrite_mac)
|
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 */
|
/* Check if this is a valid neighbor solicitation request */
|
||||||
|
|
||||||
if(ns->nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
|
if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
|
||||||
opt->nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
|
opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type neighbor solicitation request"));
|
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type neighbor solicitation request"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create pseudo header */
|
/* Create pseudo header */
|
||||||
|
|
||||||
memcpy(&pseudo.ip6_src, &hdr->ip6_src, 16);
|
pseudo.ip6_src = ip6.ip6_src;
|
||||||
memcpy(&pseudo.ip6_dst, &hdr->ip6_dst, 16);
|
pseudo.ip6_dst = ip6.ip6_dst;
|
||||||
pseudo.length = htonl(sizeof(*ns) + sizeof(*opt) + 6);
|
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
|
||||||
pseudo.next = htonl(IPPROTO_ICMPV6);
|
pseudo.next = htonl(IPPROTO_ICMPV6);
|
||||||
|
|
||||||
/* Generate checksum */
|
/* Generate checksum */
|
||||||
|
|
||||||
checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
|
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) {
|
if(checksum) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: checksum error for neighbor solicitation request"));
|
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 */
|
/* 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) {
|
if(!subnet) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
|
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)[0]),
|
||||||
ntohs(((uint16_t *) & ns->nd_ns_target)[1]),
|
ntohs(((uint16_t *) &ns.nd_ns_target)[1]),
|
||||||
ntohs(((uint16_t *) & ns->nd_ns_target)[2]),
|
ntohs(((uint16_t *) &ns.nd_ns_target)[2]),
|
||||||
ntohs(((uint16_t *) & ns->nd_ns_target)[3]),
|
ntohs(((uint16_t *) &ns.nd_ns_target)[3]),
|
||||||
ntohs(((uint16_t *) & ns->nd_ns_target)[4]),
|
ntohs(((uint16_t *) &ns.nd_ns_target)[4]),
|
||||||
ntohs(((uint16_t *) & ns->nd_ns_target)[5]),
|
ntohs(((uint16_t *) &ns.nd_ns_target)[5]),
|
||||||
ntohs(((uint16_t *) & ns->nd_ns_target)[6]),
|
ntohs(((uint16_t *) &ns.nd_ns_target)[6]),
|
||||||
ntohs(((uint16_t *) & ns->nd_ns_target)[7]));
|
ntohs(((uint16_t *) &ns.nd_ns_target)[7]));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -432,77 +601,102 @@ static void route_neighborsol(vpn_packet_t *packet)
|
||||||
|
|
||||||
/* Create neighbor advertation reply */
|
/* Create neighbor advertation reply */
|
||||||
|
|
||||||
memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */
|
memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
|
||||||
packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
|
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 */
|
ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */
|
||||||
memcpy(&hdr->ip6_src, &ns->nd_ns_target, 16); /* ... */
|
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_cksum = 0;
|
||||||
ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
|
ns.nd_ns_type = ND_NEIGHBOR_ADVERT;
|
||||||
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[0] = 0x40; /* Set solicited flag */
|
ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */
|
||||||
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[1] =
|
opt.nd_opt_type = ND_OPT_TARGET_LINKADDR;
|
||||||
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;
|
|
||||||
|
|
||||||
/* Create pseudo header */
|
/* Create pseudo header */
|
||||||
|
|
||||||
memcpy(&pseudo.ip6_src, &hdr->ip6_src, 16);
|
pseudo.ip6_src = ip6.ip6_src;
|
||||||
memcpy(&pseudo.ip6_dst, &hdr->ip6_dst, 16);
|
pseudo.ip6_dst = ip6.ip6_dst;
|
||||||
pseudo.length = htonl(sizeof(*ns) + sizeof(*opt) + 6);
|
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
|
||||||
pseudo.next = htonl(IPPROTO_ICMPV6);
|
pseudo.next = htonl(IPPROTO_ICMPV6);
|
||||||
|
|
||||||
/* Generate checksum */
|
/* Generate checksum */
|
||||||
|
|
||||||
checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
|
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 */
|
/* 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;
|
subnet_t *subnet;
|
||||||
uint8_t ipbuf[4];
|
struct in_addr addr;
|
||||||
|
|
||||||
cp();
|
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 */
|
/* First, snatch the source address from the ARP packet */
|
||||||
|
|
||||||
if(overwrite_mac)
|
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.
|
/* Copy headers from packet to structs on the stack */
|
||||||
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)
|
|
||||||
*/
|
|
||||||
|
|
||||||
arp = (struct ether_arp *)(packet->data + 14);
|
memcpy(&arp, packet->data + ether_size, arp_size);
|
||||||
|
|
||||||
/* Check if this is a valid ARP request */
|
/* Check if this is a valid ARP request */
|
||||||
|
|
||||||
if(ntohs(arp->arp_hrd) != ARPHRD_ETHER || ntohs(arp->arp_pro) != ETHERTYPE_IP ||
|
if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP ||
|
||||||
arp->arp_hln != ETHER_ADDR_LEN || arp->arp_pln != 4 || ntohs(arp->arp_op) != ARPOP_REQUEST) {
|
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"));
|
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type ARP request"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the IPv4 address exists on the VPN */
|
/* 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) {
|
if(!subnet) {
|
||||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: ARP request for unknown address %d.%d.%d.%d"),
|
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[0], arp.arp_tpa[1], arp.arp_tpa[2],
|
||||||
arp->arp_tpa[3]);
|
arp.arp_tpa[3]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,126 +705,63 @@ static void route_arp(vpn_packet_t *packet)
|
||||||
if(subnet->owner == myself)
|
if(subnet->owner == myself)
|
||||||
return; /* silently ignore */
|
return; /* silently ignore */
|
||||||
|
|
||||||
memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */
|
memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
|
||||||
packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
|
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(&addr, arp.arp_tpa, sizeof(addr)); /* save protocol addr */
|
||||||
memcpy(arp->arp_tpa, arp->arp_spa, 4); /* swap destination and source protocol address */
|
memcpy(arp.arp_tpa, arp.arp_spa, sizeof(addr)); /* swap destination and source protocol address */
|
||||||
memcpy(arp->arp_spa, ipbuf, 4); /* ... */
|
memcpy(arp.arp_spa, &addr, sizeof(addr)); /* ... */
|
||||||
|
|
||||||
memcpy(arp->arp_tha, arp->arp_sha, 10); /* set target hard/proto addr */
|
memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */
|
||||||
memcpy(arp->arp_sha, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* add fake source hard addr */
|
memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
|
||||||
arp->arp_op = htons(ARPOP_REPLY);
|
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();
|
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) {
|
switch (routing_mode) {
|
||||||
case RMODE_ROUTER:
|
case RMODE_ROUTER:
|
||||||
{
|
{
|
||||||
node_t *n = NULL;
|
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
|
|
||||||
type = ntohs(*((uint16_t *)(&packet->data[12])));
|
type = ntohs(*((uint16_t *)(&packet->data[12])));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0x0800:
|
case ETH_P_ARP:
|
||||||
n = route_ipv4(packet);
|
route_arp(source, packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x86DD:
|
case ETH_P_IP:
|
||||||
n = route_ipv6(packet);
|
route_ipv4(source, packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ETH_P_IPV6:
|
||||||
|
route_ipv6(source, packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
n = myself;
|
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet from %s (%s): unknown type %hx"), source->name, source->hostname, type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n) {
|
|
||||||
if(n == myself) {
|
|
||||||
if(overwrite_mac)
|
|
||||||
memcpy(packet->data, mymac.x, 6);
|
|
||||||
write_packet(packet);
|
|
||||||
} else
|
|
||||||
send_packet(n, packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RMODE_SWITCH:
|
case RMODE_SWITCH:
|
||||||
{
|
route_mac(source, packet);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RMODE_HUB:
|
case RMODE_HUB:
|
||||||
broadcast_packet(source, packet); /* Spread it on */
|
broadcast_packet(source, packet);
|
||||||
write_packet(packet);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_ROUTE_H__
|
||||||
|
@ -39,8 +39,7 @@ extern int macexpire;
|
||||||
|
|
||||||
extern mac_t mymac;
|
extern mac_t mymac;
|
||||||
|
|
||||||
extern void age_mac(void);
|
extern void age_subnets(void);
|
||||||
extern void route_incoming(struct node_t *, struct vpn_packet_t *);
|
extern void route(struct node_t *, struct vpn_packet_t *);
|
||||||
extern void route_outgoing(struct vpn_packet_t *);
|
|
||||||
|
|
||||||
#endif /* __TINC_ROUTE_H__ */
|
#endif /* __TINC_ROUTE_H__ */
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#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);
|
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;
|
int result;
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ subnet_t *new_subnet(void)
|
||||||
{
|
{
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
return (subnet_t *) xmalloc_and_zero(sizeof(subnet_t));
|
return xmalloc_and_zero(sizeof(subnet_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_subnet(subnet_t *subnet)
|
void free_subnet(subnet_t *subnet)
|
||||||
|
@ -177,16 +177,13 @@ void subnet_del(node_t *n, subnet_t *subnet)
|
||||||
|
|
||||||
/* Ascii representation of subnets */
|
/* Ascii representation of subnets */
|
||||||
|
|
||||||
subnet_t *str2net(const char *subnetstr)
|
bool str2net(subnet_t *subnet, const char *subnetstr)
|
||||||
{
|
{
|
||||||
int i, l;
|
int i, l;
|
||||||
subnet_t *subnet;
|
|
||||||
uint16_t x[8];
|
uint16_t x[8];
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
subnet = new_subnet();
|
|
||||||
|
|
||||||
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
|
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
|
||||||
&x[0], &x[1], &x[2], &x[3], &l) == 5) {
|
&x[0], &x[1], &x[2], &x[3], &l) == 5) {
|
||||||
subnet->type = SUBNET_IPV4;
|
subnet->type = SUBNET_IPV4;
|
||||||
|
@ -195,7 +192,7 @@ subnet_t *str2net(const char *subnetstr)
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
subnet->net.ipv4.address.x[i] = x[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",
|
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++)
|
for(i = 0; i < 8; i++)
|
||||||
subnet->net.ipv6.address.x[i] = htons(x[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) {
|
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++)
|
for(i = 0; i < 4; i++)
|
||||||
subnet->net.ipv4.address.x[i] = x[i];
|
subnet->net.ipv4.address.x[i] = x[i];
|
||||||
|
|
||||||
return subnet;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
|
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++)
|
for(i = 0; i < 8; i++)
|
||||||
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
||||||
|
|
||||||
return subnet;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx",
|
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++)
|
for(i = 0; i < 6; i++)
|
||||||
subnet->net.mac.address.x[i] = x[i];
|
subnet->net.mac.address.x[i] = x[i];
|
||||||
|
|
||||||
return subnet;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(subnet);
|
return false;
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *net2str(const subnet_t *subnet)
|
bool net2str(char *netstr, int len, const subnet_t *subnet)
|
||||||
{
|
{
|
||||||
char *netstr;
|
|
||||||
|
|
||||||
cp();
|
cp();
|
||||||
|
|
||||||
switch (subnet->type) {
|
switch (subnet->type) {
|
||||||
case SUBNET_MAC:
|
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[0],
|
||||||
subnet->net.mac.address.x[1],
|
subnet->net.mac.address.x[1],
|
||||||
subnet->net.mac.address.x[2],
|
subnet->net.mac.address.x[2],
|
||||||
|
@ -263,7 +256,7 @@ char *net2str(const subnet_t *subnet)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBNET_IPV4:
|
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[0],
|
||||||
subnet->net.ipv4.address.x[1],
|
subnet->net.ipv4.address.x[1],
|
||||||
subnet->net.ipv4.address.x[2],
|
subnet->net.ipv4.address.x[2],
|
||||||
|
@ -271,7 +264,7 @@ char *net2str(const subnet_t *subnet)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBNET_IPV6:
|
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[0]),
|
||||||
ntohs(subnet->net.ipv6.address.x[1]),
|
ntohs(subnet->net.ipv6.address.x[1]),
|
||||||
ntohs(subnet->net.ipv6.address.x[2]),
|
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.net.mac.address = *address;
|
||||||
subnet.owner = NULL;
|
subnet.owner = NULL;
|
||||||
|
|
||||||
p = (subnet_t *) avl_search(subnet_tree, &subnet);
|
p = avl_search(subnet_tree, &subnet);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +325,7 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address)
|
||||||
do {
|
do {
|
||||||
/* Go find subnet */
|
/* 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 */
|
/* Check if the found subnet REALLY matches */
|
||||||
|
|
||||||
|
@ -370,7 +363,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address)
|
||||||
do {
|
do {
|
||||||
/* Go find subnet */
|
/* 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 */
|
/* Check if the found subnet REALLY matches */
|
||||||
|
|
||||||
|
@ -394,7 +387,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address)
|
||||||
|
|
||||||
void dump_subnets(void)
|
void dump_subnets(void)
|
||||||
{
|
{
|
||||||
char *netstr;
|
char netstr[MAXNETSTR];
|
||||||
subnet_t *subnet;
|
subnet_t *subnet;
|
||||||
avl_node_t *node;
|
avl_node_t *node;
|
||||||
|
|
||||||
|
@ -403,10 +396,10 @@ void dump_subnets(void)
|
||||||
logger(LOG_DEBUG, _("Subnet list:"));
|
logger(LOG_DEBUG, _("Subnet list:"));
|
||||||
|
|
||||||
for(node = subnet_tree->head; node; node = node->next) {
|
for(node = subnet_tree->head; node; node = node->next) {
|
||||||
subnet = (subnet_t *) node->data;
|
subnet = node->data;
|
||||||
netstr = net2str(subnet);
|
if(!net2str(netstr, sizeof netstr, subnet))
|
||||||
|
continue;
|
||||||
logger(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
|
logger(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
|
||||||
free(netstr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger(LOG_DEBUG, _("End of subnet list."));
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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__
|
#ifndef __TINC_SUBNET_H__
|
||||||
|
@ -34,7 +34,6 @@ typedef enum subnet_type_t {
|
||||||
|
|
||||||
typedef struct subnet_mac_t {
|
typedef struct subnet_mac_t {
|
||||||
mac_t address;
|
mac_t address;
|
||||||
time_t lastseen;
|
|
||||||
} subnet_mac_t;
|
} subnet_mac_t;
|
||||||
|
|
||||||
typedef struct subnet_ipv4_t {
|
typedef struct subnet_ipv4_t {
|
||||||
|
@ -51,9 +50,9 @@ typedef struct subnet_ipv6_t {
|
||||||
|
|
||||||
typedef struct subnet_t {
|
typedef struct subnet_t {
|
||||||
struct node_t *owner; /* the owner of this subnet */
|
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?) */
|
subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
|
||||||
|
time_t expires; /* expiry time */
|
||||||
|
|
||||||
/* And now for the actual subnet: */
|
/* And now for the actual subnet: */
|
||||||
|
|
||||||
|
@ -64,6 +63,9 @@ typedef struct subnet_t {
|
||||||
} net;
|
} net;
|
||||||
} subnet_t;
|
} 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 subnet_t *new_subnet(void) __attribute__ ((__malloc__));
|
||||||
extern void free_subnet(subnet_t *);
|
extern void free_subnet(subnet_t *);
|
||||||
extern void init_subnets(void);
|
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 free_subnet_tree(avl_tree_t *);
|
||||||
extern void subnet_add(struct node_t *, subnet_t *);
|
extern void subnet_add(struct node_t *, subnet_t *);
|
||||||
extern void subnet_del(struct node_t *, subnet_t *);
|
extern void subnet_del(struct node_t *, subnet_t *);
|
||||||
extern char *net2str(const subnet_t *);
|
extern bool net2str(char *, int, const subnet_t *);
|
||||||
extern subnet_t *str2net(const char *);
|
extern bool str2net(subnet_t *, const char *);
|
||||||
extern subnet_t *lookup_subnet(const struct node_t *, const subnet_t *);
|
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_mac(const mac_t *);
|
||||||
extern subnet_t *lookup_subnet_ipv4(const ipv4_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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
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"
|
#include "system.h"
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
#include <lzo1x.h>
|
#include <lzo1x.h>
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <pidfile.h>
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
@ -291,7 +292,7 @@ static bool keygen(int bits)
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
fprintf(stderr, _("Generating %d bits keys:\n"), bits);
|
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) {
|
if(!rsa_key) {
|
||||||
fprintf(stderr, _("Error during key generation!\n"));
|
fprintf(stderr, _("Error during key generation!\n"));
|
||||||
|
@ -482,17 +483,10 @@ int main2(int argc, char **argv)
|
||||||
return 1;
|
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(!setup_network_connections())
|
||||||
if(do_detach) {
|
goto end;
|
||||||
logger(LOG_NOTICE, _("Restarting in %d seconds!"), maxtimeout);
|
|
||||||
sleep(maxtimeout);
|
|
||||||
} else {
|
|
||||||
logger(LOG_ERR, _("Not restarting."));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start main loop. It only exits when tinc is killed. */
|
/* Start main loop. It only exits when tinc is killed. */
|
||||||
|
|
||||||
|
@ -505,6 +499,12 @@ int main2(int argc, char **argv)
|
||||||
ifdebug(CONNECTIONS)
|
ifdebug(CONNECTIONS)
|
||||||
dump_device_stats();
|
dump_device_stats();
|
||||||
|
|
||||||
|
end:
|
||||||
logger(LOG_NOTICE, _("Terminating"));
|
logger(LOG_NOTICE, _("Terminating"));
|
||||||
|
|
||||||
|
#ifndef HAVE_MINGW
|
||||||
|
remove_pid(pidfilename);
|
||||||
|
#endif
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue