mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-06-10 09:22:45 -04:00
Set the correct mtu on windows based systems
Signed-off-by: Christopher Schenk <cschenk@mail.uni-paderborn.de> Acked-by: Selva Nair <selva.nair@gmail.com> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <20200421154612.14140-1-cschenk@mail.uni-paderborn.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg19803.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
parent
e0b49cb952
commit
0213f80ed7
3 changed files with 129 additions and 1 deletions
|
|
@ -39,7 +39,8 @@ typedef enum {
|
|||
msg_del_block_dns,
|
||||
msg_register_dns,
|
||||
msg_enable_dhcp,
|
||||
msg_register_ring_buffers
|
||||
msg_register_ring_buffers,
|
||||
msg_set_mtu
|
||||
} message_type_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -127,4 +128,11 @@ typedef struct {
|
|||
HANDLE receive_tail_moved;
|
||||
} register_ring_buffers_message_t;
|
||||
|
||||
typedef struct {
|
||||
message_header_t header;
|
||||
interface_t iface;
|
||||
short family;
|
||||
int mtu;
|
||||
} set_mtu_message_t;
|
||||
|
||||
#endif /* ifndef OPENVPN_MSG_H_ */
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ static void netsh_ifconfig(const struct tuntap_options *to,
|
|||
const in_addr_t netmask,
|
||||
const unsigned int flags);
|
||||
|
||||
static void windows_set_mtu(const int iface_index,
|
||||
const short family,
|
||||
const int mtu);
|
||||
|
||||
static void netsh_set_dns6_servers(const struct in6_addr *addr_list,
|
||||
const int addr_len,
|
||||
const char *flex_name);
|
||||
|
|
@ -214,6 +218,47 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
do_set_mtu_service(const struct tuntap *tt, const short family, const int mtu)
|
||||
{
|
||||
DWORD len;
|
||||
bool ret = false;
|
||||
ack_message_t ack;
|
||||
struct gc_arena gc = gc_new();
|
||||
HANDLE pipe = tt->options.msg_channel;
|
||||
const char *family_name = (family == AF_INET6) ? "IPv6" : "IPv4";
|
||||
set_mtu_message_t mtu_msg = {
|
||||
.header = {
|
||||
msg_set_mtu,
|
||||
sizeof(set_mtu_message_t),
|
||||
0
|
||||
},
|
||||
.iface = {.index = tt->adapter_index,.name = tt->actual_name },
|
||||
.mtu = mtu,
|
||||
.family = family
|
||||
};
|
||||
|
||||
if (!send_msg_iservice(pipe, &mtu_msg, sizeof(mtu_msg), &ack, "Set_mtu"))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ack.error_number != NO_ERROR)
|
||||
{
|
||||
msg(M_NONFATAL, "TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
|
||||
family_name, strerror_win32(ack.error_number, &gc), ack.error_number, mtu_msg.iface.index);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg(M_INFO, "%s MTU set to %d on interface %d using service", family_name, mtu, mtu_msg.iface.index);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
out:
|
||||
gc_free(&gc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* ifdef _WIN32 */
|
||||
|
||||
#ifdef TARGET_SOLARIS
|
||||
|
|
@ -1018,6 +1063,7 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
|
|||
do_address_service(true, AF_INET6, tt);
|
||||
add_route_connected_v6_net(tt, es);
|
||||
do_dns_service(true, AF_INET6, tt);
|
||||
do_set_mtu_service(tt, AF_INET6, tun_mtu);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1035,6 +1081,7 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
|
|||
add_route_connected_v6_net(tt, es);
|
||||
/* set ipv6 dns servers if any are specified */
|
||||
netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
|
||||
windows_set_mtu(tt->adapter_index, AF_INET6, tun_mtu);
|
||||
}
|
||||
#else /* platforms we have no IPv6 code for */
|
||||
msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
|
||||
|
|
@ -1404,6 +1451,14 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
|
|||
netsh_ifconfig(&tt->options, ifname, tt->local,
|
||||
tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
|
||||
}
|
||||
if (tt->options.msg_channel)
|
||||
{
|
||||
do_set_mtu_service(tt, AF_INET, tun_mtu);
|
||||
}
|
||||
else
|
||||
{
|
||||
windows_set_mtu(tt->adapter_index, AF_INET, tun_mtu);
|
||||
}
|
||||
#else /* if defined(TARGET_LINUX) */
|
||||
msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
|
||||
#endif /* if defined(TARGET_LINUX) */
|
||||
|
|
@ -5432,6 +5487,40 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
windows_set_mtu(const int iface_index, const short family,
|
||||
const int mtu)
|
||||
{
|
||||
DWORD err = 0;
|
||||
struct gc_arena gc = gc_new();
|
||||
MIB_IPINTERFACE_ROW ipiface;
|
||||
InitializeIpInterfaceEntry(&ipiface);
|
||||
const char *family_name = (family == AF_INET6) ? "IPv6" : "IPv4";
|
||||
ipiface.Family = family;
|
||||
ipiface.InterfaceIndex = iface_index;
|
||||
err = GetIpInterfaceEntry(&ipiface);
|
||||
if (err == NO_ERROR)
|
||||
{
|
||||
if (family == AF_INET)
|
||||
{
|
||||
ipiface.SitePrefixLength = 0;
|
||||
}
|
||||
ipiface.NlMtu = mtu;
|
||||
err = SetIpInterfaceEntry(&ipiface);
|
||||
}
|
||||
|
||||
if (err != NO_ERROR)
|
||||
{
|
||||
msg(M_WARN, "TUN: Setting %s mtu failed: %s [status=%u if_index=%d]",
|
||||
family_name, strerror_win32(err, &gc), err, iface_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg(M_INFO, "Successfully set %s mtu on interface %d", family_name, iface_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a TAP name for netsh commands.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1286,6 +1286,29 @@ HandleRegisterRingBuffers(const register_ring_buffers_message_t *rrb, HANDLE ovp
|
|||
return err;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
HandleMTUMessage(const set_mtu_message_t *mtu)
|
||||
{
|
||||
DWORD err = 0;
|
||||
MIB_IPINTERFACE_ROW ipiface;
|
||||
InitializeIpInterfaceEntry(&ipiface);
|
||||
ipiface.Family = mtu->family;
|
||||
ipiface.InterfaceIndex = mtu->iface.index;
|
||||
err = GetIpInterfaceEntry(&ipiface);
|
||||
if (err != NO_ERROR)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
if (mtu->family == AF_INET)
|
||||
{
|
||||
ipiface.SitePrefixLength = 0;
|
||||
}
|
||||
ipiface.NlMtu = mtu->mtu;
|
||||
|
||||
err = SetIpInterfaceEntry(&ipiface);
|
||||
return err;
|
||||
}
|
||||
|
||||
static VOID
|
||||
HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_handles,
|
||||
DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t *lists)
|
||||
|
|
@ -1300,6 +1323,7 @@ HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_
|
|||
dns_cfg_message_t dns;
|
||||
enable_dhcp_message_t dhcp;
|
||||
register_ring_buffers_message_t rrb;
|
||||
set_mtu_message_t mtu;
|
||||
} msg;
|
||||
ack_message_t ack = {
|
||||
.header = {
|
||||
|
|
@ -1374,6 +1398,13 @@ HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_
|
|||
}
|
||||
break;
|
||||
|
||||
case msg_set_mtu:
|
||||
if (msg.header.size == sizeof(msg.mtu))
|
||||
{
|
||||
ack.error_number = HandleMTUMessage(&msg.mtu);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ack.error_number = ERROR_MESSAGE_TYPE;
|
||||
MsgToEventLog(MSG_FLAGS_ERROR, TEXT("Unknown message type %d"), msg.header.type);
|
||||
|
|
|
|||
Loading…
Reference in a new issue