Start working on proper packet header

This commit is contained in:
ChillerDragon 2022-10-30 19:00:13 +01:00
parent f75eaebcee
commit b7a2cfb5c3
4 changed files with 85 additions and 19 deletions

View file

@ -3,7 +3,7 @@ require_relative 'network'
require_relative 'bytes'
class NetChunk
attr_reader :next, :data, :msg, :sys
attr_reader :next, :data, :msg, :sys, :flags
def initialize(data)
@next = nil
@ -37,6 +37,14 @@ class NetChunk
# sequence number
# in da third byte but who needs seq?!
end
def flags_vital
@flags[:vital]
end
def flags_resend
@flags[:resend]
end
end
MAX_NUM_CHUNKS = 1024

View file

@ -79,6 +79,8 @@ NET_CTRLMSG_ACCEPT = 2
NET_CTRLMSG_CLOSE = 4
NET_CTRLMSG_TOKEN = 5
NET_MAX_SEQUENCE = 1<<10
NET_CONNSTATE_OFFLINE = 0
NET_CONNSTATE_TOKEN = 1
NET_CONNSTATE_CONNECT = 2

View file

@ -1,5 +1,46 @@
require 'huffman_tw'
class PacketFlags
attr_reader :bits, :hash
def initialize(data)
@hash = {}
@bits = ''
if data.class == Hash
@bits = parse_hash(data)
@hash = data
elsif data.class == String
@hash = parse_bits(data)
@bits = data
else
raise "Flags have to be hash or string"
end
end
def parse_hash(hash)
bits = ''
bits += hash[:connection] == '1' ? '1' : '0'
bits += hash[:compressed] == '1' ? '1' : '0'
bits += hash[:resend] == '1' ? '1' : '0'
bits += hash[:control] == '1' ? '1' : '0'
bits
end
def parse_bits(four_bit_str)
# takes a 4 character string
# representing the middle of the first byte sent
# in binary representation
#
# and creates a hash out of it
hash = {}
hash[:connection] = four_bit_str[0] == '1'
hash[:compressed] = four_bit_str[1] == '1'
hash[:resend] = four_bit_str[2] == '1'
hash[:control] = four_bit_str[3] == '1'
hash
end
end
# Class holding the parsed packet data
class Packet
attr_reader :flags, :payload
@ -14,10 +55,9 @@ class Packet
# network direction (client/server)
@prefix = prefix
@huffman = Huffman.new
@flags = {}
@data = data
flags_byte = @data[0].unpack("B*")
parse_flags(flags_byte.first[2..5])
@flags = PacketFlags.new(flags_byte.first[2..5]).hash
@payload = @data[PACKET_HEADER_SIZE..]
if flags_compressed
@payload = @huffman.decompress(@payload.unpack("C*"))
@ -51,20 +91,6 @@ class Packet
puts ""
end
def parse_flags(four_bit_str)
# takes a 4 character string
# representing the middle of the first byte sent
# in binary representation
#
# and creates a hash out of it
@flags = {}
@flags[:connection] = four_bit_str[0] == '1'
@flags[:compressed] = four_bit_str[1] == '1'
@flags[:resend] = four_bit_str[2] == '1'
@flags[:control] = four_bit_str[3] == '1'
@flags
end
def flags_compressed()
@flags[:compressed]
end

View file

@ -11,25 +11,51 @@ require_relative 'lib/chunk'
require_relative 'lib/server_info'
class NetBase
attr_accessor :client_token, :server_token
attr_accessor :client_token, :server_token, :ack
def initialize
@ip = nil
@port = nil
@s = nil
@ack = 0
end
def connect(socket, ip, port)
@s = socket
@ip = ip
@port = port
@ack = 0
end
##
# Sends a packing setting the proper header for you
#
# @param payload [Array] The Integer list representing the data after the header
def send_packet(payload)
# @param flags [Hash] Packet header flags for more details check the class +PacketFlags+
def send_packet(payload, flags = {})
# unsigned char flags_ack; // 6bit flags, 2bit ack
# unsigned char ack; // 8bit ack
# unsigned char numchunks; // 8bit chunks
# unsigned char token[4]; // 32bit token
# // ffffffaa
# // aaaaaaaa
# // NNNNNNNN
# // TTTTTTTT
# // TTTTTTTT
# // TTTTTTTT
# // TTTTTTTT
flags_bits = PacketFlags.new(flags).bits
header_bits =
'00' + # unused flags? # ff
flags_bits + # ffff
@ack.to_s(2).rjust(10, '0') # aa aaaa aaaa
puts "header bits: #{header_bits}"
header = header_bits.chars.groups_of(4).map do |four_bits|
four_bits.join('').to_i(2)
end
puts "header bytes: #{str_hex(header.pack("C*"))}"
header = [0x00, 0x00, 0x01] + str_bytes(@server_token)
data = (header + payload).pack('C*')
@s.send(data, 0, @ip, @port)
@ -212,6 +238,10 @@ class TwClient
def process_server_packet(data)
chunks = BigChungusTheChunkGetter.get_chunks(data)
chunks.each do |chunk|
if chunk.flags_vital
@netbase.ack = (@netbase.ack + 1) % NET_MAX_SEQUENCE
puts "got ack: #{@netbase.ack}"
end
process_chunk(chunk)
end
end