Пример #1
0
    def _handle_client(self, sock):
        data, r_addr = sock.recvfrom(BUF_SIZE)
        if not data:
            logging.debug('UDP handle_client: data is empty')
            return
        if not self._is_local:
            addrlen = len(r_addr[0])
            if addrlen > 255:
                # drop
                return
            data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data
            try:
                response = cryptor.encrypt_all(self._password, self._method,
                                               data, self._crypto_path)
            except Exception:
                logging.debug("UDP handle_client: encrypt data failed")
                return
            if not response:
                return
        else:
            try:
                data, key, iv = cryptor.decrypt_all(self._password,
                                                    self._method, data,
                                                    self._crypto_path)
            except Exception:
                logging.debug('UDP handle_client: decrypt data failed')
                return
            if not data:
                return
            header_result = parse_header(data)
            if header_result is None:
                return
            addrtype, dest_addr, dest_port, header_length = header_result
            if self._is_tunnel:
                # remove ss header
                response = data[header_length:]
            else:
                response = b'\x00\x00\x00' + data
        client_addr = self._client_fd_to_server_addr.get(sock.fileno())

        if self._stat_callback:
            activity = {
                'remote_address': client_addr,
                'local_address': r_addr[0],
                'protocal': 'UDP',
                'type': 'UP',
                'traffic': len(data),
                'time': datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S')
            }
            self._stat_callback(self._listen_port, activity)

        if client_addr:
            logging.debug("send udp response to %s:%d" %
                          (client_addr[0], client_addr[1]))
            self._server_socket.sendto(response, client_addr)
        else:
            # this packet is from somewhere else we know
            # simply drop that packet
            pass
Пример #2
0
    def _handle_client(self, sock):
        data, r_addr = sock.recvfrom(BUF_SIZE)
        if not data:
            logging.debug('UDP handle_client: data is empty')
            return
        if self._stat_callback:
            self._stat_callback(self._listen_port, len(data))
        if not self._is_local:
            addrlen = len(r_addr[0])
            # 域名规范:域名不能超过255个字符。其中顶级域名不能超过63字符
            if addrlen > 255:
                # drop
                return
            # pack_addr(r_addr[0]):把r_addr[0]打包成shadowvpn的专用的地址header,追加到r_addr[0]头部。
            # struct.pack('>H', r_addr[1]):打包成Big-Endian格式
            data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data
            try:
                response = cryptor.encrypt_all(self._password,
                                               self._method, data,
                                               self._crypto_path)
            except Exception:
                logging.debug("UDP handle_client: encrypt data failed")
                return
            if not response:
                return
        # 本地端收到服务端发来的加密udp
        else:
            try:
                data, key, iv = cryptor.decrypt_all(self._password,
                                                    self._method, data,
                                                    self._crypto_path)
            except Exception:
                logging.debug('UDP handle_client: decrypt data failed')
                return
            if not data:
                return
            header_result = parse_header(data)
            if header_result is None:
                return
            addrtype, dest_addr, dest_port, header_length = header_result
            if self._is_tunnel:
                # remove ss header
                response = data[header_length:]
            else:
				# addrtype, dest_addr, dest_port, header_length = header_result
            	# 还原为标准的udp数据报格式,加上首3个字节
                response = b'\x00\x00\x00' + data
        client_addr = self._client_fd_to_server_addr.get(sock.fileno())
        if client_addr:
            logging.debug("send udp response to %s:%d"
                          % (client_addr[0], client_addr[1]))
            self._server_socket.sendto(response, client_addr)
        else:
            # this packet is from somewhere else we know
            # simply drop that packet
            pass
