summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/login/login.cpp33
-rwxr-xr-xtools/config.py2
2 files changed, 34 insertions, 1 deletions
diff --git a/src/login/login.cpp b/src/login/login.cpp
index 49c2438..c8a44c2 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -139,7 +139,6 @@ struct mmo_account
SEX sex;
};
-
//------------------------------
// Writing function of logs file
//------------------------------
@@ -165,6 +164,14 @@ void delete_login(Session *sess)
(void)sess;
}
+std::vector<IP4Address> recent_ips;
+
+static
+void conn_limit_empty(TimerData *, tick_t)
+{
+ recent_ips.clear();
+}
+
static
void delete_fromchar(Session *sess)
{
@@ -2413,6 +2420,22 @@ void parse_login(Session *s)
break;
}
+ if (login_conf.conn_limit_enable && !login_lan_conf.lan_subnet.covers(ip))
+ {
+ if (std::find(recent_ips.begin(), recent_ips.end(), ip) != recent_ips.end())
+ {
+ LOGIN_LOG_AND_ECHO("Connection refused: Login request flood detected. (REJECTED IP: %s)\n"_fmt, ip);
+ Packet_Fixed<0x0081> fixed_81;
+ fixed_81.error_code = 2; // already logged in (for lack of better error message)
+ send_fpacket<0x0081, 3>(s, fixed_81);
+ break;
+ }
+ else
+ {
+ recent_ips.push_back(ip);
+ }
+ }
+
result = mmo_auth(&account, s);
if (result == 1)
{
@@ -3088,6 +3111,14 @@ int do_init(Slice<ZString> argv)
).detach();
}
+ if (login::login_conf.conn_limit_enable)
+ {
+ Timer(gettick() + 1_s,
+ login::conn_limit_empty,
+ login::login_conf.conn_limit_interval
+ ).detach();
+ }
+
// add timer to check GM accounts file modification
std::chrono::seconds j = login::login_conf.gm_account_filename_check_timer;
if (j == interval_t::zero())
diff --git a/tools/config.py b/tools/config.py
index 0892973..f029777 100755
--- a/tools/config.py
+++ b/tools/config.py
@@ -523,6 +523,8 @@ def build_config():
login_conf.opt('main_server', ServerName, '{}')
login_conf.opt('userid', AccountName, '{}')
login_conf.opt('passwd', AccountPass, '{}')
+ login_conf.opt('conn_limit_enable', bool, 'true')
+ login_conf.opt('conn_limit_interval', seconds, '5_s')
admin_conf.opt('login_ip', IP4Address, 'IP4_LOCALHOST')