1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-06 17:50:40 +03:00

Cedar: send network settings to OpenVPN client in TAP mode

This commit is contained in:
Davide Beatrici 2018-12-02 20:26:38 +01:00
parent 740a4aafe1
commit fd316014d6
3 changed files with 50 additions and 57 deletions

View File

@ -216,20 +216,20 @@ void IPCAsyncThreadProc(THREAD *thread, void *param)
if (a->Ipc != NULL) if (a->Ipc != NULL)
{ {
if (a->Param.IsL3Mode) if (a->Param.DisableDhcp == false)
{ {
DHCP_OPTION_LIST cao; DHCP_OPTION_LIST cao;
Zero(&cao, sizeof(cao)); Zero(&cao, sizeof(cao));
// Get an IP address from the DHCP server in the case of L3 mode // Get an IP address from the DHCP server
Debug("IPCDhcpAllocateIP() start...\n"); Debug("IPCAsyncThreadProc(): DHCP operation in progress...\n");
if (IPCDhcpAllocateIP(a->Ipc, &cao, a->TubeForDisconnect)) if (IPCDhcpAllocateIP(a->Ipc, &cao, a->TubeForDisconnect))
{ {
UINT t; UINT t;
IP ip, subnet, gw; IP ip, subnet, gw;
Debug("IPCDhcpAllocateIP() Ok.\n"); Debug("IPCAsyncThreadProc(): IPCDhcpAllocateIP() succeeded.\n");
// Calculate the DHCP update interval // Calculate the DHCP update interval
t = cao.LeaseTime; t = cao.LeaseTime;
@ -246,8 +246,8 @@ void IPCAsyncThreadProc(THREAD *thread, void *param)
} }
// Save the options list // Save the options list
Copy(&a->L3ClientAddressOption, &cao, sizeof(DHCP_OPTION_LIST)); Copy(&a->DhcpOptionList, &cao, sizeof(DHCP_OPTION_LIST));
a->L3DhcpRenewInterval = t * 1000; a->DhcpRenewInterval = t * 1000;
// Set the obtained IP address parameters to the IPC virtual host // Set the obtained IP address parameters to the IPC virtual host
UINTToIP(&ip, cao.ClientAddress); UINTToIP(&ip, cao.ClientAddress);
@ -256,11 +256,11 @@ void IPCAsyncThreadProc(THREAD *thread, void *param)
IPCSetIPv4Parameters(a->Ipc, &ip, &subnet, &gw, &cao.ClasslessRoute); IPCSetIPv4Parameters(a->Ipc, &ip, &subnet, &gw, &cao.ClasslessRoute);
a->L3NextDhcpRenewTick = Tick64() + a->L3DhcpRenewInterval; a->DhcpNextRenewTick = Tick64() + a->DhcpRenewInterval;
} }
else else
{ {
Debug("IPCDhcpAllocateIP() Error.\n"); Debug("IPCAsyncThreadProc(): IPCDhcpAllocateIP() failed.\n");
a->DhcpAllocFailed = true; a->DhcpAllocFailed = true;

View File

@ -161,8 +161,8 @@ struct IPC_PARAM
char ClientHostname[MAX_SIZE]; char ClientHostname[MAX_SIZE];
char CryptName[MAX_SIZE]; char CryptName[MAX_SIZE];
bool BridgeMode; bool BridgeMode;
bool DisableDhcp;
UINT Mss; UINT Mss;
bool IsL3Mode;
X *ClientCertificate; X *ClientCertificate;
}; };
@ -177,9 +177,9 @@ struct IPC_ASYNC
IPC *Ipc; // IPC object (if it fails to connect, the value is NULL) IPC *Ipc; // IPC object (if it fails to connect, the value is NULL)
TUBE *TubeForDisconnect; // Tube for disconnection notification TUBE *TubeForDisconnect; // Tube for disconnection notification
UINT ErrorCode; // Error code in the case of failing to connect UINT ErrorCode; // Error code in the case of failing to connect
DHCP_OPTION_LIST L3ClientAddressOption; // Client IP address option (Only in the case of L3 mode) DHCP_OPTION_LIST DhcpOptionList; // Client IP address option
UINT64 L3DhcpRenewInterval; // DHCP update interval UINT64 DhcpRenewInterval; // DHCP update interval
UINT64 L3NextDhcpRenewTick; // DHCP renewal time of the next UINT64 DhcpNextRenewTick; // DHCP renewal time of the next
bool DhcpAllocFailed; // Failed to get IP address from the DHCP server bool DhcpAllocFailed; // Failed to get IP address from the DHCP server
}; };

