def bm_command_addr(self): addresses = self._decode_addr() for i in addresses: seenTime, stream, services, ip, port = i decodedIP = protocol.checkIPAddress(str(ip)) if stream not in state.streamsInWhichIAmParticipating: continue if decodedIP is not False and seenTime > time.time() - BMProto.addressAlive: peer = state.Peer(decodedIP, port) try: if knownnodes.knownNodes[stream][peer]["lastseen"] > seenTime: continue except KeyError: pass if len(knownnodes.knownNodes[stream]) < int(BMConfigParser().get("knownnodes", "maxnodes")): with knownnodes.knownNodesLock: try: knownnodes.knownNodes[stream][peer]["lastseen"] = seenTime except (TypeError, KeyError): knownnodes.knownNodes[stream][peer] = { "lastseen": seenTime, "rating": 0, "self": False, } addrQueue.put((stream, peer, self.destination)) return True
def bm_command_addr(self): # BMProto.bm_command_object(self) addresses = self._decode_addr() # only allow peer discovery from private IPs in order to avoid attacks from random IPs on the internet if not self.local: return True remoteport = False for i in addresses: seenTime, stream, services, ip, port = i decodedIP = protocol.checkIPAddress(ip) if stream not in state.streamsInWhichIAmParticipating: continue if seenTime < time.time( ) - BMProto.maxTimeOffset or seenTime > time.time( ) + BMProto.maxTimeOffset: continue if decodedIP is False: # if the address isn't local, interpret it as the hosts' own announcement remoteport = port if remoteport is False: return True logger.debug("received peer discovery from %s:%i (port %i):", self.destination.host, self.destination.port, remoteport) if self.local: peerDiscoveryQueue.put( state.Peer(self.destination.host, remoteport)) return True
def __init__(self, address=None, sock=None): BMProto.__init__(self, address=address, sock=sock) self.verackReceived = False self.verackSent = False self.streams = [0] self.fullyEstablished = False self.connectedAt = 0 self.skipUntil = 0 if address is None and sock is not None: self.destination = Peer(*sock.getpeername()) self.isOutbound = False TLSDispatcher.__init__(self, sock, server_side=True) self.connectedAt = time.time() logger.debug( 'Received connection from %s:%i', self.destination.host, self.destination.port) self.nodeid = randomBytes(8) elif address is not None and sock is not None: TLSDispatcher.__init__(self, sock, server_side=False) self.isOutbound = True logger.debug( 'Outbound proxy connection to %s:%i', self.destination.host, self.destination.port) else: self.destination = address self.isOutbound = True self.create_socket( socket.AF_INET6 if ":" in address.host else socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) TLSDispatcher.__init__(self, sock, server_side=False) self.connect(self.destination) logger.debug( 'Connecting to %s:%i', self.destination.host, self.destination.port) try: self.local = ( protocol.checkIPAddress( protocol.encodeHost(self.destination.host), True) and not protocol.checkSocksIP(self.destination.host) ) except socket.error: # it's probably a hostname pass self.network_group = protocol.network_group(self.destination.host) ObjectTracker.__init__(self) # pylint: disable=non-parent-init-called self.bm_proto_reset() self.set_state("bm_header", expectBytes=protocol.Header.size)
def handle_read(self): try: (recdata, addr) = self.socket.recvfrom(AdvancedDispatcher._buf_len) except socket.error as e: logger.error("socket error: %s", str(e)) return self.destination = state.Peer(addr[0], addr[1]) encodedAddr = protocol.encodeHost(addr[0]) if protocol.checkIPAddress(encodedAddr, True): self.local = True else: self.local = False # overwrite the old buffer to avoid mixing data and so that self.local works correctly self.read_buf = recdata self.bm_proto_reset() receiveDataQueue.put(self.listening)
def handle_read(self): try: (recdata, addr) = self.socket.recvfrom(AdvancedDispatcher._buf_len) except socket.error as e: logger.error("socket error: %s", str(e)) return self.destination = state.Peer(addr[0], addr[1]) encodedAddr = protocol.encodeHost(addr[0]) if protocol.checkIPAddress(encodedAddr, True): self.local = True else: self.local = False # overwrite the old buffer to avoid mixing data and so that self.local works correctly self.read_buf[0:] = recdata self.bm_proto_reset() receiveDataQueue.put(self.listening)
def processonion(data): """Process onionpeer object""" readPosition = 20 # bypass the nonce, time, and object type length = decodeVarint(data[readPosition:readPosition + 10])[1] readPosition += length stream, length = decodeVarint(data[readPosition:readPosition + 10]) readPosition += length # it seems that stream is checked in network.bmproto port, length = decodeVarint(data[readPosition:readPosition + 10]) host = protocol.checkIPAddress(data[readPosition + length:]) if not host: return peer = state.Peer(host, port) with knownnodes.knownNodesLock: knownnodes.addKnownNode(stream, peer, is_self=state.ownAddresses.get(peer))
def __init__(self, address=None, sock=None): BMProto.__init__(self, address=address, sock=sock) self.verackReceived = False self.verackSent = False self.streams = [0] self.fullyEstablished = False self.connectedAt = 0 self.skipUntil = 0 if address is None and sock is not None: self.destination = state.Peer(sock.getpeername()[0], sock.getpeername()[1]) self.isOutbound = False TLSDispatcher.__init__(self, sock, server_side=True) self.connectedAt = time.time() logger.debug("Received connection from %s:%i", self.destination.host, self.destination.port) self.nodeid = randomBytes(8) elif address is not None and sock is not None: TLSDispatcher.__init__(self, sock, server_side=False) self.isOutbound = True logger.debug("Outbound proxy connection to %s:%i", self.destination.host, self.destination.port) else: self.destination = address self.isOutbound = True if ":" in address.host: self.create_socket(socket.AF_INET6, socket.SOCK_STREAM) else: self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) TLSDispatcher.__init__(self, sock, server_side=False) self.connect(self.destination) logger.debug("Connecting to %s:%i", self.destination.host, self.destination.port) encodedAddr = protocol.encodeHost(self.destination.host) if protocol.checkIPAddress(encodedAddr, True) and not protocol.checkSocksIP(self.destination.host): self.local = True else: self.local = False #shared.connectedHostsList[self.destination] = 0 ObjectTracker.__init__(self) self.bm_proto_reset() self.set_state("bm_header", expectBytes=protocol.Header.size)
def chooseConnection(stream): haveOnion = BMConfigParser().safeGet("bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS' if state.trustedPeer: return state.trustedPeer try: retval = portCheckerQueue.get(False) portCheckerQueue.task_done() return retval except Queue.Empty: pass # with a probability of 0.5, connect to a discovered peer if random.choice((False, True)) and not haveOnion: # discovered peers are already filtered by allowed streams return getDiscoveredPeer() for _ in range(50): peer = random.choice(knownnodes.knownNodes[stream].keys()) try: rating = knownnodes.knownNodes[stream][peer]["rating"] except TypeError: print "Error in %s" % (peer) rating = 0 if haveOnion: # onion addresses have a higher priority when SOCKS if peer.host.endswith('.onion') and rating > 0: rating = 1 else: encodedAddr = protocol.encodeHost(peer.host) # don't connect to local IPs when using SOCKS if not protocol.checkIPAddress(encodedAddr, False): continue if rating > 1: rating = 1 try: if 0.05/(1.0-rating) > random.random(): return peer except ZeroDivisionError: return peer raise ValueError
def bm_command_addr(self): """Incoming addresses, process them""" # pylint: disable=redefined-outer-name addresses = self._decode_addr() for seenTime, stream, _, ip, port in addresses: decodedIP = protocol.checkIPAddress(str(ip)) if stream not in state.streamsInWhichIAmParticipating: continue if (decodedIP and time.time() - seenTime > 0 and seenTime > time.time() - ADDRESS_ALIVE and port > 0): peer = Peer(decodedIP, port) with knownnodes.knownNodesLock: # isnew = knownnodes.addKnownNode(stream, peer, seenTime) # since we don't track peers outside of knownnodes, # only spread if in knownnodes to prevent flood # DISABLED TO WORKAROUND FLOOD/LEAK # if isnew: # addrQueue.put(( # stream, peer, seenTime, self.destination)) return True
def bm_command_addr(self): # BMProto.bm_command_object(self) addresses = self._decode_addr() # only allow peer discovery from private IPs in order to avoid attacks from random IPs on the internet if not self.local: return True remoteport = False for i in addresses: seenTime, stream, services, ip, port = i decodedIP = protocol.checkIPAddress(str(ip)) if stream not in state.streamsInWhichIAmParticipating: continue if seenTime < time.time() - BMProto.maxTimeOffset or seenTime > time.time() + BMProto.maxTimeOffset: continue if decodedIP is False: # if the address isn't local, interpret it as the hosts' own announcement remoteport = port if remoteport is False: return True logger.debug("received peer discovery from %s:%i (port %i):", self.destination.host, self.destination.port, remoteport) if self.local: state.discoveredPeers[state.Peer(self.destination.host, remoteport)] = time.time() return True