diff --git a/src/Cedar/IPC.c b/src/Cedar/IPC.c index 47ad93cb..59c17e5e 100644 --- a/src/Cedar/IPC.c +++ b/src/Cedar/IPC.c @@ -116,20 +116,20 @@ void IPCAsyncThreadProc(THREAD *thread, void *param) if (a->Ipc != NULL) { - if (a->Param.IsL3Mode) + if (a->Param.DisableDhcp == false) { DHCP_OPTION_LIST cao; Zero(&cao, sizeof(cao)); - // Get an IP address from the DHCP server in the case of L3 mode - Debug("IPCDhcpAllocateIP() start...\n"); + // Get an IP address from the DHCP server + Debug("IPCAsyncThreadProc(): DHCP operation in progress...\n"); if (IPCDhcpAllocateIP(a->Ipc, &cao, a->TubeForDisconnect)) { UINT t; IP ip, subnet, gw; - Debug("IPCDhcpAllocateIP() Ok.\n"); + Debug("IPCAsyncThreadProc(): IPCDhcpAllocateIP() succeeded.\n"); // Calculate the DHCP update interval t = cao.LeaseTime; @@ -146,8 +146,8 @@ void IPCAsyncThreadProc(THREAD *thread, void *param) } // Save the options list - Copy(&a->L3ClientAddressOption, &cao, sizeof(DHCP_OPTION_LIST)); - a->L3DhcpRenewInterval = t * 1000; + Copy(&a->DhcpOptionList, &cao, sizeof(DHCP_OPTION_LIST)); + a->DhcpRenewInterval = t * 1000; // Set the obtained IP address parameters to the IPC virtual host UINTToIP(&ip, cao.ClientAddress); @@ -156,11 +156,11 @@ void IPCAsyncThreadProc(THREAD *thread, void *param) IPCSetIPv4Parameters(a->Ipc, &ip, &subnet, &gw, &cao.ClasslessRoute); - a->L3NextDhcpRenewTick = Tick64() + a->L3DhcpRenewInterval; + a->DhcpNextRenewTick = Tick64() + a->DhcpRenewInterval; } else { - Debug("IPCDhcpAllocateIP() Error.\n"); + Debug("IPCAsyncThreadProc(): IPCDhcpAllocateIP() failed.\n"); a->DhcpAllocFailed = true; diff --git a/src/Cedar/IPC.h b/src/Cedar/IPC.h index 0aa25b4a..76112c6f 100644 --- a/src/Cedar/IPC.h +++ b/src/Cedar/IPC.h @@ -66,8 +66,8 @@ struct IPC_PARAM char ClientHostname[MAX_SIZE]; char CryptName[MAX_SIZE]; bool BridgeMode; + bool DisableDhcp; UINT Mss; - bool IsL3Mode; X *ClientCertificate; UINT Layer; }; @@ -83,9 +83,9 @@ struct IPC_ASYNC IPC *Ipc; // IPC object (if it fails to connect, the value is NULL) TUBE *TubeForDisconnect; // Tube for disconnection notification 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) - UINT64 L3DhcpRenewInterval; // DHCP update interval - UINT64 L3NextDhcpRenewTick; // DHCP renewal time of the next + DHCP_OPTION_LIST DhcpOptionList; // Client IP address option + UINT64 DhcpRenewInterval; // DHCP update interval + UINT64 DhcpNextRenewTick; // DHCP renewal time of the next bool DhcpAllocFailed; // Failed to get IP address from the DHCP server }; diff --git a/src/Cedar/Proto_OpenVPN.c b/src/Cedar/Proto_OpenVPN.c index c6acc5fa..9a12ccc0 100644 --- a/src/Cedar/Proto_OpenVPN.c +++ b/src/Cedar/Proto_OpenVPN.c @@ -1073,18 +1073,12 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O 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); - if (se->Mode == OPENVPN_MODE_L3) - { - // L3 Mode - p.IsL3Mode = true; - } - else - { - // L2 Mode - p.BridgeMode = true; - } + p.BridgeMode = se->Mode == OPENVPN_MODE_L2; if (IsEmptyStr(c->ClientKey.Username) || IsEmptyStr(c->ClientKey.Password)) { @@ -2156,7 +2150,7 @@ void OvsFreeSession(OPENVPN_SESSION *se) { IP dhcp_ip; - UINTToIP(&dhcp_ip, se->IpcAsync->L3ClientAddressOption.ServerAddress); + UINTToIP(&dhcp_ip, se->IpcAsync->DhcpOptionList.ServerAddress); IPCDhcpFreeIP(se->Ipc, &dhcp_ip); IPCProcessL3Events(se->Ipc); @@ -2312,7 +2306,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) if (se->IpcAsync->Ipc != NULL) { char option_str[4096]; - char l3_options[MAX_SIZE]; + char option[MAX_SIZE]; // Successful in VPN connection Debug("OpenVPN Channel %u Established (new key).\n", j); @@ -2324,11 +2318,11 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) (OPENVPN_PING_SEND_INTERVAL / 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 // 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_subnet_mask[64]; char ip_dns1[64]; @@ -2349,22 +2343,22 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) IPToStr32(ip_subnet_mask, sizeof(ip_subnet_mask), cao->SubnetMask); - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",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", ip_client, ip_subnet_mask); - StrCat(option_str, sizeof(option_str), l3_options); + StrCat(option_str, sizeof(option_str), option); // Domain name if (IsEmptyStr(cao->DomainName) == false) { - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",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 @@ -2372,9 +2366,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) { char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer); - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",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); } @@ -2384,9 +2378,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) { char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->DnsServer2); - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",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); } @@ -2396,9 +2390,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) { char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer); - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",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); } @@ -2408,9 +2402,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) { char ip_str[64]; IPToStr32(ip_str, sizeof(ip_str), cao->WinsServer2); - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",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); } @@ -2420,9 +2414,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) { char ip_str[64]; 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); - StrCat(option_str, sizeof(option_str), l3_options); + StrCat(option_str, sizeof(option_str), option); StrCpy(ip_defgw, sizeof(ip_defgw), ip_str); } @@ -2441,12 +2435,12 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) Zero(&local_network, sizeof(IP)); IPAnd4(&local_network, &client_ip, &subnet_mask); - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",route %r %r vpn_gateway", &local_network, &cao->SubnetMask); - StrCat(option_str, sizeof(option_str), l3_options); + StrCat(option_str, sizeof(option_str), option); #endif } @@ -2460,11 +2454,11 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) if (r->Exists) { - Format(l3_options, sizeof(l3_options), + Format(option, sizeof(option), ",route %r %r vpn_gateway", &r->Network, &r->SubnetMask); - StrCat(option_str, sizeof(option_str), l3_options); + StrCat(option_str, sizeof(option_str), option); } } } @@ -2472,7 +2466,7 @@ 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 + 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 // on Linux, the TAP device must be up after the OpenVPN client is connected. @@ -2639,23 +2633,22 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol) 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 - 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); } diff --git a/src/bin/hamcore/openvpn_sample.ovpn b/src/bin/hamcore/openvpn_sample.ovpn index 5533fda3..5886d486 100644 --- a/src/bin/hamcore/openvpn_sample.ovpn +++ b/src/bin/hamcore/openvpn_sample.ovpn @@ -29,14 +29,25 @@ ;setenv UV_HOSTNAME Hostname +############################################################################### +# Disable DHCP setting. +# +# Uncomment the line if you don't want the server to send network settings to +# the client. The virtual network adapter's IP address has to be set manually, +# unless you are on Windows, which gets it automatically using DHCP. + +;setenv UV_NO_DHCP + + ############################################################################### # Push extra info about the client to the server. # # The server currently uses: # IV_HWADDR = Default gateway's MAC Address # UV_HOSTNAME = Custom hostname +# UV_NO_DHCP = Setting to disable DHCP # -# They are required in order to set an hostname for the client. +# IV_HWADDR and UV_HOSTNAME are used to set an hostname for the client. push-peer-info