示例#1
0
 def messageHandler(self, sSocket):
     serverAddr= sSocket.getpeername()[0]
     serverPort=sSocket.getpeername()[1]
     sSocket.send(messages.version_pkt(MY_IP, serverAddr,serverPort).to_bytes())
     
     
     while True:
         dataReceived = sSocket.recv(1024)
         if not dataReceived:
             #will close the socket
             break;
         msg = MsgSerializable().from_bytes(dataReceived)
         print('on_new_server')
         print('received ',msg)
         if isinstance(msg,msg_version):
             self.outbound_connections.add(serverAddr)
             sSocket.send(msg_verack().to_bytes())
             print('sent verack')
             sSocket.send(msg_getaddr().to_bytes())
             print('sent msg_getaddr')
         if isinstance(msg,msg_addr):
             for peer in msg.addrs:
                 if peer.ip not in self.outbound_connections and peer.ip != MY_IP:
                     print('new peer found'+peer.ip)
                     t = threading.Thread(target=self.connect,args=(peer.ip, peer.port))
                     t.start()
                     
                 
         time.sleep(SLEEP_TIME)
     sSocket.close()
     
示例#2
0
 def messageHandler(self, clientsocket, addr):
     while True:
         dataReceived = clientsocket.recv(1024)
         if not dataReceived:
             #will close the socket
             break;
         msg = MsgSerializable().from_bytes(dataReceived)
         print('received ',msg)
         print( isinstance(msg,msg_version))
         if isinstance(msg,msg_version):
             clientsocket.send(msg_verack().to_bytes())
             self.inbound_connections.add(addr[0])
             print('sent verack')
             clientsocket.send( messages.version_pkt(MY_IP, addr[0],self.port).to_bytes() )
             print('sent version_pkt')
         if isinstance(msg,msg_getaddr):
             perrAddrs = []
             for peer in self.inbound_connections:
                 perrAddr = CAddress()
                 perrAddr.port=self.port
                 perrAddr.nTime = int(time.time())
                 perrAddr.ip = peer
                 perrAddrs.append(perrAddr)
             rMsg= msg_addr()
             rMsg.addrs = perrAddrs
             print(rMsg)
             clientsocket.send(rMsg.to_bytes())
             print('sent msg_addr')
             
         time.sleep(SLEEP_TIME)
     clientsocket.close()
     
示例#3
0
    def capture_messages(self,
                         expected_message_types: list,
                         timeout: int = 20,
                         buf_size: int = 1024,
                         ignore_empty: bool = False) -> list:

        deadline = time() + timeout
        found = []
        partial_message = None

        while expected_message_types and time() < deadline:

            try:
                received_data = self.connection.recv(buf_size)
                if partial_message:
                    received_data = partial_message + received_data
            except socket.timeout:
                continue

            if not received_data:
                sleep(0.1)
                continue

            for raw_message in self.split_message(received_data):

                try:
                    message = MsgSerializable.from_bytes(raw_message)
                except (SerializationError, SerializationTruncationError,
                        ValueError):
                    partial_message = raw_message
                    continue

                partial_message = None
                if not message:
                    # unknown message type, skipping
                    continue

                msg_type = type(message)

                if msg_type is msg_ping:
                    logger.debug('Got ping, sending pong.')
                    self.send_pong(message)
                elif msg_type is msg_version:
                    logger.debug('Saving version')
                    self.protocol_version = message

                if msg_type in expected_message_types:
                    found.append(message)
                    expected_message_types.remove(msg_type)
                    logger.debug('Found %s, %s more to catch',
                                 msg_type.command.upper(),
                                 len(expected_message_types))

        if not expected_message_types:
            return found

        if not ignore_empty:
            logger.error('Not all messages could be captured')
示例#4
0
 def _handle_recv(self):
     while True:
         try:
             msg = MsgSerializable.stream_deserialize(
                 self.conn.makefile(mode='r'),
                 protover=self.protover)
         except Exception as e:
             msg = e
             if not self._stopflag.is_set():
                 print("Peer connection closed unexpectedly.")
             break
         finally:
             self.recvq.put(msg)