Пример #3
0
 def _handle_client(self, sock):
     data, r_addr = sock.recvfrom(BUF_SIZE)
     if not data:
         logging.debug('U[%d] UDP handle_client: data is empty' %
                       self._config['server_port'])
         return
     if self._stat_callback:
         self._stat_callback(self._listen_port, len(data))
     if not self._is_local:
         addrlen = len(r_addr[0])
         if addrlen > 255:
             # drop
             return
         data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data
         try:
             response = cryptor.encrypt_all(self._password,
                                            self._method, data,
                                            self._crypto_path)
         except Exception:
             logging.debug("UDP handle_client: encrypt data failed")
             return
         if not response:
             return
     else:
         try:
             data, key, iv = cryptor.decrypt_all(self._password,
                                                 self._method, data,
                                                 self._crypto_path)
         except Exception:
             logging.debug('UDP handle_client: decrypt data failed')
             return
         if not data:
             return
         header_result = parse_header(data)
         if header_result is None:
             return
         addrtype, dest_addr, dest_port, header_length = header_result
         if self._is_tunnel:
             # remove ss header
             response = data[header_length:]
         else:
             response = b'\x00\x00\x00' + data
     client_addr = self._client_fd_to_server_addr.get(sock.fileno())
     if client_addr:
         logging.debug("send udp response to %s:%d"
                       % (client_addr[0], client_addr[1]))
         self._server_socket.sendto(response, client_addr)
     else:
         # this packet is from somewhere else we know
         # simply drop that packet
         pass
Пример #4
0
 def _handle_client(self, sock):
     data, r_addr = sock.recvfrom(BUF_SIZE)
     if not data:
         logging.debug('UDP handle_client: data is empty')
         return
     if self._stat_callback:
         self._stat_callback(self._listen_port, len(data))
     if not self._is_local:
         addrlen = len(r_addr[0])
         if addrlen > 255:
             # drop
             return
         data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data
         try:
             response = cryptor.encrypt_all(self._password,
                                            self._method, data,
                                            self._crypto_path)
         except Exception:
             logging.debug("UDP handle_client: encrypt data failed")
             return
         if not response:
             return
     else:
         try:
             data, key, iv = cryptor.decrypt_all(self._password,
                                                 self._method, data,
                                                 self._crypto_path)
         except Exception:
             logging.debug('UDP handle_client: decrypt data failed')
             return
         if not data:
             return
         header_result = parse_header(data)
         if header_result is None:
             return
         addrtype, dest_addr, dest_port, header_length = header_result
         if self._is_tunnel:
             # remove ss header
             response = data[header_length:]
         else:
             response = b'\x00\x00\x00' + data
     client_addr = self._client_fd_to_server_addr.get(sock.fileno())
     if client_addr:
         logging.debug("send udp response to %s:%d"
                       % (client_addr[0], client_addr[1]))
         self._server_socket.sendto(response, client_addr)
     else:
         # this packet is from somewhere else we know
         # simply drop that packet
         pass
