fix: Showing wrong IP while using Reverse Proxy

This commit is contained in:
yuanyuanxiang
2025-06-28 16:50:01 +08:00
parent 659f820fd1
commit 9aa5d589c4
11 changed files with 243 additions and 220 deletions

View File

@@ -23,7 +23,7 @@
#include "InputDlg.h"
#include "CPasswordDlg.h"
#include "pwd_gen.h"
#include "parse_ip.h"
#include "common/location.h"
#include <proxy/ProxyMapDlg.h>
#include "DateVerify.h"
#include <fstream>
@@ -597,7 +597,11 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
bool modify = false;
CString loc = GetClientMapData(id, MAP_LOCATION);
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()) {
modify = true;
SetClientMapData(id, MAP_LOCATION, loc);
@@ -611,15 +615,16 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
if (modify)
SaveToFile(m_ClientMap, GetDbPath());
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++) {
n == ONLINELIST_COMPUTER_NAME ?
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.SetItemData(i,(DWORD_PTR)ContextObject);
ShowMessage("操作成功",strIP+"主机上线");
std::string tip = flag ? " (" + v[RES_CLIENT_PUBIP] + ") " : "";
ShowMessage("操作成功",strIP + tip.c_str() + "主机上线");
LeaveCriticalSection(&m_cs);
SendMasterSettings(ContextObject);
@@ -835,7 +840,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
#else
SetTimer(TIMER_CHECK, 600 * 1000, NULL);
#endif
CString tip = !ip.empty() && ip != getPublicIP() ?
IPConverter cvt;
CString tip = !ip.empty() && ip != cvt.getPublicIP() ?
CString(ip.c_str()) + " 必须是\"公网IP\"或反向代理服务器IP":
"请设置\"公网IP\"或使用反向代理服务器的IP";
ShowMessage("使用提示", tip);

View File

@@ -273,7 +273,6 @@
<ClInclude Include="InputDlg.h" />
<ClInclude Include="IOCPServer.h" />
<ClInclude Include="KeyBoardDlg.h" />
<ClInclude Include="parse_ip.h" />
<ClInclude Include="proxy\HPSocket.h" />
<ClInclude Include="proxy\HPTypeDef.h" />
<ClInclude Include="proxy\ProxyConnectServer.h" />
@@ -337,7 +336,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="parse_ip.cpp" />
<ClCompile Include="proxy\ProxyConnectServer.cpp" />
<ClCompile Include="proxy\ProxyMapDlg.cpp" />
<ClCompile Include="pwd_gen.cpp">

View File

@@ -6,7 +6,7 @@
#include "SettingDlg.h"
#include "afxdialogex.h"
#include "client/CursorInfo.h"
#include "parse_ip.h"
#include "common/location.h"
// CSettingDlg <20>Ի<EFBFBD><D4BB><EFBFBD>
@@ -63,8 +63,9 @@ END_MESSAGE_MAP()
BOOL CSettingDlg::OnInitDialog()
{
CDialog::OnInitDialog();
IPConverter cvt;
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");
//<2F><>ȡini <20>ļ<EFBFBD><C4BC>еļ<D0B5><C4BC><EFBFBD><EFBFBD>˿<EFBFBD>
int nMaxConnection = THIS_CFG.GetInt("settings", "MaxConnection");

View File

@@ -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 = "";
}
}

View File

@@ -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);

View File

@@ -531,7 +531,7 @@ void CMachineDlg::ShowNetStateList()
if (!IPAddress.Compare(_T("0.0.0.0")) || !IPAddress.Compare(_T("*.*.*.*"))) {
str = _T("---");
} else {
str = m_IPConverter->IPtoAddress(IPAddress);
str = m_IPConverter->IPtoAddress(IPAddress.GetString()).c_str();
}
m_list.SetItemText(i, j, str);
}

View File

@@ -7,11 +7,7 @@
// CMachineDlg dialog
// TODO: ʵ<><CAB5>IP<49><50>ȡ.
class IPConverter
{
public:
CString IPtoAddress(const CString& ip) { return "implement me"; }
};
#include "common/location.h"
class CMachineDlg : public DialogBase