Merge branch 'master' into 1.1
Conflicts: NEWS README doc/tinc.conf.5.in doc/tinc.texi po/nl.po src/conf.c src/connection.c src/event.c src/graph.c src/net.c src/net_packet.c src/net_socket.c src/node.c src/node.h src/openssl/rsagen.h src/protocol_auth.c src/protocol_key.c src/protocol_misc.c src/subnet.c src/subnet.h src/tincd.c
This commit is contained in:
commit
08aabbf931
34 changed files with 601 additions and 326 deletions
|
@ -9,10 +9,7 @@ ACLOCAL_AMFLAGS = -I m4
|
|||
EXTRA_DIST = config.rpath mkinstalldirs have.h system.h COPYING.README depcomp
|
||||
|
||||
ChangeLog:
|
||||
svn log > ChangeLog
|
||||
|
||||
svn-clean: maintainer-clean
|
||||
svn status --no-ignore | sed -n 's/^[?I] \+//p' | tr '\012' '\0' | xargs -r0 rm -rf
|
||||
git log > ChangeLog
|
||||
|
||||
deb:
|
||||
dpkg-buildpackage -rfakeroot
|
||||
|
|
17
NEWS
17
NEWS
|
@ -4,6 +4,23 @@ Version 1.1-cvs Work in progress
|
|||
|
||||
* Use splay trees instead of AVL trees.
|
||||
|
||||
Version 1.0.9 Dec 26 2008
|
||||
|
||||
* Fixed tinc as a service under Windows 2003.
|
||||
|
||||
* Fixed reading configuration files that do not end with a newline.
|
||||
|
||||
* Fixed crashes in situations where hostnames could not be resolved or hosts
|
||||
would disconnect at the same time as session keys were exchanged.
|
||||
|
||||
* Improved default settings of tun and tap devices on BSD platforms.
|
||||
|
||||
* Make IPv6 sockets bind only to IPv6 on Linux.
|
||||
|
||||
* Enable path MTU discovery by default.
|
||||
|
||||
* Fixed a memory leak that occured when connections were closed.
|
||||
|
||||
Version 1.0.8 May 16 2007
|
||||
|
||||
* Fixed some memory and resource leaks.
|
||||
|
|
2
README
2
README
|
@ -1,7 +1,7 @@
|
|||
This is the README file for tinc version 1.1-cvs. Installation
|
||||
instructions may be found in the INSTALL file.
|
||||
|
||||
tinc is Copyright (C) 1998-2007 by:
|
||||
tinc is Copyright (C) 1998-2009 by:
|
||||
|
||||
Ivo Timmermans,
|
||||
Guus Sliepen <guus@tinc-vpn.org>,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Before you can start compiling tinc from a clean Subversion checkout, you have
|
||||
Before you can start compiling tinc from a fresh git clone, you have
|
||||
to install the very latest versions of the following packages:
|
||||
|
||||
- OpenSSL
|
||||
|
@ -22,4 +22,4 @@ make dist
|
|||
|
||||
To clean up your working copy so that no autogenerated files remain, run:
|
||||
|
||||
make svn-clean
|
||||
git clean
|
4
THANKS
4
THANKS
|
@ -4,6 +4,7 @@ We would like to thank the following people for their contributions to tinc:
|
|||
* Allesandro Gatti
|
||||
* Andreas van Cranenburgh
|
||||
* Armijn Hemel
|
||||
* dnk
|
||||
* Cris van Pelt
|
||||
* Enrique Zanardi
|
||||
* Flynn Marquardt
|
||||
|
@ -21,6 +22,9 @@ We would like to thank the following people for their contributions to tinc:
|
|||
* Markus Goetz
|
||||
* Martin Kihlgren
|
||||
* Matias Carrasco
|
||||
* Max Rijevski
|
||||
* Menno Smits
|
||||
* Michael Tokarev
|
||||
* Miles Nordin
|
||||
* Nick Patavalis
|
||||
* Paul Littlefield
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
.Dd 2002-04-09
|
||||
.Dd 2009-03-05
|
||||
.Dt TINC.CONF 5
|
||||
.\" Manual page created by:
|
||||
.\" Ivo Timmermans
|
||||
.\" Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
.Sh NAME
|
||||
.Nm tinc.conf
|
||||
.Nd tinc daemon configuration
|
||||
|
||||
.Sh DESCRIPTION
|
||||
The files in the
|
||||
.Pa @sysconfdir@/tinc/
|
||||
directory contain runtime and security information for the tinc daemon.
|
||||
|
||||
.Sh NETWORKS
|
||||
It is perfectly ok for you to run more than one tinc daemon.
|
||||
However, in its default form,
|
||||
you will soon notice that you can't use two different configuration files without the
|
||||
.Fl c
|
||||
option.
|
||||
|
||||
.Pp
|
||||
We have thought of another way of dealing with this: network names.
|
||||
This means that you call
|
||||
|
@ -23,6 +27,7 @@ This means that you call
|
|||
with the
|
||||
.Fl n
|
||||
option, which will assign a name to this daemon.
|
||||
|
||||
.Pp
|
||||
The effect of this is that the daemon will set its configuration root to
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa / ,
|
||||
|
@ -33,6 +38,7 @@ is your argument to the
|
|||
option.
|
||||
You'll notice that messages appear in syslog as coming from
|
||||
.Nm tincd. Ns Ar NETNAME .
|
||||
|
||||
.Pp
|
||||
However, it is not strictly necessary that you call tinc with the
|
||||
.Fl n
|
||||
|
@ -48,21 +54,25 @@ the configuration file should be
|
|||
.Pa @sysconfdir@/tinc/tinc.conf ,
|
||||
and the host configuration files are now expected to be in
|
||||
.Pa @sysconfdir@/tinc/hosts/ .
|
||||
|
||||
.Pp
|
||||
But it is highly recommended that you use this feature of
|
||||
.Nm tinc ,
|
||||
because it will be so much clearer whom your daemon talks to.
|
||||
Hence, we will assume that you use it.
|
||||
|
||||
.Sh NAMES
|
||||
Each tinc daemon should have a name that is unique in the network which it will be part of.
|
||||
The name will be used by other tinc daemons for identification.
|
||||
The name has to be declared in the
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||
file.
|
||||
|
||||
.Pp
|
||||
To make things easy,
|
||||
choose something that will give unique and easy to remember names to your tinc daemon(s).
|
||||
You could try things like hostnames, owner surnames or location names.
|
||||
|
||||
.Sh PUBLIC/PRIVATE KEYS
|
||||
You should use
|
||||
.Ic tincd -K
|
||||
|
@ -81,14 +91,17 @@ The public key should be stored in the host configuration file
|
|||
.Va NAME
|
||||
stands for the name of the local tinc daemon (see
|
||||
.Sx NAMES ) .
|
||||
|
||||
.Sh SERVER CONFIGURATION
|
||||
The server configuration of the daemon is done in the file
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf .
|
||||
This file consists of comments (lines started with a
|
||||
.Li # )
|
||||
or assignments in the form of:
|
||||
|
||||
.Pp
|
||||
.Va Variable Li = Ar Value .
|
||||
|
||||
.Pp
|
||||
The variable names are case insensitive, and any spaces, tabs,
|
||||
newlines and carriage returns are ignored.
|
||||
|
@ -96,30 +109,37 @@ Note: it is not required that you put in the
|
|||
.Li =
|
||||
sign, but doing so improves readability.
|
||||
If you leave it out, remember to replace it with at least one space character.
|
||||
|
||||
.Pp
|
||||
Here are all valid variables, listed in alphabetical order.
|
||||
The default value is given between parentheses.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Va AddressFamily Li = ipv4 | ipv6 | any Pq any
|
||||
This option affects the address family of listening and outgoing sockets.
|
||||
If
|
||||
.Qq any
|
||||
is selected, then depending on the operating system both IPv4 and IPv6 or just
|
||||
IPv6 listening sockets will be created.
|
||||
|
||||
.It Va BindToAddress Li = Ar address Bq experimental
|
||||
If your computer has more than one IPv4 or IPv6 address,
|
||||
.Nm tinc
|
||||
will by default listen on all of them for incoming connections.
|
||||
It is possible to bind only to a single address with this variable.
|
||||
|
||||
.Pp
|
||||
This option may not work on all platforms.
|
||||
|
||||
.It Va BindToInterface Li = Ar interface Bq experimental
|
||||
If your computer has more than one network interface,
|
||||
.Nm tinc
|
||||
will by default listen on all of them for incoming connections.
|
||||
It is possible to bind only to a single interface with this variable.
|
||||
|
||||
.Pp
|
||||
This option may not work on all platforms.
|
||||
|
||||
.It Va ConnectTo Li = Ar name
|
||||
Specifies which other tinc daemon to connect to on startup.
|
||||
Multiple
|
||||
|
@ -130,12 +150,14 @@ The names should be known to this tinc daemon
|
|||
(i.e., there should be a host configuration file for the name on the
|
||||
.Va ConnectTo
|
||||
line).
|
||||
|
||||
.Pp
|
||||
If you don't specify a host with
|
||||
.Va ConnectTo ,
|
||||
.Nm tinc
|
||||
won't try to connect to other daemons at all,
|
||||
and will instead just listen for incoming connections.
|
||||
|
||||
.It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc
|
||||
The virtual network device to use.
|
||||
.Nm tinc
|
||||
|
@ -147,14 +169,59 @@ instead of
|
|||
.Va Device .
|
||||
The info pages of the tinc package contain more information
|
||||
about configuring the virtual network device.
|
||||
|
||||
.It Va DeviceType Li = tun | tunnohead | tunifhead | tap Po only supported on BSD platforms Pc
|
||||
The type of the virtual network device.
|
||||
Tinc will normally automatically select the right type, and this option should not be used.
|
||||
However, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
||||
using this option might help.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It tun
|
||||
Set type to tun.
|
||||
Depending on the platform, this can either be with or without an address family header (see below).
|
||||
|
||||
.It tunnohead
|
||||
Set type to tun without an address family header.
|
||||
Tinc will expect packets read from the virtual network device to start with an IP header.
|
||||
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
||||
|
||||
.It tunifhead
|
||||
Set type to tun with an address family header.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with a four byte header containing the address family,
|
||||
followed by an IP header.
|
||||
This mode should support both IPv4 and IPv6 packets.
|
||||
|
||||
.It tap
|
||||
Set type to tap.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with an Ethernet header.
|
||||
.El
|
||||
|
||||
.It Va GraphDumpFile Li = Ar filename Bq experimental
|
||||
If this option is present,
|
||||
.Nm tinc
|
||||
will dump the current network graph to the file
|
||||
.Ar filename
|
||||
every minute, unless there were no changes to the graph.
|
||||
The file is in a format that can be read by graphviz tools.
|
||||
If
|
||||
.Ar filename
|
||||
starts with a pipe symbol |,
|
||||
then the rest of the filename is interpreted as a shell command
|
||||
that is executed, the graph is then sent to stdin.
|
||||
|
||||
.It Va Hostnames Li = yes | no Pq no
|
||||
This option selects whether IP addresses (both real and on the VPN) should
|
||||
be resolved. Since DNS lookups are blocking, it might affect tinc's
|
||||
efficiency, even stopping the daemon for a few seconds every time it does
|
||||
a lookup if your DNS server is not responding.
|
||||
|
||||
.Pp
|
||||
This does not affect resolving hostnames to IP addresses from the
|
||||
host configuration files.
|
||||
|
||||
.It Va Interface Li = Ar interface
|
||||
Defines the name of the interface corresponding to the virtual network device.
|
||||
Depending on the operating system and the type of device this may or may not actually set the name of the interface.
|
||||
|
@ -162,58 +229,73 @@ Under Windows, this variable is used to select which network interface will be u
|
|||
If you specified a
|
||||
.Va Device ,
|
||||
this variable is almost always already correctly set.
|
||||
|
||||
.It Va KeyExpire Li = Ar seconds Pq 3600
|
||||
This option controls the period the encryption keys used to encrypt the data are valid.
|
||||
It is common practice to change keys at regular intervals to make it even harder for crackers,
|
||||
even though it is thought to be nearly impossible to crack a single key.
|
||||
|
||||
.It Va MACExpire Li = Ar seconds Pq 600
|
||||
This option controls the amount of time MAC addresses are kept before they are removed.
|
||||
This only has effect when
|
||||
.Va Mode
|
||||
is set to
|
||||
.Qq switch .
|
||||
|
||||
.It Va MaxTimeout Li = Ar seconds Pq 900
|
||||
This is the maximum delay before trying to reconnect to other tinc daemons.
|
||||
|
||||
.It Va Mode Li = router | switch | hub Pq router
|
||||
This option selects the way packets are routed to other daemons.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It router
|
||||
In this mode
|
||||
.Va Subnet
|
||||
variables in the host configuration files will be used to form a routing table.
|
||||
Only unicast packets of routable protocols (IPv4 and IPv6) are supported in this mode.
|
||||
|
||||
.Pp
|
||||
This is the default mode, and unless you really know you need another mode, don't change it.
|
||||
|
||||
.It switch
|
||||
In this mode the MAC addresses of the packets on the VPN will be used to
|
||||
dynamically create a routing table just like an Ethernet switch does.
|
||||
Unicast, multicast and broadcast packets of every protocol that runs over Ethernet are supported in this mode
|
||||
at the cost of frequent broadcast ARP requests and routing table updates.
|
||||
|
||||
.Pp
|
||||
This mode is primarily useful if you want to bridge Ethernet segments.
|
||||
|
||||
.It hub
|
||||
This mode is almost the same as the switch mode, but instead
|
||||
every packet will be broadcast to the other daemons
|
||||
while no routing table is managed.
|
||||
.El
|
||||
|
||||
.It Va Name Li = Ar name Bq required
|
||||
This is the name which identifies this tinc daemon.
|
||||
It must be unique for the virtual private network this daemon will connect to.
|
||||
|
||||
.It Va PingInterval Li = Ar seconds Pq 60
|
||||
The number of seconds of inactivity that
|
||||
.Nm tinc
|
||||
will wait before sending a probe to the other end.
|
||||
|
||||
.It Va PingTimeout Li = Ar seconds Pq 5
|
||||
The number of seconds to wait for a response to pings or to allow meta
|
||||
connections to block. If the other end doesn't respond within this time,
|
||||
the connection is terminated,
|
||||
and the others will be notified of this.
|
||||
|
||||
.It Va PriorityInheritance Li = yes | no Po no Pc Bq experimental
|
||||
When this option is enabled the value of the TOS field of tunneled IPv4 packets
|
||||
will be inherited by the UDP packets that are sent out.
|
||||
|
||||
.It Va PrivateKey Li = Ar key Bq obsolete
|
||||
The private RSA key of this tinc daemon.
|
||||
It will allow this tinc daemon to authenticate itself to other daemons.
|
||||
|
||||
.It Va PrivateKeyFile Li = Ar filename Po Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /rsa_key.priv Pc
|
||||
The file in which the private RSA key of this tinc daemon resides.
|
||||
Note that there must be exactly one of
|
||||
|
@ -221,17 +303,20 @@ Note that there must be exactly one of
|
|||
or
|
||||
.Va PrivateKeyFile
|
||||
specified in the configuration file.
|
||||
|
||||
.It Va TunnelServer Li = yes | no Po no Pc Bq experimental
|
||||
When this option is enabled tinc will no longer forward information between other tinc daemons,
|
||||
and will only allow nodes and subnets on the VPN which are present in the
|
||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||
directory.
|
||||
.El
|
||||
|
||||
.Sh HOST CONFIGURATION FILES
|
||||
The host configuration files contain all information needed
|
||||
to establish a connection to those hosts.
|
||||
A host configuration file is also required for the local tinc daemon,
|
||||
it will use it to read in it's listen port, public key and subnets.
|
||||
|
||||
.Pp
|
||||
The idea is that these files are portable.
|
||||
You can safely mail your own host configuration file to someone else.
|
||||
|
@ -240,6 +325,7 @@ and now his tinc daemon will be able to connect to your tinc daemon.
|
|||
Since host configuration files only contain public keys,
|
||||
no secrets are revealed by sending out this information.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Va Address Li = Ar address Bq recommended
|
||||
The IP address or hostname of this tinc daemon on the real network.
|
||||
This will only be used when trying to make an outgoing connection to this tinc daemon.
|
||||
|
@ -247,6 +333,7 @@ Multiple
|
|||
.Va Address
|
||||
variables can be specified, in which case each address will be tried until a working
|
||||
connection has been established.
|
||||
|
||||
.It Va Cipher Li = Ar cipher Pq blowfish
|
||||
The symmetric cipher algorithm used to encrypt UDP packets.
|
||||
Any cipher supported by OpenSSL is recognised.
|
||||
|
@ -254,16 +341,19 @@ Furthermore, specifying
|
|||
.Qq none
|
||||
will turn off packet encryption.
|
||||
It is best to use only those ciphers which support CBC mode.
|
||||
|
||||
.It Va Compression Li = Ar level Pq 0
|
||||
This option sets the level of compression used for UDP packets.
|
||||
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
|
||||
10 (fast lzo) and 11 (best lzo).
|
||||
|
||||
.It Va Digest Li = Ar digest Pq sha1
|
||||
The digest algorithm used to authenticate UDP packets.
|
||||
Any digest supported by OpenSSL is recognised.
|
||||
Furthermore, specifying
|
||||
.Qq none
|
||||
will turn off packet authentication.
|
||||
|
||||
.It Va IndirectData Li = yes | no Pq no
|
||||
This option specifies whether other tinc daemons besides the one you specified with
|
||||
.Va ConnectTo
|
||||
|
@ -271,23 +361,30 @@ can make a direct connection to you.
|
|||
This is especially useful if you are behind a firewall
|
||||
and it is impossible to make a connection from the outside to your tinc daemon.
|
||||
Otherwise, it is best to leave this option out or set it to no.
|
||||
|
||||
.It Va MACLength Li = Ar length Pq 4
|
||||
The length of the message authentication code used to authenticate UDP packets.
|
||||
Can be anything from
|
||||
.Qq 0
|
||||
up to the length of the digest produced by the digest algorithm.
|
||||
.It Va PMTU Li = Ar mtu Po 1514 Pc Bq experimental
|
||||
|
||||
.It Va PMTU Li = Ar mtu Po 1514 Pc
|
||||
This option controls the initial path MTU to this node.
|
||||
.It Va PMTUDiscovery Li = yes | no Po no Pc Bq experimental
|
||||
|
||||
.It Va PMTUDiscovery Li = yes | no Po yes Pc
|
||||
When this option is enabled, tinc will try to discover the path MTU to this node.
|
||||
After the path MTU has been discovered, it will be enforced on the VPN.
|
||||
|
||||
.It Va Port Li = Ar port Pq 655
|
||||
The port number on which this tinc daemon is listening for incoming connections.
|
||||
|
||||
.It Va PublicKey Li = Ar key Bq obsolete
|
||||
The public RSA key of this tinc daemon.
|
||||
It will be used to cryptographically verify it's identity and to set up a secure connection.
|
||||
|
||||
.It Va PublicKeyFile Li = Ar filename Bq obsolete
|
||||
The file in which the public RSA key of this tinc daemon resides.
|
||||
|
||||
.Pp
|
||||
From version 1.0pre4 on
|
||||
.Nm tinc
|
||||
|
@ -296,7 +393,8 @@ the above two options then are not necessary.
|
|||
Either the PEM format is used, or exactly one of the above two options must be specified
|
||||
in each host configuration file,
|
||||
if you want to be able to establish a connection with that host.
|
||||
.It Va Subnet Li = Ar address Ns Op Li / Ns Ar prefixlength
|
||||
|
||||
.It Va Subnet Li = Ar address Ns Op Li / Ns Ar prefixlength Ns Op Li # Ns Ar weight
|
||||
The subnet which this tinc daemon will serve.
|
||||
.Nm tinc
|
||||
tries to look up which other daemon it should send a packet to by searching the appropriate subnet.
|
||||
|
@ -305,6 +403,7 @@ it will be sent to the daemon who has this subnet in his host configuration file
|
|||
Multiple
|
||||
.Va Subnet
|
||||
variables can be specified.
|
||||
|
||||
.Pp
|
||||
Subnets can either be single MAC, IPv4 or IPv6 addresses,
|
||||
in which case a subnet consisting of only that single address is assumed,
|
||||
|
@ -316,6 +415,14 @@ Note that subnets like 192.168.1.1/24 are invalid!
|
|||
Read a networking HOWTO/FAQ/guide if you don't understand this.
|
||||
IPv6 subnets are notated like fec0:0:0:1:0:0:0:0/64.
|
||||
MAC addresses are notated like 0:1a:2b:3c:4d:5e.
|
||||
|
||||
.Pp
|
||||
A Subnet can be given a weight to indicate its priority over identical Subnets
|
||||
owned by different nodes. The default weight is 10. Lower values indicate
|
||||
higher priority. Packets will be sent to the node with the highest priority,
|
||||
unless that node is not reachable, in which case the node with the next highest
|
||||
priority will be tried, and so on.
|
||||
|
||||
.It Va TCPOnly Li = yes | no Pq no
|
||||
If this variable is set to yes,
|
||||
then the packets are tunnelled over the TCP connection instead of a UDP connection.
|
||||
|
@ -324,38 +431,48 @@ from behind a masquerading firewall,
|
|||
or if UDP packet routing is disabled somehow.
|
||||
Setting this options also implicitly sets IndirectData.
|
||||
.El
|
||||
|
||||
.Sh SCRIPTS
|
||||
Apart from reading the server and host configuration files,
|
||||
tinc can also run scripts at certain moments.
|
||||
Under Windows (not Cygwin), the scripts should have the extension
|
||||
.Pa .bat .
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||
This is the most important script.
|
||||
If it is present it will be executed right after the tinc daemon has been started and has connected to the virtual network device.
|
||||
It should be used to set up the corresponding network interface,
|
||||
but can also be used to start other things.
|
||||
Under Windows you can use the Network Connections control panel instead of creating this script.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||
This script is started right before the tinc daemon quits.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -up
|
||||
This script is started when the tinc daemon with name
|
||||
.Ar HOST
|
||||
becomes reachable.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/ Ns Ar HOST Ns Pa -down
|
||||
This script is started when the tinc daemon with name
|
||||
.Ar HOST
|
||||
becomes unreachable.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-up
|
||||
This script is started when any host becomes reachable.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /host-down
|
||||
This script is started when any host becomes unreachable.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-up
|
||||
This script is started when a Subnet becomes reachable.
|
||||
The Subnet and the node it belongs to are passed in environment variables.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /subnet-down
|
||||
This script is started when a Subnet becomes unreachable.
|
||||
.El
|
||||
|
||||
.Pp
|
||||
The scripts are started without command line arguments, but can make use of certain environment variables.
|
||||
Under UNIX like operating systems the names of environment variables must be preceded by a
|
||||
|
@ -367,49 +484,65 @@ files, they have to be put between
|
|||
.Li %
|
||||
signs.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Ev NETNAME
|
||||
If a netname was specified, this environment variable contains it.
|
||||
|
||||
.It Ev NAME
|
||||
Contains the name of this tinc daemon.
|
||||
|
||||
.It Ev DEVICE
|
||||
Contains the name of the virtual network device that tinc uses.
|
||||
|
||||
.It Ev INTERFACE
|
||||
Contains the name of the virtual network interface that tinc uses.
|
||||
This should be used for commands like
|
||||
.Pa ifconfig .
|
||||
|
||||
.It Ev NODE
|
||||
When a host becomes (un)reachable, this is set to its name.
|
||||
If a subnet becomes (un)reachable, this is set to the owner of that subnet.
|
||||
|
||||
.It Ev REMOTEADDRESS
|
||||
When a host becomes (un)reachable, this is set to its real address.
|
||||
|
||||
.It Ev REMOTEPORT
|
||||
When a host becomes (un)reachable, this is set to the port number it uses for communication with other tinc daemons.
|
||||
|
||||
.It Ev SUBNET
|
||||
When a subnet becomes (un)reachable, this is set to the subnet.
|
||||
.El
|
||||
|
||||
.Sh FILES
|
||||
The most important files are:
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It Pa @sysconfdir@/tinc/
|
||||
The top directory for configuration files.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf
|
||||
The default name of the server configuration file for net
|
||||
.Ar NETNAME .
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||
Host configuration files are kept in this directory.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-up
|
||||
If an executable file with this name exists,
|
||||
it will be executed right after the tinc daemon has connected to the virtual network device.
|
||||
It can be used to set up the corresponding network interface.
|
||||
|
||||
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc-down
|
||||
If an executable file with this name exists,
|
||||
it will be executed right before the tinc daemon is going to close
|
||||
its connection to the virtual network device.
|
||||
.El
|
||||
|
||||
.Sh SEE ALSO
|
||||
.Xr tincd 8 ,
|
||||
.Pa http://www.tinc-vpn.org/ ,
|
||||
.Pa http://www.linuxdoc.org/LDP/nag2/ .
|
||||
|
||||
.Pp
|
||||
The full documentation for
|
||||
.Nm tinc
|
||||
|
@ -417,6 +550,7 @@ is maintained as a Texinfo manual.
|
|||
If the info and tinc programs are properly installed at your site, the command
|
||||
.Ic info tinc
|
||||
should give you access to the complete manual.
|
||||
|
||||
.Pp
|
||||
.Nm tinc
|
||||
comes with ABSOLUTELY NO WARRANTY.
|
||||
|
|
162
doc/tinc.texi
162
doc/tinc.texi
|
@ -16,7 +16,7 @@
|
|||
|
||||
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
|
||||
|
||||
Copyright @copyright{} 1998-2006 Ivo Timmermans,
|
||||
Copyright @copyright{} 1998-2009 Ivo Timmermans,
|
||||
Guus Sliepen <guus@@tinc-vpn.org> and
|
||||
Wessel Dankers <wsl@@tinc-vpn.org>.
|
||||
|
||||
|
@ -43,7 +43,7 @@ permission notice identical to this one.
|
|||
@cindex copyright
|
||||
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
|
||||
|
||||
Copyright @copyright{} 1998-2007 Ivo Timmermans,
|
||||
Copyright @copyright{} 1998-2009 Ivo Timmermans,
|
||||
Guus Sliepen <guus@@tinc-vpn.org> and
|
||||
Wessel Dankers <wsl@@tinc-vpn.org>.
|
||||
|
||||
|
@ -226,8 +226,7 @@ support tinc.
|
|||
@section Configuring the kernel
|
||||
|
||||
@menu
|
||||
* Configuration of Linux kernels 2.1.60 up to 2.4.0::
|
||||
* Configuration of Linux kernels 2.4.0 and higher::
|
||||
* Configuration of Linux kernels::
|
||||
* Configuration of FreeBSD kernels::
|
||||
* Configuration of OpenBSD kernels::
|
||||
* Configuration of NetBSD kernels::
|
||||
|
@ -238,51 +237,11 @@ support tinc.
|
|||
|
||||
|
||||
@c ==================================================================
|
||||
@node Configuration of Linux kernels 2.1.60 up to 2.4.0
|
||||
@subsection Configuration of Linux kernels 2.1.60 up to 2.4.0
|
||||
|
||||
@cindex ethertap
|
||||
For kernels up to 2.4.0, you need a kernel that supports the ethertap device.
|
||||
Most distributions come with kernels that already support this.
|
||||
If not, here are the options you have to turn on when configuring a new kernel:
|
||||
|
||||
@example
|
||||
Code maturity level options
|
||||
[*] Prompt for development and/or incomplete code/drivers
|
||||
Networking options
|
||||
[*] Kernel/User netlink socket
|
||||
<M> Netlink device emulation
|
||||
Network device support
|
||||
<M> Ethertap network tap
|
||||
@end example
|
||||
|
||||
If you want to run more than one instance of tinc or other programs that use
|
||||
the ethertap, you have to compile the ethertap driver as a module, otherwise
|
||||
you can also choose to compile it directly into the kernel.
|
||||
|
||||
If you decide to build any of these as dynamic kernel modules, it's a good idea
|
||||
to add these lines to @file{/etc/modules.conf}:
|
||||
|
||||
@example
|
||||
alias char-major-36 netlink_dev
|
||||
alias tap0 ethertap
|
||||
options tap0 -o tap0 unit=0
|
||||
alias tap1 ethertap
|
||||
options tap1 -o tap1 unit=1
|
||||
...
|
||||
alias tap@emph{N} ethertap
|
||||
options tap@emph{N} -o tap@emph{N} unit=@emph{N}
|
||||
@end example
|
||||
|
||||
Add as much alias/options lines as necessary.
|
||||
|
||||
|
||||
@c ==================================================================
|
||||
@node Configuration of Linux kernels 2.4.0 and higher
|
||||
@subsection Configuration of Linux kernels 2.4.0 and higher
|
||||
@node Configuration of Linux kernels
|
||||
@subsection Configuration of Linux kernels
|
||||
|
||||
@cindex Universal tun/tap
|
||||
For kernels 2.4.0 and higher, you need a kernel that supports the Universal tun/tap device.
|
||||
For tinc to work, you need a kernel that supports the Universal tun/tap device.
|
||||
Most distributions come with kernels that already support this.
|
||||
Here are the options you have to turn on when configuring a new kernel:
|
||||
|
||||
|
@ -296,11 +255,6 @@ Network device support
|
|||
It's not necessary to compile this driver as a module, even if you are going to
|
||||
run more than one instance of tinc.
|
||||
|
||||
If you have an early 2.4 kernel, you can choose both the tun/tap driver and the
|
||||
`Ethertap network tap' device. This latter is marked obsolete, and chances are
|
||||
that it won't even function correctly anymore. Make sure you select the
|
||||
universal tun/tap driver.
|
||||
|
||||
If you decide to build the tun/tap driver as a kernel module, add these lines
|
||||
to @file{/etc/modules.conf}:
|
||||
|
||||
|
@ -324,9 +278,9 @@ Using tap devices is recommended.
|
|||
For OpenBSD version 2.9 and higher,
|
||||
the tun driver is included in the default kernel configuration.
|
||||
There is also a kernel patch from @uref{http://diehard.n-r-g.com/stuff/openbsd/}
|
||||
which adds a tap device to OpenBSD.
|
||||
This should work with tinc.
|
||||
|
||||
which adds a tap device to OpenBSD which should work with tinc,
|
||||
but with recent versions of OpenBSD,
|
||||
a tun device can act as a tap device by setting the link0 option with ifconfig.
|
||||
|
||||
@c ==================================================================
|
||||
@node Configuration of NetBSD kernels
|
||||
|
@ -632,40 +586,16 @@ files on your system.
|
|||
@subsection Device files
|
||||
|
||||
@cindex device files
|
||||
First, you'll need the special device file(s) that form the interface
|
||||
between the kernel and the daemon.
|
||||
Most operating systems nowadays come with the necessary device files by default,
|
||||
or they have a mechanism to create them on demand.
|
||||
|
||||
The permissions for these files have to be such that only the super user
|
||||
may read/write to this file. You'd want this, because otherwise
|
||||
eavesdropping would become a bit too easy. This does, however, imply
|
||||
that you'd have to run tincd as root.
|
||||
|
||||
If you use Linux and have a kernel version prior to 2.4.0, you have to make the
|
||||
ethertap devices:
|
||||
If you use Linux and do not have udev installed,
|
||||
you may need to create the following device file if it does not exist:
|
||||
|
||||
@example
|
||||
mknod -m 600 /dev/tap0 c 36 16
|
||||
mknod -m 600 /dev/tap1 c 36 17
|
||||
...
|
||||
mknod -m 600 /dev/tap@emph{N} c 36 @emph{N+16}
|
||||
mknod -m 600 /dev/net/tun c 10 200
|
||||
@end example
|
||||
|
||||
There is a maximum of 16 ethertap devices.
|
||||
|
||||
If you use the universal tun/tap driver, you have to create the
|
||||
following device file (unless it already exist):
|
||||
|
||||
@example
|
||||
mknod -m 600 /dev/tun c 10 200
|
||||
@end example
|
||||
|
||||
If you use Linux, and you run the new 2.4 kernel using the devfs filesystem,
|
||||
then the tun/tap device will probably be automatically generated as
|
||||
@file{/dev/net/tun}.
|
||||
|
||||
Unlike the ethertap device, you do not need multiple device files if
|
||||
you are planning to run multiple tinc daemons.
|
||||
|
||||
|
||||
@c ==================================================================
|
||||
@node Other files
|
||||
|
@ -885,6 +815,48 @@ Under Windows, use @var{Interface} instead of @var{Device}.
|
|||
Note that you can only use one device per daemon.
|
||||
See also @ref{Device files}.
|
||||
|
||||
@cindex DeviceType
|
||||
@item DeviceType = <tun|tunnohead|tunifhead|tap> (only supported on BSD platforms)
|
||||
The type of the virtual network device.
|
||||
Tinc will normally automatically select the right type, and this option should not be used.
|
||||
However, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
||||
using this option might help.
|
||||
|
||||
@table @asis
|
||||
@item tun
|
||||
Set type to tun.
|
||||
Depending on the platform, this can either be with or without an address family header (see below).
|
||||
|
||||
@cindex tunnohead
|
||||
@item tunnohead
|
||||
Set type to tun without an address family header.
|
||||
Tinc will expect packets read from the virtual network device to start with an IP header.
|
||||
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
||||
|
||||
@cindex tunifhead
|
||||
@item tunifhead
|
||||
Set type to tun with an address family header.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with a four byte header containing the address family,
|
||||
followed by an IP header.
|
||||
This mode should support both IPv4 and IPv6 packets.
|
||||
|
||||
@item tap
|
||||
Set type to tap.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with an Ethernet header.
|
||||
@end table
|
||||
|
||||
@cindex GraphDumpFile
|
||||
@item GraphDumpFile = <@var{filename}> [experimental]
|
||||
If this option is present,
|
||||
tinc will dump the current network graph to the file @var{filename}
|
||||
every minute, unless there were no changes to the graph.
|
||||
The file is in a format that can be read by graphviz tools.
|
||||
If @var{filename} starts with a pipe symbol |,
|
||||
then the rest of the filename is interpreted as a shell command
|
||||
that is executed, the graph is then sent to stdin.
|
||||
|
||||
@cindex Hostnames
|
||||
@item Hostnames = <yes|no> (no)
|
||||
This option selects whether IP addresses (both real and on the VPN)
|
||||
|
@ -945,7 +917,8 @@ This only has effect when Mode is set to "switch".
|
|||
|
||||
@cindex Name
|
||||
@item Name = <@var{name}> [required]
|
||||
This is a symbolic name for this connection. It can be anything
|
||||
This is a symbolic name for this connection.
|
||||
The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _).
|
||||
|
||||
@cindex PingInterval
|
||||
@item PingInterval = <@var{seconds}> (60)
|
||||
|
@ -1032,6 +1005,15 @@ The length of the message authentication code used to authenticate UDP packets.
|
|||
Can be anything from 0
|
||||
up to the length of the digest produced by the digest algorithm.
|
||||
|
||||
@cindex PMTU
|
||||
@item PMTU = <@var{mtu}> (1514)
|
||||
This option controls the initial path MTU to this node.
|
||||
|
||||
@cindex PMTUDiscovery
|
||||
@item PMTUDiscovery = <yes|no> (yes)
|
||||
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.
|
||||
|
||||
@cindex Port
|
||||
@item Port = <@var{port}> (655)
|
||||
This is the port this tinc daemon listens on.
|
||||
|
@ -1056,7 +1038,7 @@ in each host configuration file, if you want to be able to establish a
|
|||
connection with that host.
|
||||
|
||||
@cindex Subnet
|
||||
@item Subnet = <@var{address}[/@var{prefixlength}]>
|
||||
@item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]>
|
||||
The subnet which this tinc daemon will serve.
|
||||
Tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet.
|
||||
If the packet matches a subnet,
|
||||
|
@ -1080,8 +1062,14 @@ example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes
|
|||
/22. This conforms to standard CIDR notation as described in
|
||||
@uref{ftp://ftp.isi.edu/in-notes/rfc1519.txt, RFC1519}
|
||||
|
||||
A Subnet can be given a weight to indicate its priority over identical Subnets
|
||||
owned by different nodes. The default weight is 10. Lower values indicate
|
||||
higher priority. Packets will be sent to the node with the highest priority,
|
||||
unless that node is not reachable, in which case the node with the next highest
|
||||
priority will be tried, and so on.
|
||||
|
||||
@cindex TCPonly
|
||||
@item TCPonly = <yes|no> (no) [experimental]
|
||||
@item TCPonly = <yes|no> (no)
|
||||
If this variable is set to yes, then the packets are tunnelled over a
|
||||
TCP connection instead of a UDP connection. This is especially useful
|
||||
for those who want to run a tinc daemon from behind a masquerading
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction BSD tun/tap device
|
||||
Copyright (C) 2001-2005 Ivo Timmermans,
|
||||
2001-2007 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2001-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -27,6 +27,7 @@
|
|||
#include "net.h"
|
||||
#include "route.h"
|
||||
#include "utils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#define DEFAULT_DEVICE "/dev/tun0"
|
||||
|
||||
|
@ -37,12 +38,12 @@ typedef enum device_type {
|
|||
} device_type_t;
|
||||
|
||||
int device_fd = -1;
|
||||
char *device;
|
||||
char *iface;
|
||||
char *device_info;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
static char *device_info = NULL;
|
||||
static int device_total_in = 0;
|
||||
static int device_total_out = 0;
|
||||
#ifdef HAVE_OPENBSD
|
||||
#if defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD)
|
||||
static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
|
||||
#else
|
||||
static device_type_t device_type = DEVICE_TYPE_TUN;
|
||||
|
@ -54,10 +55,10 @@ bool setup_device(void) {
|
|||
cp();
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
||||
device = DEFAULT_DEVICE;
|
||||
device = xstrdup(DEFAULT_DEVICE);
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
|
||||
iface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
|
||||
iface = xstrdup(rindex(device, '/') ? rindex(device, '/') + 1 : device);
|
||||
|
||||
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
|
||||
logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
|
||||
|
@ -78,7 +79,7 @@ bool setup_device(void) {
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
if(strstr(device, "tap"))
|
||||
if(strstr(device, "tap") || routing_mode != RMODE_ROUTER)
|
||||
device_type = DEVICE_TYPE_TAP;
|
||||
}
|
||||
|
||||
|
@ -139,6 +140,9 @@ void close_device(void) {
|
|||
cp();
|
||||
|
||||
close(device_fd);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
conf.c -- configuration code
|
||||
Copyright (C) 1998 Robert van der Meulen
|
||||
1998-2005 Ivo Timmermans
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000 Cris van Pelt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -287,6 +287,8 @@ static char *readline(FILE * fp, char **buf, size_t *buflen) {
|
|||
size = newsize;
|
||||
} else {
|
||||
*newline = '\0'; /* kill newline */
|
||||
if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */
|
||||
newline[-1] = '\0';
|
||||
break; /* yay */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
conf.h -- header for conf.c
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -60,5 +60,6 @@ extern int read_config_file(splay_tree_t *, const char *);
|
|||
extern bool read_server_config(void);
|
||||
extern FILE *ask_and_open(const char *, const char *, const char *);
|
||||
extern bool is_safe_path(const char *);
|
||||
extern bool disable_old_keys(FILE *);
|
||||
|
||||
#endif /* __TINC_CONF_H__ */
|
||||
|
|
|
@ -80,6 +80,9 @@ void free_connection(connection_t *c) {
|
|||
if(c->hischallenge)
|
||||
free(c->hischallenge);
|
||||
|
||||
if(c->config_tree)
|
||||
exit_configuration(&c->config_tree);
|
||||
|
||||
if(c->buffer)
|
||||
bufferevent_free(c->buffer);
|
||||
|
||||
|
@ -110,9 +113,9 @@ int dump_connections(struct evbuffer *out) {
|
|||
for(node = connection_tree->head; node; node = node->next) {
|
||||
c = node->data;
|
||||
if(evbuffer_add_printf(out,
|
||||
_(" %s at %s options %lx socket %d status %04x\n"),
|
||||
c->name, c->hostname, c->options, c->socket,
|
||||
c->status.value) == -1)
|
||||
_(" %s at %s options %lx socket %d status %04x\n"),
|
||||
c->name, c->hostname, c->options, c->socket,
|
||||
c->status.value) == -1)
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction with Windows tap driver in a Cygwin environment
|
||||
Copyright (C) 2002-2005 Ivo Timmermans,
|
||||
2002-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2002-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -38,7 +38,7 @@ int device_fd = -1;
|
|||
static HANDLE device_handle = INVALID_HANDLE_VALUE;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
char *device_info = NULL;
|
||||
static char *device_info = NULL;
|
||||
|
||||
static int device_total_in = 0;
|
||||
static int device_total_out = 0;
|
||||
|
@ -225,6 +225,9 @@ void close_device(void) {
|
|||
CloseHandle(device_handle);
|
||||
|
||||
kill(reader_pid, SIGKILL);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
graph.c -- graph algorithms
|
||||
Copyright (C) 2001-2006 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2001-2009 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2001-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -443,6 +443,7 @@ int dump_graph(struct evbuffer *out) {
|
|||
}
|
||||
|
||||
void graph(void) {
|
||||
subnet_cache_flush();
|
||||
sssp_dijkstra();
|
||||
check_reachability();
|
||||
mst_kruskal();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction with Linux ethertap and tun/tap device
|
||||
Copyright (C) 2001-2005 Ivo Timmermans,
|
||||
2001-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2001-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include "net.h"
|
||||
#include "route.h"
|
||||
#include "utils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
typedef enum device_type_t {
|
||||
DEVICE_TYPE_ETHERTAP,
|
||||
|
@ -43,10 +44,10 @@ typedef enum device_type_t {
|
|||
|
||||
int device_fd = -1;
|
||||
static device_type_t device_type;
|
||||
char *device;
|
||||
char *iface;
|
||||
char ifrname[IFNAMSIZ];
|
||||
char *device_info;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
static char ifrname[IFNAMSIZ];
|
||||
static char *device_info;
|
||||
|
||||
static int device_total_in = 0;
|
||||
static int device_total_out = 0;
|
||||
|
@ -57,13 +58,13 @@ bool setup_device(void) {
|
|||
cp();
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
||||
device = DEFAULT_DEVICE;
|
||||
device = xstrdup(DEFAULT_DEVICE);
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
|
||||
#ifdef HAVE_LINUX_IF_TUN_H
|
||||
iface = netname;
|
||||
iface = xstrdup(netname);
|
||||
#else
|
||||
iface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
|
||||
iface = xstrdup(rindex(device, '/') ? rindex(device, '/') + 1 : device);
|
||||
#endif
|
||||
device_fd = open(device, O_RDWR | O_NONBLOCK);
|
||||
|
||||
|
@ -91,11 +92,13 @@ bool setup_device(void) {
|
|||
|
||||
if(!ioctl(device_fd, TUNSETIFF, &ifr)) {
|
||||
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
|
||||
iface = ifrname;
|
||||
if(iface) free(iface);
|
||||
iface = xstrdup(ifrname);
|
||||
} else if(!ioctl(device_fd, (('T' << 8) | 202), &ifr)) {
|
||||
logger(LOG_WARNING, _("Old ioctl() request was needed for %s"), device);
|
||||
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
|
||||
iface = ifrname;
|
||||
if(iface) free(iface);
|
||||
iface = xstrdup(ifrname);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -103,7 +106,9 @@ bool setup_device(void) {
|
|||
overwrite_mac = true;
|
||||
device_info = _("Linux ethertap device");
|
||||
device_type = DEVICE_TYPE_ETHERTAP;
|
||||
iface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
|
||||
if(iface)
|
||||
free(iface);
|
||||
iface = xstrdup(rindex(device, '/') ? rindex(device, '/') + 1 : device);
|
||||
}
|
||||
|
||||
logger(LOG_INFO, _("%s is a %s"), device, device_info);
|
||||
|
@ -115,6 +120,9 @@ void close_device(void) {
|
|||
cp();
|
||||
|
||||
close(device_fd);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction with Windows tap driver in a MinGW environment
|
||||
Copyright (C) 2002-2005 Ivo Timmermans,
|
||||
2002-2007 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2002-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -38,7 +38,7 @@ int device_fd = 0;
|
|||
static HANDLE device_handle = INVALID_HANDLE_VALUE;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
char *device_info = NULL;
|
||||
static char *device_info = NULL;
|
||||
|
||||
static int device_total_in = 0;
|
||||
static int device_total_out = 0;
|
||||
|
@ -52,7 +52,7 @@ static struct packetbuf {
|
|||
|
||||
static int nbufs = 64;
|
||||
|
||||
DWORD WINAPI tapreader(void *bla) {
|
||||
static DWORD WINAPI tapreader(void *bla) {
|
||||
int sock, err, status;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo hint = {
|
||||
|
@ -311,6 +311,9 @@ void close_device(void) {
|
|||
cp();
|
||||
|
||||
CloseHandle(device_handle);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net.c -- most of the network code
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
|
18
src/net.h
18
src/net.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net.h -- header for net.c
|
||||
Copyright (C) 1998-2005 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -38,8 +38,6 @@
|
|||
|
||||
#define MAXSOCKETS 8 /* Probably overkill... */
|
||||
|
||||
#define MAXQUEUELENGTH 8 /* Maximum number of packats in a single queue */
|
||||
|
||||
typedef struct mac_t {
|
||||
uint8_t x[6];
|
||||
} mac_t;
|
||||
|
@ -87,17 +85,6 @@ typedef struct vpn_packet_t {
|
|||
uint8_t data[MAXSIZE];
|
||||
} vpn_packet_t;
|
||||
|
||||
typedef struct queue_element_t {
|
||||
void *packet;
|
||||
struct queue_element_t *prev;
|
||||
struct queue_element_t *next;
|
||||
} queue_element_t;
|
||||
|
||||
typedef struct packet_queue_t {
|
||||
queue_element_t *head;
|
||||
queue_element_t *tail;
|
||||
} packet_queue_t;
|
||||
|
||||
typedef struct listen_socket_t {
|
||||
struct event ev_tcp;
|
||||
struct event ev_udp;
|
||||
|
@ -107,6 +94,7 @@ typedef struct listen_socket_t {
|
|||
} listen_socket_t;
|
||||
|
||||
#include "conf.h"
|
||||
#include "list.h"
|
||||
|
||||
typedef struct outgoing_t {
|
||||
char *name;
|
||||
|
@ -117,6 +105,8 @@ typedef struct outgoing_t {
|
|||
struct event ev;
|
||||
} outgoing_t;
|
||||
|
||||
extern list_t *outgoing_list;
|
||||
|
||||
extern int maxoutbufsize;
|
||||
extern int seconds_till_retry;
|
||||
extern int addressfamily;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_packet.c -- Handles in- and outgoing VPN packets
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -83,6 +83,7 @@ static void send_mtu_probe_handler(int fd, short events, void *data) {
|
|||
memset(packet.data, 0, 14);
|
||||
randomize(packet.data + 14, len - 14);
|
||||
packet.len = len;
|
||||
packet.priority = 0;
|
||||
|
||||
ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending MTU probe length %d to %s (%s)"), len, n->name, n->hostname);
|
||||
|
||||
|
@ -244,6 +245,8 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
|
|||
inpkt = outpkt;
|
||||
}
|
||||
|
||||
inpkt->priority = 0;
|
||||
|
||||
if(!inpkt->data[12] && !inpkt->data[13])
|
||||
mtu_probe_h(n, inpkt);
|
||||
else
|
||||
|
@ -256,6 +259,10 @@ void receive_tcppacket(connection_t *c, char *buffer, int len) {
|
|||
cp();
|
||||
|
||||
outpkt.len = len;
|
||||
if(c->options & OPTION_TCPONLY)
|
||||
outpkt.priority = 0;
|
||||
else
|
||||
outpkt.priority = -1;
|
||||
memcpy(outpkt.data, buffer, len);
|
||||
|
||||
receive_packet(c->node, &outpkt);
|
||||
|
@ -269,7 +276,6 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
|||
vpn_packet_t *outpkt;
|
||||
int origlen;
|
||||
size_t outlen;
|
||||
vpn_packet_t *copy;
|
||||
static int priority = 0;
|
||||
int origpriority;
|
||||
int sock;
|
||||
|
@ -280,26 +286,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
|
|||
|
||||
if(!n->status.validkey) {
|
||||
ifdebug(TRAFFIC) logger(LOG_INFO,
|
||||
_("No valid key known yet for %s (%s), queueing packet"),
|
||||
_("No valid key known yet for %s (%s), forwarding via TCP"),
|
||||
n->name, n->hostname);
|
||||
|
||||
/* Since packet is on the stack of handle_tap_input(), we have to make a copy of it first. */
|
||||
|
||||
*(copy = xmalloc(sizeof *copy)) = *inpkt;
|
||||
|
||||
list_insert_tail(n->queue, copy);
|
||||
|
||||
if(n->queue->count > MAXQUEUELENGTH)
|
||||
list_delete_head(n->queue);
|
||||
|
||||
if(!n->status.waitingforkey)
|
||||
send_req_key(n->nexthop->connection, myself, n);
|
||||
|
||||
n->status.waitingforkey = true;
|
||||
|
||||
send_tcppacket(n->nexthop->connection, origpkt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!n->minmtu && (inpkt->data[12] | inpkt->data[13])) {
|
||||
ifdebug(TRAFFIC) logger(LOG_INFO,
|
||||
_("No minimum MTU established yet for %s (%s), forwarding via TCP"),
|
||||
n->name, n->hostname);
|
||||
|
||||
send_tcppacket(n->nexthop->connection, origpkt);
|
||||
}
|
||||
|
||||
origlen = inpkt->len;
|
||||
origpriority = inpkt->priority;
|
||||
|
||||
|
@ -403,13 +410,13 @@ void send_packet(const node_t *n, vpn_packet_t *packet) {
|
|||
return;
|
||||
}
|
||||
|
||||
via = (n->via == myself) ? n->nexthop : n->via;
|
||||
via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
|
||||
|
||||
if(via != n)
|
||||
ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet to %s via %s (%s)"),
|
||||
ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending packet to %s via %s (%s)"),
|
||||
n->name, via->name, n->via->hostname);
|
||||
|
||||
if((myself->options | via->options) & OPTION_TCPONLY) {
|
||||
if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) {
|
||||
if(!send_tcppacket(via->connection, packet))
|
||||
terminate_connection(via->connection, true);
|
||||
} else
|
||||
|
@ -438,21 +445,8 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
|
|||
}
|
||||
}
|
||||
|
||||
void flush_queue(node_t *n) {
|
||||
list_node_t *node, *next;
|
||||
|
||||
cp();
|
||||
|
||||
ifdebug(TRAFFIC) logger(LOG_INFO, _("Flushing queue for %s (%s)"), n->name, n->hostname);
|
||||
|
||||
for(node = n->queue->head; node; node = next) {
|
||||
next = node->next;
|
||||
send_udppacket(n, node->data);
|
||||
list_delete_node(n->queue, node);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_incoming_vpn_data(int sock, short events, void *data) {
|
||||
void handle_incoming_vpn_data(int sock, short events, void *data)
|
||||
{
|
||||
vpn_packet_t pkt;
|
||||
char *hostname;
|
||||
sockaddr_t from;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_setup.c -- Setup.
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -242,9 +242,6 @@ bool setup_myself(void) {
|
|||
if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice) && choice)
|
||||
myself->options |= OPTION_TCPONLY;
|
||||
|
||||
if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice)
|
||||
myself->options |= OPTION_PMTU_DISCOVERY;
|
||||
|
||||
if(myself->options & OPTION_TCPONLY)
|
||||
myself->options |= OPTION_INDIRECT;
|
||||
|
||||
|
@ -265,6 +262,10 @@ bool setup_myself(void) {
|
|||
} else
|
||||
routing_mode = RMODE_ROUTER;
|
||||
|
||||
if(routing_mode == RMODE_ROUTER)
|
||||
if(!get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) || choice)
|
||||
myself->options |= OPTION_PMTU_DISCOVERY;
|
||||
|
||||
get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance);
|
||||
|
||||
#if !defined(SOL_IP) || !defined(IP_TOS)
|
||||
|
@ -490,7 +491,7 @@ bool setup_network_connections(void) {
|
|||
pingtimeout = pinginterval;
|
||||
|
||||
if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize))
|
||||
maxoutbufsize = 4 * MTU;
|
||||
maxoutbufsize = 10 * MTU;
|
||||
|
||||
if(!setup_myself())
|
||||
return false;
|
||||
|
@ -514,21 +515,16 @@ void close_network_connections(void) {
|
|||
for(node = connection_tree->head; node; node = next) {
|
||||
next = node->next;
|
||||
c = node->data;
|
||||
|
||||
if(c->outgoing) {
|
||||
if(c->outgoing->ai)
|
||||
freeaddrinfo(c->outgoing->ai);
|
||||
free(c->outgoing->name);
|
||||
free(c->outgoing);
|
||||
c->outgoing = NULL;
|
||||
}
|
||||
|
||||
c->outgoing = false;
|
||||
terminate_connection(c, false);
|
||||
}
|
||||
|
||||
list_delete_list(outgoing_list);
|
||||
|
||||
if(myself && myself->connection) {
|
||||
subnet_update(myself, NULL, false);
|
||||
terminate_connection(myself->connection, false);
|
||||
free_connection(myself->connection);
|
||||
}
|
||||
|
||||
for(i = 0; i < listen_sockets; i++) {
|
||||
|
@ -552,6 +548,8 @@ void close_network_connections(void) {
|
|||
|
||||
execute_script("tinc-down", envp);
|
||||
|
||||
if(myport) free(myport);
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
free(envp[i]);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_socket.c -- Handle various kinds of sockets.
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2007 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -48,6 +48,7 @@ int seconds_till_retry = 5;
|
|||
|
||||
listen_socket_t listen_socket[MAXSOCKETS];
|
||||
int listen_sockets;
|
||||
list_t *outgoing_list = NULL;
|
||||
|
||||
/* Setup sockets */
|
||||
|
||||
|
@ -188,24 +189,16 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
|
|||
#endif
|
||||
|
||||
#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
|
||||
{
|
||||
bool choice;
|
||||
|
||||
if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
|
||||
option = IP_PMTUDISC_DO;
|
||||
setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof option);
|
||||
}
|
||||
if(myself->options & OPTION_PMTU_DISCOVERY) {
|
||||
option = IP_PMTUDISC_DO;
|
||||
setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
|
||||
{
|
||||
bool choice;
|
||||
|
||||
if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
|
||||
option = IPV6_PMTUDISC_DO;
|
||||
setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof option);
|
||||
}
|
||||
if(myself->options & OPTION_PMTU_DISCOVERY) {
|
||||
option = IPV6_PMTUDISC_DO;
|
||||
setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -412,8 +405,6 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
|
|||
if(!outgoing->cfg) {
|
||||
logger(LOG_ERR, _("No address specified for %s"), c->name);
|
||||
free_connection(c);
|
||||
free(outgoing->name);
|
||||
free(outgoing);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -486,13 +477,37 @@ void handle_new_meta_connection(int sock, short events, void *data) {
|
|||
send_id(c);
|
||||
}
|
||||
|
||||
void try_outgoing_connections(void) {
|
||||
void free_outgoing(outgoing_t *outgoing) {
|
||||
if(outgoing->ai)
|
||||
freeaddrinfo(outgoing->ai);
|
||||
|
||||
if(outgoing->name)
|
||||
free(outgoing->name);
|
||||
|
||||
free(outgoing);
|
||||
}
|
||||
|
||||
void try_outgoing_connections(void)
|
||||
{
|
||||
static config_t *cfg = NULL;
|
||||
char *name;
|
||||
outgoing_t *outgoing;
|
||||
|
||||
connection_t *c;
|
||||
splay_node_t *node;
|
||||
|
||||
cp();
|
||||
|
||||
if(outgoing_list) {
|
||||
for(node = connection_tree->head; node; node = node->next) {
|
||||
c = node->data;
|
||||
c->outgoing = NULL;
|
||||
}
|
||||
|
||||
list_delete_list(outgoing_list);
|
||||
}
|
||||
|
||||
outgoing_list = list_alloc((list_action_t)free_outgoing);
|
||||
|
||||
for(cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
|
||||
get_config_string(cfg, &name);
|
||||
|
||||
|
@ -506,6 +521,7 @@ void try_outgoing_connections(void) {
|
|||
|
||||
outgoing = xmalloc_and_zero(sizeof *outgoing);
|
||||
outgoing->name = name;
|
||||
list_insert_tail(outgoing_list, outgoing);
|
||||
setup_outgoing_connection(outgoing);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
node.c -- node tree management
|
||||
Copyright (C) 2001-2006 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2001-2009 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2001-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -73,7 +73,6 @@ node_t *new_node(void) {
|
|||
|
||||
n->subnet_tree = new_subnet_tree();
|
||||
n->edge_tree = new_edge_tree();
|
||||
n->queue = list_alloc((list_action_t) free);
|
||||
n->mtu = MTU;
|
||||
n->maxmtu = MTU;
|
||||
|
||||
|
@ -83,9 +82,6 @@ node_t *new_node(void) {
|
|||
void free_node(node_t *n) {
|
||||
cp();
|
||||
|
||||
if(n->queue)
|
||||
list_delete_list(n->queue);
|
||||
|
||||
if(n->subnet_tree)
|
||||
free_subnet_tree(n->subnet_tree);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
node.h -- header for node.c
|
||||
Copyright (C) 2001-2006 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2001-2009 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2001-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -60,8 +60,6 @@ typedef struct node_t {
|
|||
|
||||
int compression; /* Compressionlevel, 0 = no compression */
|
||||
|
||||
list_t *queue; /* Queue for packets awaiting to be encrypted */
|
||||
|
||||
int distance;
|
||||
struct node_t *nexthop; /* nearest node from us to him */
|
||||
struct node_t *via; /* next hop for UDP packets */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
process.c -- process management functions
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2007 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol_auth.c -- handle the meta-protocol, authentication
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2007 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -363,7 +363,7 @@ bool send_ack(connection_t *c) {
|
|||
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)
|
||||
if(myself->options & OPTION_PMTU_DISCOVERY)
|
||||
c->options |= OPTION_PMTU_DISCOVERY;
|
||||
|
||||
get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight);
|
||||
|
@ -448,6 +448,10 @@ bool ack_h(connection_t *c, char *request) {
|
|||
|
||||
n->connection = c;
|
||||
c->node = n;
|
||||
if(!(c->options & options & OPTION_PMTU_DISCOVERY)) {
|
||||
c->options &= ~OPTION_PMTU_DISCOVERY;
|
||||
options &= ~OPTION_PMTU_DISCOVERY;
|
||||
}
|
||||
c->options |= options;
|
||||
|
||||
if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol_key.c -- handle the meta-protocol, key exchange
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -248,7 +248,5 @@ bool ans_key_h(connection_t *c, char *request) {
|
|||
if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
|
||||
send_mtu_probe(from);
|
||||
|
||||
flush_queue(from);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -151,9 +151,10 @@ bool send_tcppacket(connection_t *c, vpn_packet_t *packet)
|
|||
{
|
||||
cp();
|
||||
|
||||
/* If there already is a lot of data in the outbuf buffer, discard this packet. */
|
||||
/* If there already is a lot of data in the outbuf buffer, discard this packet.
|
||||
We use a very simple Random Early Drop algorithm. */
|
||||
|
||||
if(c->buffer->output->off > maxoutbufsize)
|
||||
if(2.0 * c->buffer->output->off / (double)maxoutbufsize - 1 > drand48())
|
||||
return true;
|
||||
|
||||
if(!send_request(c, "%d %hd", PACKET, packet->len))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol_subnet.c -- handle the meta-protocol, subnets
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -83,15 +83,19 @@ bool add_subnet_h(connection_t *c, char *request)
|
|||
|
||||
owner = lookup_node(name);
|
||||
|
||||
if(tunnelserver && owner != myself && owner != c->node) {
|
||||
/* in case of tunnelserver, ignore indirect subnet registrations */
|
||||
ifdebug(PROTOCOL) logger(LOG_WARNING, _("Ignoring indirect %s from %s (%s) for %s"),
|
||||
"ADD_SUBNET", c->name, c->hostname, subnetstr);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!owner) {
|
||||
owner = new_node();
|
||||
owner->name = xstrdup(name);
|
||||
node_add(owner);
|
||||
}
|
||||
|
||||
if(tunnelserver && owner != myself && owner != c->node)
|
||||
return false;
|
||||
|
||||
/* Check if we already know this subnet */
|
||||
|
||||
if(lookup_subnet(owner, &s))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- raw socket
|
||||
Copyright (C) 2002-2005 Ivo Timmermans,
|
||||
2002-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2002-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -29,12 +29,13 @@
|
|||
#include "logger.h"
|
||||
#include "utils.h"
|
||||
#include "route.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
int device_fd = -1;
|
||||
char *device;
|
||||
char *iface;
|
||||
char ifrname[IFNAMSIZ];
|
||||
char *device_info;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
static char ifrname[IFNAMSIZ];
|
||||
static char *device_info;
|
||||
|
||||
static int device_total_in = 0;
|
||||
static int device_total_out = 0;
|
||||
|
@ -45,12 +46,11 @@ bool setup_device(void) {
|
|||
|
||||
cp();
|
||||
|
||||
if(!get_config_string
|
||||
(lookup_config(config_tree, "Interface"), &iface))
|
||||
iface = "eth0";
|
||||
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
|
||||
iface = xstrdup("eth0");
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
||||
device = iface;
|
||||
device = xstrdup(iface);
|
||||
|
||||
device_info = _("raw socket");
|
||||
|
||||
|
@ -88,6 +88,9 @@ void close_device(void) {
|
|||
cp();
|
||||
|
||||
close(device_fd);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
|
|
54
src/route.c
54
src/route.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
route.c -- routing
|
||||
Copyright (C) 2000-2005 Ivo Timmermans,
|
||||
2000-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -391,7 +391,14 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet)
|
|||
if(!checklength(source, packet, ether_size + ip_size))
|
||||
return;
|
||||
|
||||
route_ipv4_unicast(source, packet);
|
||||
if(((packet->data[30] & 0xf0) == 0xe0) || (
|
||||
packet->data[30] == 255 &&
|
||||
packet->data[31] == 255 &&
|
||||
packet->data[32] == 255 &&
|
||||
packet->data[33] == 255))
|
||||
broadcast_packet(source, packet);
|
||||
else
|
||||
route_ipv4_unicast(source, packet);
|
||||
}
|
||||
|
||||
/* RFC 2463 */
|
||||
|
@ -529,6 +536,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet)
|
|||
struct nd_opt_hdr opt;
|
||||
subnet_t *subnet;
|
||||
uint16_t checksum;
|
||||
bool has_opt;
|
||||
|
||||
struct {
|
||||
struct in6_addr ip6_src; /* source address */
|
||||
|
@ -539,9 +547,11 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet)
|
|||
|
||||
cp();
|
||||
|
||||
if(!checklength(source, packet, ether_size + ip6_size + ns_size + opt_size + ETH_ALEN))
|
||||
if(!checklength(source, packet, ether_size + ip6_size + ns_size))
|
||||
return;
|
||||
|
||||
has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN;
|
||||
|
||||
if(source != myself) {
|
||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Got neighbor solicitation request from %s (%s) while in router mode!"), source->name, source->hostname);
|
||||
return;
|
||||
|
@ -551,7 +561,8 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet)
|
|||
|
||||
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);
|
||||
if(has_opt)
|
||||
memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size);
|
||||
|
||||
/* First, snatch the source address from the neighbor solicitation packet */
|
||||
|
||||
|
@ -561,7 +572,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet)
|
|||
/* Check if this is a valid neighbor solicitation request */
|
||||
|
||||
if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
|
||||
opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
|
||||
(has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) {
|
||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: received unknown type neighbor solicitation request"));
|
||||
return;
|
||||
}
|
||||
|
@ -570,15 +581,20 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet)
|
|||
|
||||
pseudo.ip6_src = ip6.ip6_src;
|
||||
pseudo.ip6_dst = ip6.ip6_dst;
|
||||
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
|
||||
if(has_opt)
|
||||
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
|
||||
else
|
||||
pseudo.length = htonl(ns_size);
|
||||
pseudo.next = htonl(IPPROTO_ICMPV6);
|
||||
|
||||
/* Generate checksum */
|
||||
|
||||
checksum = inet_checksum(&pseudo, sizeof pseudo, ~0);
|
||||
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(has_opt) {
|
||||
checksum = inet_checksum(&opt, opt_size, checksum);
|
||||
checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum);
|
||||
}
|
||||
|
||||
if(checksum) {
|
||||
ifdebug(TRAFFIC) logger(LOG_WARNING, _("Cannot route packet: checksum error for neighbor solicitation request"));
|
||||
|
@ -616,7 +632,8 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet)
|
|||
ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */
|
||||
ip6.ip6_src = ns.nd_ns_target;
|
||||
|
||||
memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
|
||||
if(has_opt)
|
||||
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_cksum = 0;
|
||||
ns.nd_ns_type = ND_NEIGHBOR_ADVERT;
|
||||
|
@ -627,15 +644,20 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet)
|
|||
|
||||
pseudo.ip6_src = ip6.ip6_src;
|
||||
pseudo.ip6_dst = ip6.ip6_dst;
|
||||
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
|
||||
if(has_opt)
|
||||
pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
|
||||
else
|
||||
pseudo.length = htonl(ns_size);
|
||||
pseudo.next = htonl(IPPROTO_ICMPV6);
|
||||
|
||||
/* Generate checksum */
|
||||
|
||||
checksum = inet_checksum(&pseudo, sizeof pseudo, ~0);
|
||||
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(has_opt) {
|
||||
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;
|
||||
|
||||
|
@ -643,7 +665,8 @@ static void route_neighborsol(node_t *source, vpn_packet_t *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);
|
||||
if(has_opt)
|
||||
memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size);
|
||||
|
||||
send_packet(source, packet);
|
||||
}
|
||||
|
@ -660,7 +683,10 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet)
|
|||
return;
|
||||
}
|
||||
|
||||
route_ipv6_unicast(source, packet);
|
||||
if(packet->data[38] == 255)
|
||||
broadcast_packet(source, packet);
|
||||
else
|
||||
route_ipv6_unicast(source, packet);
|
||||
}
|
||||
|
||||
/* RFC 826 */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction with Solaris tun device
|
||||
Copyright (C) 2001-2005 Ivo Timmermans,
|
||||
2001-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2001-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -31,13 +31,14 @@
|
|||
#include "logger.h"
|
||||
#include "net.h"
|
||||
#include "utils.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#define DEFAULT_DEVICE "/dev/tun"
|
||||
|
||||
int device_fd = -1;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
char *device_info = NULL;
|
||||
static char *device_info = NULL;
|
||||
|
||||
static int device_total_in = 0;
|
||||
static int device_total_out = 0;
|
||||
|
@ -50,7 +51,7 @@ bool setup_device(void) {
|
|||
cp();
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
||||
device = DEFAULT_DEVICE;
|
||||
device = xstrdup(DEFAULT_DEVICE);
|
||||
|
||||
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
|
||||
logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
|
||||
|
@ -111,6 +112,9 @@ void close_device(void) {
|
|||
cp();
|
||||
|
||||
close(device_fd);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
|
|
197
src/subnet.c
197
src/subnet.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
subnet.c -- handle subnet lookups and lists
|
||||
Copyright (C) 2000-2006 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2000-2009 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2000-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -37,6 +37,23 @@
|
|||
|
||||
splay_tree_t *subnet_tree;
|
||||
|
||||
/* Subnet lookup cache */
|
||||
|
||||
static ipv4_t cache_ipv4_address[2];
|
||||
static subnet_t *cache_ipv4_subnet[2];
|
||||
static bool cache_ipv4_valid[2];
|
||||
static int cache_ipv4_slot;
|
||||
|
||||
static ipv6_t cache_ipv6_address[2];
|
||||
static subnet_t *cache_ipv6_subnet[2];
|
||||
static bool cache_ipv6_valid[2];
|
||||
static int cache_ipv6_slot;
|
||||
|
||||
void subnet_cache_flush() {
|
||||
cache_ipv4_valid[0] = cache_ipv4_valid[1] = false;
|
||||
cache_ipv6_valid[0] = cache_ipv6_valid[1] = false;
|
||||
}
|
||||
|
||||
/* Subnet comparison */
|
||||
|
||||
static int subnet_compare_mac(const subnet_t *a, const subnet_t *b)
|
||||
|
@ -45,6 +62,11 @@ static int subnet_compare_mac(const subnet_t *a, const subnet_t *b)
|
|||
|
||||
result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof a->net.mac.address);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = a->weight - b->weight;
|
||||
|
||||
if(result || !a->owner || !b->owner)
|
||||
return result;
|
||||
|
||||
|
@ -55,12 +77,17 @@ static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b)
|
|||
{
|
||||
int result;
|
||||
|
||||
result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof a->net.ipv4.address);
|
||||
result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = a->net.ipv4.prefixlength - b->net.ipv4.prefixlength;
|
||||
result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t));
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = a->weight - b->weight;
|
||||
|
||||
if(result || !a->owner || !b->owner)
|
||||
return result;
|
||||
|
@ -72,12 +99,17 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b)
|
|||
{
|
||||
int result;
|
||||
|
||||
result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof a->net.ipv6.address);
|
||||
result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t));
|
||||
|
||||
result = a->net.ipv6.prefixlength - b->net.ipv6.prefixlength;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = a->weight - b->weight;
|
||||
|
||||
if(result || !a->owner || !b->owner)
|
||||
return result;
|
||||
|
@ -118,6 +150,8 @@ void init_subnets(void)
|
|||
cp();
|
||||
|
||||
subnet_tree = splay_alloc_tree((splay_compare_t) subnet_compare, (splay_action_t) free_subnet);
|
||||
|
||||
subnet_cache_flush();
|
||||
}
|
||||
|
||||
void exit_subnets(void)
|
||||
|
@ -167,6 +201,8 @@ void subnet_add(node_t *n, subnet_t *subnet)
|
|||
|
||||
splay_insert(subnet_tree, subnet);
|
||||
splay_insert(n->subnet_tree, subnet);
|
||||
|
||||
subnet_cache_flush();
|
||||
}
|
||||
|
||||
void subnet_del(node_t *n, subnet_t *subnet)
|
||||
|
@ -175,6 +211,8 @@ void subnet_del(node_t *n, subnet_t *subnet)
|
|||
|
||||
splay_delete(n->subnet_tree, subnet);
|
||||
splay_delete(subnet_tree, subnet);
|
||||
|
||||
subnet_cache_flush();
|
||||
}
|
||||
|
||||
/* Ascii representation of subnets */
|
||||
|
@ -183,16 +221,18 @@ bool str2net(subnet_t *subnet, const char *subnetstr)
|
|||
{
|
||||
int i, l;
|
||||
uint16_t x[8];
|
||||
int weight = 10;
|
||||
|
||||
cp();
|
||||
|
||||
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
|
||||
&x[0], &x[1], &x[2], &x[3], &l) == 5) {
|
||||
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d",
|
||||
&x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) {
|
||||
if(l < 0 || l > 32)
|
||||
return false;
|
||||
|
||||
subnet->type = SUBNET_IPV4;
|
||||
subnet->net.ipv4.prefixlength = l;
|
||||
subnet->weight = weight;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
if(x[i] > 255)
|
||||
|
@ -203,14 +243,15 @@ bool str2net(subnet_t *subnet, const char *subnetstr)
|
|||
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#%d",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
|
||||
&l) == 9) {
|
||||
&l, &weight) >= 9) {
|
||||
if(l < 0 || l > 128)
|
||||
return false;
|
||||
|
||||
subnet->type = SUBNET_IPV6;
|
||||
subnet->net.ipv6.prefixlength = l;
|
||||
subnet->weight = weight;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
||||
|
@ -218,9 +259,10 @@ bool str2net(subnet_t *subnet, const char *subnetstr)
|
|||
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#%d", &x[0], &x[1], &x[2], &x[3], &weight) >= 4) {
|
||||
subnet->type = SUBNET_IPV4;
|
||||
subnet->net.ipv4.prefixlength = 32;
|
||||
subnet->weight = weight;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
if(x[i] > 255)
|
||||
|
@ -231,10 +273,11 @@ bool str2net(subnet_t *subnet, const char *subnetstr)
|
|||
return true;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7]) == 8) {
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx#%d",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &weight) >= 8) {
|
||||
subnet->type = SUBNET_IPV6;
|
||||
subnet->net.ipv6.prefixlength = 128;
|
||||
subnet->weight = weight;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
||||
|
@ -242,9 +285,10 @@ bool str2net(subnet_t *subnet, const char *subnetstr)
|
|||
return true;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5]) == 6) {
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx#%d",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) {
|
||||
subnet->type = SUBNET_MAC;
|
||||
subnet->weight = weight;
|
||||
|
||||
for(i = 0; i < 6; i++)
|
||||
subnet->net.mac.address.x[i] = x[i];
|
||||
|
@ -266,24 +310,28 @@ bool net2str(char *netstr, int len, const subnet_t *subnet)
|
|||
|
||||
switch (subnet->type) {
|
||||
case SUBNET_MAC:
|
||||
snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx#%d",
|
||||
subnet->net.mac.address.x[0],
|
||||
subnet->net.mac.address.x[1],
|
||||
subnet->net.mac.address.x[2],
|
||||
subnet->net.mac.address.x[3],
|
||||
subnet->net.mac.address.x[4], subnet->net.mac.address.x[5]);
|
||||
subnet->net.mac.address.x[4],
|
||||
subnet->net.mac.address.x[5],
|
||||
subnet->weight);
|
||||
break;
|
||||
|
||||
case SUBNET_IPV4:
|
||||
snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d",
|
||||
snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d#%d",
|
||||
subnet->net.ipv4.address.x[0],
|
||||
subnet->net.ipv4.address.x[1],
|
||||
subnet->net.ipv4.address.x[2],
|
||||
subnet->net.ipv4.address.x[3], subnet->net.ipv4.prefixlength);
|
||||
subnet->net.ipv4.address.x[3],
|
||||
subnet->net.ipv4.prefixlength,
|
||||
subnet->weight);
|
||||
break;
|
||||
|
||||
case SUBNET_IPV6:
|
||||
snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
|
||||
snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d",
|
||||
ntohs(subnet->net.ipv6.address.x[0]),
|
||||
ntohs(subnet->net.ipv6.address.x[1]),
|
||||
ntohs(subnet->net.ipv6.address.x[2]),
|
||||
|
@ -292,7 +340,8 @@ bool net2str(char *netstr, int len, const subnet_t *subnet)
|
|||
ntohs(subnet->net.ipv6.address.x[5]),
|
||||
ntohs(subnet->net.ipv6.address.x[6]),
|
||||
ntohs(subnet->net.ipv6.address.x[7]),
|
||||
subnet->net.ipv6.prefixlength);
|
||||
subnet->net.ipv6.prefixlength,
|
||||
subnet->weight);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -332,80 +381,96 @@ subnet_t *lookup_subnet_mac(const mac_t *address)
|
|||
|
||||
subnet_t *lookup_subnet_ipv4(const ipv4_t *address)
|
||||
{
|
||||
subnet_t *p, subnet = {0};
|
||||
subnet_t *p, *r = NULL, subnet = {0};
|
||||
splay_node_t *n;
|
||||
int i;
|
||||
|
||||
cp();
|
||||
|
||||
// Check if this address is cached
|
||||
|
||||
for(i = 0; i < 2; i++) {
|
||||
if(!cache_ipv4_valid[i])
|
||||
continue;
|
||||
if(!memcmp(address, &cache_ipv4_address[i], sizeof *address))
|
||||
return cache_ipv4_subnet[i];
|
||||
}
|
||||
|
||||
// Search all subnets for a matching one
|
||||
|
||||
subnet.type = SUBNET_IPV4;
|
||||
subnet.net.ipv4.address = *address;
|
||||
subnet.net.ipv4.prefixlength = 32;
|
||||
subnet.owner = NULL;
|
||||
|
||||
do {
|
||||
/* Go find subnet */
|
||||
for(n = subnet_tree->head; n; n = n->next) {
|
||||
p = n->data;
|
||||
|
||||
if(!p || p->type != subnet.type)
|
||||
continue;
|
||||
|
||||
p = splay_search_closest_smaller(subnet_tree, &subnet);
|
||||
|
||||
/* Check if the found subnet REALLY matches */
|
||||
|
||||
if(p) {
|
||||
if(p->type != SUBNET_IPV4) {
|
||||
p = NULL;
|
||||
if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) {
|
||||
r = p;
|
||||
if(p->owner->status.reachable)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength))
|
||||
break;
|
||||
else {
|
||||
/* Otherwise, see if there is a bigger enclosing subnet */
|
||||
|
||||
subnet.net.ipv4.prefixlength = p->net.ipv4.prefixlength - 1;
|
||||
if(subnet.net.ipv4.prefixlength < 0 || subnet.net.ipv4.prefixlength > 32)
|
||||
return NULL;
|
||||
maskcpy(&subnet.net.ipv4.address, &p->net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address);
|
||||
}
|
||||
}
|
||||
} while(p);
|
||||
}
|
||||
|
||||
return p;
|
||||
// Cache the result
|
||||
|
||||
cache_ipv4_slot = !cache_ipv4_slot;
|
||||
memcpy(&cache_ipv4_address[cache_ipv4_slot], address, sizeof *address);
|
||||
cache_ipv4_subnet[cache_ipv4_slot] = r;
|
||||
cache_ipv4_valid[cache_ipv4_slot] = true;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
subnet_t *lookup_subnet_ipv6(const ipv6_t *address)
|
||||
{
|
||||
subnet_t *p, subnet = {0};
|
||||
subnet_t *p, *r = NULL, subnet = {0};
|
||||
splay_node_t *n;
|
||||
int i;
|
||||
|
||||
cp();
|
||||
|
||||
// Check if this address is cached
|
||||
|
||||
for(i = 0; i < 2; i++) {
|
||||
if(!cache_ipv6_valid[i])
|
||||
continue;
|
||||
if(!memcmp(address, &cache_ipv6_address[i], sizeof *address))
|
||||
return cache_ipv6_subnet[i];
|
||||
}
|
||||
|
||||
// Search all subnets for a matching one
|
||||
|
||||
subnet.type = SUBNET_IPV6;
|
||||
subnet.net.ipv6.address = *address;
|
||||
subnet.net.ipv6.prefixlength = 128;
|
||||
subnet.owner = NULL;
|
||||
|
||||
do {
|
||||
/* Go find subnet */
|
||||
for(n = subnet_tree->head; n; n = n->next) {
|
||||
p = n->data;
|
||||
|
||||
if(!p || p->type != subnet.type)
|
||||
continue;
|
||||
|
||||
p = splay_search_closest_smaller(subnet_tree, &subnet);
|
||||
|
||||
/* Check if the found subnet REALLY matches */
|
||||
|
||||
if(p) {
|
||||
if(p->type != SUBNET_IPV6)
|
||||
return NULL;
|
||||
|
||||
if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength))
|
||||
if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) {
|
||||
r = p;
|
||||
if(p->owner->status.reachable)
|
||||
break;
|
||||
else {
|
||||
/* Otherwise, see if there is a bigger enclosing subnet */
|
||||
|
||||
subnet.net.ipv6.prefixlength = p->net.ipv6.prefixlength - 1;
|
||||
if(subnet.net.ipv6.prefixlength < 0 || subnet.net.ipv6.prefixlength > 128)
|
||||
return NULL;
|
||||
maskcpy(&subnet.net.ipv6.address, &p->net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address);
|
||||
}
|
||||
}
|
||||
} while(p);
|
||||
}
|
||||
|
||||
return p;
|
||||
// Cache the result
|
||||
|
||||
cache_ipv6_slot = !cache_ipv6_slot;
|
||||
memcpy(&cache_ipv6_address[cache_ipv6_slot], address, sizeof *address);
|
||||
cache_ipv6_subnet[cache_ipv6_slot] = r;
|
||||
cache_ipv6_valid[cache_ipv6_slot] = true;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
subnet.h -- header for subnet.c
|
||||
Copyright (C) 2000-2006 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2000-2009 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2000-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -53,6 +53,7 @@ typedef struct subnet_t {
|
|||
|
||||
subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
|
||||
time_t expires; /* expiry time */
|
||||
int weight; /* weight (higher value is higher priority) */
|
||||
|
||||
/* And now for the actual subnet: */
|
||||
|
||||
|
@ -82,5 +83,6 @@ extern subnet_t *lookup_subnet_mac(const mac_t *);
|
|||
extern subnet_t *lookup_subnet_ipv4(const ipv4_t *);
|
||||
extern subnet_t *lookup_subnet_ipv6(const ipv6_t *);
|
||||
extern int dump_subnets(struct evbuffer *);
|
||||
extern void subnet_cache_flush(void);
|
||||
|
||||
#endif /* __TINC_SUBNET_H__ */
|
||||
|
|
16
src/tincd.c
16
src/tincd.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
tincd.c -- the main file for tincd
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2007 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -229,6 +229,14 @@ static void make_names(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void free_names() {
|
||||
if (identname) free(identname);
|
||||
if (netname) free(netname);
|
||||
if (controlsocketname) free(controlsocketname);
|
||||
if (logfilename) free(logfilename);
|
||||
if (confbase) free(confbase);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
program_name = argv[0];
|
||||
|
@ -245,7 +253,7 @@ int main(int argc, char **argv)
|
|||
if(show_version) {
|
||||
printf(_("%s version %s (built %s %s, protocol %d)\n"), PACKAGE,
|
||||
VERSION, __DATE__, __TIME__, PROT_CURRENT);
|
||||
printf(_("Copyright (C) 1998-2007 Ivo Timmermans, Guus Sliepen and others.\n"
|
||||
printf(_("Copyright (C) 1998-2009 Ivo Timmermans, Guus Sliepen and others.\n"
|
||||
"See the AUTHORS file for a complete list.\n\n"
|
||||
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
|
||||
"and you are welcome to redistribute it under certain conditions;\n"
|
||||
|
@ -331,11 +339,11 @@ int main2(int argc, char **argv)
|
|||
|
||||
/* Shutdown properly. */
|
||||
|
||||
close_network_connections();
|
||||
|
||||
ifdebug(CONNECTIONS)
|
||||
dump_device_stats();
|
||||
|
||||
close_network_connections();
|
||||
|
||||
end:
|
||||
logger(LOG_NOTICE, _("Terminating"));
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- UML network socket
|
||||
Copyright (C) 2002-2005 Ivo Timmermans,
|
||||
2002-2006 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2002-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
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
|
||||
|
@ -36,9 +36,9 @@ static int request_fd = -1;
|
|||
static int data_fd = -1;
|
||||
static int write_fd = -1;
|
||||
static int state = 0;
|
||||
char *device;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
char *device_info;
|
||||
static char *device_info;
|
||||
|
||||
extern char *identname;
|
||||
extern bool running;
|
||||
|
@ -169,6 +169,9 @@ void close_device(void) {
|
|||
close(write_fd);
|
||||
|
||||
unlink(device);
|
||||
|
||||
free(device);
|
||||
if(iface) free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
|
|
Loading…
Reference in a new issue