示例#1
0
文件: client.py 项目: nitori/ircd
    def __init__(self, server, writer: StreamWriter):
        self.remote_addr = writer.get_extra_info('peername')
        self.remote_host, self.remote_port = self.remote_addr

        self.local_addr = writer.get_extra_info('sockname')
        self.local_host, self.local_port = self.local_addr

        self.server = server
        self.writer = writer

        # state
        self.registered = False
        self.nickname = None
        self.user = None
        self.realname = None
        self.vhost = None
示例#2
0
    async def handle_connection(self, reader: StreamReader, writer: StreamWriter):
        temp_ref = TempRef()
        world_packet_manager = WorldPacketManager(temp_ref=temp_ref, reader=reader, writer=writer)

        peername = writer.get_extra_info('peername')
        Logger.debug('[World Server]: Accept connection from {}'.format(peername))

        Logger.info('[World Server]: trying to process auth session')
        auth = AuthManager(reader, writer, temp_ref=temp_ref, world_packet_manager=world_packet_manager)
        await auth.process(step=AuthStep.SECOND)

        self._register_tasks()

        while True:
            try:
                request = await asyncio.wait_for(reader.read(4096), timeout=1.0)
                if request:
                    response = await asyncio.wait_for(world_packet_manager.process(request), timeout=1.0)

                    if response:
                        for packet in response:
                            writer.write(packet)
                            await writer.drain()

            except TimeoutError:
                continue

            except Exception as e:
                Logger.error('[World Server]: exception, {}'.format(e))
                traceback.print_exc()
                break

        writer.close()
示例#3
0
    async def handle_connection(self, reader: StreamReader, writer: StreamWriter):
        peername = writer.get_extra_info('peername')
        Logger.info('[Login Server]: Accepted connection from {}'.format(peername))

        temp_ref = TempRef()

        auth = AuthManager(reader, writer, temp_ref=temp_ref)
        await auth.process(step=AuthStep.FIRST)
        writer.close()
示例#4
0
    async def handle_connection(self, reader: StreamReader,
                                writer: StreamWriter):
        self._register_tasks()

        temp_ref = TempRef()
        world_packet_manager = WorldPacketManager(temp_ref=temp_ref,
                                                  reader=reader,
                                                  writer=writer)

        Logger.info('[World Server]: trying to process auth session')
        auth = AuthManager(reader,
                           writer,
                           temp_ref=temp_ref,
                           world_packet_manager=world_packet_manager,
                           session_keys=self.session_keys)

        is_authenticated = await auth.process(step=AuthStep.SECOND)

        if is_authenticated:

            peer_name = writer.get_extra_info('peername')
            Logger.success(
                '[World Server]: Accept connection from {}'.format(peer_name))

            while True:
                try:
                    request = await asyncio.wait_for(reader.read(4096),
                                                     timeout=0.01)
                    if request:
                        response = await asyncio.wait_for(
                            world_packet_manager.process(request),
                            timeout=0.01)

                        if response:
                            for packet in response:
                                writer.write(packet)
                                await writer.drain()

                except TimeoutError:
                    pass

                except BrokenPipeError:
                    pass

                except Exception as e:
                    Logger.error('[World Server]: exception, {}'.format(e))
                    traceback.print_exc()
                    break
                finally:
                    await asyncio.sleep(0.01)

        writer.close()
示例#5
0
    async def handle_connection(self, reader: StreamReader,
                                writer: StreamWriter):
        peername = writer.get_extra_info('peername')
        Logger.info(
            '[Login Server]: Accepted connection from {}'.format(peername))

        auth = AuthManager(reader, writer)

        while not reader.at_eof():
            response = await auth.process()
            if not response:
                break

        Logger.warning('[Login Server]: closing...')
        writer.close()
示例#6
0
async def make_client(reader: StreamReader, writer: StreamWriter):

    # get peer name
    peer_name = writer.get_extra_info(PEER_NAME)
    print(f"Recieved request for peer: {peer_name}")

    # get subscriber channel and add to list
    subscriber_chan = await read_msg(reader)

    # adding this writer to subscriber list as well
    SUBSCRIBER_LIST[subscriber_chan].append(writer)

    # spawn a async task for this writer to pull msgs off to queue and send to subscribers
    asyncio.create_task(msg_writer(writer, SEND_QUEUE[writer]))

    try:
        while True:
            chan = await read_msg(reader)
            if chan not in CHAN_QUEUE:
                # create a queue where we will enqueue msgs for given channel
                CHAN_QUEUE[chan] = Queue(maxsize=CHAN_QUEUE_SIZE)
                # spawn up new channel sender
                asyncio.create_task(channel_sender(chan))

            data = await read_msg(reader)
            """
            put the msg onto the queue for this channel
            channel sender will pull msg off this queue and then put it in 
            the respective writers queues
            """
            await CHAN_QUEUE[chan].put(data)

    except asyncio.CancelledError:
        print(f"remote peer closing : {peer_name}")
        writer.close()
        await writer.wait_closed()

    except asyncio.IncompleteReadError:
        print(f"remote peer {peer_name} disconnected")

    finally:
        print(f"remote peer {peer_name} closed")
        # remove our writer form channel list
        SUBSCRIBER_LIST[subscriber_chan].remove(writer)

        # close async task for this writer
        await SEND_QUEUE[writer].put(None)
