def should_throw_alg_exception_if_packet_seen_before_password(): engine = engine_fake() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # scenario: gruel_recv happens without a password having been set b_error = False try: r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_heartbeat_payload())) except: b_error = True if b_error: return True else: log('expected an exception, did not get one') return False
def at_turn(self, activity): data = self.cog.pull() if data: activity.mark( l='scenario_broadcast_listen', s='found data in cog') log('! received [%s] :)'%data)
def engine_on_tcp_condrop(self, cs_tcp_condrop): engine = cs_tcp_condrop.engine client_sid = cs_tcp_condrop.client_sid message = cs_tcp_condrop.message # self.received = None log('** conndrop callback %s'%(client_sid))
def at_turn(self, activity): if self.orb.turn_count >= self.exit_turn: activity.mark( l='scenario_close_tcp_servers', s='reached turn count') log('ordering remove for %s'%self.sid) engine.close_tcp_server(self.sid) self.orb.cogs.remove(self)
def engine_on_tcp_condrop(self, cs_tcp_condrop): engine = cs_tcp_condrop.engine client_sid = cs_tcp_condrop.client_sid message = cs_tcp_condrop.message # log("condrop/%s/%s/%s"%(self.cog_h, client_sid, message)) while self.q_received: self.q_received.pop()
def engine_on_tcp_connect(self, cs_tcp_connect): engine = cs_tcp_connect.engine client_sid = cs_tcp_connect.client_sid addr = cs_tcp_connect.addr port = cs_tcp_connect.port # log('connect/%s/%s/%s'%(client_sid, addr, port)) self.received = deque()
def engine_on_tcp_condrop(self, cs_tcp_condrop): engine = cs_tcp_condrop.engine client_sid = cs_tcp_condrop.client_sid message = cs_tcp_condrop.message # log("condrop/%s/%s/%s"%(self.name, client_sid, message)) self.received = None self.b_dropped = True
def engine_on_tcp_condrop(self, cs_tcp_condrop): engine = cs_tcp_condrop.engine client_sid = cs_tcp_condrop.client_sid message = cs_tcp_condrop.message # log("condrop/%s/%s/%s" % (self.name, client_sid, message)) key = (engine, client_sid) del self.received[key]
def engine_on_tcp_condrop(self, cs_tcp_condrop): engine = cs_tcp_condrop.engine client_sid = cs_tcp_condrop.client_sid message = cs_tcp_condrop.message # log("condrop/[snoop]/%s/%s"%(client_sid, message)) self.client_sid = None self._open_server()
def on_announce_tcp_connect(self, ip, port): if self.ip_validator.is_ok(ip): self.orb.nearcast(cog_h=self.cog_h, message_h='nearnote', s='confirm that %s is ok' % (ip)) else: log('invalid ip %s' % ip) self.orb.nearcast(cog_h=self.cog_h, message_h='please_tcp_boot')
def on_start_service(self, ip, port, password): if self.server_sid != None: log('weird: already listening to server (%s)'%self.server_sid) raise Exception('algorithm exception') if self.client_sid != None: log('weird: client connectied') raise Exception('algorithm exception') self.server_addr = ip self.server_port = port self._engine_raise_server()
def engine_on_tcp_connect(self, cs_tcp_connect): engine = cs_tcp_connect.engine client_sid = cs_tcp_connect.client_sid addr = cs_tcp_connect.addr port = cs_tcp_connect.port # self._close_server() self.q_outbound = deque() self.client_sid = client_sid log("connect/[snoop]/%s/%s/%s" % (client_sid, addr, port))
def engine_on_tcp_connect(self, cs_tcp_connect): engine = cs_tcp_connect.engine client_sid = cs_tcp_connect.client_sid addr = cs_tcp_connect.addr port = cs_tcp_connect.port # log("connect/%s/%s/%s/%s" % (self.name, client_sid, addr, port)) key = (engine, client_sid) self.received[key] = deque() engine.send(sid=client_sid, data='')
def at_turn(self, activity): if self.turn_count <= 30: log('turn %s'%self.turn_count) elif self.turn_count == 30: log('test should have succeeded or dropped by here.') # for cog in self.cogs: cog.at_turn( activity=activity) self.turn_count += 1
def on_line(self, line): log('on_line %s'%(line)) (head, rest) = parse_command_line( line=line) if head == None: return elif head == 'connect': self.cog_console.mi_nearcast_connect() else: self.cog_console.mi_network_write( m='error, no command %s'%(head))
def event_loop(self): ''' Lets the engine take ownership of the application's initiative by running the event loop. Typically, an application would set up its orbs, add them to the engine, and then call this function to surrender initiative to the engine. ''' timeout = 0 try: while True: timeout = self.turn(timeout=timeout) except QuitEvent as e: log('QuitEvent [%s]' % (e.message))
def on_nearcast_message(self, cog_h, message_h, d_fields): if not self.b_enabled: return def format_message(): sb = [] sb.append('%s>%s' % (cog_h, message_h)) for key in self.nearcast_schema[message_h]: sb.append('%s:%s' % (key, d_fields[key])) return '/'.join(sb) nice = format_message() log(nice)
def engine_on_tcp_connect(self, cs_tcp_connect): engine = cs_tcp_connect.engine client_sid = cs_tcp_connect.client_sid addr = cs_tcp_connect.addr port = cs_tcp_connect.port # self._close_server() self._register_client( client_sid=client_sid) # log("connect/[snoop]/%s/%s/%s"%( client_sid, addr, port))
def metasock_create_broadcast_sender(engine, sid, addr, port): log('metasock_create_broadcast_sender %s (%s:%s)' % (sid, addr, port)) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.connect((addr, port)) # ms = Metasock(engine, sid, addr, port) ms.sock = sock ms.can_it_recv = False ms.can_it_send = True ms.is_it_a_tcp_server = False ms.is_it_a_tcp_client = False return ms
def metasock_create_broadcast_listener(engine, sid, addr, port, cb_sub_recv): log('metasock_create_broadcast_listener %s (%s:%s)' % (sid, addr, port)) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((addr, port)) sock.setblocking(0) # ms = Metasock(engine, sid, addr, port) ms.sock = sock ms.can_it_recv = True ms.can_it_send = False ms.recv_len = engine.mtu ms.cb_sub_recv = cb_sub_recv return ms
def engine_on_tcp_connect(self, cs_tcp_connect): engine = cs_tcp_connect.engine client_sid = cs_tcp_connect.client_sid addr = cs_tcp_connect.addr port = cs_tcp_connect.port # log("connect/%s/%s/%s/%s"%( self.cog_h, client_sid, addr, port)) engine.send( sid=client_sid, data='')
def scenario_broadcast_post_with_del(engine): addr = '127.255.255.255' port = 50000 log('to test this, qd %s %s'%(addr, port)) # class Cog(object): def __init__(self, engine, orb, addr, port): self.engine = engine self.orb = orb self.addr = addr self.port = port # self.sid = engine.open_broadcast_sender( addr=addr, port=port) self.last_t = time.time() self.count_turns = 0 def at_turn(self, activity): t = time.time() if t - self.last_t > 1: activity.mark( l='scenario_broadcast_post_with_del', s='time interval') log('sending to %s:%s'%(self.addr, self.port)) engine.send( sid=self.sid, data='from poke [%s]'%(t)) self.last_t = t self.count_turns += 1 if self.count_turns == 20: activity.mark( l='scenario_broadcast_post_with_del', s='count interval') log('cog is self-closing') engine.close_broadcast_sender(self.sid) self.orb.cogs.remove(self) class Orb(object): def __init__(self, engine): self.engine = engine # self.cogs = [] def at_turn(self, activity): for cog in self.cogs: cog.at_turn( activity=activity) orb = Orb(engine) engine.add_orb(orb) cog = Cog(engine, orb, addr, port) orb.cogs.append(cog) engine.event_loop()
def _engine_on_tcp_recv(self, cs_tcp_recv): engine = cs_tcp_recv.engine client_sid = cs_tcp_recv.client_sid data = cs_tcp_recv.data # # we unpack the message and broadcast it so that the login # server can look at it try: d_gruel = self.gruel_puff.unpack( payload=data) self.nc_gruel_recv( d_gruel=d_gruel) except: log('Could not parse payload. Likely protocol error.') self.nc_please_tcp_boot()
def engine_on_tcp_connect(self, cs_tcp_connect): addr = cs_tcp_connect.addr port = cs_tcp_connect.port engine = cs_tcp_connect.engine sid = cs_tcp_connect.client_sid # log("%s: connect from %s:%s"%( self.name, addr, port)) key = (engine, sid) self.received[key] = deque() engine.send( sid=sid, data='hello, %s:%s!\n'%(addr, port))
def at_turn(self, activity): if self.b_dropped: return while self.received: activity.mark( l='scenario_tcp_client_mixed_scenarios', s='received data from net') log('client|%s'%(self.received.popleft().strip())) if self.orb.turn_count == self.close_turn: log('closing %s/%s on turn %s'%( self.name, self.sid, self.orb.turn_count)) activity.mark( l='scenario_tcp_client_mixed_scenarios', s='reached turn count') engine.close_tcp_client(self.sid) self.orb.cogs.remove(self)
def metasock_create_accepted_tcp_client(engine, sid, csock, addr, port, cb_tcp_condrop, cb_tcp_recv, cb_ms_close): """This is in the chain of functions that get called after a tcp server accepts a client connection.""" log('metasock_create_accepted_tcp_client %s (%s:%s)' % (sid, addr, port)) ms = Metasock(engine, sid, addr, port) ms.sock = csock ms.can_it_recv = True ms.can_it_send = True ms.recv_len = engine.mtu ms.is_it_a_tcp_server = False ms.is_it_a_tcp_client = True ms.cb_tcp_condrop = cb_tcp_condrop ms.cb_tcp_recv = cb_tcp_recv ms.cb_ms_close = cb_ms_close return ms
def metasock_create_tcp_client(engine, sid, addr, port, cb_tcp_connect, cb_tcp_condrop, cb_tcp_recv): log('metasock_create_tcp_client %s (%s:%s)' % (sid, addr, port)) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(0) sock.connect_ex((addr, port)) # ms = Metasock(engine, sid, addr, port) ms.sock = sock ms.can_it_recv = True ms.can_it_send = True ms.recv_len = engine.mtu ms.is_it_a_tcp_server = False ms.is_it_a_tcp_client = True ms.is_tcp_client_connecting = True ms.cb_tcp_connect = cb_tcp_connect ms.cb_tcp_condrop = cb_tcp_condrop ms.cb_tcp_recv = cb_tcp_recv return ms
def at_turn(self, activity): t = time.time() if t - self.last_t > 1: activity.mark( l='scenario_broadcast_post_with_del', s='time interval') log('sending to %s:%s'%(self.addr, self.port)) engine.send( sid=self.sid, data='from poke [%s]'%(t)) self.last_t = t self.count_turns += 1 if self.count_turns == 20: activity.mark( l='scenario_broadcast_post_with_del', s='count interval') log('cog is self-closing') engine.close_broadcast_sender(self.sid) self.orb.cogs.remove(self)
def distribute(self): ''' The event loop should periodically call this. This message distributes pending nearcast messages from a buffer and out to the cogs. ''' while self.pending: (cog_h, message_h, d_fields) = self.pending.popleft() rname = 'on_%s' % (message_h) if self.nearcast_snoop: self.nearcast_snoop.on_nearcast_message(cog_h=cog_h, message_h=message_h, d_fields=d_fields) for cog in self.cogs: if rname in dir(cog): fn = getattr(cog, rname) try: fn(**d_fields) except: log('problem is %s:%s' % (cog.cog_h, rname)) raise
def on_gruel_recv(self, d_gruel): if None == self.expected_password: raise Exception("Alg exception. Expected password is empty.") message_h = d_gruel['message_h'] if self.state == ServerCustomsState.awaiting_login: if message_h != 'client_login': log('expected client_login but got %s'%(message_h)) self._to_rejection( s='expected login message first') return self._attempt_to_handle_login( d_gruel=d_gruel) elif self.state == ServerCustomsState.authorised: if message_h == 'client_login': self._to_rejection( s='it is invalid to log in twice') return elif message_h == 'server_greet': self._to_rejection('client sent server_greet. invalid.') return elif message_h == 'server_bye': self._to_rejection('client sent server_bye. invalid.') return elif message_h == 'heartbeat': raise Exception('xxx') elif message_h == 'docdata': b_complete = d_gruel['b_complete'] data = d_gruel['data'] # self.recv_doc_buffer.append(data) if b_complete == 1: doc = ''.join(self.recv_doc_buffer) self.recv_doc_buffer = [] self.nc_doc_recv( doc=doc) return else: raise Exception('xxx') else: log('Currently disconnecting client. Ignoring %s.'%message_h) return