mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Interop_OpenVPN: set "subnet" topology and remove workaround for "net30" topology on Win32
The workaround was required for the "net30" topology because: "There is a problem in your selection of --ifconfig endpoints [local=192.168.30.10, remote=192.168.30.1]. The local and remote VPN endpoints must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver. Try 'openvpn --show-valid-subnets' option for more info." See https://community.openvpn.net/openvpn/wiki/Topology for detailed info.
This commit is contained in:
parent
88424e2522
commit
2692bb6b8e
@ -223,13 +223,13 @@ void IPCAsyncThreadProc(THREAD *thread, void *param)
|
||||
Zero(&cao, sizeof(cao));
|
||||
|
||||
// Get an IP address from the DHCP server in the case of L3 mode
|
||||
Debug("IPCDhcpAllocateIPEx() start...\n");
|
||||
if (IPCDhcpAllocateIPEx(a->Ipc, &cao, a->TubeForDisconnect, a->Param.IsOpenVPN))
|
||||
Debug("IPCDhcpAllocateIP() start...\n");
|
||||
if (IPCDhcpAllocateIP(a->Ipc, &cao, a->TubeForDisconnect))
|
||||
{
|
||||
UINT t;
|
||||
IP ip, subnet, gw;
|
||||
|
||||
Debug("IPCDhcpAllocateIPEx() Ok.\n");
|
||||
Debug("IPCDhcpAllocateIP() Ok.\n");
|
||||
|
||||
// Calculate the DHCP update interval
|
||||
t = cao.LeaseTime;
|
||||
@ -260,7 +260,7 @@ void IPCAsyncThreadProc(THREAD *thread, void *param)
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug("IPCDhcpAllocateIPEx() Error.\n");
|
||||
Debug("IPCDhcpAllocateIP() Error.\n");
|
||||
|
||||
a->DhcpAllocFailed = true;
|
||||
|
||||
@ -791,39 +791,20 @@ bool IPCDhcpRequestInformIP(IPC *ipc, DHCP_OPTION_LIST *opt, TUBE *discon_poll_t
|
||||
|
||||
// Make a request for IP addresses using DHCP
|
||||
bool IPCDhcpAllocateIP(IPC *ipc, DHCP_OPTION_LIST *opt, TUBE *discon_poll_tube)
|
||||
{
|
||||
return IPCDhcpAllocateIPEx(ipc, opt, discon_poll_tube, false);
|
||||
}
|
||||
bool IPCDhcpAllocateIPEx(IPC *ipc, DHCP_OPTION_LIST *opt, TUBE *discon_poll_tube, bool openvpn_compatible)
|
||||
{
|
||||
DHCP_OPTION_LIST req;
|
||||
DHCPV4_DATA *d, *d2;
|
||||
UINT tran_id = Rand32();
|
||||
bool ok;
|
||||
UINT request_ip = 0;
|
||||
IP current_scanning_ip;
|
||||
UCHAR current_scanning_addr8;
|
||||
UCHAR begin_scanning_addr8;
|
||||
UINT64 giveup = Tick64() + (UINT64)IPC_DHCP_TIMEOUT_TOTAL_GIVEUP;
|
||||
LIST *release_list;
|
||||
bool ret = false;
|
||||
// Validate arguments
|
||||
if (ipc == NULL || opt == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
release_list = NewListFast(NULL);
|
||||
|
||||
Zero(¤t_scanning_ip, sizeof(current_scanning_ip));
|
||||
current_scanning_addr8 = 0;
|
||||
begin_scanning_addr8 = 0;
|
||||
|
||||
LABEL_RETRY_FOR_OPENVPN:
|
||||
tran_id = Rand32();
|
||||
// Send a DHCP Discover
|
||||
Zero(&req, sizeof(req));
|
||||
req.RequestedIp = request_ip;
|
||||
req.RequestedIp = 0;
|
||||
req.Opcode = DHCP_DISCOVER;
|
||||
StrCpy(req.Hostname, sizeof(req.Hostname), ipc->ClientHostname);
|
||||
IPCDhcpSetConditionalUserClass(ipc, &req);
|
||||
@ -831,7 +812,7 @@ LABEL_RETRY_FOR_OPENVPN:
|
||||
d = IPCSendDhcpRequest(ipc, NULL, tran_id, &req, DHCP_OFFER, IPC_DHCP_TIMEOUT, discon_poll_tube);
|
||||
if (d == NULL)
|
||||
{
|
||||
goto LABEL_CLEANUP;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Analyze the DHCP Offer
|
||||
@ -860,75 +841,7 @@ LABEL_RETRY_FOR_OPENVPN:
|
||||
if (ok == false)
|
||||
{
|
||||
FreeDHCPv4Data(d);
|
||||
goto LABEL_CLEANUP;
|
||||
}
|
||||
|
||||
if (openvpn_compatible)
|
||||
{
|
||||
UINT ip = d->ParsedOptionList->ClientAddress;
|
||||
|
||||
if (OvsIsCompatibleL3IP(ip) == false)
|
||||
{
|
||||
char tmp[64];
|
||||
|
||||
DHCP_OPTION_LIST req;
|
||||
IPC_DHCP_RELEASE_QUEUE *q;
|
||||
|
||||
// If the offered IP address is not used, place the address
|
||||
// in release memo list to release at the end of this function
|
||||
Zero(&req, sizeof(req));
|
||||
req.Opcode = DHCP_RELEASE;
|
||||
req.ServerAddress = d->ParsedOptionList->ServerAddress;
|
||||
|
||||
q = ZeroMalloc(sizeof(IPC_DHCP_RELEASE_QUEUE));
|
||||
Copy(&q->Req, &req, sizeof(DHCP_OPTION_LIST));
|
||||
q->TranId = tran_id;
|
||||
Copy(q->MacAddress, ipc->MacAddress, 6);
|
||||
|
||||
Add(release_list, q);
|
||||
|
||||
FreeDHCPv4Data(d);
|
||||
|
||||
if (Tick64() >= giveup)
|
||||
{
|
||||
goto LABEL_CLEANUP;
|
||||
}
|
||||
|
||||
if (IsZero(¤t_scanning_ip, sizeof(IP)))
|
||||
{
|
||||
UINTToIP(¤t_scanning_ip, ip);
|
||||
current_scanning_addr8 = current_scanning_ip.addr[3];
|
||||
|
||||
if ((current_scanning_addr8 % 4) != 1)
|
||||
{
|
||||
current_scanning_addr8 = (UCHAR)(((((UINT)current_scanning_addr8 - 1) / 4) + 1) * 4 + 1);
|
||||
}
|
||||
|
||||
begin_scanning_addr8 = current_scanning_addr8;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_scanning_addr8 += 4;
|
||||
|
||||
if (current_scanning_addr8 == begin_scanning_addr8)
|
||||
{
|
||||
goto LABEL_CLEANUP;
|
||||
}
|
||||
}
|
||||
|
||||
current_scanning_ip.addr[3] = current_scanning_addr8;
|
||||
|
||||
request_ip = IPToUINT(¤t_scanning_ip);
|
||||
|
||||
IPToStr32(tmp, sizeof(tmp), request_ip);
|
||||
|
||||
// Generate another MAC address
|
||||
ipc->MacAddress[5]++;
|
||||
|
||||
Debug("Trying Allocating IP for OpenVPN: %s\n", tmp);
|
||||
|
||||
goto LABEL_RETRY_FOR_OPENVPN;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a DHCP Request
|
||||
@ -943,7 +856,7 @@ LABEL_RETRY_FOR_OPENVPN:
|
||||
if (d2 == NULL)
|
||||
{
|
||||
FreeDHCPv4Data(d);
|
||||
goto LABEL_CLEANUP;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Analyze the DHCP Ack
|
||||
@ -973,7 +886,7 @@ LABEL_RETRY_FOR_OPENVPN:
|
||||
{
|
||||
FreeDHCPv4Data(d);
|
||||
FreeDHCPv4Data(d2);
|
||||
goto LABEL_CLEANUP;
|
||||
return false;
|
||||
}
|
||||
|
||||
Copy(opt, d2->ParsedOptionList, sizeof(DHCP_OPTION_LIST));
|
||||
@ -981,34 +894,7 @@ LABEL_RETRY_FOR_OPENVPN:
|
||||
FreeDHCPv4Data(d);
|
||||
FreeDHCPv4Data(d2);
|
||||
|
||||
ret = true;
|
||||
|
||||
LABEL_CLEANUP:
|
||||
if (release_list != NULL)
|
||||
{
|
||||
// Release the IP address that was acquired from the DHCP server to no avail on the way
|
||||
UINT i;
|
||||
UCHAR mac_backup[6];
|
||||
|
||||
Copy(mac_backup, ipc->MacAddress, 6);
|
||||
|
||||
for (i = 0;i < LIST_NUM(release_list);i++)
|
||||
{
|
||||
IPC_DHCP_RELEASE_QUEUE *q = LIST_DATA(release_list, i);
|
||||
|
||||
Copy(ipc->MacAddress, q->MacAddress, 6);
|
||||
FreeDHCPv4Data(IPCSendDhcpRequest(ipc, NULL, q->TranId, &q->Req, 0, 0, NULL));
|
||||
|
||||
IPCProcessInterrupts(ipc);
|
||||
|
||||
Free(q);
|
||||
}
|
||||
|
||||
Copy(ipc->MacAddress, mac_backup, 6);
|
||||
|
||||
ReleaseList(release_list);
|
||||
}
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send out a DHCP request, and wait for a corresponding response
|
||||
|
@ -118,7 +118,6 @@
|
||||
#define IPC_ARP_LIFETIME (3 * 60 * 1000)
|
||||
#define IPC_ARP_GIVEUPTIME (1 * 1000)
|
||||
#define IPC_DHCP_TIMEOUT (5 * 1000)
|
||||
#define IPC_DHCP_TIMEOUT_TOTAL_GIVEUP (20 * 1000)
|
||||
#define IPC_DHCP_MIN_LEASE 5
|
||||
#define IPC_DHCP_DEFAULT_LEASE 3600
|
||||
|
||||
@ -164,7 +163,6 @@ struct IPC_PARAM
|
||||
bool BridgeMode;
|
||||
UINT Mss;
|
||||
bool IsL3Mode;
|
||||
bool IsOpenVPN;
|
||||
X *ClientCertificate;
|
||||
};
|
||||
|
||||
@ -256,7 +254,6 @@ DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION
|
||||
BUF *IPCBuildDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION_LIST *opt);
|
||||
BUF *IPCBuildDhcpRequestOptions(IPC *ipc, DHCP_OPTION_LIST *opt);
|
||||
bool IPCDhcpAllocateIP(IPC *ipc, DHCP_OPTION_LIST *opt, TUBE *discon_poll_tube);
|
||||
bool IPCDhcpAllocateIPEx(IPC *ipc, DHCP_OPTION_LIST *opt, TUBE *discon_poll_tube, bool openvpn_compatible);
|
||||
bool IPCDhcpRequestInformIP(IPC *ipc, DHCP_OPTION_LIST *opt, TUBE *discon_poll_tube, IP *client_ip);
|
||||
void IPCDhcpRenewIP(IPC *ipc, IP *dhcp_server);
|
||||
void IPCDhcpFreeIP(IPC *ipc, IP *dhcp_server);
|
||||
|
@ -720,8 +720,6 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O
|
||||
p.ClientCertificate = c->ClientCert.X;
|
||||
}
|
||||
|
||||
p.IsOpenVPN = true;
|
||||
|
||||
// Calculate the MSS
|
||||
p.Mss = OvsCalcTcpMss(s, se, c);
|
||||
Debug("MSS=%u\n", p.Mss);
|
||||
@ -1984,9 +1982,6 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
|
||||
// if the L3 mode to the option character string
|
||||
DHCP_OPTION_LIST *cao = &se->IpcAsync->L3ClientAddressOption;
|
||||
char ip_client[64];
|
||||
char ip_tunnel_endpoint[64];
|
||||
UINT ip_tunnel_endpoint_32;
|
||||
char ip_network[64];
|
||||
char ip_subnet_mask[64];
|
||||
char ip_dns1[64];
|
||||
char ip_dns2[64];
|
||||
@ -2003,25 +1998,17 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
|
||||
IPToStr32(ip_client, sizeof(ip_client),
|
||||
cao->ClientAddress);
|
||||
|
||||
// Generate a virtual gateway address to be passed to the OpenVPN
|
||||
ip_tunnel_endpoint_32 = Endian32(cao->ClientAddress);
|
||||
ip_tunnel_endpoint_32++;
|
||||
ip_tunnel_endpoint_32 = Endian32(ip_tunnel_endpoint_32);
|
||||
IPToStr32(ip_tunnel_endpoint, sizeof(ip_tunnel_endpoint), ip_tunnel_endpoint_32);
|
||||
|
||||
// Create a subnet information for the LAN
|
||||
IPToStr32(ip_network, sizeof(ip_network),
|
||||
GetNetworkAddress(cao->ClientAddress,
|
||||
cao->SubnetMask));
|
||||
|
||||
IPToStr32(ip_subnet_mask, sizeof(ip_subnet_mask),
|
||||
cao->SubnetMask);
|
||||
|
||||
Format(l3_options, sizeof(l3_options),
|
||||
",topology subnet");
|
||||
StrCat(option_str, sizeof(option_str), l3_options);
|
||||
|
||||
Format(l3_options, sizeof(l3_options),
|
||||
",ifconfig %s %s",
|
||||
// ",ifconfig %s %s,route %s %s %s 1",
|
||||
ip_client, ip_tunnel_endpoint, ip_network, ip_subnet_mask,
|
||||
ip_tunnel_endpoint);
|
||||
ip_client,
|
||||
ip_subnet_mask);
|
||||
StrCat(option_str, sizeof(option_str), l3_options);
|
||||
|
||||
// Domain name
|
||||
@ -2083,11 +2070,13 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
|
||||
// Default gateway
|
||||
if (cao->Gateway != 0)
|
||||
{
|
||||
char ip_str[64];
|
||||
IPToStr32(ip_str, sizeof(ip_str), cao->Gateway);
|
||||
Format(l3_options, sizeof(l3_options),
|
||||
",route-gateway %s,redirect-gateway def1", ip_tunnel_endpoint);
|
||||
",route-gateway %s,redirect-gateway def1", ip_str);
|
||||
StrCat(option_str, sizeof(option_str), l3_options);
|
||||
|
||||
IPToStr32(ip_defgw, sizeof(ip_defgw), cao->Gateway);
|
||||
StrCpy(ip_defgw, sizeof(ip_defgw), ip_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2542,20 +2531,6 @@ int OvsCompareSessionList(void *p1, void *p2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Identify whether the IP address is compatible to the tun device of OpenVPN
|
||||
bool OvsIsCompatibleL3IP(UINT ip)
|
||||
{
|
||||
IP p;
|
||||
|
||||
UINTToIP(&p, ip);
|
||||
if ((p.addr[3] % 4) == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a new OpenVPN server
|
||||
OPENVPN_SERVER *NewOpenVpnServer(CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event)
|
||||
{
|
||||
|
@ -364,7 +364,6 @@ void OvsFreeList(LIST *o);
|
||||
bool OvsHasEntry(LIST *o, char *key);
|
||||
UINT OvsPeekStringFromFifo(FIFO *f, char *str, UINT str_size);
|
||||
void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c);
|
||||
bool OvsIsCompatibleL3IP(UINT ip);
|
||||
UINT OvsCalcTcpMss(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c);
|
||||
|
||||
CIPHER *OvsGetCipher(char *name);
|
||||
|
Loading…
Reference in New Issue
Block a user