2004-10-01 18:22:06 +00:00
|
|
|
/*
|
|
|
|
have.h -- include headers which are known to exist
|
2006-04-26 13:52:58 +00:00
|
|
|
Copyright (C) 1998-2005 Ivo Timmermans
|
2016-04-14 21:24:22 +00:00
|
|
|
2003-2016 Guus Sliepen <guus@tinc-vpn.org>
|
2004-10-01 18:22:06 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
2009-09-24 22:01:00 +00:00
|
|
|
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.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2004-10-01 18:22:06 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __TINC_HAVE_H__
|
|
|
|
#define __TINC_HAVE_H__
|
|
|
|
|
2010-05-01 13:37:11 +00:00
|
|
|
#ifdef HAVE_MINGW
|
|
|
|
#define WINVER WindowsXP
|
2010-11-12 15:15:29 +00:00
|
|
|
#define WIN32_LEAN_AND_MEAN
|
2010-05-01 13:37:11 +00:00
|
|
|
#endif
|
|
|
|
|
2004-10-01 18:22:06 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
2016-04-14 15:03:01 +00:00
|
|
|
#include <stdbool.h>
|
2004-10-01 18:22:06 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
2013-12-07 21:19:39 +00:00
|
|
|
#include <limits.h>
|
Use a smarter algorithm for choosing MTU discovery probe sizes.
Currently, tinc uses a naive algorithm for choosing MTU discovery probe
sizes, picking a size at random between minmtu and maxmtu.
This is of course suboptimal - since the behavior of probes is
deterministic (assuming no packet loss), it seems likely that using a
non-deterministic discovery algorithm will not yield the best results.
Furthermore, the randomness introduces a lot of variation in convergence
times.
The random solution also suffers from pathological cases - since it's
using a uniform distribution, it doesn't take into account the fact that
it's often more interesting to send small probes rather than large ones,
because getting replies is the only way we can make progress (assuming
the worst case scenario in which the OS doesn't know anything, therefore
keeping maxmtu constant). This can lead to absurd situations where the
discovery algorithm is close to the real MTU, but can't get to it
because the random number generator keeps generating numbers that are
past it.
The algorithm implemented in this patch aims to improve on the naive
random algorithm. It is organized around "cycles" of 8 probes; the sizes
of the probes decrease as we go through the cycle, thus making sure the
algorithm can cover lots of ground quickly (in case we're far from
actual MTU), but also examining the local area (in case we're close to
actual MTU). Using cycles ensures that the algorithm will "go back" to
large probes to better cover the new interval and to protect against
packet loss.
For the probe size itself, various mathematical models were simulated in
an attempt to find the one that converges the fastest; it has been
determined that using an exponential based on the size of the remaining
interval was the most effective option. The exponential is adjusted with
a magic multiplier fine-tuned to make tinc jump to the "most
interesting" (i.e. 1400+) section as soon as discovery starts.
Simulations indicate that assuming no packet loss and no help from the
OS (i.e. maxmtu stays constant), this algorithm will typically converge
to the *exact* MTU value in less than 10 probes, and will get within 8
bytes in less than 5 probes, for actual MTUs between 1417 and ~1450
(which is the range the algorithm is fine-tuned for). In contrast, the
previous algorithm gives results all over the place, sometimes taking
30+ probes to get in the ballpark. Because of the issues with the
distribution, the previous algorithm sometimes never gets to the precise
MTU value within any reasonable amount of time - in contrast, the new
algorithm will always get to the precise value in less than 30 probes,
even if the actual MTU is completely outside the optimized range.
2014-12-30 16:34:48 +00:00
|
|
|
#include <math.h>
|
2016-04-14 15:03:01 +00:00
|
|
|
#include <time.h>
|
2004-10-01 18:22:06 +00:00
|
|
|
|
2009-09-14 22:24:31 +00:00
|
|
|
#ifdef HAVE_MINGW
|
|
|
|
#include <w32api.h>
|
2012-06-25 13:01:42 +00:00
|
|
|
#include <winsock2.h>
|
2009-09-14 22:24:31 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <ws2tcpip.h>
|
|
|
|
#endif
|
|
|
|
|
2004-10-01 18:22:06 +00:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
|
|
|
#include <termios.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_INTTYPES_H
|
|
|
|
#include <inttypes.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Include system specific headers */
|
|
|
|
|
|
|
|
#ifdef HAVE_SYSLOG_H
|
|
|
|
#include <syslog.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif
|
|
|
|
|
2008-12-14 12:47:26 +00:00
|
|
|
|
2004-10-01 18:22:06 +00:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_FILE_H
|
|
|
|
#include <sys/file.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_WAIT_H
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_IOCTL_H
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_PARAM_H
|
|
|
|
#include <sys/param.h>
|
|
|
|
#endif
|
|
|
|
|
2011-02-12 17:22:14 +00:00
|
|
|
#ifdef HAVE_SYS_RESOURCE_H
|
|
|
|
#include <sys/resource.h>
|
|
|
|
#endif
|
|
|
|
|
2009-11-05 22:29:28 +00:00
|
|
|
#ifdef HAVE_SYS_UN_H
|
|
|
|
#include <sys/un.h>
|
|
|
|
#endif
|
|
|
|
|
2010-03-01 22:44:46 +00:00
|
|
|
#ifdef HAVE_DIRENT_H
|
|
|
|
#include <dirent.h>
|
|
|
|
#endif
|
|
|
|
|
2004-10-01 18:22:06 +00:00
|
|
|
/* SunOS really wants sys/socket.h BEFORE net/if.h,
|
|
|
|
and FreeBSD wants these lines below the rest. */
|
|
|
|
|
|
|
|
#ifdef HAVE_NETDB_H
|
|
|
|
#include <netdb.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NET_IF_H
|
|
|
|
#include <net/if.h>
|
|
|
|
#endif
|
|
|
|
|
2004-11-10 23:20:59 +00:00
|
|
|
#ifdef HAVE_NET_IF_TYPES_H
|
|
|
|
#include <net/if_types.h>
|
|
|
|
#endif
|
|
|
|
|
2004-11-01 17:04:28 +00:00
|
|
|
#ifdef HAVE_NET_IF_TUN_H
|
|
|
|
#include <net/if_tun.h>
|
|
|
|
#endif
|
|
|
|
|
2011-02-12 17:22:14 +00:00
|
|
|
#ifdef HAVE_NET_TUN_IF_TUN_H
|
|
|
|
#include <net/tun/if_tun.h>
|
|
|
|
#endif
|
|
|
|
|
2004-11-01 17:04:28 +00:00
|
|
|
#ifdef HAVE_NET_IF_TAP_H
|
|
|
|
#include <net/if_tap.h>
|
|
|
|
#endif
|
|
|
|
|
2011-02-12 17:22:14 +00:00
|
|
|
#ifdef HAVE_NET_TAP_IF_TAP_H
|
|
|
|
#include <net/tap/if_tap.h>
|
|
|
|
#endif
|
|
|
|
|
2004-10-01 18:22:06 +00:00
|
|
|
#ifdef HAVE_NETINET_IN_SYSTM_H
|
|
|
|
#include <netinet/in_systm.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_ARPA_INET_H
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IP_H
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_TCP_H
|
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN6_H
|
|
|
|
#include <netinet/in6.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IP6_H
|
|
|
|
#include <netinet/ip6.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NET_ETHERNET_H
|
|
|
|
#include <net/ethernet.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NET_IF_ARP_H
|
|
|
|
#include <net/if_arp.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IP_ICMP_H
|
|
|
|
#include <netinet/ip_icmp.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_ICMP6_H
|
|
|
|
#include <netinet/icmp6.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IF_ETHER_H
|
|
|
|
#include <netinet/if_ether.h>
|
|
|
|
#endif
|
|
|
|
|
2015-02-09 14:16:36 +00:00
|
|
|
#ifdef HAVE_ARPA_NAMESER_H
|
|
|
|
#include <arpa/nameser.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_RESOLV_H
|
|
|
|
#include <resolv.h>
|
|
|
|
#endif
|
|
|
|
|
2015-06-18 21:58:31 +00:00
|
|
|
#ifdef HAVE_LINUX_IF_TUN_H
|
|
|
|
#include <linux/if_tun.h>
|
|
|
|
#endif
|
|
|
|
|
2016-04-08 15:49:49 +00:00
|
|
|
#ifdef HAVE_GETOPT_H
|
|
|
|
#include <getopt.h>
|
|
|
|
#else
|
|
|
|
#include "getopt.h"
|
|
|
|
#endif
|
|
|
|
|
2015-02-09 14:16:36 +00:00
|
|
|
#ifdef STATUS
|
|
|
|
#undef STATUS
|
|
|
|
#endif
|
|
|
|
|
2012-07-21 14:26:55 +00:00
|
|
|
#ifdef HAVE_MINGW
|
|
|
|
#define SLASH "\\"
|
|
|
|
#else
|
|
|
|
#define SLASH "/"
|
|
|
|
#endif
|
|
|
|
|
2004-10-01 18:22:06 +00:00
|
|
|
#endif /* __TINC_SYSTEM_H__ */
|