Ejemplo n.º 1
0
 def handle_close(self):
     if self.isOutbound and not self.fullyEstablished:
         knownnodes.decreaseRating(self.destination)
     if self.fullyEstablished:
         UISignalQueue.put(('updateNetworkStatusTab', (self.isOutbound, False, self.destination)))
         if self.isOutbound:
             Dandelion().maybeRemoveStem(self)
     BMProto.handle_close(self)
Ejemplo n.º 2
0
 def handle_close(self):
     if self.isOutbound and not self.fullyEstablished:
         knownnodes.decreaseRating(self.destination)
     if self.fullyEstablished:
         UISignalQueue.put(('updateNetworkStatusTab', (self.isOutbound, False, self.destination)))
         if self.isOutbound:
             Dandelion().maybeRemoveStem(self)
     BMProto.handle_close(self)
Ejemplo n.º 3
0
 def handle_close(self):
     """Callback for connection being closed."""
     host_is_global = self.isOutbound or not self.local and not state.socksIP
     if self.fullyEstablished:
         UISignalQueue.put((
             'updateNetworkStatusTab',
             (self.isOutbound, False, self.destination)
         ))
         if host_is_global:
             knownnodes.addKnownNode(
                 self.streams, self.destination, time.time())
             Dandelion().maybeRemoveStem(self)
     elif host_is_global:
         knownnodes.decreaseRating(self.destination)
     BMProto.handle_close(self)
Ejemplo n.º 4
0
 def handle_close(self, reason=None):
     if self.isOutbound and not self.fullyEstablished:
         knownnodes.decreaseRating(self.destination)
     BMProto.handle_close(self, reason)