示例#5
0
	def _process_message(self, **kwargs):
		msg = MsgSerializable.stream_deserialize(Wrapper(self.my_socket))

		if msg.command == b"version":  # TODO conglomerate these message strings into a dictionary
		    # Send Verack
		    # print('version: ', msg.strSubVer, msg.nVersion)
		    self.my_socket.send( msg_verack().to_bytes() )
		    return "version"
		elif msg.command == b"verack":
		    # print("verack: ", msg)
		    return "verack"
		elif msg.command == b"inv":
			pass
			# print("inv: ", msg.inv)
			# print(dir(msg))
			# print(type(msg.inv))
		elif msg.command == b"ping":
			# print("ping: ", msg)
			self.my_socket.send(msg_pong(msg.nonce).to_bytes())

		elif msg.command == b"getheaders":
			pass
			# print("getheaders received ")

		elif msg.command == b"addr":  # TODO this needs multi-message support
			# print("addr: size ", len(msg.addrs))
			for address in msg.addrs:
				node = Link(address.ip, address.port)
				self.results.add(node)
			return True
		elif msg.command == b"getdata":
			# print("getdata: ", msg.inv)
			if 'transaction' not in kwargs:
				return False
			the_tx =  kwargs['transaction']
			for request in msg.inv:
				if request.hash == the_tx.GetHash():
					print(threading.current_thread().name,"sending tx: ", self.link)
					# new message to send transaction
					to_send = msg_tx()
					to_send.tx = the_tx
					self.my_socket.send(to_send.to_bytes())
					# print("SENT OUR PC BRO TRANSACTION")
					return "donedone"
		else:
		    pass
		    # print("something else: ", msg.command, msg)

		return False
示例#6
0
 def process_data(self):
     while True:
         if len(self.recvbuf) < 4:
             return
         if self.recvbuf[:4] != self.netmagic.MESSAGE_START:
             raise ValueError("got garbage %s" % repr(self.recvbuf))
         if len(self.recvbuf) < 4 + 12 + 4 + 4:
             return
         msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
         if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
             return
         message = self.recvbuf[:4+12+4+4+msglen]
         self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
         f = BytesIO(message)
         try:
             msg = MsgSerializable.stream_deserialize(f)
         except ValueError:
             raise ValueError("invalid deserialization %s" % repr(self.recvbuf))  # noqa
         if msg is None:
             return
         self.got_message(msg)
示例#7
0
 def process_data(self):
     while True:
         if len(self.recvbuf) < 4:
             return
         if self.recvbuf[:4] != self.netmagic.MESSAGE_START:
             raise ValueError("got garbage %s" % repr(self.recvbuf))
         if len(self.recvbuf) < 4 + 12 + 4 + 4:
             return
         msglen = struct.unpack("<i", self.recvbuf[4 + 12:4 + 12 + 4])[0]
         if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
             return
         message = self.recvbuf[:4 + 12 + 4 + 4 + msglen]
         self.recvbuf = self.recvbuf[4 + 12 + 4 + 4 + msglen:]
         f = BytesIO(message)
         try:
             msg = MsgSerializable.stream_deserialize(f)
         except ValueError:
             raise ValueError("invalid deserialization %s" %
                              repr(self.recvbuf))  # noqa
         if msg is None:
             return
         self.got_message(msg)
示例#8
0
    def getblock(self, blkhash) -> CBlock:
        # block = self.blk_cache.get(blkhash)
        # if block is not None:
        #     return block

        ser_hash = b2lx(blkhash)
        try:
            # Lookup the block index, seek in the file
            fpos = self.db.get(('blocks:'+ser_hash).encode())
            fpos = struct.unpack('i', fpos)[0]
            self.blk_read.seek(fpos)
            # read and decode "block" msg
            msg = MsgSerializable.stream_deserialize(self.blk_read)
            if msg is None:
                return None
            block = msg.block
        except KeyError:
            return None

        # self.blk_cache.put(blkhash, block)

        return block
