mirror of https://github.com/fail2ban/fail2ban
Merge branch '0.10' into 0.11
commit
ccb1daf30a
|
@ -76,6 +76,10 @@ class RequestHandler(asynchat.async_chat):
|
||||||
#logSys.debug("Received raw data: " + str(data))
|
#logSys.debug("Received raw data: " + str(data))
|
||||||
self.__buffer.append(data)
|
self.__buffer.append(data)
|
||||||
|
|
||||||
|
# exception identifies deserialization errors (exception by load in pickle):
|
||||||
|
class LoadError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
##
|
##
|
||||||
# Handles a new request.
|
# Handles a new request.
|
||||||
#
|
#
|
||||||
|
@ -93,7 +97,12 @@ class RequestHandler(asynchat.async_chat):
|
||||||
self.close_when_done()
|
self.close_when_done()
|
||||||
return
|
return
|
||||||
# Deserialize
|
# Deserialize
|
||||||
message = loads(message)
|
try:
|
||||||
|
message = loads(message)
|
||||||
|
except Exception as e:
|
||||||
|
logSys.error('PROTO-error: load message failed: %s', e,
|
||||||
|
exc_info=logSys.getEffectiveLevel()<logging.DEBUG)
|
||||||
|
raise RequestHandler.LoadError(e)
|
||||||
# Gives the message to the transmitter.
|
# Gives the message to the transmitter.
|
||||||
if self.__transmitter:
|
if self.__transmitter:
|
||||||
message = self.__transmitter.proceed(message)
|
message = self.__transmitter.proceed(message)
|
||||||
|
@ -104,8 +113,9 @@ class RequestHandler(asynchat.async_chat):
|
||||||
# Sends the response to the client.
|
# Sends the response to the client.
|
||||||
self.push(message + CSPROTO.END)
|
self.push(message + CSPROTO.END)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logSys.error("Caught unhandled exception: %r", e,
|
if not isinstance(e, RequestHandler.LoadError): # pragma: no cover - normally unreachable
|
||||||
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
logSys.error("Caught unhandled exception: %r", e,
|
||||||
|
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
||||||
# Sends the response to the client.
|
# Sends the response to the client.
|
||||||
message = dumps("ERROR: %s" % e, HIGHEST_PROTOCOL)
|
message = dumps("ERROR: %s" % e, HIGHEST_PROTOCOL)
|
||||||
self.push(message + CSPROTO.END)
|
self.push(message + CSPROTO.END)
|
||||||
|
@ -200,23 +210,21 @@ class AsyncServer(asyncore.dispatcher):
|
||||||
def handle_accept(self):
|
def handle_accept(self):
|
||||||
try:
|
try:
|
||||||
conn, addr = self.accept()
|
conn, addr = self.accept()
|
||||||
except socket.error as e: # pragma: no cover
|
except Exception as e: # pragma: no cover
|
||||||
self.__errCount['accept'] += 1
|
self.__errCount['accept'] += 1
|
||||||
if self.__errCount['accept'] < 20:
|
if self.__errCount['accept'] < 20:
|
||||||
logSys.warning("Socket error: %s", e)
|
logSys.warning("Accept socket error: %s", e,
|
||||||
|
exc_info=(self.__errCount['accept'] <= 1))
|
||||||
elif self.__errCount['accept'] == 20:
|
elif self.__errCount['accept'] == 20:
|
||||||
logSys.error("Too many acceptor errors - stop logging errors")
|
logSys.error("Too many acceptor errors - stop logging errors")
|
||||||
elif self.__errCount['accept'] > 100:
|
elif self.__errCount['accept'] > 100:
|
||||||
if (
|
if (
|
||||||
e.args[0] == errno.EMFILE # [Errno 24] Too many open files
|
(isinstance(e, socket.error) and e.args[0] == errno.EMFILE) # [Errno 24] Too many open files
|
||||||
or sum(self.__errCount.itervalues()) > 1000
|
or sum(self.__errCount.itervalues()) > 1000
|
||||||
):
|
):
|
||||||
logSys.critical("Too many errors - critical count reached %r", err_count)
|
logSys.critical("Too many errors - critical count reached %r", self.__errCount)
|
||||||
self.stop()
|
self.stop()
|
||||||
return
|
return
|
||||||
except TypeError as e: # pragma: no cover
|
|
||||||
logSys.warning("Type error: %s", e)
|
|
||||||
return
|
|
||||||
if self.__errCount['accept']:
|
if self.__errCount['accept']:
|
||||||
self.__errCount['accept'] -= 1;
|
self.__errCount['accept'] -= 1;
|
||||||
AsyncServer.__markCloseOnExec(conn)
|
AsyncServer.__markCloseOnExec(conn)
|
||||||
|
@ -265,6 +273,13 @@ class AsyncServer(asyncore.dispatcher):
|
||||||
stopflg = False
|
stopflg = False
|
||||||
if self.__active:
|
if self.__active:
|
||||||
self.__loop = False
|
self.__loop = False
|
||||||
|
# shutdown socket here:
|
||||||
|
if self.socket:
|
||||||
|
try:
|
||||||
|
self.socket.shutdown(socket.SHUT_RDWR)
|
||||||
|
except socket.error: # pragma: no cover - normally unreachable
|
||||||
|
pass
|
||||||
|
# close connection:
|
||||||
asyncore.dispatcher.close(self)
|
asyncore.dispatcher.close(self)
|
||||||
# If not the loop thread (stops self in handler), wait (a little bit)
|
# If not the loop thread (stops self in handler), wait (a little bit)
|
||||||
# for the server leaves loop, before remove socket
|
# for the server leaves loop, before remove socket
|
||||||
|
@ -284,14 +299,8 @@ class AsyncServer(asyncore.dispatcher):
|
||||||
|
|
||||||
def stop_communication(self):
|
def stop_communication(self):
|
||||||
if self.__transmitter:
|
if self.__transmitter:
|
||||||
logSys.debug("Stop communication")
|
logSys.debug("Stop communication, shutdown")
|
||||||
self.__transmitter = None
|
self.__transmitter = None
|
||||||
# shutdown socket here:
|
|
||||||
if self.socket:
|
|
||||||
try:
|
|
||||||
self.socket.shutdown(socket.SHUT_RDWR)
|
|
||||||
except socket.error: # pragma: no cover - normally unreachable
|
|
||||||
pass
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Stops the server.
|
# Stops the server.
|
||||||
|
|
|
@ -102,7 +102,7 @@ class Utils():
|
||||||
def unset(self, k):
|
def unset(self, k):
|
||||||
try:
|
try:
|
||||||
del self._cache[k]
|
del self._cache[k]
|
||||||
except KeyError: # pragma: no cover
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1640,6 +1640,8 @@ class DNSUtilsTests(unittest.TestCase):
|
||||||
c.set(i, i)
|
c.set(i, i)
|
||||||
for i in xrange(5):
|
for i in xrange(5):
|
||||||
self.assertEqual(c.get(i), i)
|
self.assertEqual(c.get(i), i)
|
||||||
|
# remove unavailable key:
|
||||||
|
c.unset('a'); c.unset('a')
|
||||||
|
|
||||||
def testCacheMaxSize(self):
|
def testCacheMaxSize(self):
|
||||||
c = Utils.Cache(maxCount=5, maxTime=60)
|
c = Utils.Cache(maxCount=5, maxTime=60)
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Socket(LogCaptureTestCase):
|
||||||
LogCaptureTestCase.setUp(self)
|
LogCaptureTestCase.setUp(self)
|
||||||
super(Socket, self).setUp()
|
super(Socket, self).setUp()
|
||||||
self.server = AsyncServer(self)
|
self.server = AsyncServer(self)
|
||||||
sock_fd, sock_name = tempfile.mkstemp('fail2ban.sock', 'socket')
|
sock_fd, sock_name = tempfile.mkstemp('fail2ban.sock', 'f2b-socket')
|
||||||
os.close(sock_fd)
|
os.close(sock_fd)
|
||||||
os.remove(sock_name)
|
os.remove(sock_name)
|
||||||
self.sock_name = sock_name
|
self.sock_name = sock_name
|
||||||
|
@ -120,7 +120,7 @@ class Socket(LogCaptureTestCase):
|
||||||
|
|
||||||
# test wrong message:
|
# test wrong message:
|
||||||
self.assertEqual(client.send([[TestMsg()]]), 'ERROR: test unpickle error')
|
self.assertEqual(client.send([[TestMsg()]]), 'ERROR: test unpickle error')
|
||||||
self.assertLogged("Caught unhandled exception", "test unpickle error", all=True)
|
self.assertLogged("PROTO-error: load message failed:", "test unpickle error", all=True)
|
||||||
|
|
||||||
# test good message again:
|
# test good message again:
|
||||||
self.assertEqual(client.send(testMessage), testMessage)
|
self.assertEqual(client.send(testMessage), testMessage)
|
||||||
|
|
Loading…
Reference in New Issue