Ejemplo n.º 5
0
    def loop(self):  # pylint: disable=too-many-branches,too-many-statements
        """Main Connectionpool's loop"""
        # pylint: disable=too-many-locals
        # defaults to empty loop if outbound connections are maxed
        spawnConnections = False
        acceptConnections = True
        if BMConfigParser().safeGetBoolean('bitmessagesettings',
                                           'dontconnect'):
            acceptConnections = False
        elif BMConfigParser().safeGetBoolean('bitmessagesettings',
                                             'sendoutgoingconnections'):
            spawnConnections = True
        socksproxytype = BMConfigParser().safeGet('bitmessagesettings',
                                                  'socksproxytype', '')
        onionsocksproxytype = BMConfigParser().safeGet('bitmessagesettings',
                                                       'onionsocksproxytype',
                                                       '')
        if (socksproxytype[:5] == 'SOCKS'
                and not BMConfigParser().safeGetBoolean(
                    'bitmessagesettings', 'sockslisten')
                and '.onion' not in BMConfigParser().safeGet(
                    'bitmessagesettings', 'onionhostname', '')):
            acceptConnections = False

        # pylint: disable=too-many-nested-blocks
        if spawnConnections:
            if not knownnodes.knownNodesActual:
                self.startBootstrappers()
                knownnodes.knownNodesActual = True
            if not self._bootstrapped:
                self._bootstrapped = True
                Proxy.proxy = (BMConfigParser().safeGet(
                    'bitmessagesettings',
                    'sockshostname'), BMConfigParser().safeGetInt(
                        'bitmessagesettings', 'socksport'))
                # TODO AUTH
                # TODO reset based on GUI settings changes
                try:
                    if not onionsocksproxytype.startswith("SOCKS"):
                        raise ValueError
                    Proxy.onion_proxy = (BMConfigParser().safeGet(
                        'network', 'onionsockshostname',
                        None), BMConfigParser().safeGet(
                            'network', 'onionsocksport', None))
                except ValueError:
                    Proxy.onion_proxy = None
            established = sum(1 for c in self.outboundConnections.values()
                              if (c.connected and c.fullyEstablished))
            pending = len(self.outboundConnections) - established
            if established < BMConfigParser().safeGetInt(
                    'bitmessagesettings', 'maxoutboundconnections'):
                for i in range(state.maximumNumberOfHalfOpenConnections -
                               pending):
                    try:
                        chosen = self.trustedPeer or chooseConnection(
                            helper_random.randomchoice(self.streams))
                    except ValueError:
                        continue
                    if chosen in self.outboundConnections:
                        continue
                    if chosen.host in self.inboundConnections:
                        continue
                    # don't connect to self
                    if chosen in state.ownAddresses:
                        continue
                    # don't connect to the hosts from the same
                    # network group, defense against sibyl attacks
                    host_network_group = protocol.network_group(chosen.host)
                    same_group = False
                    for j in self.outboundConnections.values():
                        if host_network_group == j.network_group:
                            same_group = True
                            if chosen.host == j.destination.host:
                                knownnodes.decreaseRating(chosen)
                            break
                    if same_group:
                        continue

                    try:
                        if chosen.host.endswith(
                                ".onion") and Proxy.onion_proxy:
                            if onionsocksproxytype == "SOCKS5":
                                self.addConnection(Socks5BMConnection(chosen))
                            elif onionsocksproxytype == "SOCKS4a":
                                self.addConnection(Socks4aBMConnection(chosen))
                        elif socksproxytype == "SOCKS5":
                            self.addConnection(Socks5BMConnection(chosen))
                        elif socksproxytype == "SOCKS4a":
                            self.addConnection(Socks4aBMConnection(chosen))
                        else:
                            self.addConnection(TCPConnection(chosen))
                    except socket.error as e:
                        if e.errno == errno.ENETUNREACH:
                            continue

                    self._lastSpawned = time.time()
        else:
            for i in self.connections():
                # FIXME: rating will be increased after next connection
                i.handle_close()

        if acceptConnections:
            if not self.listeningSockets:
                if BMConfigParser().safeGet('network', 'bind') == '':
                    self.startListening()
                else:
                    for bind in re.sub(
                            r'[^\w.]+', ' ',
                            BMConfigParser().safeGet('network',
                                                     'bind')).split():
                        self.startListening(bind)
                logger.info('Listening for incoming connections.')
            if not self.udpSockets:
                if BMConfigParser().safeGet('network', 'bind') == '':
                    self.startUDPSocket()
                else:
                    for bind in re.sub(
                            r'[^\w.]+', ' ',
                            BMConfigParser().safeGet('network',
                                                     'bind')).split():
                        self.startUDPSocket(bind)
                    self.startUDPSocket(False)
                logger.info('Starting UDP socket(s).')
        else:
            if self.listeningSockets:
                for i in self.listeningSockets.values():
                    i.close_reason = "Stopping listening"
                    i.accepting = i.connecting = i.connected = False
                logger.info('Stopped listening for incoming connections.')
            if self.udpSockets:
                for i in self.udpSockets.values():
                    i.close_reason = "Stopping UDP socket"
                    i.accepting = i.connecting = i.connected = False
                logger.info('Stopped udp sockets.')

        loopTime = float(self._spawnWait)
        if self._lastSpawned < time.time() - self._spawnWait:
            loopTime = 2.0
        asyncore.loop(timeout=loopTime, count=1000)

        reaper = []
        for i in self.connections():
            minTx = time.time() - 20
            if i.fullyEstablished:
                minTx -= 300 - 20
            if i.lastTx < minTx:
                if i.fullyEstablished:
                    i.append_write_buf(protocol.CreatePacket('ping'))
                else:
                    i.close_reason = "Timeout (%is)" % (time.time() - i.lastTx)
                    i.set_state("close")
        for i in (self.connections() + self.listeningSockets.values() +
                  self.udpSockets.values()):
            if not (i.accepting or i.connecting or i.connected):
                reaper.append(i)
            else:
                try:
                    if i.state == "close":
                        reaper.append(i)
                except AttributeError:
                    pass
        for i in reaper:
            self.removeConnection(i)