Commit 580acbba authored by StevenWdV's avatar StevenWdV

Initial progress

parent ac65fec7
......@@ -4,8 +4,7 @@
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>4a25d660-d6ae-48ba-bb8c-606d64c90d2e</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>
</StartupFile>
<StartupFile>bTCP_server.py</StartupFile>
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
......@@ -22,6 +21,9 @@
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<ItemGroup>
<Compile Include="btcp.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="bTCP_client.py" />
<Compile Include="bTCP_server.py" />
<Compile Include="testframework.py" />
......
import socket
import struct
import select
import threading
import binascii
import copy
import random
header_format = "!IHHBBHI"
header_size = 16
class btcp_header(object):
def __init__(self, streamId: int, synNr: int, ackNr: int, flags: int, window: int, dataLength: int, checksum: int):
self.streamId = streamId
self.synNr = synNr
self.ackNr = ackNr
self.flags = flags
self.window = window
self.dataLength = dataLength
self.checksum = checksum
class btcp_flags(object):
def __init__(self, flags: int):
self.fin = bool(flags & 1)
self.ack = bool(flags & 1 << 1)
self.syn = bool(flags & 1 << 2)
def to_int(self) -> int:
return self.syn << 2 | self.ack << 1 | self.fin
def pack_header(header: btcp_header) -> bytes:
return struct.pack(header_format,
header.streamId,
header.synNr,
header.ackNr,
header.flags,
header.window,
header.dataLength,
header.checksum)
def unpack_header(header: bytes) -> header:
return btcp_header(expand(struct.unpack(header_format, header)))
class btcp_packet(object):
def __init__(swlf, header: btcp_header, data: bytes):
self.header = header
self.data = data
def compute_checksum(self) -> int:
header_copy = copy.deepcopy(self.header)
header_copy.checksum = 0
return binascii.crc32(pack_header(header_copy) + data)
def verify_checksum(self) -> bool:
return compute_checksum() == self.header.checksum
def set_checksum(self):
self.header.checksum = compute_checksum()
def recv_packet(sock: socket.socket) -> btcp_packet:
header = unpack_header(sock.recv(header_size))
return btcp_packet(header, sock.recv(header.dataLength))
window_size = 50
class btcp_stream(object):
def __init__(self, server: btcp_server, initMsg: btcp_header):
assert btcp_flags(initMsg.flags).syn
self.server = server
self.id = initMsg.streamId
self.recvSynNr = initMsg.synNr
self.recvAckNr = initMsg.synNr + 1
self.sendSynNr = randint(0, 0xffFFffFF)
self.sendAckNr = self.sendSynNr
synAckFlags = btcp_flags(0)
synAckFlags.syn = synAckFlags.ack = True
synAckHeader = btcp_header(self.id, self.sendSynNr, self.recvAckNr, synAckFlags.to_int(), window_size, 0, 0)
synAckPacket = btcp_packet(synAckHeader, b"")
synAckPacket.set_checksum()
server.sendNoAck(synAckPacket)
def pass_msg(self, packet: btcp_packet):
#TODO
0
# self.streamId = streamId
# self.synNr = synNr
# self.ackNr = ackNr
# self.flags = flags
# self.window = window
# self.dataLength = dataLength
# self.checksum = checksum
class btcp_server(object):
def background(self):
while True:
packet = recv_packet(self.sock)
if not packet.verify_checksum():
print("Invalid checksum")
continue
if packet.header.streamId in self.streams:
self.streams[packet.header.streamId].pass_msg(packet)
else:
flags = btcp_flags(packet.header.flags)
if (flags.syn and not flags.ack and not flags.fin and packet.header.ackNr == 0
and packet.header.windows == 0 and packet.header.dataLength == 0):
self.streams[packet.header.streamId] = btcp_stream(packet.header)
else:
print("Unknown stream")
def send(packet: btcp_packet):
self.sock.send(packet.header + packet.data)
def __init__(self, addr: (str, int)):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
self.sock.bind(addr)
self.streams = {}
self.read_thread = threading.Thread(None, self.background)
self.read_thread.start()
#def accept(self) -> btcp_connection:
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment