This commit is contained in:
committed by
Salad Dais
parent
7f4bf038d7
commit
e290c1377c
@@ -23,12 +23,12 @@ class Circuit(object):
|
||||
self.allow_timeout = True
|
||||
self.last_packet_out_id = 0 #id of the packet we last sent
|
||||
self.last_packet_in_id = 0 #id of the packet we last received
|
||||
#packets waiting to be acked, can be resent
|
||||
self.unacked_packets = {} #map of packet_id to packet
|
||||
|
||||
self.acks = [] #packets we need to ack
|
||||
self.unacked_packets = {} #packets we want acked, can be resent
|
||||
self.unack_packet_count = 0
|
||||
self.unack_packet_bytes = 9
|
||||
#packets waiting to be acked, can't be resent
|
||||
self.final_retry_packets = {} #map of packet_id to packet
|
||||
self.unack_packet_bytes = 0
|
||||
self.final_retry_packets = {} #packets we want acked, can't be resent
|
||||
self.final_packet_count = 0
|
||||
|
||||
def next_packet_id(self):
|
||||
@@ -39,7 +39,15 @@ class Circuit(object):
|
||||
#go through the packets waiting to be acked, and set them as acked
|
||||
pass
|
||||
|
||||
def collect_ack(self, packet_id):
|
||||
""" set a packet_id that this circuit needs to eventually ack
|
||||
(need to send ack out)"""
|
||||
self.acks.append(packet_id)
|
||||
|
||||
|
||||
def add_reliable_packet(self, sock, message_buffer, buffer_length, **kwds):
|
||||
""" add a packet that we want to be acked
|
||||
(want an incoming ack) """
|
||||
packet = Packet(sock, message_buffer, buffer_length, kwds)
|
||||
self.unack_packet_count += 1
|
||||
self.unack_packet_bytes += buffer_length
|
||||
@@ -61,11 +69,17 @@ class CircuitManager(object):
|
||||
#to a list
|
||||
pass
|
||||
|
||||
def get_circuit(self, host):
|
||||
if host in self.circuit_map:
|
||||
return self.circuit_map[host]
|
||||
|
||||
return None
|
||||
|
||||
def add_circuit(self, host, packet_in_id):
|
||||
circuit = Circuit(host, packet_in_id)
|
||||
|
||||
self.circuit_map[host] = circuit
|
||||
return circuit
|
||||
|
||||
def remove_circuit_data(self, host):
|
||||
pass
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import struct
|
||||
from uuid import UUID
|
||||
|
||||
from pyogp.lib.base.message.message_types import MsgType
|
||||
from pyogp.lib.base.message.message_types import MsgType, sizeof
|
||||
|
||||
class DataUnpacker(object):
|
||||
def __init__(self):
|
||||
@@ -24,9 +24,12 @@ class DataUnpacker(object):
|
||||
self.unpacker[MsgType.MVT_LLUUID] = self.__unpack_uuid
|
||||
self.unpacker[MsgType.MVT_BOOL] = '>B'
|
||||
self.unpacker[MsgType.MVT_IP_ADDR] = self.__unpack_string
|
||||
self.unpacker[MsgType.MVT_IP_PORT] = '>H'
|
||||
self.unpacker[MsgType.MVT_IP_PORT] = '>H'
|
||||
|
||||
def unpack_data(self, data, data_type):
|
||||
def unpack_data(self, data, data_type, start_index = 0):
|
||||
if start_index != 0:
|
||||
data = data[start_index:start_index+sizeof(data_type)]
|
||||
|
||||
if data_type in self.unpacker:
|
||||
unpack = self.unpacker[data_type]
|
||||
if callable(unpack):
|
||||
|
||||
@@ -8,17 +8,24 @@ from pyogp.lib.base.message.message_template_builder import MessageTemplateBuild
|
||||
from pyogp.lib.base.message.message_template_reader import MessageTemplateReader
|
||||
from pyogp.lib.base.message.message_template_dict import TemplateDictionary
|
||||
from pyogp.lib.base.message.message_dict import MessageDictionary
|
||||
from pyogp.lib.base.message.circuitdata import CircuitManager
|
||||
from pyogp.lib.base.message.message_types import PackFlags, sizeof
|
||||
from pyogp.lib.base.message.data_unpacker import DataUnpacker
|
||||
from pyogp.lib.base.message.net import *
|
||||
|
||||
class MessageSystem(object):
|
||||
def __init__(self):
|
||||
def __init__(self, port):
|
||||
#holds the details of the message, or how the messages should be sent,
|
||||
#built, and read
|
||||
self.message_details = None
|
||||
self.builder = None
|
||||
self.reader = None
|
||||
self.circuit_info = None
|
||||
self.socket = None
|
||||
|
||||
self.message_details = None
|
||||
self.builder = None
|
||||
self.reader = None
|
||||
self.circuit_manager = CircuitManager()
|
||||
self.port = port
|
||||
self.socket = None
|
||||
#the ID of the packet we most recently received
|
||||
self.receive_packet_id = -1
|
||||
|
||||
self.llsd_builder = LLSDMessageBuilder()
|
||||
#self.llsd_reader = LLSDMessageReader()
|
||||
|
||||
@@ -26,6 +33,10 @@ class MessageSystem(object):
|
||||
self.template_builder = MessageTemplateBuilder(template_dict)
|
||||
self.template_reader = MessageTemplateReader(template_dict)
|
||||
|
||||
self.socket = start_udp_connection(self.port)
|
||||
|
||||
self.unpacker = DataUnpacker()
|
||||
|
||||
def load_template(self, template_file, details_file):
|
||||
#use the parser to load the message_template.msg message templates
|
||||
parser = MessageTemplateParser(msg_tmpl)
|
||||
@@ -33,10 +44,100 @@ class MessageSystem(object):
|
||||
|
||||
return MessageDictionary(details_file), TemplateDictionary(template_list)
|
||||
|
||||
def find_circuit(self, host):
|
||||
circuit = self.circuit_manager.get_circuit(host)
|
||||
if circuit == None:
|
||||
#there is a case where we want to return None,
|
||||
#when the last packet was protected
|
||||
circuit = self.circuit_manager.add_circuit(host, self.receive_packet_id)
|
||||
|
||||
return circuit
|
||||
|
||||
def receive_check(self):
|
||||
#determine if we have any messages that can be received through UDP
|
||||
#also, check and decode the message we have received
|
||||
pass
|
||||
|
||||
#just sets it to the last reader we used
|
||||
self.reader = self.template_reader
|
||||
valid_packet = False
|
||||
acks = 0
|
||||
recv_reliable = False
|
||||
|
||||
while True:
|
||||
recv_reliable = False
|
||||
msg_buf, msg_size = receive_packet(self.socket)
|
||||
|
||||
#we have a message
|
||||
if msg_size > 0:
|
||||
#determine packet flags
|
||||
flag = ord(msg_buf[0])
|
||||
self.receive_packet_id = \
|
||||
self.unpacker.unpack_data(msg_buf[1:1+sizeof(MsgType.U32)], MsgType.U32)
|
||||
|
||||
#determine sender
|
||||
host = get_sender()
|
||||
circuit = self.find_circuit(host)
|
||||
|
||||
#ACK_FLAG - means the incoming packet is acking some old packets of ours
|
||||
if flag & PackFlags.LL_ACK_FLAG:
|
||||
#apparently, the number of acks is stored at the end
|
||||
#msg_size -= 1
|
||||
#acks += msg_buf[msg_size]
|
||||
#2 == packet ID size, 6 = min packet size
|
||||
#msg_size -= acks * 2 + 6
|
||||
|
||||
#looop
|
||||
#read the packet ID of the packets that the incoming packet is acking
|
||||
#tell the circuit that the packet with ID has been acked
|
||||
#end loop
|
||||
#if the circuit has no unacked packets, remove it from unacked circuits
|
||||
pass
|
||||
|
||||
#RELIABLE - means the message wants to be acked by us
|
||||
if flag & PackFlags.LL_RELIABLE_FLAG:
|
||||
recv_reliable = True
|
||||
|
||||
#RESENT - packet that wasn't previously acked was resent
|
||||
if flag & PackFlags.LL_RESENT_FLAG:
|
||||
#check if its a duplicate and the sender messed up somewhere
|
||||
#case - ack we sent wasn't received by the sender
|
||||
pass
|
||||
|
||||
valid_packet = self.template_reader.validate_message(msg_buf, msg_size)
|
||||
|
||||
#make sure packet validated correctly
|
||||
if valid_packet == True:
|
||||
#Case - UseCircuitCode - only packet allowed to be valid on an unprotected circuit
|
||||
if circuit == None:
|
||||
valid_packet = False
|
||||
continue
|
||||
#Case - trusted packets can only come in over trusted circuits
|
||||
elif circuit.is_trusted() and \
|
||||
self.template_reader.is_trusted() == False:
|
||||
valid_packet = False
|
||||
continue
|
||||
#Case - make sure its not a banned packet
|
||||
#...
|
||||
|
||||
valid_packet = self.template_reader.read_message(msg_buf)
|
||||
|
||||
#make sure packet was read correctly (still valid)
|
||||
if valid_packet == True:
|
||||
if recv_reliable == True:
|
||||
circuit.collect_ack(self.receive_packet_id)
|
||||
|
||||
#we are attempting to get a single packet, so break once we get it
|
||||
#or we have no more messages to read
|
||||
if valid_packet == True and msg_size > 0:
|
||||
break
|
||||
|
||||
#now determine if the packet we got was valid (and therefore is stored
|
||||
#in the reader)
|
||||
if valid_packet == False:
|
||||
self.template_reader.clear_message()
|
||||
|
||||
return valid_packet
|
||||
|
||||
|
||||
def send_reliable(self, host):
|
||||
""" Wants to be acked """
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import socket
|
||||
#from pyogp.lib.base.message.zerocode import *
|
||||
|
||||
#maybe put this isnt' a class
|
||||
|
||||
@@ -8,7 +9,9 @@ def send_packet(socket, send_buffer, size, ip_addr, port):
|
||||
|
||||
#returns message and size, or None if error
|
||||
def receive_packet(socket):
|
||||
pass
|
||||
buf = 10000
|
||||
data, addr = socket.recvfrom(buf)
|
||||
return data, len(data)
|
||||
|
||||
def start_udp_connection(port):
|
||||
""" Starts a udp connection, returning socket and port. """
|
||||
|
||||
@@ -11,7 +11,7 @@ class TestMessageSystem(unittest.TestCase):
|
||||
pass
|
||||
|
||||
def setUp(self):
|
||||
self.message_system = MessageSystem()
|
||||
self.message_system = MessageSystem(80)
|
||||
|
||||
def test_init(self):
|
||||
assert self.message_system.message_dict.get_message_flavor('UseCircuitCode') \
|
||||
|
||||
Reference in New Issue
Block a user