Пример #5
0
def test():
    import time
    import threading
    import struct
    from shadowsocks import cryptor

    logging.basicConfig(level=5,
                        format='%(asctime)s %(levelname)-8s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    enc = []
    eventloop.TIMEOUT_PRECISION = 1

    def run_server():
        config = {
            'server': '127.0.0.1',
            'local_port': 1081,
            'port_password': {
                '8381': 'foobar1',
                '8382': 'foobar2'
            },
            'method': 'aes-256-cfb',
            'manager_address': '127.0.0.1:6001',
            'timeout': 60,
            'fast_open': False,
            'verbose': 2
        }
        manager = Manager(config)
        enc.append(manager)
        manager.run()

    t = threading.Thread(target=run_server)
    t.start()
    time.sleep(1)
    manager = enc[0]
    cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    cli.connect(('127.0.0.1', 6001))

    # test add and remove
    time.sleep(1)
    cli.send(b'add: {"server_port":7001, "password":"******"}')
    time.sleep(1)
    assert 7001 in manager._relays
    data, addr = cli.recvfrom(1506)
    assert b'ok' in data

    cli.send(b'remove: {"server_port":8381}')
    time.sleep(1)
    assert 8381 not in manager._relays
    data, addr = cli.recvfrom(1506)
    assert b'ok' in data
    logging.info('add and remove test passed')

    # test statistics for TCP
    header = common.pack_addr(b'google.com') + struct.pack('>H', 80)
    data = cryptor.encrypt_all(b'asdfadsfasdf', 'aes-256-cfb',
                               header + b'GET /\r\n\r\n')
    tcp_cli = socket.socket()
    tcp_cli.connect(('127.0.0.1', 7001))
    tcp_cli.send(data)
    tcp_cli.recv(4096)
    tcp_cli.close()

    data, addr = cli.recvfrom(1506)
    data = common.to_str(data)
    assert data.startswith('stat: ')
    data = data.split('stat:')[1]
    stats = shell.parse_json_in_str(data)
    assert '7001' in stats
    logging.info('TCP statistics test passed')

    # test statistics for UDP
    header = common.pack_addr(b'127.0.0.1') + struct.pack('>H', 80)
    data = cryptor.encrypt_all(b'foobar2', 'aes-256-cfb', header + b'test')
    udp_cli = socket.socket(type=socket.SOCK_DGRAM)
    udp_cli.sendto(data.encode(), ('127.0.0.1', 8382))
    tcp_cli.close()

    data, addr = cli.recvfrom(1506)
    data = common.to_str(data)
    assert data.startswith('stat: ')
    data = data.split('stat:')[1]
    stats = json.loads(data)
    assert '8382' in stats
    logging.info('UDP statistics test passed')

    manager._loop.stop()
    t.join()
Пример #6
0
def test():
    import time
    import threading
    import struct
    from shadowsocks import cryptor

    logging.basicConfig(level=5,
                        format='%(asctime)s %(levelname)-8s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    enc = []
    eventloop.TIMEOUT_PRECISION = 1

    def run_server():
        config = {
            'server': '127.0.0.1',
            'local_port': 1081,
            'port_password': {
                '8381': 'foobar1',
                '8382': 'foobar2'
            },
            'method': 'aes-256-cfb',
            'manager_address': '127.0.0.1:6001',
            'timeout': 60,
            'fast_open': False,
            'verbose': 2
        }
        manager = Manager(config)
        enc.append(manager)
        manager.run()

    t = threading.Thread(target=run_server)
    t.start()
    time.sleep(1)
    manager = enc[0]
    cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    cli.connect(('127.0.0.1', 6001))

    # test add and remove
    time.sleep(1)
    cli.send(b'add: {"server_port":7001, "password":"******"}')
    time.sleep(1)
    assert 7001 in manager._relays
    data, addr = cli.recvfrom(1506)
    assert b'ok' in data

    cli.send(b'remove: {"server_port":8381}')
    time.sleep(1)
    assert 8381 not in manager._relays
    data, addr = cli.recvfrom(1506)
    assert b'ok' in data
    logging.info('add and remove test passed')

    # test statistics for TCP
    header = common.pack_addr(b'google.com') + struct.pack('>H', 80)
    data = cryptor.encrypt_all(b'asdfadsfasdf', 'aes-256-cfb',
                               header + b'GET /\r\n\r\n')
    tcp_cli = socket.socket()
    tcp_cli.connect(('127.0.0.1', 7001))
    tcp_cli.send(data)
    tcp_cli.recv(4096)
    tcp_cli.close()

    data, addr = cli.recvfrom(1506)
    data = common.to_str(data)
    assert data.startswith('stat: ')
    data = data.split('stat:')[1]
    stats = shell.parse_json_in_str(data)
    assert '7001' in stats
    logging.info('TCP statistics test passed')

    # test statistics for UDP
    header = common.pack_addr(b'127.0.0.1') + struct.pack('>H', 80)
    data = cryptor.encrypt_all(b'foobar2', 'aes-256-cfb',
                               header + b'test')
    udp_cli = socket.socket(type=socket.SOCK_DGRAM)
    udp_cli.sendto(data, ('127.0.0.1', 8382))
    tcp_cli.close()

    data, addr = cli.recvfrom(1506)
    data = common.to_str(data)
    assert data.startswith('stat: ')
    data = data.split('stat:')[1]
    stats = json.loads(data)
    assert '8382' in stats
    logging.info('UDP statistics test passed')

    manager._loop.stop()
    t.join()