Made various network parameters manually configurable.

This commit is contained in:
Exynox 2023-12-09 17:02:17 +02:00
parent 10bd4d5075
commit da120f69e0
3 changed files with 107 additions and 85 deletions

View File

@ -21,12 +21,24 @@
using std::string;
BYTE g_bChannel = 0;
// Networking
char g_szPublicBindIP[16] = "0.0.0.0";
char g_szPublicIP[16] = "0";
WORD mother_port = 50080;
int passes_per_sec = 25;
WORD db_port = 0;
char g_szInternalBindIP[16] = "0.0.0.0";
char g_szInternalIP[16] = "0";
WORD p2p_port = 50900;
char db_addr[ADDRESS_MAX_LEN + 1];
WORD db_port = 0;
char teen_addr[ADDRESS_MAX_LEN + 1] = {0};
WORD teen_port = 0;
// End of networking
BYTE g_bChannel = 0;
int passes_per_sec = 25;
int save_event_second_cycle = passes_per_sec * 120; // 3ºÐ
int ping_event_second_cycle = passes_per_sec * 60;
bool g_bNoMoreClient = false;
@ -49,8 +61,6 @@ BYTE guild_mark_min_level = 3;
bool no_wander = false;
int g_iUserLimit = 32768;
char g_szPublicIP[16] = "0";
char g_szInternalIP[16] = "0";
bool g_bSkillDisable = false;
int g_iFullUserCount = 1200;
int g_iBusyUserCount = 650;
@ -89,9 +99,6 @@ string g_stBlockDate = "30000705";
extern string g_stLocale;
char teen_addr[ADDRESS_MAX_LEN + 1] = {0};
WORD teen_port = 0;
int SPEEDHACK_LIMIT_COUNT = 50;
int SPEEDHACK_LIMIT_BONUS = 80;
int g_iSyncHackLimitCount = 20; // 10 -> 20 2013 09 11 CYH
@ -208,16 +215,44 @@ static void FN_log_adminpage()
dev_log(LOG_DEB0, "ADMIN_PAGE_PASSWORD = %s", g_stAdminPagePassword.c_str());
}
/**
* Checks if a given IPv4 address is in the Private Address Space as per RFC1918
* @param address
* @return True if address is private, false otherwise
*/
bool IsPrivateIP(const in_addr &address)
{
const auto CLASS_A_PRIVATE = inet_addr("10.0.0.0");
const auto CLASS_A_PRIVATE_NETMASK = inet_addr("255.0.0.0");
if ((address.s_addr & CLASS_A_PRIVATE_NETMASK) == CLASS_A_PRIVATE)
return true;
const auto CLASS_B_PRIVATE = inet_addr("172.16.0.0");
const auto CLASS_B_PRIVATE_NETMASK = inet_addr("255.240.0.0");
if ((address.s_addr & CLASS_B_PRIVATE_NETMASK) == CLASS_B_PRIVATE)
return true;
const auto CLASS_C_PRIVATE = inet_addr("192.168.0.0");
const auto CLASS_C_PRIVATE_NETMASK = inet_addr("255.255.0.0");
if ((address.s_addr & CLASS_C_PRIVATE_NETMASK) == CLASS_C_PRIVATE)
return true;
return false;
}
/**
* Retrieves the first private and public IP addresses and allocates them
* to g_szInternalIP and g_szPublicIP respectively
* @return True on success, false on system failure.
*/
bool GetIPInfo()
{
#ifndef __WIN32__
struct ifaddrs* ifaddrp = NULL;
ifaddrs* ifaddrp = nullptr;
if (0 != getifaddrs(&ifaddrp))
return false;
for( struct ifaddrs* ifap=ifaddrp ; NULL != ifap ; ifap = ifap->ifa_next )
for (ifaddrs* ifap = ifaddrp; ifap != nullptr; ifap = ifap->ifa_next)
{
struct sockaddr_in * sai = (struct sockaddr_in *) ifap->ifa_addr;
@ -225,68 +260,23 @@ bool GetIPInfo()
sai->sin_addr.s_addr == 0 || // ignore if address is 0.0.0.0
sai->sin_addr.s_addr == 16777343) // ignore if address is 127.0.0.1
continue;
#else
WSADATA wsa_data;
char host_name[100];
HOSTENT* host_ent;
int n = 0;
if (WSAStartup(0x0101, &wsa_data)) {
return false;
}
gethostname(host_name, sizeof(host_name));
host_ent = gethostbyname(host_name);
if (host_ent == NULL) {
return false;
}
for ( ; host_ent->h_addr_list[n] != NULL; ++n) {
struct sockaddr_in addr;
struct sockaddr_in* sai = &addr;
memcpy(&sai->sin_addr.s_addr, host_ent->h_addr_list[n], host_ent->h_length);
#endif
char * netip = inet_ntoa(sai->sin_addr);
if (!strncmp(netip, "192.168", 7)) // ignore if address is starting with 192
if (IsPrivateIP(sai->sin_addr) && g_szInternalIP[0] == '0')
{
strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
#ifndef __WIN32__
fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
fprintf(stderr, "INTERNAL_IP: %s\n", netip);
#endif
}
else if (!strncmp(netip, "10.", 3))
{
strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
#ifndef __WIN32__
fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
fprintf(stderr, "INTERNAL_IP: %s\n", netip);
#endif
char * ip = inet_ntoa(sai->sin_addr);
strlcpy(g_szInternalIP, ip, sizeof(g_szInternalIP));
fprintf(stderr, "Internal IP automatically configured: %s interface %s\n", ip, ifap->ifa_name);
}
else if (g_szPublicIP[0] == '0')
{
strlcpy(g_szPublicIP, netip, sizeof(g_szPublicIP));
#ifndef __WIN32__
fprintf(stderr, "PUBLIC_IP: %s interface %s\n", netip, ifap->ifa_name);
#else
fprintf(stderr, "PUBLIC_IP: %s\n", netip);
#endif
char * ip = inet_ntoa(sai->sin_addr);
strlcpy(g_szPublicIP, ip, sizeof(g_szPublicIP));
fprintf(stderr, "Public IP automatically configured: %s interface %s\n", ip, ifap->ifa_name);
}
}
#ifndef __WIN32__
freeifaddrs( ifaddrp );
#else
WSACleanup();
#endif
if (g_szPublicIP[0] != '0')
freeifaddrs(ifaddrp);
return true;
else
return false;
}
void config_init(const string& st_localeServiceName)
@ -318,7 +308,7 @@ void config_init(const string& st_localeServiceName)
if (!GetIPInfo())
{
fprintf(stderr, "Can not get public ip address\n");
fprintf(stderr, "Failure in retrieving IP address information!\n");
exit(1);
}
@ -699,12 +689,6 @@ void config_init(const string& st_localeServiceName)
continue;
}
TOKEN("port")
{
str_to_number(mother_port, value_string);
continue;
}
TOKEN("log_keep_days")
{
int i = 0;
@ -719,6 +703,36 @@ void config_init(const string& st_localeServiceName)
continue;
}
TOKEN("public_ip")
{
strlcpy(g_szPublicIP, value_string, sizeof(g_szPublicIP));
continue;
}
TOKEN("public_bind_ip")
{
strlcpy(g_szPublicBindIP, value_string, sizeof(g_szPublicBindIP));
continue;
}
TOKEN("port")
{
str_to_number(mother_port, value_string);
continue;
}
TOKEN("internal_ip")
{
strlcpy(g_szInternalIP, value_string, sizeof(g_szInternalIP));
continue;
}
TOKEN("internal_bind_ip")
{
strlcpy(g_szInternalBindIP, value_string, sizeof(g_szInternalBindIP));
continue;
}
TOKEN("p2p_port")
{
str_to_number(p2p_port, value_string);
@ -970,11 +984,6 @@ void config_init(const string& st_localeServiceName)
g_strWebMallURL = value_string;
}
TOKEN("bind_ip")
{
strlcpy(g_szPublicIP, value_string, sizeof(g_szPublicIP));
}
TOKEN("view_range")
{
str_to_number(VIEW_RANGE, value_string);

View File

@ -9,9 +9,12 @@ enum
void config_init(const std::string& st_localeServiceName); // default "" is CONFIG
extern char sql_addr[256];
extern char g_szPublicBindIP[16];
extern char g_szPublicIP[16];
extern WORD mother_port;
extern char g_szInternalBindIP[16];
extern char g_szInternalIP[16];
extern WORD p2p_port;
extern char db_addr[ADDRESS_MAX_LEN + 1];
@ -49,9 +52,6 @@ extern std::string g_stHostname;
extern std::string g_stLocale;
extern std::string g_stLocaleFilename;
extern char g_szPublicIP[16];
extern char g_szInternalIP[16];
extern int (*is_twobyte) (const char * str);
extern int (*check_name) (const char * str);

View File

@ -615,6 +615,17 @@ int start(int argc, char **argv)
signal_timer_disable();
// Initialize the network stack
// Check if the public and internal IP addresses were configured
if (g_szInternalIP[0] == '0') {
fprintf(stderr, "Public IP address could not be automatically detected. Manually set the IP and try again.");
return 0;
}
if (g_szPublicIP[0] == '0') {
fprintf(stderr, "Public IP address could not be automatically detected. Manually set the IP and try again.");
return 0;
}
// Create a new libevent base and listen for new connections
ev_base = event_base_new();
if (!ev_base) {
@ -632,7 +643,7 @@ int start(int argc, char **argv)
// Main TCP listener
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(g_szPublicIP);
sin.sin_addr.s_addr = inet_addr(g_szPublicBindIP);
sin.sin_port = htons(mother_port);
tcp_listener = evconnlistener_new_bind(
@ -645,11 +656,12 @@ int start(int argc, char **argv)
sys_err("TCP listener initialization FAILED!");
return 0;
}
fprintf(stdout, "TCP listening on %s:%u\n", g_szPublicBindIP, mother_port);
evconnlistener_set_error_cb(tcp_listener, AcceptError);
// Game P2P listener
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(g_szPublicIP);
sin.sin_addr.s_addr = inet_addr(g_szInternalBindIP);
sin.sin_port = htons(p2p_port);
p2p_listener = evconnlistener_new_bind(
@ -662,6 +674,7 @@ int start(int argc, char **argv)
sys_err("P2P listener initialization FAILED!");
return 0;
}
fprintf(stdout, "P2P listening on %s:%u\n", g_szInternalBindIP, p2p_port);
evconnlistener_set_error_cb(p2p_listener, AcceptError);
// Create client connections