View File

@ -964,18 +964,12 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O
StrCpy(p.ClientHostname, sizeof(p.ClientHostname), EntryListStrValue(pi, "IV_HWADDR")); StrCpy(p.ClientHostname, sizeof(p.ClientHostname), EntryListStrValue(pi, "IV_HWADDR"));
} }
// Check whether the client doesn't want DHCP
p.DisableDhcp = EntryListHasKey(pi, "UV_NO_DHCP");
FreeEntryList(pi); FreeEntryList(pi);
if (se->Mode == OPENVPN_MODE_L3) p.BridgeMode = se->Mode == OPENVPN_MODE_L2;
{
// L3 Mode
p.IsL3Mode = true;
}
else
{
// L2 Mode
p.BridgeMode = true;
}
if (c->ClientCert.X != NULL) if (c->ClientCert.X != NULL)
{ {
@ -2035,7 +2029,7 @@ void OvsFreeSession(OPENVPN_SESSION *se)
{ {
IP dhcp_ip; IP dhcp_ip;
UINTToIP(&dhcp_ip, se->IpcAsync->L3ClientAddressOption.ServerAddress); UINTToIP(&dhcp_ip, se->IpcAsync->DhcpOptionList.ServerAddress);
IPCDhcpFreeIP(se->Ipc, &dhcp_ip); IPCDhcpFreeIP(se->Ipc, &dhcp_ip);
IPCProcessL3Events(se->Ipc); IPCProcessL3Events(se->Ipc);
@ -2191,7 +2185,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
if (se->IpcAsync->Ipc != NULL) if (se->IpcAsync->Ipc != NULL)
{ {
char option_str[4096]; char option_str[4096];
char l3_options[MAX_SIZE]; char option[MAX_SIZE];
// Successful in VPN connection // Successful in VPN connection
Debug("OpenVPN Channel %u Established (new key).\n", j); Debug("OpenVPN Channel %u Established (new key).\n", j);
@ -2203,11 +2197,11 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
(OPENVPN_PING_SEND_INTERVAL / 1000), (OPENVPN_PING_SEND_INTERVAL / 1000),
(OPENVPN_RECV_TIMEOUT / 1000)); (OPENVPN_RECV_TIMEOUT / 1000));
if (se->Mode == OPENVPN_MODE_L3) if (se->IpcAsync->Param.DisableDhcp == false)
{ {
// Add such as the IP address that was acquired from the DHCP server // Add such as the IP address that was acquired from the DHCP server
// if the L3 mode to the option character string // if the L3 mode to the option character string
DHCP_OPTION_LIST *cao = &se->IpcAsync->L3ClientAddressOption; DHCP_OPTION_LIST *cao = &se->IpcAsync->DhcpOptionList;
char ip_client[64]; char ip_client[64];
char ip_subnet_mask[64]; char ip_subnet_mask[64];
char ip_dns1[64]; char ip_dns1[64];
@ -2228,22 +2222,22 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
IPToStr32(ip_subnet_mask, sizeof(ip_subnet_mask), IPToStr32(ip_subnet_mask, sizeof(ip_subnet_mask),
cao->SubnetMask); cao->SubnetMask);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",topology subnet"); ",topology subnet");
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",ifconfig %s %s", ",ifconfig %s %s",
ip_client, ip_client,
ip_subnet_mask); ip_subnet_mask);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
// Domain name // Domain name
if (IsEmptyStr(cao->DomainName) == false) if (IsEmptyStr(cao->DomainName) == false)
{ {
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",dhcp-option DOMAIN %s", cao->DomainName); ",dhcp-option DOMAIN %s", cao->DomainName);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
} }
// DNS server address 1 // DNS server address 1
@ -2251,9 +2245,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{ {
char ip_str[64]; char ip_str[64];
IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer); IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",dhcp-option DNS %s", ip_str); ",dhcp-option DNS %s", ip_str);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
StrCpy(ip_dns1, sizeof(ip_dns1), ip_str); StrCpy(ip_dns1, sizeof(ip_dns1), ip_str);
} }
@ -2263,9 +2257,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{ {
char ip_str[64]; char ip_str[64];
IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer2); IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer2);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",dhcp-option DNS %s", ip_str); ",dhcp-option DNS %s", ip_str);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
StrCpy(ip_dns2, sizeof(ip_dns2), ip_str); StrCpy(ip_dns2, sizeof(ip_dns2), ip_str);
} }
@ -2275,9 +2269,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{ {
char ip_str[64]; char ip_str[64];
IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer); IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",dhcp-option WINS %s", ip_str); ",dhcp-option WINS %s", ip_str);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
StrCpy(ip_wins1, sizeof(ip_wins1), ip_str); StrCpy(ip_wins1, sizeof(ip_wins1), ip_str);
} }
@ -2287,9 +2281,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{ {
char ip_str[64]; char ip_str[64];
IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer2); IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer2);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",dhcp-option WINS %s", ip_str); ",dhcp-option WINS %s", ip_str);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
StrCpy(ip_wins2, sizeof(ip_wins2), ip_str); StrCpy(ip_wins2, sizeof(ip_wins2), ip_str);
} }
@ -2299,9 +2293,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{ {
char ip_str[64]; char ip_str[64];
IPToStr32(ip_str, sizeof(ip_str), cao->Gateway); IPToStr32(ip_str, sizeof(ip_str), cao->Gateway);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",route-gateway %s,redirect-gateway def1", ip_str); ",route-gateway %s,redirect-gateway def1", ip_str);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
StrCpy(ip_defgw, sizeof(ip_defgw), ip_str); StrCpy(ip_defgw, sizeof(ip_defgw), ip_str);
} }
@ -2320,12 +2314,12 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
Zero(&local_network, sizeof(IP)); Zero(&local_network, sizeof(IP));
IPAnd4(&local_network, &client_ip, &subnet_mask); IPAnd4(&local_network, &client_ip, &subnet_mask);
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",route %r %r vpn_gateway", ",route %r %r vpn_gateway",
&local_network, &local_network,
&cao->SubnetMask); &cao->SubnetMask);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
#endif #endif
} }
@ -2339,11 +2333,11 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
if (r->Exists) if (r->Exists)
{ {
Format(l3_options, sizeof(l3_options), Format(option, sizeof(option),
",route %r %r vpn_gateway", ",route %r %r vpn_gateway",
&r->Network, &r->SubnetMask); &r->Network, &r->SubnetMask);
StrCat(option_str, sizeof(option_str), l3_options); StrCat(option_str, sizeof(option_str), option);
} }
} }
} }
@ -2351,7 +2345,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
OvsLog(s, se, c, "LP_SET_IPV4_PARAM", OvsLog(s, se, c, "LP_SET_IPV4_PARAM",
ip_client, ip_subnet_mask, ip_defgw, ip_dns1, ip_dns2, ip_wins1, ip_wins2); ip_client, ip_subnet_mask, ip_defgw, ip_dns1, ip_dns2, ip_wins1, ip_wins2);
} }
else else if (se->Mode == OPENVPN_MODE_L2)
{ {
// OpenVPN L2 mode. To fix the bug of OpenVPN 2.4.6 and particular version of kernel mode TAP driver // 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. // on Linux, the TAP device must be up after the OpenVPN client is connected.
@ -2502,23 +2496,22 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
if (se->Ipc != NULL) if (se->Ipc != NULL)
{ {
if (se->Mode == OPENVPN_MODE_L3) if (se->IpcAsync != NULL && se->IpcAsync->Param.DisableDhcp == false)
{ {
if (se->IpcAsync != NULL) if (se->IpcAsync->DhcpNextRenewTick <= s->Now)
{ {
// Update DHCP address // Update DHCP address
if (se->IpcAsync->L3NextDhcpRenewTick <= s->Now)
{
IP ip; IP ip;
UINTToIP(&ip, se->IpcAsync->DhcpOptionList.ServerAddress);
se->IpcAsync->L3NextDhcpRenewTick = s->Now + se->IpcAsync->L3DhcpRenewInterval; se->IpcAsync->DhcpNextRenewTick = s->Now + se->IpcAsync->DhcpRenewInterval;
UINTToIP(&ip, se->IpcAsync->L3ClientAddressOption.ServerAddress);
IPCDhcpRenewIP(se->Ipc, &ip); IPCDhcpRenewIP(se->Ipc, &ip);
} }
} }
if (se->Mode == OPENVPN_MODE_L3)
{
IPCProcessL3Events(se->Ipc); IPCProcessL3Events(se->Ipc);
} }