From a185e1671b52c12148ab7989e4faf756ab650876 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Fri, 6 Jun 2014 22:52:02 +0800 Subject: [PATCH 1/4] add some status protection --- setup.py | 2 +- shadowsocks/eventloop.py | 6 ++++-- shadowsocks/tcprelay.py | 14 +++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 0263846..efdb366 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open('README.rst') as f: setup( name="shadowsocks", - version="2.0", + version="2.0.1", license='MIT', description="A fast tunnel proxy that help you get through firewalls", author='clowwindy', diff --git a/shadowsocks/eventloop.py b/shadowsocks/eventloop.py index d75905d..c9de6ef 100644 --- a/shadowsocks/eventloop.py +++ b/shadowsocks/eventloop.py @@ -204,9 +204,11 @@ class EventLoop(object): logging.error(e) continue for handler in self._handlers: - # no exceptions should be raised by users # TODO when there are a lot of handlers - handler(events) + try: + handler(events) + except (OSError, IOError) as e: + logging.error(e) # from tornado diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 8f12218..5f66962 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -57,6 +57,7 @@ STAGE_HELLO = 1 STAGE_UDP_ASSOC = 2 STAGE_REPLY = 4 STAGE_STREAM = 5 +STAGE_DESTROYED = -1 # stream direction STREAM_UP = 0 @@ -137,7 +138,7 @@ class TCPRelayHandler(object): def _write_to_sock(self, data, sock): if not data or not sock: - return + return False uncomplete = False try: l = len(data) @@ -152,6 +153,7 @@ class TCPRelayHandler(object): else: logging.error(e) self.destroy() + return False if uncomplete: if sock == self._local_sock: self._data_to_write_to_local.append(data) @@ -168,6 +170,7 @@ class TCPRelayHandler(object): self._update_stream(STREAM_UP, WAIT_STATUS_READING) else: logging.error('write_all_to_sock:unknown socket') + return True def _handle_stage_reply(self, data): if self._is_local: @@ -367,10 +370,14 @@ class TCPRelayHandler(object): self.destroy() def handle_event(self, sock, event): + if self._stage == STAGE_DESTROYED: + return # order is important if sock == self._remote_sock: if event & eventloop.POLL_IN: self._on_remote_read() + if self._stage == STAGE_DESTROYED: + return if event & eventloop.POLL_OUT: self._on_remote_write() if event & eventloop.POLL_ERR: @@ -378,6 +385,8 @@ class TCPRelayHandler(object): elif sock == self._local_sock: if event & eventloop.POLL_IN: self._on_local_read() + if self._stage == STAGE_DESTROYED: + return if event & eventloop.POLL_OUT: self._on_local_write() if event & eventloop.POLL_ERR: @@ -386,6 +395,9 @@ class TCPRelayHandler(object): logging.warn('unknown socket') def destroy(self): + if self._stage == STAGE_DESTROYED: + return + self._stage = STAGE_DESTROYED if self._remote_address: logging.debug('destroy: %s:%d' % self._remote_address) From 816592b67467fa435903f76b6dcd9c23a0b4783e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Fri, 6 Jun 2014 22:57:57 +0800 Subject: [PATCH 2/4] add more log --- shadowsocks/eventloop.py | 4 ++++ shadowsocks/server.py | 2 ++ shadowsocks/tcprelay.py | 12 ++++++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/shadowsocks/eventloop.py b/shadowsocks/eventloop.py index c9de6ef..e8af800 100644 --- a/shadowsocks/eventloop.py +++ b/shadowsocks/eventloop.py @@ -202,6 +202,8 @@ class EventLoop(object): continue else: logging.error(e) + import traceback + traceback.print_exc() continue for handler in self._handlers: # TODO when there are a lot of handlers @@ -209,6 +211,8 @@ class EventLoop(object): handler(events) except (OSError, IOError) as e: logging.error(e) + import traceback + traceback.print_exc() # from tornado diff --git a/shadowsocks/server.py b/shadowsocks/server.py index 2e35698..13c2452 100755 --- a/shadowsocks/server.py +++ b/shadowsocks/server.py @@ -69,6 +69,8 @@ def main(): loop.run() except (KeyboardInterrupt, IOError, OSError) as e: logging.error(e) + import traceback + traceback.print_exc() os._exit(0) if int(config['workers']) > 1: diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 5f66962..64b65d2 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -26,6 +26,7 @@ import socket import errno import struct import logging +import traceback import encrypt import eventloop from common import parse_header @@ -152,6 +153,7 @@ class TCPRelayHandler(object): uncomplete = True else: logging.error(e) + traceback.print_exc() self.destroy() return False if uncomplete: @@ -202,6 +204,7 @@ class TCPRelayHandler(object): self.destroy() else: logging.error(e) + traceback.print_exc() self.destroy() def _handle_stage_hello(self, data): @@ -277,8 +280,8 @@ class TCPRelayHandler(object): self._stage = STAGE_REPLY self._update_stream(STREAM_UP, WAIT_STATUS_READWRITING) self._update_stream(STREAM_DOWN, WAIT_STATUS_READING) - except Exception: - import traceback + except Exception as e: + logging.error(e) traceback.print_exc() # TODO use logging when debug completed self.destroy() @@ -336,8 +339,8 @@ class TCPRelayHandler(object): data = self._encryptor.encrypt(data) try: self._write_to_sock(data, self._local_sock) - except Exception: - import traceback + except Exception as e: + logging.error(e) traceback.print_exc() # TODO use logging when debug completed self.destroy() @@ -540,6 +543,7 @@ class TCPRelay(object): continue else: logging.error(e) + traceback.print_exc() else: if sock: handler = self._fd_to_handlers.get(fd, None) From d7d125082fec771f0cbd222b75f6ea9df49942ec Mon Sep 17 00:00:00 2001 From: clowwindy Date: Fri, 6 Jun 2014 23:10:00 +0800 Subject: [PATCH 3/4] handle POLL_ERR first --- shadowsocks/tcprelay.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 64b65d2..c93b6fc 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -364,11 +364,13 @@ class TCPRelayHandler(object): def _on_local_error(self): if self._local_sock: + logging.debug('got local error') logging.error(eventloop.get_sock_error(self._local_sock)) self.destroy() def _on_remote_error(self): if self._remote_sock: + logging.debug('got remote error') logging.error(eventloop.get_sock_error(self._remote_sock)) self.destroy() @@ -377,23 +379,27 @@ class TCPRelayHandler(object): return # order is important if sock == self._remote_sock: + if event & eventloop.POLL_ERR: + self._on_remote_error() + if self._stage == STAGE_DESTROYED: + return if event & eventloop.POLL_IN: self._on_remote_read() if self._stage == STAGE_DESTROYED: return if event & eventloop.POLL_OUT: self._on_remote_write() - if event & eventloop.POLL_ERR: - self._on_remote_error() elif sock == self._local_sock: + if event & eventloop.POLL_ERR: + self._on_local_error() + if self._stage == STAGE_DESTROYED: + return if event & eventloop.POLL_IN: self._on_local_read() if self._stage == STAGE_DESTROYED: return if event & eventloop.POLL_OUT: self._on_local_write() - if event & eventloop.POLL_ERR: - self._on_local_error() else: logging.warn('unknown socket') @@ -525,9 +531,9 @@ class TCPRelay(object): def _handle_events(self, events): for sock, fd, event in events: - # if sock: - # logging.debug('fd %d %s', fd, - # eventloop.EVENT_NAMES.get(event, event)) + if sock: + logging.debug('fd %d %s', fd, + eventloop.EVENT_NAMES.get(event, event)) if sock == self._server_socket: if event & eventloop.POLL_ERR: # TODO From 4b630d08142a0a727ed34221b0f17a56697211a1 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Fri, 6 Jun 2014 23:16:19 +0800 Subject: [PATCH 4/4] update CHANGES --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 5935325..3c46d24 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +2.0.1 2014-06-05 +- Better logging +- Maybe fix bad file descriptor + 2.0 2014-06-05 - Use a new event model - Remove gevent