Fixed the connect and command DoS checkers to work more stably and not exclude too much. Resolves #779.
This commit is contained in:
parent
0b35279bc2
commit
cb0417fe7f
1 changed files with 29 additions and 14 deletions
|
|
@ -11,8 +11,11 @@ from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, PCONN
|
||||||
_MOD_IMPORT = None
|
_MOD_IMPORT = None
|
||||||
|
|
||||||
# throttles
|
# throttles
|
||||||
_MIN_TIME_BETWEEN_CONNECTS = 1.0 / float(settings.MAX_CONNECTION_RATE) if float(settings.MAX_CONNECTION_RATE) > 0 else 1.0 / 5.0
|
_MAX_CONNECTION_RATE = float(settings.MAX_CONNECTION_RATE)
|
||||||
_MIN_TIME_BETWEEN_CMDS = 1.0 / float(settings.MAX_COMMAND_RATE) if float(settings.MAX_COMMAND_RATE) > 0 else -10
|
_MAX_COMMAND_RATE = float(settings.MAX_COMMAND_RATE)
|
||||||
|
|
||||||
|
_MIN_TIME_BETWEEN_CONNECTS = 1.0 / float(settings.MAX_CONNECTION_RATE)
|
||||||
|
#_MIN_TIME_BETWEEN_COMMANDS = 1.0 / float(settings.MAX_COMMAND_RATE)
|
||||||
_ERROR_COMMAND_OVERFLOW = settings.COMMAND_RATE_WARNING
|
_ERROR_COMMAND_OVERFLOW = settings.COMMAND_RATE_WARNING
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
@ -40,7 +43,11 @@ class PortalSessionHandler(SessionHandler):
|
||||||
self.latest_sessid = 0
|
self.latest_sessid = 0
|
||||||
self.uptime = time()
|
self.uptime = time()
|
||||||
self.connection_time = 0
|
self.connection_time = 0
|
||||||
self.time_last_connect = time()
|
|
||||||
|
self.connection_counter = 0
|
||||||
|
self.connection_counter_reset = time()
|
||||||
|
self.command_counter = 0
|
||||||
|
self.command_counter_reset = time()
|
||||||
|
|
||||||
def at_server_connection(self):
|
def at_server_connection(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -74,11 +81,14 @@ class PortalSessionHandler(SessionHandler):
|
||||||
session.sessid = self.latest_sessid
|
session.sessid = self.latest_sessid
|
||||||
|
|
||||||
now = time()
|
now = time()
|
||||||
|
self.connection_counter += 1
|
||||||
|
|
||||||
if now - self.time_last_connect < _MIN_TIME_BETWEEN_CONNECTS:
|
if self.connection_counter > _MAX_CONNECTION_RATE:
|
||||||
# we have too many connections per second. Delay.
|
if now - self.connection_counter_reset < 1.0:
|
||||||
#print " delaying connecting", session.sessid
|
# our rate is higher than MAX_CONNECTION_RATE / second
|
||||||
reactor.callLater(_MIN_TIME_BETWEEN_CONNECTS, self.connect, session)
|
reactor.callLater(_MIN_TIME_BETWEEN_CONNECTS, self.connect, session)
|
||||||
|
self.connection_counter = 0
|
||||||
|
self.last_connetion_counter_reset = now
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.portal.amp_protocol:
|
if not self.portal.amp_protocol:
|
||||||
|
|
@ -87,8 +97,6 @@ class PortalSessionHandler(SessionHandler):
|
||||||
reactor.callLater(0.5, self.connect, session)
|
reactor.callLater(0.5, self.connect, session)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.time_last_connect = now
|
|
||||||
|
|
||||||
# sync with server-side
|
# sync with server-side
|
||||||
sessdata = session.get_sync_data()
|
sessdata = session.get_sync_data()
|
||||||
self.sessions[session.sessid] = session
|
self.sessions[session.sessid] = session
|
||||||
|
|
@ -358,12 +366,19 @@ class PortalSessionHandler(SessionHandler):
|
||||||
Data is serialized before passed on.
|
Data is serialized before passed on.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
now = time()
|
||||||
# data throttle (anti DoS measure)
|
# data throttle (anti DoS measure)
|
||||||
prev_cmd_last = session.cmd_last
|
self.command_counter += 1
|
||||||
session.cmd_last = time()
|
if self.command_counter > _MAX_COMMAND_RATE:
|
||||||
if session.cmd_last - prev_cmd_last < _MIN_TIME_BETWEEN_CMDS:
|
self.command_counter = 0
|
||||||
|
if now - session.cmd_last < 1.0:
|
||||||
|
session.cmd_last = now
|
||||||
|
#reactor.callLater(_MIN_TIME_BETWEEN_COMMANDS,
|
||||||
|
# self.data_in(session, text=text, **kwargs))
|
||||||
self.data_out(session.sessid, text=_ERROR_COMMAND_OVERFLOW)
|
self.data_out(session.sessid, text=_ERROR_COMMAND_OVERFLOW)
|
||||||
return
|
return
|
||||||
|
session.cmd_last = now
|
||||||
|
|
||||||
# relay data to Server
|
# relay data to Server
|
||||||
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
|
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
|
||||||
msg=text,
|
msg=text,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue