def get_name(self):
     #do this until we have a name
     while self.name == '':
         #prompt user
         msg_name_prompt = message.Message()
         msg_name_prompt.clear()
         msg_name_prompt.set_text('Please input your name')
         self.send(message.pack(msg_name_prompt))
         #get name from socket
         msg_client_name = message.Message(data=message.unpack(self.conn.recv(DATA_SIZE)))
         while msg_client_name.get_type() == 'ping':
             self.handle_ping()
             msg_client_name = message.Message(data=message.unpack(self.conn.recv(DATA_SIZE)))
         name_from_client = msg_client_name.get_text()
         #check name length
         if len(name_from_client) > NAME_SIZE_LIMIT:
             msg_name_too_long = message.Message()
             msg_name_too_long.set_text('That name is too long')
             self.send(message.pack(msg_name_too_long))
         else:
             #check name isnt already taken
             name_taken = False
             for c in CLIENTS:
                 if name_from_client == c.name:
                     name_taken = True
             if name_taken:
                 msg_name_taken = message.Message()
                 msg_name_taken.set_text('That name is already taken')
                 self.send(message.pack(msg_name_taken))
             else:
                 #if we pass all the tests then set the clien name
                 self.name = name_from_client
    def run(self):
        try:
            #get the name from the client
            self.get_name()

            #tell everyone there is a new client
            msg_user_join = message.Message()
            msg_user_join.set_type('text')
            msg_user_join.set_text('{} has joined the chat!'.format(self.name))
            msg_user_join.set_time(get_time())
            print(message.pack(msg_user_join))
            broadcast(message.pack(msg_user_join))

            #add this client to the client list
            CLIENTS.append(self)

            msg_data = self.conn.recv(DATA_SIZE)
            while msg_data:
                msg = message.Message(data=message.unpack(msg_data))
                if msg.get_text() != None:
                    msg.set_time(time.strftime('%H:%M:%S', time.localtime()))
                    msg.set_sender(self.name, color=self.name_color, clan=self.clan)

                    if msg.get_type() == 'ping':
                        self.handle_ping()
                    elif msg.get_type() == 'leave':
                        self.leave()
                    elif msg.get_type() == 'text':
                        if msg.get_text().split()[0] in USER_COMMANDS:
                            if not handle_user_command(self, msg):
                                msg_invalid_command = message.Message()
                                msg_invalid_command.set_type('text')
                                msg_invalid_command.set_text('Invalid command. view /help')
                                self.send(message.pack(msg_invalid_command))
                            print('PASS')
                        else:
                            if len(msg.get_text()) > MSG_SIZE_MAX:
                                error_msg = message.Message()
                                error_msg.set_type('error')
                                error_msg.set_sender('[SERVER]')
                                error_msg.set_time(get_time())
                                error_msg.set_text('Your message was too long. Max is 200 characters.')
                                self.send(message.pack(error_msg))
                                print('{} attempted to send a LARGE message'.format(self.address))
                            else:
                                #the formatted message as it will be sent to all users
                                msg.print()
                                broadcast(message.pack(msg))
                    else:
                        print('Unknown message type: {}'.format(message.unpack(msg)))
                msg_data = self.conn.recv(DATA_SIZE)
        except Exception as e:
            print(e)
            print("Connection Lost to {}".format(self.address))
            self.leave()
Example #3
0
    def get_name(self):
        #do this until we have a name
        while self.name == '':

            #prompt user
            msg_name_prompt = message.Message()
            msg_name_prompt.clear()
            msg_name_prompt.set_text('Please input your name')
            self.send(message.pack(msg_name_prompt))

            try:
                #get name from socket while the message received is not a ping
                msg_client_name = message.Message(data=message.unpack(self.conn.recv(DATA_SIZE)))
                while msg_client_name.get_type() == 'ping':
                    self.handle_ping()
                    msg_client_name = message.Message(data=message.unpack(self.conn.recv(DATA_SIZE)))
                name_from_client = msg_client_name.get_text()
            except:
                #if the data from the client is malformed then restart this process
                break

            #verify name length
            if len(name_from_client) > NAME_SIZE_LIMIT:
                # if the name is too long restart
                msg_name_too_long = message.Message()
                msg_name_too_long.set_type('text')
                msg_name_too_long.set_text('That name is too long. Max: {} characters'.format(NAME_SIZE_LIMIT))
                self.send(message.pack(msg_name_too_long))
            else:
                #verify name isnt already taken
                name_taken = False
                for c in CLIENTS:
                    if name_from_client == c.name:
                        name_taken = True

                # if the name is taken then restart
                if name_taken:
                    msg_name_taken = message.Message()
                    msg_name_taken.set_type('text')
                    msg_name_taken.set_text('That name is already taken')
                    self.send(message.pack(msg_name_taken))
                else:
                    #if we pass all the tests then set the clien name
                    self.name = name_from_client
Example #4
0
def listen_loop(socket):
    try:
        msg_data = socket.recv(DATA_SIZE)
        while RUNNING and msg_data:
            #msg = message.Message(data=message.unpack(data))
            #msg.print()
            msg_recv = message.Message(data=message.unpack(msg_data))
            if msg_recv.get_type() != 'ping':
                print(msg_recv)
            msg_data = socket.recv(DATA_SIZE)
    except Exception as e:
        print(e)
        print('Connection to server lost!!!')
Example #5
0
def passage_outbound_messages(outbound_socket, userland_outbound_queue, driver):
   try:
      outbound_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
      peer = outbound_socket.getpeername()

      outbound_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
      outbound_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, KEEPALIVE_PROBE_COUNT)
      outbound_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, KEEPALIVE_IDLE_TIMEOUT)
      outbound_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, KEEPALIVE_RETRY_SEND_PROBE)

      while True:
         try:
            syslog.syslog(syslog.LOG_INFO, "Pulling packet from output queue (down)...")
            id, payload = message.unpack(userland_outbound_queue.pull())

            if id not in TYPE_BY_ID:
               raise InvalidApplicationMessage("The type of the message in the queue is invalid.", id)

            if len(payload) > MAX_PAYLOAD:
               raise InvalidApplicationMessage("The lenght of the payload is greater than the expected.", payload)

            type = TYPE_BY_ID[id]
            if type == 'LOOP' and struct.unpack(">B", payload[2])[0] == LOOP_SUBTYPE_BY_NAME['BreakLinkForced']:
               syslog.syslog(syslog.LOG_INFO, "Breaking the link forced. Shutdown the socket...")
               return

            if type == 'LOOP' and not driver.handle_loop_message(payload[2:]):
                continue #loop message dicarted

            size = struct.pack('>H', len(payload))
            
            assert len(type) == 4
            assert len(size) == 2

            syslog.syslog(syslog.LOG_DEBUG, "Sending %s packet to the remote node %s: %s [%s]" % (type, str(peer), " ".join(map(lambda c: hex(ord(c)), type+size+payload)), "".join([(c if ord('0') <= ord(c) <= ord('Z') else '.') for c in type+size+payload]) ))
            _send(outbound_socket, type+size+payload, peer)
            ack = _recv(outbound_socket, 1, peer)
            if ack != "A":
               raise InvalidNetworkMessage("The ACK has is invalid '%s' for the message sent" % hex(ord(ack)), type+size+payload, peer)

         except InvalidApplicationMessage, e:
            syslog.syslog(syslog.LOG_CRIT, "%s\n%s" % (traceback.format_exc(), str(e)))

   except socket.error, e:
      raise UnstableChannel("The other side (other peer) is not responding. It seem to be down.", peer, e)
Example #6
0
def listen_loop(socket):
    try:
        #receive data
        msg_data = socket.recv(DATA_SIZE)
        while RUNNING and msg_data:
            #msg = message.Message(data=message.unpack(data))
            #msg.print()
            msg_recv = message.Message(data=message.unpack(msg_data))

            #print the message if it isnt a ping
            if msg_recv.get_type() != 'ping':
                print(msg_recv)

            #continue to receive data
            msg_data = socket.recv(DATA_SIZE)
    except Exception as e:
        #handle exceptions
        print(e)
        print('Connection to server lost!!!')
Example #7
0
    def run(self):
        try:
            #get the name from the client
            self.get_name()

            #tell everyone there is a new client
            msg_user_join = message.Message()
            msg_user_join.set_type('text')
            msg_user_join.set_text('{} has joined the chat!'.format(self.name))
            msg_user_join.set_time(get_time())
            broadcast(message.pack(msg_user_join))

            #add this client to the client list
            CLIENTS.append(self)

            # main data listen loop
            msg_data = self.conn.recv(DATA_SIZE)
            while msg_data:
                # turn the data into a message
                msg = message.Message(data=message.unpack(msg_data))
                if msg.get_text() != None:
                    # set the values of the message such as the time and the sender
                    msg.set_time(get_time())
                    msg.set_sender(self.name, color=self.name_color, clan=self.clan)

                    #handle message types
                    if msg.get_type() == 'ping':
                        self.handle_ping()
                    elif msg.get_type() == 'leave':
                        self.leave()
                    elif msg.get_type() == 'text':
                        #check if the msg the user sent is a command
                        if msg.get_text().split()[0] in USER_COMMANDS:
                            #handle the user command
                            if not handle_user_command(self, msg):
                                #if the user command fails
                                #tell the user
                                msg_invalid_command = message.Message()
                                msg_invalid_command.set_type('text')
                                msg_invalid_command.set_text('Invalid command. view /help')
                                self.send(message.pack(msg_invalid_command))
                        else:
                            #check the text from the user is smaller than the max acceptable size
                            if len(msg.get_text()) > MSG_SIZE_MAX:
                                error_msg = message.Message()
                                error_msg.set_type('error')
                                error_msg.set_sender('[SERVER]')
                                error_msg.set_time(get_time())
                                error_msg.set_text('Your message was too long. Max is 200 characters.')
                                self.send(message.pack(error_msg))
                                print('{} attempted to send a LARGE message'.format(self.address))
                            else:
                                #broadcast the message to the clients
                                broadcast(message.pack(msg))
                                if SHOW_CLIENT_MESSAGES:
                                    print(msg)
                    else:
                        #handle unknown cases
                        print('Unknown message type: {}'.format(message.unpack(msg)))
                #continue to listen for data from the client
                msg_data = self.conn.recv(DATA_SIZE)
        except Exception as e:
            #handle exceptions
            #i am not the most familiar with the python exceptions
            #so im printing as much information to both learn and debug
            #this does lead to a messy server console
            exc_information = sys.exc_info()
            print(exc_information)
            print("Connection Lost to {}".format(self.address))
            self.leave()
Example #8
0
def passage_outbound_messages(outbound_socket, userland_outbound_queue,
                              driver):
    try:
        outbound_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        peer = outbound_socket.getpeername()

        outbound_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        outbound_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT,
                                   KEEPALIVE_PROBE_COUNT)
        outbound_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE,
                                   KEEPALIVE_IDLE_TIMEOUT)
        outbound_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL,
                                   KEEPALIVE_RETRY_SEND_PROBE)

        while True:
            try:
                syslog.syslog(syslog.LOG_INFO,
                              "Pulling packet from output queue (down)...")
                id, payload = message.unpack(userland_outbound_queue.pull())

                if id not in TYPE_BY_ID:
                    raise InvalidApplicationMessage(
                        "The type of the message in the queue is invalid.", id)

                if len(payload) > MAX_PAYLOAD:
                    raise InvalidApplicationMessage(
                        "The lenght of the payload is greater than the expected.",
                        payload)

                type = TYPE_BY_ID[id]
                if type == 'LOOP' and struct.unpack(
                        ">B", payload[2]
                )[0] == LOOP_SUBTYPE_BY_NAME['BreakLinkForced']:
                    syslog.syslog(
                        syslog.LOG_INFO,
                        "Breaking the link forced. Shutdown the socket...")
                    return

                if type == 'LOOP' and not driver.handle_loop_message(
                        payload[2:]):
                    continue  #loop message dicarted

                size = struct.pack('>H', len(payload))

                assert len(type) == 4
                assert len(size) == 2

                syslog.syslog(
                    syslog.LOG_DEBUG,
                    "Sending %s packet to the remote node %s: %s [%s]" %
                    (type, str(peer), " ".join(
                        map(lambda c: hex(ord(c)), type + size + payload)),
                     "".join([(c if ord('0') <= ord(c) <= ord('Z') else '.')
                              for c in type + size + payload])))
                _send(outbound_socket, type + size + payload, peer)
                ack = _recv(outbound_socket, 1, peer)
                if ack != "A":
                    raise InvalidNetworkMessage(
                        "The ACK has is invalid '%s' for the message sent" %
                        hex(ord(ack)), type + size + payload, peer)

            except InvalidApplicationMessage, e:
                syslog.syslog(syslog.LOG_CRIT,
                              "%s\n%s" % (traceback.format_exc(), str(e)))

    except socket.error, e:
        raise UnstableChannel(
            "The other side (other peer) is not responding. It seem to be down.",
            peer, e)