"header" + handle_code()

This commit is contained in:
Maxim Khomutov 2023-07-07 17:56:29 +03:00
parent 3defc99389
commit 252a5399ab
2 changed files with 66 additions and 45 deletions

View File

@ -18,26 +18,49 @@ class TCPServer:
self.host = host self.host = host
self.port = port self.port = port
async def send(self, data, sync):
pass
async def recv(self, client): async def recv(self, client):
not_alive = client.is_disconnected() if not client.is_disconnected():
if not not_alive: self.log.debug(f"Client with {client.nick}({client.cid}) disconnected")
self.log.debug(f"Client with ID {client.cid} disconnected") return
return ""
header = await client.loop.sock_recv(client.socket, 4) # header: 4 bytes
data = b"" data = b""
while True: while True:
chunk = await client.loop.sock_recv(client.socket, 10) chunk = await client.loop.sock_recv(client.socket, 1)
if not chunk: if not chunk:
break break
data += chunk data += chunk
int_header = 0
for i in range(len(header)):
int_header += header[i]
self.log.debug(f"header: `{header}`; int_header: `{int_header}`; data: `{data}`;")
if int_header <= 0:
client.kick("Invalid packet - header negative")
return
if not int_header < 100 * MB:
client.kick("Header size limit exceeded")
self.log.warn(f"Client {client.nick}({client.cid}) sent header of >100MB - "
f"assuming malicious intent and disconnecting the client.")
return
# TODO: read Data
if len(data) != int_header:
self.log.debug(f"WARN Expected to read {int_header} bytes, instead got {len(data)}")
# TODO: ABG: DeComp(Data)
abg = b"ABG:"
if len(data) > len(abg) and data.startswith(abg):
data = data[len(abg):]
# return DeComp(Data);
return data return data
async def auth_client(self, sock): async def auth_client(self, sock):
# TODO: Authentication # TODO: Authentication
client = self.Core.create_client(sock) client = self.Core.create_client(sock)
self.log.debug(f"Client: \"IP: {client.addr!r}; ID: {client.cid}\" - started authentication!") self.log.debug(f"Client: \"IP: {client.addr!r}; ID: {client.cid}\" - Authentication!")
data = await self.recv(client) data = await self.recv(client)
self.log.debug(f"recv1 data: {data}") self.log.debug(f"recv1 data: {data}")
if len(data) > 50: if len(data) > 50:
@ -47,48 +70,50 @@ class TCPServer:
client.kick("Outdated Version.") client.kick("Outdated Version.")
return return
else: else:
self.log.debug('tcp_send(b"A")') pass
client.tcp_send(b"A") # self.log.debug('tcp_send(b"A")')
# client.tcp_send(b"A")
data = await self.recv(client) # data = await self.recv(client)
self.log.debug(f"recv2 data: {data}") # self.log.debug(f"recv2 data: {data}")
client.kick("TODO Authentication") client.kick("TODO Authentication")
return False
async def handle_download(self, sock):
# TODO: HandleDownload
self.log.debug(f"Client: \"IP: {0!r}; ID: {0}\" - HandleDownload!")
return False
async def handle_code(self, code, sock):
match code:
case "C":
return await self.auth_client(sock)
case "D":
return await self.handle_download(sock)
case "P":
sock.send(b"P")
return True
case _:
self.log.error(f"Unknown code: {code}")
return False
async def handle_client(self, sock): async def handle_client(self, sock):
while True: while True:
try: try:
data = sock.recv(1) data = sock.recv(1)
if not data: if not data:
break break
message = data.decode("utf-8").strip() code = data.decode()
addr = sock.getsockname() self.log.debug(f"Received {code!r} from {sock.getsockname()!r}")
self.log.debug(f"Received {message!r} from {addr!r}") if not await self.handle_code(code, sock):
code = message[0] break
match code:
case "C":
await self.auth_client(sock)
case "D":
# TODO: HandleDownload
print("TODO: HandleDownload")
case "P":
# TODO: Понять что это и зачем...
sock.sendall(b"P")
case _:
self.log.error(f"Unknown code: {code}")
except Exception as e: except Exception as e:
print("Error:", e) self.log.error(f"Error: {e}")
traceback.print_exc() traceback.print_exc()
break break
print("Error while connecting..") sock.close()
self.log.error("Error while connecting..")
# async def start(self):
# self.log.debug("Starting TCP server.")
# server = await asyncio.start_server(self.handle_client, self.host, self.port, family=socket.AF_INET)
# self.log.debug(f"Serving on {server.sockets[0].getsockname()}")
# async with server:
# await server.serve_forever()
async def start(self): async def start(self):
self.log.debug("Starting TCP server.") self.log.debug("Starting TCP server.")

View File

@ -17,14 +17,10 @@ class TCPServer:
self.Core = core self.Core = core
self.host = host self.host = host
self.port = port self.port = port
async def recv(self, client: Client) -> bytes: ...
async def send(self, data, sync) -> None: ...
async def recv(self, writer: Client) -> bytes: ...
async def auth_client(self, sock: socket.socket) -> None: ... async def auth_client(self, sock: socket.socket) -> None: ...
async def handle_download(self, sock: socket.socket) -> None: ...
async def handle_code(self, code: str, sock: socket.socket) -> None: ...
async def handle_client(self, sock: socket.socket) -> None: ... async def handle_client(self, sock: socket.socket) -> None: ...
async def start(self) -> None: ... async def start(self) -> None: ...