示例#7
0
    async def handle_connection(self, reader: StreamReader,
                                writer: StreamWriter):
        peername = writer.get_extra_info('peername')
        Logger.info(
            '[Login Server]: Accepted connection from {}'.format(peername))

        connection = Connection(reader=reader,
                                writer=writer,
                                peername=peername)
        world_packet_mgr = WorldPacketManager(connection=connection)

        while True:
            try:
                await LoginServer.process_request(reader, writer,
                                                  world_packet_mgr)
            except TimeoutError:
                continue
            finally:
                await asyncio.sleep(Config.Realm.Settings.min_timeout)
示例#8
0
    async def handle_connection(self, reader: StreamReader,
                                writer: StreamWriter):
        peername = writer.get_extra_info('peername')
        Logger.debug(
            '[World Server]: Accept connection from {}'.format(peername))

        await self.accept_connection(peername)

        auth = AuthSessionManager(reader, writer)
        auth.prepare()
        await auth.process()

        # If I understand it correctly, after SMSG_AUTH_RESPONSE server should waiting for CMSG_CHAR_ENUM
        # But next request never sends by client. Client stucks on 'Connected'
        try:
            next_request = await asyncio.wait_for(reader.read(1024),
                                                  timeout=1.0)
            Logger.debug(
                '[World Server]: next request = {}'.format(next_request))
        except TimeoutError:
            Logger.error('[World Server]: next request was not received')
        finally:
            Logger.warning('[World Server]: closing...')
示例#9
0
    async def initial_connection_check(self, reader: StreamReader,
                                       writer: StreamWriter):
        host_port = writer.get_extra_info('peername')
        new_user: Optional[User] = None
        try:
            # 1. send plain message
            writer.write(b'hello')
            await writer.drain()

            # 2. receive other's header
            try:
                received = await asyncio.wait_for(reader.read(BUFFER_SIZE),
                                                  5.0)
                if len(received) == 0:
                    raise PeerToPeerError('empty msg receive')
                header = json.loads(received.decode())
            except asyncio.TimeoutError:
                raise PeerToPeerError('timeout on other\'s header receive')
            except json.JSONDecodeError:
                raise PeerToPeerError(
                    'json decode error on other\'s header receive')

            # 3. generate new user
            user_header = UserHeader(**header)
            new_user = User(user_header, self.number, reader, writer,
                            host_port, AESCipher.create_key(), SERVER_SIDE)
            self.number += 1
            if new_user.header.name == V.SERVER_NAME:
                raise ConnectionAbortedError('Same origin connection')

            # 4. send my public key
            my_sec, my_pub = generate_keypair()
            send = json.dumps({'public-key': my_pub}).encode()
            await new_user.send(send)
            self.traffic.put_traffic_up(send)

            # 5. receive public key
            try:
                receive = await new_user.recv()
                self.traffic.put_traffic_down(receive)
                if len(receive) == 0:
                    raise ConnectionAbortedError('received msg is zero.')
                data = json.loads(receive.decode())
            except asyncio.TimeoutError:
                raise PeerToPeerError('timeout on public key receive')
            except json.JSONDecodeError:
                raise PeerToPeerError(
                    'json decode error on public key receive')

            # 6. encrypt and send AES key and header
            send = json.dumps({
                'aes-key': new_user.aeskey,
                'header': self.get_server_header(),
            })
            key = generate_shared_key(my_sec, data['public-key'])
            encrypted = AESCipher.encrypt(key, send.encode())
            await new_user.send(encrypted)
            self.traffic.put_traffic_up(encrypted)

            # 7. receive accept signal
            try:
                encrypted = await new_user.recv()
                self.traffic.put_traffic_down(encrypted)
            except asyncio.TimeoutError:
                raise PeerToPeerError('timeout on accept signal receive')
            receive = AESCipher.decrypt(new_user.aeskey, encrypted)
            if receive != b'accept':
                raise PeerToPeerError(f"Not accept signal! {receive}")

            # 8. accept connection
            log.info(
                f"established connection as server from {new_user.header.name} {new_user.get_host_port()}"
            )
            asyncio.ensure_future(self.receive_loop(new_user))
            # server port's reachable check
            await asyncio.sleep(1.0)
            await self.check_reachable(new_user)
            return
        except (ConnectionAbortedError, ConnectionResetError) as e:
            msg = f"disconnect error {host_port} {e}"
        except PeerToPeerError as e:
            msg = f"peer2peer error {host_port} {e}"
        except Exception as e:
            msg = "InitialConnCheck: {}".format(e)
            log.error(msg, exc_info=True)

        # EXCEPTION!
        if new_user:
            # remove user
            self.remove_connection(new_user, msg)
        else:
            # close socket
            log.debug(msg)
            try:
                writer.write(msg.encode())
                await writer.drain()
            except Exception:
                pass
            try:
                writer.close()
            except Exception:
                pass
示例#10
0
 def new_client(self, reader: StreamReader, writer: StreamWriter):
     addr = writer.get_extra_info('peername')
     clnt = client.Client(self, writer)
     asyncio. async (self.protocol_handler(reader, clnt))
     yield from self.queue.put((EVENT_NEW_CLIENT, clnt))