示例#9
0
 def run(self):
     while self.stop_client != True:
         # Read and store the data from the socket
         data = self.socket.recv(64)
         self.buffer.write(data)
         try:
             # Go at the beginning of the buffer
             self.buffer.seek(0)
             # Deserialize the message
             message = MsgSerializable().stream_deserialize(self.buffer)
             # Reset the buffer
             remaining = self.buffer.read()
             self.buffer = BytesIO()
             self.buffer.write(remaining)
             # Call handle function
             if message is not None:
                 handle_func_name = "handle_" + message.command.decode(
                     "utf-8")
                 handle_func = getattr(self, handle_func_name, None)
                 if handle_func:
                     handle_func(message)
         except SerializationTruncationError:
             # Read more data from the socket
             pass
 def test_read_msg_verack(self):
     f = BytesIO(self.verackbytes)
     m = MsgSerializable.stream_deserialize(f)
     self.assertEqual(m.command, msg_verack.command)
示例#11
0
 def test_fail_invalid_message(self):
     bad_verack_bytes = b'\xf8' + self.verackbytes[1:]
     f = BytesIO(bad_verack_bytes)
     with self.assertRaises(ValueError):
         MsgSerializable.stream_deserialize(f)
示例#12
0
    def run(self):
        try:
            self.s.connect((self.addr.ip, self.addr.port))
            version_pkt(self.addr.ip, self.addr.port).stream_serialize(self.s)
        except Exception as e:
            print(e)
            print("{}, {}: Version handshake failed with {}:{}".format(datetime.datetime.now(), self.name, self.addr.ip, self.addr.port))
            self._stop_request.set()

        # Make sure we dont send an addr or inv straight away
        self.lastaddr = time.time()
        self.lastinv = time.time()

        while not self._stop_request.is_set():
            # Send at most one of these three
            if time.time() - self.lastping > PING_INTERVAL:
                msg_ping(random.getrandbits(64)).stream_serialize(self.s)
                self.lastping = time.time()
            elif time.time() - self.lastaddr > ADDR_INTERVAL:
                out = msg_addr()
                # Grab 10 random addresses
                with address_lock:
                    random_addresses = random.sample(addresses, min(10, len(addresses)))
                for address in random_addresses:
                    caddr = CAddress()
                    # Lie a bit
                    caddr.nTime = int(time.time()) - random.randrange(300)
                    caddr.nServices = address.services
                    caddr.port = address.port
                    caddr.ip = address.ip
                    out.addrs.append(caddr)
                out.stream_serialize(self.s)
                self.lastaddr = time.time()
            elif time.time() - self.lastinv > INV_INTERVAL:
                out = msg_inv()
                out_inv = CInv()
                out_inv.type = BLOCK_TYPE
                out_inv.hash = guess_latest_block()
                out.inv = [out_inv]
                out.stream_serialize(self.s)
                self.lastinv = time.time()
            try:
                msg = MsgSerializable.stream_deserialize(self.s)
                t = time.time()

                if isinstance(msg, msg_version):
                    msg_verack().stream_serialize(self.s)
                elif isinstance(msg, msg_verack):
                    print("{}, {}: Version handshake complete".format(datetime.datetime.now(), self.name))
                elif isinstance(msg, msg_ping):
                    result = push({
                        "me": {
                            "ip": my_ipv4,
                            "port": my_port
                        },
                        "time": t,
                        "type": "ping",
                        "peer": {
                            "ip": self.addr.ip,
                            "port": self.addr.port
                        },
                        "last": {
                            "ping": self.lastping,
                            "inv": self.lastinv,
                            "addr": self.lastaddr
                        },
                        "raw": base64.b64encode(msg.to_bytes()).decode('utf-8'),
                        "data": msg.nonce
                    })
                    msg_pong(nonce=msg.nonce).stream_serialize(self.s)
                elif isinstance(msg, msg_pong):
                    result = push({
                        "me": {
                            "ip": my_ipv4,
                            "port": my_port
                        },
                        "time": t,
                        "type": "pong",
                        "peer": {
                            "ip": self.addr.ip,
                            "port": self.addr.port
                        },
                        "last": {
                            "ping": self.lastping,
                            "inv": self.lastinv,
                            "addr": self.lastaddr
                        },
                        "raw": base64.b64encode(msg.to_bytes()).decode('utf-8'),
                        "data": msg.nonce
                    })
                elif isinstance(msg, msg_getheaders):
                    pass
                elif isinstance(msg, msg_alert):
                    pass
                elif isinstance(msg, msg_inv):
                    if any(item.type == BLOCK_TYPE for item in msg.inv):
                        result = push({
                            "me": {
                                "ip": my_ipv4,
                                "port": my_port
                            },
                            "time": t,
                            "type": "inv",
                            "peer": {
                                "ip": self.addr.ip,
                                "port": self.addr.port
                            },
                            "last": {
                                "ping": self.lastping,
                                "inv": self.lastinv,
                                "addr": self.lastaddr
                            },
                            "raw": base64.b64encode(msg.to_bytes()).decode('utf-8'),
                            "data": [
                                {
                                    "type": "block" if item.type == BLOCK_TYPE else "tx",
                                    "hash": b2lx(item.hash)
                                } for item in msg.inv
                            ]
                        })
                    for inv in msg.inv:
                        if inv.type == BLOCK_TYPE:
                            append_latest_block(inv.hash)
                elif isinstance(msg, msg_addr):
                    discover_new_addresses(msg.addrs)
                else:
                    print("{}, {}: Unhandled message type: {}".format(datetime.datetime.now(), self.name, msg.command.decode('utf-8')))
            except socket.timeout:
                continue
            except SerializationTruncationError:
                print("{}, {}: **************** Socket closed. ****************".format(datetime.datetime.now(), self.name))
                break
        self.s.close()
        print("{}, {}: Stopped.".format(datetime.datetime.now(), self.name))
