Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cedar/Protocol.c')
-rw-r--r--src/Cedar/Protocol.c236
1 files changed, 211 insertions, 25 deletions
diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c
index ff48382b..2fc3c22b 100644
--- a/src/Cedar/Protocol.c
+++ b/src/Cedar/Protocol.c
@@ -9392,6 +9392,10 @@ char *WsErrorCodeToString(UINT err)
case ERR_MSCHAP2_PASSWORD_NEED_RESET:
ret = "e_user_password_must_reset";
break;
+
+ case ERR_DHCP_SERVER_NOT_RUNNING:
+ ret = "e_dhcp_server_not_running";
+ break;
}
return ret;
}
@@ -9419,6 +9423,18 @@ UINT MvpnDoAccept(CONNECTION *c, WS *w)
UINT client_udp_acceleration_port = 0;
UCHAR client_udp_acceleration_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V2] = {0};
UDP_ACCEL *udp_accel = NULL;
+ bool l3_ipv4_enable = false;
+ bool l3_ipv4_dynamic = false;
+ IP l3_ipv4_ip = {0};
+ IP l3_ipv4_mask = {0};
+ IP l3_ipv4_gw = {0};
+ IP l3_ipv4_dns1 = {0};
+ IP l3_ipv4_dns2 = {0};
+ IP l3_ipv4_wins1 = {0};
+ IP l3_ipv4_wins2 = {0};
+ IP l3_ipv4_dhcp_server = {0};
+ char l3_ipv4_classless_routes[4096] = {0};
+ bool l3_ipv4_dhcp_allocated = false;
if (c == NULL || w == NULL)
{
@@ -9478,6 +9494,40 @@ UINT MvpnDoAccept(CONNECTION *c, WS *w)
Zero(client_hub_name, sizeof(client_hub_name));
PackGetStr(client_hello, "NetworkName", client_hub_name, sizeof(client_hub_name));
+ l3_ipv4_enable = PackGetBool(client_hello, "L3HelperIPv4Enable");
+ if (l3_ipv4_enable)
+ {
+ char tmp[256];
+ bool ok = false;
+
+ PackGetStr(client_hello, "L3HelperIPv4AddressType", tmp, sizeof(tmp));
+
+ if (StrCmpi(tmp, MVPN_ADDRESS_TYPE_STATIC) == 0)
+ {
+ // Static IP address
+ l3_ipv4_dynamic = false;
+
+ if (PackGetIp(client_hello, "L3HelperIPv4Address", &l3_ipv4_ip) &&
+ PackGetIp(client_hello, "L3HelperIPv4SubnetMask", &l3_ipv4_mask) &&
+ PackGetIp(client_hello, "L3HelperIPv4Gateway", &l3_ipv4_gw))
+ {
+ ok = true;
+ }
+ }
+ else if (StrCmpi(tmp, MVPN_ADDRESS_TYPE_DYNAMIC) == 0)
+ {
+ // Dynamic IP address
+ l3_ipv4_dynamic = true;
+ ok = true;
+ }
+
+ if (ok == false)
+ {
+ ret = ERR_PROTOCOL_ERROR;
+ goto LABEL_CLEANUP;
+ }
+ }
+
// Phase 2: Send a Server Hello packet
server_hello = WsNewErrorPack(ERR_NO_ERROR);
StrCpy(server_impl, sizeof(server_impl), "Test Server");
@@ -9613,6 +9663,49 @@ LABEL_EXIT_AUTH_RETRY:
"Transport", "TCP_WebSocket");
}
+ if (ipc != NULL && l3_ipv4_enable)
+ {
+ // L3 IPv4 helper is enabled
+ if (l3_ipv4_dynamic == false)
+ {
+ // Static IP
+ IPCSetIPv4Parameters(ipc, &l3_ipv4_ip, &l3_ipv4_mask,
+ &l3_ipv4_gw, NULL);
+ }
+ else
+ {
+ // Dynamic IP
+ DHCP_OPTION_LIST cao;
+
+ Zero(&cao, sizeof(cao));
+
+ if (IPCDhcpAllocateIP(ipc, &cao, NULL) == false)
+ {
+ // DHCP alloc failed
+ ret = ERR_DHCP_SERVER_NOT_RUNNING;
+ goto LABEL_CLEANUP;
+ }
+
+ l3_ipv4_dhcp_allocated = true;
+
+ UINTToIP(&l3_ipv4_dhcp_server, cao.ServerAddress);
+
+ UINTToIP(&l3_ipv4_ip, cao.ClientAddress);
+ UINTToIP(&l3_ipv4_mask, cao.SubnetMask);
+ UINTToIP(&l3_ipv4_gw, cao.Gateway);
+ UINTToIP(&l3_ipv4_dns1, cao.DnsServer);
+ UINTToIP(&l3_ipv4_dns2, cao.DnsServer2);
+ UINTToIP(&l3_ipv4_wins1, cao.WinsServer);
+ UINTToIP(&l3_ipv4_wins2, cao.WinsServer2);
+
+ BuildClasslessRouteTableStr(l3_ipv4_classless_routes, sizeof(l3_ipv4_classless_routes),
+ &cao.ClasslessRoute);
+
+ IPCSetIPv4Parameters(ipc, &l3_ipv4_ip, &l3_ipv4_mask,
+ &l3_ipv4_gw, &cao.ClasslessRoute);
+ }
+ }
+
if (ipc != NULL && use_udp_acceleration)
{
udp_accel = NewUdpAccel(c->Cedar, (c->FirstSock->IsRUDPSocket ? NULL : &c->FirstSock->LocalIP),
@@ -9638,6 +9731,7 @@ LABEL_EXIT_AUTH_RETRY:
PackAddInt(ok_pack, "HeartBeatInterval", heartbeat_interval);
PackAddInt(ok_pack, "DisconnectTimeout", disconnect_timeout);
PackAddStr(ok_pack, "NetworkName", ipc->HubName);
+
if (udp_accel != NULL)
{
PackAddBool(ok_pack, "UseUdpAcceleration", true);
@@ -9651,6 +9745,23 @@ LABEL_EXIT_AUTH_RETRY:
{
PackAddBool(ok_pack, "UseUdpAcceleration", false);
}
+
+ PackAddBool(ok_pack, "L3HelperIPv4Enable", l3_ipv4_enable);
+
+ if (l3_ipv4_enable)
+ {
+ PackAddStr(ok_pack, "L3HelperIPv4AddressType",
+ l3_ipv4_dynamic ? MVPN_ADDRESS_TYPE_DYNAMIC : MVPN_ADDRESS_TYPE_STATIC);
+ PackAddIp(ok_pack, "L3HelperIPv4Address", &l3_ipv4_ip);
+ PackAddIp(ok_pack, "L3HelperIPv4SubnetMask", &l3_ipv4_mask);
+ PackAddIp(ok_pack, "L3HelperIPv4Gateway", &l3_ipv4_gw);
+ PackAddIp(ok_pack, "L3HelperIPv4DnsServer1", &l3_ipv4_dns1);
+ PackAddIp(ok_pack, "L3HelperIPv4DnsServer2", &l3_ipv4_dns2);
+ PackAddIp(ok_pack, "L3HelperIPv4WinsServer1", &l3_ipv4_wins1);
+ PackAddIp(ok_pack, "L3HelperIPv4WinsServer2", &l3_ipv4_wins2);
+ PackAddStr(ok_pack, "L3HelperIPv4PushedStaticRoutes", l3_ipv4_classless_routes);
+ }
+
WsSendPack(w, ok_pack);
FreePack(ok_pack);
@@ -9711,36 +9822,85 @@ LABEL_EXIT_AUTH_RETRY:
}
// IPC --> send_fifo or UDP accelerator
- while (true)
+ if (l3_ipv4_enable == false)
{
- BLOCK *l2_packet = IPCRecvL2(ipc);
- UCHAR packet_type;
- USHORT packet_size;
- if (l2_packet == NULL)
- {
- break;
- }
- if (UdpAccelIsSendReady(udp_accel, true))
+ // Ethernet
+ while (true)
{
- // Send via UDP accelerator
- UdpAccelSend(udp_accel, l2_packet->Buf, l2_packet->Size,
- MVPN_PACKET_TYPE_ETHERNET, udp_accel->MaxUdpPacketSize,
- false);
+ BLOCK *l2_packet = IPCRecvL2(ipc);
+ UCHAR packet_type;
+ USHORT packet_size;
+ if (l2_packet == NULL)
+ {
+ break;
+ }
+ if (UdpAccelIsSendReady(udp_accel, true))
+ {
+ // Send via UDP accelerator
+ UdpAccelSend(udp_accel, l2_packet->Buf, l2_packet->Size,
+ MVPN_PACKET_TYPE_ETHERNET, udp_accel->MaxUdpPacketSize,
+ false);
+ }
+ else
+ {
+ // Send via WebSocket
+ if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE)
+ {
+ packet_size = Endian16(l2_packet->Size);
+ packet_type = MVPN_PACKET_TYPE_ETHERNET;
+ WriteFifo(send_fifo, &magic_number, 4);
+ WriteFifo(send_fifo, &packet_type, 1);
+ WriteFifo(send_fifo, &packet_size, 2);
+ WriteFifo(send_fifo, l2_packet->Buf, (USHORT)l2_packet->Size);
+ }
+ }
+ FreeBlock(l2_packet);
}
- else
+ }
+ else
+ {
+ UINT num = 0;
+
+L_V4_RETRY:
+ // IPv4
+ IPCProcessL3Events(ipc);
+
+ while (true)
{
- // Send via WebSocket
- if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE)
+ BLOCK *l3_packet = IPCRecvIPv4(ipc);
+ UCHAR packet_type;
+ USHORT packet_size;
+ if (l3_packet == NULL)
+ {
+ num++;
+ if (num <= 1)
+ {
+ goto L_V4_RETRY;
+ }
+ break;
+ }
+ if (UdpAccelIsSendReady(udp_accel, true))
+ {
+ // Send via UDP accelerator
+ UdpAccelSend(udp_accel, l3_packet->Buf, l3_packet->Size,
+ MVPN_PACKET_TYPE_IPV4, udp_accel->MaxUdpPacketSize,
+ false);
+ }
+ else
{
- packet_size = Endian16(l2_packet->Size);
- packet_type = MVPN_PACKET_TYPE_ETHERNET;
- WriteFifo(send_fifo, &magic_number, 4);
- WriteFifo(send_fifo, &packet_type, 1);
- WriteFifo(send_fifo, &packet_size, 2);
- WriteFifo(send_fifo, l2_packet->Buf, (USHORT)l2_packet->Size);
+ // Send via WebSocket
+ if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE)
+ {
+ packet_size = Endian16(l3_packet->Size);
+ packet_type = MVPN_PACKET_TYPE_IPV4;
+ WriteFifo(send_fifo, &magic_number, 4);
+ WriteFifo(send_fifo, &packet_type, 1);
+ WriteFifo(send_fifo, &packet_size, 2);
+ WriteFifo(send_fifo, l3_packet->Buf, (USHORT)l3_packet->Size);
+ }
}
+ FreeBlock(l3_packet);
}
- FreeBlock(l2_packet);
}
// send_fifo --> MVPN Client
@@ -9819,7 +9979,17 @@ LABEL_EXIT_AUTH_RETRY:
if (packet_type == MVPN_PACKET_TYPE_ETHERNET)
{
- IPCSendL2(ipc, packet_data, packet_size);
+ if (l3_ipv4_enable == false)
+ {
+ IPCSendL2(ipc, packet_data, packet_size);
+ }
+ }
+ else if (packet_type == MVPN_PACKET_TYPE_IPV4)
+ {
+ if (l3_ipv4_enable)
+ {
+ IPCSendIPv4(ipc, packet_data, packet_size);
+ }
}
Free(packet_data);
@@ -9847,7 +10017,17 @@ LABEL_EXIT_AUTH_RETRY:
if (packet_type == MVPN_PACKET_TYPE_ETHERNET)
{
- IPCSendL2(ipc, packet_data, packet_size);
+ if (l3_ipv4_enable == false)
+ {
+ IPCSendL2(ipc, packet_data, packet_size);
+ }
+ }
+ else if (packet_type == MVPN_PACKET_TYPE_IPV4)
+ {
+ if (l3_ipv4_enable)
+ {
+ IPCSendIPv4(ipc, packet_data, packet_size);
+ }
}
FreeBlock(b);
@@ -9885,6 +10065,12 @@ LABEL_EXIT_AUTH_RETRY:
}
}
+ if (l3_ipv4_dhcp_allocated)
+ {
+ IPCDhcpFreeIP(ipc, &l3_ipv4_dhcp_server);
+ IPCProcessL3Events(ipc);
+ }
+
LABEL_CLEANUP:
if (ret != ERR_NO_ERROR)
{