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)
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)
def handle_close(self, reason=None): if self.isOutbound and not self.fullyEstablished: knownnodes.decreaseRating(self.destination) BMProto.handle_close(self, reason)
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)