Commit dc5f64be authored by StevenWdV's avatar StevenWdV

More progress

parent 580acbba
......@@ -9,81 +9,96 @@ 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
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 __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 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)))
return struct.pack(header_format,
header.streamId,
header.synNr,
header.ackNr,
header.flags,
header.window,
header.dataLength,
header.checksum)
def unpack_header(header: bytes) -> btcp_header:
return btcp_header(*struct.unpack(header_format, header))
class btcp_packet(object):
def __init__(swlf, header: btcp_header, data: bytes):
self.header = header
self.data = data
def __init__(self, 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 compute_checksum(self) -> int:
header_copy = copy.deepcopy(self.header)
header_copy.checksum = 0
return binascii.crc32(pack_header(header_copy) + self.data)
def verify_checksum(self) -> bool:
return compute_checksum() == self.header.checksum
def verify_checksum(self) -> bool:
return self.compute_checksum() == self.header.checksum
def set_checksum(self):
self.header.checksum = self.compute_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))
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
def __init__(self, server: btcp_server, initMsg: btcp_header):
self.server = server
self.id = initMsg.streamId
self.recvSynNr = initMsg.synNr # Last received
self.recvAckNr = initMsg.synNr + 1 # First still to be recived
self.sendSynNr = random.randint(0, 0xffFFffFF) # Last sent
self.sendAckNr = self.sendSynNr # First not acked by other
self.sendBuffer = []
self.receiveBuffer = []
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()
self.sendBuffer.append(synAckPacket)
def pass_msg(self, packet: btcp_packet):
flags = btcp_flags(packet.header.flags)
if flags.syn:
print("Unexpected SYN")
# TODO
# self.streamId = streamId
# self.synNr = synNr
......@@ -93,34 +108,35 @@ class btcp_stream(object):
# 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
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(self, 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:
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