From 58e2f74f7fed8a8bde4b600d17d623b22657073c Mon Sep 17 00:00:00 2001 From: Daiyuu Nobori Date: Sat, 1 Dec 2018 16:20:30 +0900 Subject: [PATCH] Added the "OpenVPNPushDummyIPv4AddressOnL2Mode" option for the OpenVPN L2 mode. To fix the bug of OpenVPN 2.4.6 and particular version of kernel mode TAP driver on Linux, the TAP device must be up after the OpenVPN client is connected. However there is no direct push instruction to do so to OpenVPN client. Therefore we push the dummy IPv4 address (RFC7600) to the OpenVPN client to enforce the TAP driver UP state. --- src/Cedar/Cedar.c | 2 ++ src/Cedar/Cedar.h | 1 + src/Cedar/Proto_OpenVPN.c | 12 ++++++++++++ src/Cedar/Server.c | 13 +++++++++++++ 4 files changed, 28 insertions(+) diff --git a/src/Cedar/Cedar.c b/src/Cedar/Cedar.c index 16694de2..8f60d1e3 100644 --- a/src/Cedar/Cedar.c +++ b/src/Cedar/Cedar.c @@ -1554,6 +1554,8 @@ CEDAR *NewCedar(X *server_x, K *server_k) StrCpy(c->OpenVPNDefaultClientOption, sizeof(c->OpenVPNDefaultClientOption), OVPN_DEF_CLIENT_OPTION_STRING); + c->OpenVPNPushDummyIPv4AddressOnL2Mode = true; // Default true. Override by the config file. + #ifdef BETA_NUMBER c->Beta = BETA_NUMBER; #endif // BETA_NUMBER diff --git a/src/Cedar/Cedar.h b/src/Cedar/Cedar.h index b67fc975..30da531e 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -1083,6 +1083,7 @@ typedef struct CEDAR char OpenVPNDefaultClientOption[MAX_SIZE]; // OpenVPN: Default Client Option String bool OpenVPNObfuscation; // OpenVPN: Obfuscation mode char OpenVPNObfuscationMask[MAX_SIZE]; // OpenVPN: String (mask) for XOR obfuscation + bool OpenVPNPushDummyIPv4AddressOnL2Mode; // OpenVPN: Push a dummy IPv4 address on L2 mode } CEDAR; // Type of CEDAR diff --git a/src/Cedar/Proto_OpenVPN.c b/src/Cedar/Proto_OpenVPN.c index 4015796a..b6af9a0a 100644 --- a/src/Cedar/Proto_OpenVPN.c +++ b/src/Cedar/Proto_OpenVPN.c @@ -2351,6 +2351,18 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) OvsLog(s, se, c, "LP_SET_IPV4_PARAM", ip_client, ip_subnet_mask, ip_defgw, ip_dns1, ip_dns2, ip_wins1, ip_wins2); } + else + { + // OpenVPN L2 mode. To fix the bug of OpenVPN 2.4.6 and particular version of kernel mode TAP driver + // on Linux, the TAP device must be up after the OpenVPN client is connected. + // However there is no direct push instruction to do so to OpenVPN client. + // Therefore we push the dummy IPv4 address (RFC7600) to the OpenVPN client. + + if (s->Cedar->OpenVPNPushDummyIPv4AddressOnL2Mode) + { + StrCat(option_str, sizeof(option_str), ",ifconfig 192.0.0.8 255.255.255.240"); + } + } WriteFifo(c->SslPipe->SslInOut->SendFifo, option_str, StrSize(option_str)); diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index 9c3788b9..06e335c1 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -5872,6 +5872,17 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f) } } + // OpenVPN Push a dummy IPv4 address on L2 mode + if (CfgIsItem(f, "OpenVPNPushDummyIPv4AddressOnL2Mode") == false) + { + // Default enable + c->OpenVPNPushDummyIPv4AddressOnL2Mode = true; + } + else + { + c->OpenVPNPushDummyIPv4AddressOnL2Mode = CfgGetBool(f, "OpenVPNPushDummyIPv4AddressOnL2Mode"); + } + // Disable the NAT-traversal feature s->DisableNatTraversal = CfgGetBool(f, "DisableNatTraversal"); @@ -6289,6 +6300,8 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s) CfgAddStr(f, "OpenVPNDefaultClientOption", c->OpenVPNDefaultClientOption); + CfgAddBool(f, "OpenVPNPushDummyIPv4AddressOnL2Mode", c->OpenVPNPushDummyIPv4AddressOnL2Mode); + if (c->Bridge == false) { OPENVPN_SSTP_CONFIG config;