mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-06-13 10:56:19 -04:00
Merge branch 'feat_ipv6_transport'
This commit is contained in:
commit
dcf4bcc2d9
23 changed files with 1567 additions and 268 deletions
81
README.ipv6
Normal file
81
README.ipv6
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
[ Last updated: 25-Mar-2011. ]
|
||||
|
||||
OpenVPN-2.1 over UDP6/TCP6 README for ipv6-0.4.x patch releases:
|
||||
( --udp6 and --tcp6-{client,server} )
|
||||
|
||||
* Availability
|
||||
Source code under GPLv2 from http://github.com/jjo/openvpn-ipv6
|
||||
|
||||
Distro ready repos/packages:
|
||||
o Debian sid official repo, by Alberto Gonzalez Iniesta,
|
||||
starting from openvpn_2.1~rc20-2
|
||||
o Gentoo official portage tree, by Marcel Pennewiss:
|
||||
- https://bugs.gentoo.org/show_bug.cgi?id=287896
|
||||
o Ubuntu package, by Bernhard Schmidt:
|
||||
- https://launchpad.net/~berni/+archive/ipv6/+packages
|
||||
o Freetz.org, milestone freetz-1.2
|
||||
- http://trac.freetz.org/milestone/freetz-1.2
|
||||
|
||||
* Status:
|
||||
o OK:
|
||||
- upd6,tcp6: GNU/Linux, win32, openbsd-4.7, freebsd-8.1
|
||||
- udp4->upd6,tcp4->tcp6 (ipv4/6 mapped): GNU/Linux
|
||||
(gives a warning on local!=remote proto matching)
|
||||
o NOT:
|
||||
- win32: tcp4->tcp6 (ipv4/6 mapped) fails w/connection refused
|
||||
o NOT tested:
|
||||
- mgmt console
|
||||
|
||||
* Build setup:
|
||||
./configure --enable-ipv6 (by default)
|
||||
|
||||
* Usage:
|
||||
For IPv6 just specify "-p upd6" an proper IPv6 hostnames, adapting the example
|
||||
from man page ...
|
||||
|
||||
On may:
|
||||
openvpn --proto udp6 --remote <june_IPv6_addr> --dev tun1 \
|
||||
--ifconfig 10.4.0.1 10.4.0.2 --verb 5 --secret key
|
||||
|
||||
On june:
|
||||
openvpn --proto udp6 --remote <may_IPv6_addr> --dev tun1 \
|
||||
--ifconfig 10.4.0.2 10.4.0.1 --verb 5 --secret key
|
||||
|
||||
Same for --proto tcp6-client, tcp6-server.
|
||||
|
||||
* Main code changes summary:
|
||||
- socket.h: New struct openvpn_sockaddr type that holds sockaddrs and pktinfo,
|
||||
(here I omitted #ifdef USE_PF_xxxx, see socket.h )
|
||||
|
||||
struct openvpn_sockaddr {
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr_in6 in6;
|
||||
} addr;
|
||||
};
|
||||
|
||||
struct link_socket_addr
|
||||
{
|
||||
struct openvpn_sockaddr local;
|
||||
struct openvpn_sockaddr remote;
|
||||
struct openvpn_sockaddr actual;
|
||||
};
|
||||
|
||||
PRO: allows simple type overloading: local.addr.sa, local.addr.in, local.addr.in6 ... etc
|
||||
(also local.pi.in and local.pi.in6)
|
||||
|
||||
- several function prototypes moved from sockaddr_in to openvpn_sockaddr
|
||||
- several new sockaddr functions needed to "generalize" AF_xxxx operations:
|
||||
addr_copy(), addr_zero(), ...etc
|
||||
proto_is_udp(), proto_is_dgram(), proto_is_net()
|
||||
|
||||
* TODO: See TODO.ipv6
|
||||
|
||||
--
|
||||
JuanJo Ciarlante jjo () google () com ............................
|
||||
: :
|
||||
. Linux IP Aliasing author .
|
||||
. Modular algo (AES et all) support for FreeSWAN/OpenSWAN author .
|
||||
. OpenVPN over IPv6 support .
|
||||
:...... plus other scattered free software bits in the wild ...:
|
||||
30
TODO.ipv6
Normal file
30
TODO.ipv6
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
[ Last updated: 11-Nov-2009. ]
|
||||
|
||||
* All platforms:
|
||||
o mgmt console: as currently passes straight in_addr_t bits around
|
||||
|
||||
o make possible to get AF from getaddrinfo() answer, ie allow openvpn to
|
||||
use ipv4/6 if DNS returns A/AAAA without specifying protocol.
|
||||
Hard: requires deep changes in initialization/calling logic
|
||||
|
||||
o use AI_PASSIVE
|
||||
|
||||
o the getaddr()/getaddr6() interface is not prepared for handling socktype
|
||||
"tagging", currently I abuse the sockflags bits for getting the ai_socktype
|
||||
downstream.
|
||||
|
||||
o implement comparison for mapped addesses: server in dual stack
|
||||
listening IPv6 must permit incoming streams from allowed IPv4 peer,
|
||||
currently you need to pass eg: --remote ffff::1.2.3.4
|
||||
|
||||
o do something with multi mode learn routes, for now just ignoring
|
||||
ipv6 addresses seems the most sensible thing to do, because there's
|
||||
no support for intra-tunnel ipv6 stuff.
|
||||
|
||||
* win32:
|
||||
o find out about mapped addresses, as I can't make it work
|
||||
with bound at ::1 and connect to 127.0.0.1
|
||||
|
||||
* N/A:
|
||||
o this is ipv6 *endpoint* support, so don't expect "ifconfig6"-like
|
||||
support in this patch
|
||||
|
|
@ -123,5 +123,9 @@ AC_DEFUN([TYPE_SOCKLEN_T],
|
|||
AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
|
||||
[type to use in place of socklen_t if not defined])],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>])
|
||||
#ifdef WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#endif])
|
||||
])
|
||||
|
|
|
|||
17
buffer.c
17
buffer.c
|
|
@ -214,6 +214,23 @@ buf_printf (struct buffer *buf, const char *format, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
buf_puts(struct buffer *buf, const char *str)
|
||||
{
|
||||
int ret = false;
|
||||
uint8_t *ptr = BEND (buf);
|
||||
int cap = buf_forward_capacity (buf);
|
||||
if (cap > 0)
|
||||
{
|
||||
strncpynt ((char *)ptr,str, cap);
|
||||
*(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
|
||||
buf->len += (int) strlen ((char *)ptr);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is necessary due to certain buggy implementations of snprintf,
|
||||
* that don't guarantee null termination for size > 0.
|
||||
|
|
|
|||
5
buffer.h
5
buffer.h
|
|
@ -276,6 +276,11 @@ bool buf_printf (struct buffer *buf, const char *format, ...)
|
|||
#endif
|
||||
;
|
||||
|
||||
/*
|
||||
* puts append to a buffer with overflow check
|
||||
*/
|
||||
bool buf_puts (struct buffer *buf, const char *str);
|
||||
|
||||
/*
|
||||
* Like snprintf but guarantees null termination for size > 0
|
||||
*/
|
||||
|
|
|
|||
16
configure.ac
16
configure.ac
|
|
@ -146,6 +146,12 @@ AC_ARG_ENABLE(multihome,
|
|||
[MULTIHOME="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
[ --disable-ipv6 Disable UDP/IPv6 support],
|
||||
[PF_INET6="$enableval"],
|
||||
[PF_INET6="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(port-share,
|
||||
[ --disable-port-share Disable TCP server port-share support (--port-share)],
|
||||
[PORT_SHARE="$enableval"],
|
||||
|
|
@ -566,6 +572,16 @@ LDFLAGS="$LDFLAGS -Wl,--fatal-warnings"
|
|||
AC_CHECK_FUNC(epoll_create, AC_DEFINE(HAVE_EPOLL_CREATE, 1, [epoll_create function is defined]))
|
||||
LDFLAGS="$OLDLDFLAGS"
|
||||
|
||||
dnl ipv6 support
|
||||
if test "$PF_INET6" = "yes"; then
|
||||
AC_CHECKING([for struct sockaddr_in6 for IPv6 support])
|
||||
AC_CHECK_TYPE(
|
||||
[struct sockaddr_in6],
|
||||
[AC_DEFINE(USE_PF_INET6, 1, [struct sockaddr_in6 is needed for IPv6 peer support])],
|
||||
[],
|
||||
[#include "syshead.h"])
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl check for valgrind tool
|
||||
dnl
|
||||
|
|
|
|||
43
init.c
43
init.c
|
|
@ -96,7 +96,7 @@ update_options_ce_post (struct options *options)
|
|||
*/
|
||||
if (options->pull
|
||||
&& options->ping_rec_timeout_action == PING_UNDEF
|
||||
&& options->ce.proto == PROTO_UDPv4)
|
||||
&& proto_is_dgram(options->ce.proto))
|
||||
{
|
||||
options->ping_rec_timeout = PRE_PULL_INITIAL_PING_RESTART;
|
||||
options->ping_rec_timeout_action = PING_RESTART;
|
||||
|
|
@ -1150,7 +1150,12 @@ initialization_sequence_completed (struct context *c, const unsigned int flags)
|
|||
const char *detail = "SUCCESS";
|
||||
if (c->c1.tuntap)
|
||||
tun_local = c->c1.tuntap->local;
|
||||
tun_remote = htonl (c->c1.link_socket_addr.actual.dest.sa.sin_addr.s_addr);
|
||||
/* TODO(jjo): for ipv6 this will convert some 32bits in the ipv6 addr
|
||||
* to a meaningless ipv4 address.
|
||||
* In any case, is somewhat inconsistent to send local tunnel
|
||||
* addr with remote _endpoint_ addr (?)
|
||||
*/
|
||||
tun_remote = htonl (c->c1.link_socket_addr.actual.dest.addr.in4.sin_addr.s_addr);
|
||||
if (flags & ISC_ERRORS)
|
||||
detail = "ERROR";
|
||||
management_set_state (management,
|
||||
|
|
@ -1569,7 +1574,7 @@ do_deferred_options (struct context *c, const unsigned int found)
|
|||
#ifdef ENABLE_OCC
|
||||
if (found & OPT_P_EXPLICIT_NOTIFY)
|
||||
{
|
||||
if (c->options.ce.proto != PROTO_UDPv4 && c->options.explicit_exit_notification)
|
||||
if (!proto_is_udp(c->options.ce.proto) && c->options.explicit_exit_notification)
|
||||
{
|
||||
msg (D_PUSH, "OPTIONS IMPORT: --explicit-exit-notify can only be used with --proto udp");
|
||||
c->options.explicit_exit_notification = 0;
|
||||
|
|
@ -1664,13 +1669,22 @@ socket_restart_pause (struct context *c)
|
|||
switch (c->options.ce.proto)
|
||||
{
|
||||
case PROTO_UDPv4:
|
||||
#ifdef USE_PF_INET6
|
||||
case PROTO_UDPv6:
|
||||
#endif
|
||||
if (proxy)
|
||||
sec = c->options.ce.connect_retry_seconds;
|
||||
break;
|
||||
case PROTO_TCPv4_SERVER:
|
||||
#ifdef USE_PF_INET6
|
||||
case PROTO_TCPv6_SERVER:
|
||||
#endif
|
||||
sec = 1;
|
||||
break;
|
||||
case PROTO_TCPv4_CLIENT:
|
||||
#ifdef USE_PF_INET6
|
||||
case PROTO_TCPv6_CLIENT:
|
||||
#endif
|
||||
sec = c->options.ce.connect_retry_seconds;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2810,7 +2824,7 @@ do_setup_fast_io (struct context *c)
|
|||
#ifdef WIN32
|
||||
msg (M_INFO, "NOTE: --fast-io is disabled since we are running on Windows");
|
||||
#else
|
||||
if (c->options.ce.proto != PROTO_UDPv4)
|
||||
if (!proto_is_udp(c->options.ce.proto))
|
||||
msg (M_INFO, "NOTE: --fast-io is disabled since we are not using UDP");
|
||||
else
|
||||
{
|
||||
|
|
@ -3086,7 +3100,11 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
|
|||
/* link_socket_mode allows CM_CHILD_TCP
|
||||
instances to inherit acceptable fds
|
||||
from a top-level parent */
|
||||
if (c->options.ce.proto == PROTO_TCPv4_SERVER)
|
||||
if (c->options.ce.proto == PROTO_TCPv4_SERVER
|
||||
#ifdef USE_PF_INET6
|
||||
|| c->options.ce.proto == PROTO_TCPv6_SERVER
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (c->mode == CM_TOP)
|
||||
link_socket_mode = LS_MODE_TCP_LISTEN;
|
||||
|
|
@ -3361,17 +3379,8 @@ inherit_context_child (struct context *dest,
|
|||
{
|
||||
CLEAR (*dest);
|
||||
|
||||
switch (src->options.ce.proto)
|
||||
{
|
||||
case PROTO_UDPv4:
|
||||
dest->mode = CM_CHILD_UDP;
|
||||
break;
|
||||
case PROTO_TCPv4_SERVER:
|
||||
dest->mode = CM_CHILD_TCP;
|
||||
break;
|
||||
default:
|
||||
ASSERT (0);
|
||||
}
|
||||
/* proto_is_dgram will ASSERT(0) if proto is invalid */
|
||||
dest->mode = proto_is_dgram(src->options.ce.proto)? CM_CHILD_UDP : CM_CHILD_TCP;
|
||||
|
||||
dest->gc = gc_new ();
|
||||
|
||||
|
|
@ -3477,7 +3486,7 @@ inherit_context_top (struct context *dest,
|
|||
dest->c2.es_owned = false;
|
||||
|
||||
dest->c2.event_set = NULL;
|
||||
if (src->options.ce.proto == PROTO_UDPv4)
|
||||
if (proto_is_dgram(src->options.ce.proto))
|
||||
do_event_set_init (dest, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
62
install-win32/makeopenvpn
Normal file → Executable file
62
install-win32/makeopenvpn
Normal file → Executable file
|
|
@ -2,35 +2,65 @@
|
|||
|
||||
H=`pwd`
|
||||
|
||||
# get version.nsi definitions
|
||||
. autodefs/defs.sh
|
||||
case "`uname -o 2>/dev/null`" in
|
||||
*inux)
|
||||
|
||||
if gcc --version &>/dev/null && [ -d "$OPENSSL_DIR" ] && [ -d "$LZO_DIR" ] && [ -d "$PKCS11_HELPER_DIR" ]; then
|
||||
# cross-compiling, make dude's life easier
|
||||
XAUTOCONF="--host=i586-mingw32msvc --build=i386-linux $XAUTOCONF"
|
||||
export CC=i586-mingw32msvc-gcc
|
||||
export CXXCPP=i586-mingw32msvc-cpp
|
||||
export CXX=i586-mingw32msvc-g++
|
||||
# this requires the human to setup these environ vars:
|
||||
# OPENSSL_DIR LZO_DIR PKCS11_HELPER_DIR
|
||||
OPENSSL_INC_DIR=$OPENSSL_DIR/include
|
||||
OPENSSL_LIB_DIR=$OPENSSL_DIR/out
|
||||
LZO_INC_DIR=$LZO_DIR/include
|
||||
LZO_LIB_DIR=$LZO_DIR/src/.libs
|
||||
PKCS11_INC_DIR=$PKCS11_HELPER_DIR/include/pkcs11-helper-1.0/
|
||||
PKCS11_LIB_DIR=$PKCS11_HELPER_DIR/lib/.libs/
|
||||
;;
|
||||
*)
|
||||
# get version.nsi definitions
|
||||
. autodefs/defs.sh
|
||||
XAUTOCONF=""
|
||||
# default configuration creates relative-path environ vars:
|
||||
OPENSSL_INC_DIR=$H/$OPENSSL_DIR/include
|
||||
OPENSSL_LIB_DIR=$H/$OPENSSL_DIR/out
|
||||
LZO_INC_DIR=$H/$LZO_DIR/include
|
||||
LZO_LIB_DIR=$H/$LZO_DIR
|
||||
PKCS11_INC_DIR=$H/$PKCS11_HELPER_DIR/usr/local/include
|
||||
PKCS11_LIB_DIR=$H/$PKCS11_HELPER_DIR/usr/local/lib
|
||||
;;
|
||||
esac
|
||||
if $CC --version &>/dev/null && [ -d "$OPENSSL_DIR" ] && [ -d "$LZO_DIR" ] && [ -d "$PKCS11_HELPER_DIR" ]; then
|
||||
# build OpenVPN binary
|
||||
|
||||
if ! [ -f Makefile ]; then
|
||||
autoreconf -i -v \
|
||||
&& ./configure \
|
||||
&& ./configure $XAUTOCONF \
|
||||
--enable-strict \
|
||||
--prefix=$H/windest \
|
||||
MAN2HTML=true \
|
||||
--with-ssl-headers=$H/$OPENSSL_DIR/include \
|
||||
--with-ssl-lib=$H/$OPENSSL_DIR/out \
|
||||
--with-lzo-headers=$H/$LZO_DIR/include \
|
||||
--with-lzo-lib=$H/$LZO_DIR \
|
||||
--with-pkcs11-helper-headers=$H/$PKCS11_HELPER_DIR/usr/local/include \
|
||||
--with-pkcs11-helper-lib=$H/$PKCS11_HELPER_DIR/usr/local/lib
|
||||
--with-ssl-headers=$OPENSSL_INC_DIR \
|
||||
--with-ssl-lib=$OPENSSL_LIB_DIR \
|
||||
--with-lzo-headers=$LZO_INC_DIR \
|
||||
--with-lzo-lib=$LZO_LIB_DIR \
|
||||
--with-pkcs11-helper-headers=$PKCS11_INC_DIR \
|
||||
--with-pkcs11-helper-lib=$PKCS11_LIB_DIR \
|
||||
|| exit 1
|
||||
fi
|
||||
|
||||
make -j $MAKE_JOBS && make install
|
||||
|
||||
if [ -n "$GENOOUT" ];then
|
||||
# copy OpenVPN and service executables to GENOUT/bin
|
||||
mkdir -p $GENOUT/bin &>/dev/null
|
||||
cp windest/sbin/openvpn.exe $GENOUT/bin
|
||||
cp windest/sbin/openvpnserv.exe $GENOUT/bin
|
||||
if [ -z "$NO_STRIP" ]; then
|
||||
strip $GENOUT/bin/openvpn.exe
|
||||
strip $GENOUT/bin/openvpnserv.exe
|
||||
mkdir -p $GENOUT/bin &>/dev/null
|
||||
cp windest/sbin/openvpn.exe $GENOUT/bin
|
||||
cp windest/sbin/openvpnserv.exe $GENOUT/bin
|
||||
if [ -z "$NO_STRIP" ]; then
|
||||
strip $GENOUT/bin/openvpn.exe
|
||||
strip $GENOUT/bin/openvpnserv.exe
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo DID NOT BUILD openvpn.exe and openvpnserv.exe because one or more of gcc, OPENSSL_DIR, LZO_DIR, or PKCS11_HELPER_DIR directories were missing
|
||||
|
|
|
|||
10
manage.c
10
manage.c
|
|
@ -1999,9 +1999,9 @@ man_settings_init (struct man_settings *ms,
|
|||
/*
|
||||
* Initialize socket address
|
||||
*/
|
||||
ms->local.sa.sin_family = AF_INET;
|
||||
ms->local.sa.sin_addr.s_addr = 0;
|
||||
ms->local.sa.sin_port = htons (port);
|
||||
ms->local.addr.in4.sin_family = AF_INET;
|
||||
ms->local.addr.in4.sin_addr.s_addr = 0;
|
||||
ms->local.addr.in4.sin_port = htons (port);
|
||||
|
||||
/*
|
||||
* Run management over tunnel, or
|
||||
|
|
@ -2013,7 +2013,7 @@ man_settings_init (struct man_settings *ms,
|
|||
}
|
||||
else
|
||||
{
|
||||
ms->local.sa.sin_addr.s_addr = getaddr
|
||||
ms->local.addr.in4.sin_addr.s_addr = getaddr
|
||||
(GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -2472,7 +2472,7 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i
|
|||
&& man->connection.state == MS_INITIAL)
|
||||
{
|
||||
/* listen on our local TUN/TAP IP address */
|
||||
man->settings.local.sa.sin_addr.s_addr = htonl (tun_local_ip);
|
||||
man->settings.local.addr.in4.sin_addr.s_addr = htonl (tun_local_ip);
|
||||
man_connection_init (man);
|
||||
}
|
||||
|
||||
|
|
|
|||
30
mroute.c
30
mroute.c
|
|
@ -226,25 +226,47 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
|
|||
const struct openvpn_sockaddr *osaddr,
|
||||
bool use_port)
|
||||
{
|
||||
if (osaddr->sa.sin_family == AF_INET)
|
||||
switch (osaddr->addr.sa.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
if (use_port)
|
||||
{
|
||||
addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
|
||||
addr->netbits = 0;
|
||||
addr->len = 6;
|
||||
memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4);
|
||||
memcpy (addr->addr + 4, &osaddr->sa.sin_port, 2);
|
||||
memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4);
|
||||
memcpy (addr->addr + 4, &osaddr->addr.in4.sin_port, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr->type = MR_ADDR_IPV4;
|
||||
addr->netbits = 0;
|
||||
addr->len = 4;
|
||||
memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4);
|
||||
memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6:
|
||||
if (use_port)
|
||||
{
|
||||
addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
|
||||
addr->netbits = 0;
|
||||
addr->len = 18;
|
||||
memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16);
|
||||
memcpy (addr->addr + 16, &osaddr->addr.in6.sin6_port, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr->type = MR_ADDR_IPV6;
|
||||
addr->netbits = 0;
|
||||
addr->len = 16;
|
||||
memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16);
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
5
mtcp.c
5
mtcp.c
|
|
@ -150,6 +150,11 @@ multi_tcp_instance_specific_init (struct multi_context *m, struct multi_instance
|
|||
ASSERT (mi->context.c2.link_socket);
|
||||
ASSERT (mi->context.c2.link_socket->info.lsa);
|
||||
ASSERT (mi->context.c2.link_socket->mode == LS_MODE_TCP_ACCEPT_FROM);
|
||||
ASSERT (mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET
|
||||
#ifdef USE_PF_INET6
|
||||
|| mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET6
|
||||
#endif
|
||||
);
|
||||
if (!mroute_extract_openvpn_sockaddr (&mi->real, &mi->context.c2.link_socket->info.lsa->actual.dest, true))
|
||||
{
|
||||
msg (D_MULTI_ERRORS, "MULTI TCP: TCP client address is undefined");
|
||||
|
|
|
|||
38
multi.c
38
multi.c
|
|
@ -1058,8 +1058,8 @@ multi_learn_in_addr_t (struct multi_context *m,
|
|||
struct mroute_addr addr;
|
||||
|
||||
CLEAR (remote_si);
|
||||
remote_si.sa.sin_family = AF_INET;
|
||||
remote_si.sa.sin_addr.s_addr = htonl (a);
|
||||
remote_si.addr.in4.sin_family = AF_INET;
|
||||
remote_si.addr.in4.sin_addr.s_addr = htonl (a);
|
||||
ASSERT (mroute_extract_openvpn_sockaddr (&addr, &remote_si, false));
|
||||
|
||||
if (netbits >= 0)
|
||||
|
|
@ -2496,9 +2496,9 @@ management_callback_kill_by_addr (void *arg, const in_addr_t addr, const int por
|
|||
int count = 0;
|
||||
|
||||
CLEAR (saddr);
|
||||
saddr.sa.sin_family = AF_INET;
|
||||
saddr.sa.sin_addr.s_addr = htonl (addr);
|
||||
saddr.sa.sin_port = htons (port);
|
||||
saddr.addr.in4.sin_family = AF_INET;
|
||||
saddr.addr.in4.sin_addr.s_addr = htonl (addr);
|
||||
saddr.addr.in4.sin_port = htons (port);
|
||||
if (mroute_extract_openvpn_sockaddr (&maddr, &saddr, true))
|
||||
{
|
||||
hash_iterator_init (m->iter, &hi);
|
||||
|
|
@ -2675,16 +2675,24 @@ tunnel_server (struct context *top)
|
|||
{
|
||||
ASSERT (top->options.mode == MODE_SERVER);
|
||||
|
||||
switch (top->options.ce.proto) {
|
||||
case PROTO_UDPv4:
|
||||
tunnel_server_udp (top);
|
||||
break;
|
||||
case PROTO_TCPv4_SERVER:
|
||||
tunnel_server_tcp (top);
|
||||
break;
|
||||
default:
|
||||
ASSERT (0);
|
||||
}
|
||||
#ifdef USE_PF_INET6
|
||||
if (proto_is_dgram(top->options.ce.proto))
|
||||
tunnel_server_udp(top);
|
||||
else
|
||||
tunnel_server_tcp(top);
|
||||
#else
|
||||
switch (top->options.ce.proto)
|
||||
{
|
||||
case PROTO_UDPv4:
|
||||
tunnel_server_udp (top);
|
||||
break;
|
||||
case PROTO_TCPv4_SERVER:
|
||||
tunnel_server_tcp (top);
|
||||
break;
|
||||
default:
|
||||
ASSERT (0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
|||
2
occ.c
2
occ.c
|
|
@ -369,7 +369,7 @@ process_received_occ_msg (struct context *c)
|
|||
c->c2.max_send_size_remote,
|
||||
c->c2.max_recv_size_local);
|
||||
if (!c->options.fragment
|
||||
&& c->options.ce.proto == PROTO_UDPv4
|
||||
&& (proto_is_dgram(c->options.ce.proto))
|
||||
&& c->c2.max_send_size_local > TUN_MTU_MIN
|
||||
&& (c->c2.max_recv_size_remote < c->c2.max_send_size_local
|
||||
|| c->c2.max_recv_size_local < c->c2.max_send_size_remote))
|
||||
|
|
|
|||
10
openvpn.8
10
openvpn.8
|
|
@ -5450,13 +5450,16 @@ or
|
|||
script execution.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B trusted_ip
|
||||
.B trusted_ip (or trusted_ip6)
|
||||
Actual IP address of connecting client or peer which has been authenticated.
|
||||
Set prior to execution of
|
||||
.B \-\-ipchange, \-\-client-connect,
|
||||
and
|
||||
.B \-\-client-disconnect
|
||||
scripts.
|
||||
If using ipv6 endpoints (udp6, tcp6),
|
||||
.B trusted_ip6
|
||||
will be set instead.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B trusted_port
|
||||
|
|
@ -5468,7 +5471,7 @@ and
|
|||
scripts.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B untrusted_ip
|
||||
.B untrusted_ip (or untrusted_ip6)
|
||||
Actual IP address of connecting client or peer which has not been authenticated
|
||||
yet. Sometimes used to
|
||||
.B nmap
|
||||
|
|
@ -5480,6 +5483,9 @@ Set prior to execution of
|
|||
and
|
||||
.B \-\-auth-user-pass-verify
|
||||
scripts.
|
||||
If using ipv6 endpoints (udp6, tcp6),
|
||||
.B untrusted_ip6
|
||||
will be set instead.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B untrusted_port
|
||||
|
|
|
|||
100
options.c
100
options.c
|
|
@ -79,6 +79,12 @@ const char title_string[] =
|
|||
#endif
|
||||
#ifdef ENABLE_EUREPHIA
|
||||
" [eurephia]"
|
||||
#endif
|
||||
#if ENABLE_IP_PKTINFO
|
||||
" [MH]"
|
||||
#endif
|
||||
#ifdef USE_PF_INET6
|
||||
" [PF_INET6]"
|
||||
#endif
|
||||
" built on " __DATE__
|
||||
;
|
||||
|
|
@ -102,6 +108,9 @@ static const char usage_message[] =
|
|||
"--proto p : Use protocol p for communicating with peer.\n"
|
||||
" p = udp (default), tcp-server, or tcp-client\n"
|
||||
"--proto-force p : only consider protocol p in list of connection profiles.\n"
|
||||
#ifdef USE_PF_INET6
|
||||
" p = udp6, tcp6-server, or tcp6-client (ipv6)\n"
|
||||
#endif
|
||||
"--connect-retry n : For --proto tcp-client, number of seconds to wait\n"
|
||||
" between connection retries (default=%d).\n"
|
||||
"--connect-timeout n : For --proto tcp-client, connection timeout (in seconds).\n"
|
||||
|
|
@ -1707,11 +1716,27 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
* Sanity check on TCP mode options
|
||||
*/
|
||||
|
||||
if (ce->connect_retry_defined && ce->proto != PROTO_TCPv4_CLIENT)
|
||||
msg (M_USAGE, "--connect-retry doesn't make sense unless also used with --proto tcp-client");
|
||||
if (ce->connect_retry_defined && ce->proto != PROTO_TCPv4_CLIENT
|
||||
#ifdef USE_PF_INET6
|
||||
&& ce->proto != PROTO_TCPv6_CLIENT
|
||||
#endif
|
||||
)
|
||||
msg (M_USAGE, "--connect-retry doesn't make sense unless also used with --proto tcp-client"
|
||||
#ifdef USE_PF_INET6
|
||||
" or tcp6-client"
|
||||
#endif
|
||||
);
|
||||
|
||||
if (ce->connect_timeout_defined && ce->proto != PROTO_TCPv4_CLIENT)
|
||||
msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with --proto tcp-client");
|
||||
if (ce->connect_timeout_defined && ce->proto != PROTO_TCPv4_CLIENT
|
||||
#ifdef USE_PF_INET6
|
||||
&& ce->proto != PROTO_TCPv6_CLIENT
|
||||
#endif
|
||||
)
|
||||
msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with --proto tcp-client"
|
||||
#ifdef USE_PF_INET6
|
||||
" or tcp6-client"
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Sanity check on MTU parameters
|
||||
|
|
@ -1720,7 +1745,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
msg (M_USAGE, "only one of --tun-mtu or --link-mtu may be defined (note that --ifconfig implies --link-mtu %d)", LINK_MTU_DEFAULT);
|
||||
|
||||
#ifdef ENABLE_OCC
|
||||
if (ce->proto != PROTO_UDPv4 && options->mtu_test)
|
||||
if (!proto_is_udp(ce->proto) && options->mtu_test)
|
||||
msg (M_USAGE, "--mtu-test only makes sense with --proto udp");
|
||||
#endif
|
||||
|
||||
|
|
@ -1733,7 +1758,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
* Sanity check on --local, --remote, and --ifconfig
|
||||
*/
|
||||
|
||||
if (string_defined_equal (ce->local, ce->remote)
|
||||
if (proto_is_net(ce->proto)
|
||||
&& string_defined_equal (ce->local, ce->remote)
|
||||
&& ce->local_port == ce->remote_port)
|
||||
msg (M_USAGE, "--remote and --local addresses are the same");
|
||||
|
||||
|
|
@ -1798,16 +1824,20 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
*/
|
||||
|
||||
#ifdef ENABLE_FRAGMENT
|
||||
if (ce->proto != PROTO_UDPv4 && options->fragment)
|
||||
if (!proto_is_udp(ce->proto) && options->fragment)
|
||||
msg (M_USAGE, "--fragment can only be used with --proto udp");
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OCC
|
||||
if (ce->proto != PROTO_UDPv4 && options->explicit_exit_notification)
|
||||
if (!proto_is_udp(ce->proto) && options->explicit_exit_notification)
|
||||
msg (M_USAGE, "--explicit-exit-notify can only be used with --proto udp");
|
||||
#endif
|
||||
|
||||
if (!ce->remote && ce->proto == PROTO_TCPv4_CLIENT)
|
||||
if (!ce->remote && (ce->proto == PROTO_TCPv4_CLIENT
|
||||
#ifdef USE_PF_INET6
|
||||
|| ce->proto == PROTO_TCPv6_CLIENT
|
||||
#endif
|
||||
))
|
||||
msg (M_USAGE, "--remote MUST be used in TCP Client mode");
|
||||
|
||||
#ifdef ENABLE_HTTP_PROXY
|
||||
|
|
@ -1825,7 +1855,12 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
msg (M_USAGE, "--socks-proxy can not be used in TCP Server mode");
|
||||
#endif
|
||||
|
||||
if (ce->proto == PROTO_TCPv4_SERVER && connection_list_defined (options))
|
||||
if ((ce->proto == PROTO_TCPv4_SERVER
|
||||
#ifdef USE_PF_INET6
|
||||
|| ce->proto == PROTO_TCPv6_SERVER
|
||||
#endif
|
||||
)
|
||||
&& connection_list_defined (options))
|
||||
msg (M_USAGE, "TCP server mode allows at most one --remote address");
|
||||
|
||||
#if P2MP_SERVER
|
||||
|
|
@ -1839,11 +1874,28 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
msg (M_USAGE, "--mode server only works with --dev tun or --dev tap");
|
||||
if (options->pull)
|
||||
msg (M_USAGE, "--pull cannot be used with --mode server");
|
||||
if (!(ce->proto == PROTO_UDPv4 || ce->proto == PROTO_TCPv4_SERVER))
|
||||
msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server");
|
||||
if (!(proto_is_udp(ce->proto) || ce->proto == PROTO_TCPv4_SERVER
|
||||
#ifdef USE_PF_INET6
|
||||
|| ce->proto == PROTO_TCPv6_SERVER
|
||||
#endif
|
||||
))
|
||||
msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"
|
||||
#ifdef USE_PF_INET6
|
||||
" or proto tcp6-server"
|
||||
#endif
|
||||
);
|
||||
#if PORT_SHARE
|
||||
if ((options->port_share_host || options->port_share_port) && ce->proto != PROTO_TCPv4_SERVER)
|
||||
msg (M_USAGE, "--port-share only works in TCP server mode (--proto tcp-server)");
|
||||
if ((options->port_share_host || options->port_share_port) &&
|
||||
(ce->proto != PROTO_TCPv4_SERVER
|
||||
#ifdef USE_PF_INET6
|
||||
&& ce->proto != PROTO_TCPv6_SERVER
|
||||
#endif
|
||||
))
|
||||
msg (M_USAGE, "--port-share only works in TCP server mode (--proto tcp-server"
|
||||
#ifdef USE_PF_INET6
|
||||
" or tcp6-server"
|
||||
#endif
|
||||
")");
|
||||
#endif
|
||||
if (!options->tls_server)
|
||||
msg (M_USAGE, "--mode server requires --tls-server");
|
||||
|
|
@ -1871,9 +1923,17 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
msg (M_USAGE, "--inetd cannot be used with --mode server");
|
||||
if (options->ipchange)
|
||||
msg (M_USAGE, "--ipchange cannot be used with --mode server (use --client-connect instead)");
|
||||
if (!(ce->proto == PROTO_UDPv4 || ce->proto == PROTO_TCPv4_SERVER))
|
||||
msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server");
|
||||
if (ce->proto != PROTO_UDPv4 && (options->cf_max || options->cf_per))
|
||||
if (!(proto_is_dgram(ce->proto) || ce->proto == PROTO_TCPv4_SERVER
|
||||
#ifdef USE_PF_INET6
|
||||
|| ce->proto == PROTO_TCPv6_SERVER
|
||||
#endif
|
||||
))
|
||||
msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"
|
||||
#ifdef USE_PF_INET6
|
||||
" or --proto tcp6-server"
|
||||
#endif
|
||||
);
|
||||
if (!proto_is_udp(ce->proto) && (options->cf_max || options->cf_per))
|
||||
msg (M_USAGE, "--connect-freq only works with --mode server --proto udp. Try --max-clients instead.");
|
||||
if (!(dev == DEV_TYPE_TAP || (dev == DEV_TYPE_TUN && options->topology == TOP_SUBNET)) && options->ifconfig_pool_netmask)
|
||||
msg (M_USAGE, "The third parameter to --ifconfig-pool (netmask) is only valid in --dev tap mode");
|
||||
|
|
@ -1964,7 +2024,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
|
|||
/*
|
||||
* Check consistency of replay options
|
||||
*/
|
||||
if ((ce->proto != PROTO_UDPv4)
|
||||
if ((!proto_is_udp(ce->proto))
|
||||
&& (options->replay_window != defaults.replay_window
|
||||
|| options->replay_time != defaults.replay_time))
|
||||
msg (M_USAGE, "--replay-window only makes sense with --proto udp");
|
||||
|
|
@ -2137,6 +2197,10 @@ options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce)
|
|||
{
|
||||
if (ce->proto == PROTO_TCPv4)
|
||||
ce->proto = PROTO_TCPv4_CLIENT;
|
||||
#ifdef USE_PF_INET6
|
||||
else if (ce->proto == PROTO_TCPv6)
|
||||
ce->proto = PROTO_TCPv6_CLIENT;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
6
ps.c
6
ps.c
|
|
@ -320,9 +320,9 @@ sock_addr_set (struct openvpn_sockaddr *osaddr,
|
|||
const int port)
|
||||
{
|
||||
CLEAR (*osaddr);
|
||||
osaddr->sa.sin_family = AF_INET;
|
||||
osaddr->sa.sin_addr.s_addr = htonl (addr);
|
||||
osaddr->sa.sin_port = htons (port);
|
||||
osaddr->addr.in4.sin_family = AF_INET;
|
||||
osaddr->addr.in4.sin_addr.s_addr = htonl (addr);
|
||||
osaddr->addr.in4.sin_port = htons (port);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
|||
24
route.c
24
route.c
|
|
@ -581,13 +581,23 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
|
|||
if (!local)
|
||||
{
|
||||
/* route remote host to original default gateway */
|
||||
add_route3 (rl->spec.remote_host,
|
||||
~0,
|
||||
rl->spec.net_gateway,
|
||||
tt,
|
||||
flags,
|
||||
es);
|
||||
rl->did_local = true;
|
||||
#ifdef USE_PF_INET6
|
||||
/* if remote_host is not ipv4 (ie: ipv6), just skip
|
||||
* adding this special /32 route */
|
||||
if (rl->spec.remote_host != IPV4_INVALID_ADDR) {
|
||||
#endif
|
||||
add_route3 (rl->spec.remote_host,
|
||||
~0,
|
||||
rl->spec.net_gateway,
|
||||
tt,
|
||||
flags,
|
||||
es);
|
||||
rl->did_local = true;
|
||||
#ifdef USE_PF_INET6
|
||||
} else {
|
||||
dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* route DHCP/DNS server traffic through original default gateway */
|
||||
|
|
|
|||
245
socket.h
245
socket.h
|
|
@ -70,7 +70,13 @@ typedef uint16_t packet_size_type;
|
|||
struct openvpn_sockaddr
|
||||
{
|
||||
/*int dummy;*/ /* add offset to force a bug if sa not explicitly dereferenced */
|
||||
struct sockaddr_in sa;
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in in4;
|
||||
#ifdef USE_PF_INET6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
} addr;
|
||||
};
|
||||
|
||||
/* actual address of remote, based on source address of received packets */
|
||||
|
|
@ -79,7 +85,17 @@ struct link_socket_actual
|
|||
/*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */
|
||||
struct openvpn_sockaddr dest;
|
||||
#if ENABLE_IP_PKTINFO
|
||||
struct in_pktinfo pi;
|
||||
union {
|
||||
#ifdef HAVE_IN_PKTINFO
|
||||
struct in_pktinfo in4;
|
||||
#endif
|
||||
#ifdef IP_RECVDSTADDR
|
||||
struct in_addr in4;
|
||||
#endif
|
||||
#ifdef USE_PF_INET6
|
||||
struct in6_pktinfo in6;
|
||||
#endif
|
||||
} pi;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -199,6 +215,7 @@ struct link_socket
|
|||
# define SF_TCP_NODELAY (1<<1)
|
||||
# define SF_PORT_SHARE (1<<2)
|
||||
# define SF_HOST_RANDOMIZE (1<<3)
|
||||
# define SF_GETADDRINFO_DGRAM (1<<4)
|
||||
unsigned int sockflags;
|
||||
|
||||
/* for stream sockets */
|
||||
|
|
@ -371,6 +388,12 @@ void setenv_link_socket_actual (struct env_set *es,
|
|||
|
||||
void bad_address_length (int actual, int expected);
|
||||
|
||||
#ifdef USE_PF_INET6
|
||||
/* IPV4_INVALID_ADDR: returned by link_socket_current_remote()
|
||||
* to ease redirect-gateway logic for ipv4 tunnels on ipv6 endpoints
|
||||
*/
|
||||
#define IPV4_INVALID_ADDR 0xffffffff
|
||||
#endif
|
||||
in_addr_t link_socket_current_remote (const struct link_socket_info *info);
|
||||
|
||||
void link_socket_connection_initiated (const struct buffer *buf,
|
||||
|
|
@ -410,6 +433,14 @@ socket_descriptor_t create_socket_tcp (void);
|
|||
socket_descriptor_t socket_do_accept (socket_descriptor_t sd,
|
||||
struct link_socket_actual *act,
|
||||
const bool nowait);
|
||||
/*
|
||||
* proto related
|
||||
*/
|
||||
bool proto_is_net(int proto);
|
||||
bool proto_is_dgram(int proto);
|
||||
bool proto_is_udp(int proto);
|
||||
bool proto_is_tcp(int proto);
|
||||
|
||||
|
||||
#if UNIX_SOCK_SUPPORT
|
||||
|
||||
|
|
@ -455,6 +486,11 @@ struct resolve_list {
|
|||
#define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8)
|
||||
#define GETADDR_RANDOMIZE (1<<9)
|
||||
|
||||
/* [ab]use flags bits to get socktype info downstream */
|
||||
/* TODO(jjo): resolve tradeoff between hackiness|args-overhead */
|
||||
#define GETADDR_DGRAM (1<<10)
|
||||
#define dnsflags_to_socktype(flags) ((flags & GETADDR_DGRAM) ? SOCK_DGRAM : SOCK_STREAM)
|
||||
|
||||
in_addr_t getaddr (unsigned int flags,
|
||||
const char *hostname,
|
||||
int resolve_retry_seconds,
|
||||
|
|
@ -472,23 +508,38 @@ in_addr_t getaddr_multi (unsigned int flags,
|
|||
* Transport protocol naming and other details.
|
||||
*/
|
||||
|
||||
#define PROTO_UDPv4 0
|
||||
#define PROTO_TCPv4_SERVER 1
|
||||
#define PROTO_TCPv4_CLIENT 2
|
||||
#define PROTO_TCPv4 3
|
||||
#define PROTO_N 4
|
||||
/*
|
||||
* Use enum's instead of #define to allow for easier
|
||||
* optional proto support
|
||||
*/
|
||||
enum proto_num {
|
||||
PROTO_NONE, /* catch for uninitialized */
|
||||
PROTO_UDPv4,
|
||||
PROTO_TCPv4_SERVER,
|
||||
PROTO_TCPv4_CLIENT,
|
||||
PROTO_TCPv4,
|
||||
#ifdef USE_PF_INET6
|
||||
PROTO_UDPv6,
|
||||
PROTO_TCPv6_SERVER,
|
||||
PROTO_TCPv6_CLIENT,
|
||||
PROTO_TCPv6,
|
||||
#endif
|
||||
PROTO_N
|
||||
};
|
||||
|
||||
int ascii2proto (const char* proto_name);
|
||||
const char *proto2ascii (int proto, bool display_form);
|
||||
const char *proto2ascii_all (struct gc_arena *gc);
|
||||
int proto_remote (int proto, bool remote);
|
||||
const char *addr_family_name(int af);
|
||||
|
||||
/*
|
||||
* Overhead added to packets by various protocols.
|
||||
*/
|
||||
#define IPv4_UDP_HEADER_SIZE 28
|
||||
#define IPv4_TCP_HEADER_SIZE 40
|
||||
#define IPv6_UDP_HEADER_SIZE 40
|
||||
#define IPv6_UDP_HEADER_SIZE 48
|
||||
#define IPv6_TCP_HEADER_SIZE 60
|
||||
|
||||
extern const int proto_overhead[];
|
||||
|
||||
|
|
@ -518,7 +569,7 @@ is_proto_tcp(const int p)
|
|||
static inline bool
|
||||
link_socket_proto_connection_oriented (int proto)
|
||||
{
|
||||
return proto == PROTO_TCPv4_SERVER || proto == PROTO_TCPv4_CLIENT;
|
||||
return !proto_is_dgram(proto);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -533,7 +584,36 @@ link_socket_connection_oriented (const struct link_socket *sock)
|
|||
static inline bool
|
||||
addr_defined (const struct openvpn_sockaddr *addr)
|
||||
{
|
||||
return addr->sa.sin_addr.s_addr != 0;
|
||||
if (!addr) return 0;
|
||||
switch (addr->addr.sa.sa_family) {
|
||||
case AF_INET: return addr->addr.in4.sin_addr.s_addr != 0;
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&addr->addr.in6.sin6_addr);
|
||||
#endif
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
static inline bool
|
||||
addr_defined_ipi (const struct link_socket_actual *lsa)
|
||||
{
|
||||
#if ENABLE_IP_PKTINFO
|
||||
if (!lsa) return 0;
|
||||
switch (lsa->dest.addr.sa.sa_family) {
|
||||
#ifdef HAVE_IN_PKTINFO
|
||||
case AF_INET: return lsa->pi.in4.ipi_spec_dst.s_addr != 0;
|
||||
#endif
|
||||
#ifdef IP_RECVDSTADDR
|
||||
case AF_INET: return lsa->pi.in4.s_addr != 0;
|
||||
#endif
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&lsa->pi.in6.ipi6_addr);
|
||||
#endif
|
||||
default: return 0;
|
||||
}
|
||||
#else
|
||||
ASSERT(0);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -545,20 +625,50 @@ link_socket_actual_defined (const struct link_socket_actual *act)
|
|||
static inline bool
|
||||
addr_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)
|
||||
{
|
||||
return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr;
|
||||
switch(a1->addr.sa.sa_family) {
|
||||
case AF_INET:
|
||||
return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr;
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6:
|
||||
return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr);
|
||||
#endif
|
||||
}
|
||||
ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline in_addr_t
|
||||
addr_host (const struct openvpn_sockaddr *s)
|
||||
addr_host (const struct openvpn_sockaddr *addr)
|
||||
{
|
||||
return ntohl (s->sa.sin_addr.s_addr);
|
||||
/*
|
||||
* "public" addr returned is checked against ifconfig for
|
||||
* possible clash: non sense for now given
|
||||
* that we do ifconfig only IPv4
|
||||
*/
|
||||
#if defined(USE_PF_INET6)
|
||||
if(addr->addr.sa.sa_family != AF_INET)
|
||||
return 0;
|
||||
#else
|
||||
ASSERT(addr->addr.sa.sa_family == AF_INET);
|
||||
#endif
|
||||
return ntohl (addr->addr.in4.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)
|
||||
{
|
||||
return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr
|
||||
&& a1->sa.sin_port == a2->sa.sin_port;
|
||||
switch(a1->addr.sa.sa_family) {
|
||||
case AF_INET:
|
||||
return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr
|
||||
&& a1->addr.in4.sin_port == a2->addr.in4.sin_port;
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6:
|
||||
return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)
|
||||
&& a1->addr.in6.sin6_port == a2->addr.in6.sin6_port;
|
||||
#endif
|
||||
}
|
||||
ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -571,6 +681,74 @@ addr_match_proto (const struct openvpn_sockaddr *a1,
|
|||
: addr_port_match (a1, a2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
addr_zero_host(struct openvpn_sockaddr *addr)
|
||||
{
|
||||
switch(addr->addr.sa.sa_family) {
|
||||
case AF_INET:
|
||||
addr->addr.in4.sin_addr.s_addr = 0;
|
||||
break;
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6:
|
||||
memset(&addr->addr.in6.sin6_addr, 0, sizeof (struct in6_addr));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
addr_copy_sa(struct openvpn_sockaddr *dst, const struct openvpn_sockaddr *src)
|
||||
{
|
||||
dst->addr = src->addr;
|
||||
}
|
||||
|
||||
static inline void
|
||||
addr_copy_host(struct openvpn_sockaddr *dst, const struct openvpn_sockaddr *src)
|
||||
{
|
||||
switch(src->addr.sa.sa_family) {
|
||||
case AF_INET:
|
||||
dst->addr.in4.sin_addr.s_addr = src->addr.in4.sin_addr.s_addr;
|
||||
break;
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6:
|
||||
dst->addr.in6.sin6_addr = src->addr.in6.sin6_addr;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
addr_inet4or6(struct sockaddr *addr)
|
||||
{
|
||||
return addr->sa_family == AF_INET || addr->sa_family == AF_INET6;
|
||||
}
|
||||
|
||||
int addr_guess_family(int proto, const char *name);
|
||||
static inline int
|
||||
af_addr_size(unsigned short af)
|
||||
{
|
||||
#if defined(USE_PF_INET6) || defined (USE_PF_UNIX)
|
||||
switch(af) {
|
||||
case AF_INET: return sizeof (struct sockaddr_in);
|
||||
#ifdef USE_PF_UNIX
|
||||
case AF_UNIX: return sizeof (struct sockaddr_un);
|
||||
#endif
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6: return sizeof (struct sockaddr_in6);
|
||||
#endif
|
||||
default:
|
||||
#if 0
|
||||
/* could be called from socket_do_accept() with empty addr */
|
||||
msg (M_ERR, "Bad address family: %d\n", af);
|
||||
ASSERT(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#else /* only AF_INET */
|
||||
return sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool
|
||||
link_socket_actual_match (const struct link_socket_actual *a1, const struct link_socket_actual *a2)
|
||||
{
|
||||
|
|
@ -627,14 +805,18 @@ link_socket_verify_incoming_addr (struct buffer *buf,
|
|||
{
|
||||
if (buf->len > 0)
|
||||
{
|
||||
if (from_addr->dest.sa.sin_family != AF_INET)
|
||||
return false;
|
||||
if (!link_socket_actual_defined (from_addr))
|
||||
return false;
|
||||
if (info->remote_float || !addr_defined (&info->lsa->remote))
|
||||
return true;
|
||||
if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto))
|
||||
return true;
|
||||
switch (from_addr->dest.addr.sa.sa_family) {
|
||||
#ifdef USE_PF_INET6
|
||||
case AF_INET6:
|
||||
#endif
|
||||
case AF_INET:
|
||||
if (!link_socket_actual_defined (from_addr))
|
||||
return false;
|
||||
if (info->remote_float || !addr_defined (&info->lsa->remote))
|
||||
return true;
|
||||
if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -740,7 +922,7 @@ link_socket_read (struct link_socket *sock,
|
|||
int maxsize,
|
||||
struct link_socket_actual *from)
|
||||
{
|
||||
if (sock->info.proto == PROTO_UDPv4)
|
||||
if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */
|
||||
{
|
||||
int res;
|
||||
|
||||
|
|
@ -751,10 +933,10 @@ link_socket_read (struct link_socket *sock,
|
|||
#endif
|
||||
return res;
|
||||
}
|
||||
else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT)
|
||||
else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */
|
||||
{
|
||||
/* from address was returned by accept */
|
||||
from->dest.sa = sock->info.lsa->actual.dest.sa;
|
||||
addr_copy_sa(&from->dest, &sock->info.lsa->actual.dest);
|
||||
return link_socket_read_tcp (sock, buf);
|
||||
}
|
||||
else
|
||||
|
|
@ -809,13 +991,14 @@ link_socket_write_udp_posix (struct link_socket *sock,
|
|||
struct buffer *buf,
|
||||
struct link_socket_actual *to);
|
||||
|
||||
if (sock->sockflags & SF_USE_IP_PKTINFO)
|
||||
if (proto_is_udp(sock->info.proto) && (sock->sockflags & SF_USE_IP_PKTINFO)
|
||||
&& addr_defined_ipi(to))
|
||||
return link_socket_write_udp_posix_sendmsg (sock, buf, to);
|
||||
else
|
||||
#endif
|
||||
return sendto (sock->sd, BPTR (buf), BLEN (buf), 0,
|
||||
(struct sockaddr *) &to->dest.sa,
|
||||
(socklen_t) sizeof (to->dest.sa));
|
||||
(struct sockaddr *) &to->dest.addr.sa,
|
||||
(socklen_t) af_addr_size(to->dest.addr.sa.sa_family));
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
@ -846,11 +1029,11 @@ link_socket_write (struct link_socket *sock,
|
|||
struct buffer *buf,
|
||||
struct link_socket_actual *to)
|
||||
{
|
||||
if (sock->info.proto == PROTO_UDPv4)
|
||||
if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */
|
||||
{
|
||||
return link_socket_write_udp (sock, buf, to);
|
||||
}
|
||||
else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT)
|
||||
else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */
|
||||
{
|
||||
return link_socket_write_tcp (sock, buf, to);
|
||||
}
|
||||
|
|
|
|||
18
socks.c
18
socks.c
|
|
@ -299,9 +299,9 @@ recv_socks_reply (socket_descriptor_t sd,
|
|||
|
||||
if (addr != NULL)
|
||||
{
|
||||
addr->sa.sin_family = AF_INET;
|
||||
addr->sa.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
addr->sa.sin_port = htons (0);
|
||||
addr->addr.in4.sin_family = AF_INET;
|
||||
addr->addr.in4.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
addr->addr.in4.sin_port = htons (0);
|
||||
}
|
||||
|
||||
while (len < 4 + alen + 2)
|
||||
|
|
@ -388,8 +388,8 @@ recv_socks_reply (socket_descriptor_t sd,
|
|||
/* ATYP == 1 (IP V4 address) */
|
||||
if (atyp == '\x01' && addr != NULL)
|
||||
{
|
||||
memcpy (&addr->sa.sin_addr, buf + 4, sizeof (addr->sa.sin_addr));
|
||||
memcpy (&addr->sa.sin_port, buf + 8, sizeof (addr->sa.sin_port));
|
||||
memcpy (&addr->addr.in4.sin_addr, buf + 4, sizeof (addr->addr.in4.sin_addr));
|
||||
memcpy (&addr->addr.in4.sin_port, buf + 8, sizeof (addr->addr.in4.sin_port));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -507,8 +507,8 @@ socks_process_incoming_udp (struct buffer *buf,
|
|||
if (atyp != 1) /* ATYP == 1 (IP V4) */
|
||||
goto error;
|
||||
|
||||
buf_read (buf, &from->dest.sa.sin_addr, sizeof (from->dest.sa.sin_addr));
|
||||
buf_read (buf, &from->dest.sa.sin_port, sizeof (from->dest.sa.sin_port));
|
||||
buf_read (buf, &from->dest.addr.in4.sin_addr, sizeof (from->dest.addr.in4.sin_addr));
|
||||
buf_read (buf, &from->dest.addr.in4.sin_port, sizeof (from->dest.addr.in4.sin_port));
|
||||
|
||||
return;
|
||||
|
||||
|
|
@ -540,8 +540,8 @@ socks_process_outgoing_udp (struct buffer *buf,
|
|||
buf_write_u16 (&head, 0); /* RSV = 0 */
|
||||
buf_write_u8 (&head, 0); /* FRAG = 0 */
|
||||
buf_write_u8 (&head, '\x01'); /* ATYP = 1 (IP V4) */
|
||||
buf_write (&head, &to->dest.sa.sin_addr, sizeof (to->dest.sa.sin_addr));
|
||||
buf_write (&head, &to->dest.sa.sin_port, sizeof (to->dest.sa.sin_port));
|
||||
buf_write (&head, &to->dest.addr.in4.sin_addr, sizeof (to->dest.addr.in4.sin_addr));
|
||||
buf_write (&head, &to->dest.addr.in4.sin_port, sizeof (to->dest.addr.in4.sin_port));
|
||||
|
||||
return 10;
|
||||
}
|
||||
|
|
|
|||
12
syshead.h
12
syshead.h
|
|
@ -28,6 +28,10 @@
|
|||
/*
|
||||
* Only include if not during configure
|
||||
*/
|
||||
#ifdef WIN32
|
||||
/* USE_PF_INET6: win32 ipv6 exists only after 0x0501 (XP) */
|
||||
#define WINVER 0x0501
|
||||
#endif
|
||||
#ifndef PACKAGE_NAME
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
|
@ -339,6 +343,9 @@
|
|||
#ifdef WIN32
|
||||
#include <iphlpapi.h>
|
||||
#include <wininet.h>
|
||||
/* The following two headers are needed of USE_PF_INET6 */
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
|
|
@ -383,9 +390,10 @@
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Does this platform support linux-style IP_PKTINFO?
|
||||
* Does this platform support linux-style IP_PKTINFO
|
||||
* or bsd-style IP_RECVDSTADDR ?
|
||||
*/
|
||||
#if defined(ENABLE_MULTIHOME) && defined(HAVE_IN_PKTINFO) && defined(IP_PKTINFO) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG)
|
||||
#if defined(ENABLE_MULTIHOME) && ((defined(HAVE_IN_PKTINFO)&&defined(IP_PKTINFO)) || defined(IP_RECVDSTADDR)) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG)
|
||||
#define ENABLE_IP_PKTINFO 1
|
||||
#else
|
||||
#define ENABLE_IP_PKTINFO 0
|
||||
|
|
|
|||
2
tun.c
2
tun.c
|
|
@ -1697,7 +1697,9 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
|
|||
strerror(errno));
|
||||
}
|
||||
|
||||
#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */
|
||||
info.flags |= IFF_MULTICAST;
|
||||
#endif
|
||||
|
||||
if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) {
|
||||
msg (M_WARN | M_ERRNO, "Can't set interface info: %s",
|
||||
|
|
|
|||
5
win32.h
5
win32.h
|
|
@ -195,7 +195,10 @@ struct overlapped_io {
|
|||
DWORD flags;
|
||||
int status;
|
||||
bool addr_defined;
|
||||
struct sockaddr_in addr;
|
||||
union {
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_in6 addr6;
|
||||
};
|
||||
int addrlen;
|
||||
struct buffer buf_init;
|
||||
struct buffer buf;
|
||||
|
|
|
|||
Loading…
Reference in a new issue