示例#13
0
 def send_pkt(self, pkt: MsgSerializable):
     self.sock.send(pkt.to_bytes())
示例#14
0
    def capture_messages(self,
                         expected_message_types: list,
                         timeout: int = 20,
                         buf_size: int = 1024,
                         ignore_empty: bool = False) -> list:
        '''
        Method for receiving messages from network nodes.

        Args:
            expected_message_types (list): list of message types to search for
            timeout (int): timeout for waiting for messages
            buf_size (int): buffer size that is going to be used for receiving messages
            ignore_empty (bool): flag for ignoring errors if the message that we're looking for wasn't found.
                Eg. this flag can be set to True when looking for reject messages because the absence of the
                reject message is not an error.

        Returns:
            list, None: list of received messages or None if none or not all expected message types were found

        Example:
            >>> from bitcoin.messages import msg_verack, msg_version
            >>> network.capture_messages([msg_version, msg_verack])
        '''
        deadline = time() + timeout
        found = []
        partial_message = None

        while expected_message_types and time() < deadline:

            try:
                received_data = self.connection.recv(buf_size)
                if partial_message:
                    received_data = partial_message + received_data
            except socket.timeout:
                continue

            if not received_data:
                sleep(0.1)
                continue

            for raw_message in self.split_message(received_data):

                try:
                    message = MsgSerializable.from_bytes(raw_message)
                except (SerializationError, SerializationTruncationError,
                        ValueError):
                    partial_message = raw_message
                    continue

                partial_message = None
                if not message:
                    # unknown message type, skipping
                    continue

                msg_type = type(message)

                if msg_type is msg_ping:
                    logger.debug('Got ping, sending pong.')
                    self.send_pong(message)
                elif msg_type is msg_version:
                    logger.debug('Saving version')
                    self.protocol_version = message

                if msg_type in expected_message_types:
                    found.append(message)
                    expected_message_types.remove(msg_type)
                    logger.debug('Found %s, %s more to catch',
                                 msg_type.command.upper(),
                                 len(expected_message_types))

        if not expected_message_types:
            return found

        if not ignore_empty:
            logger.error('Not all messages could be captured')