def run(self): # If there is a trusted peer then we don't want to accept # incoming connections so we'll just abandon the thread if shared.trustedPeer: return while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect') and shared.shutdown == 0: self.stop.wait(1) helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten') and shared.shutdown == 0: self.stop.wait(5) logger.info('Listening for incoming connections.') # First try listening on an IPv6 socket. This should also be # able to accept connections on IPv4. If that's not available # we'll fall back to IPv4-only. try: sock = self._createListenSocket(socket.AF_INET6) except socket.error, e: if (isinstance(e.args, tuple) and e.args[0] in (errno.EAFNOSUPPORT, errno.EPFNOSUPPORT, errno.ENOPROTOOPT)): sock = self._createListenSocket(socket.AF_INET) else: raise
def run(self): # If there is a trusted peer then we don't want to accept # incoming connections so we'll just abandon the thread if shared.trustedPeer: return while shared.safeConfigGetBoolean( 'bitmessagesettings', 'dontconnect') and shared.shutdown == 0: self.stop.wait(1) helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. But if on SOCKS and have an onionhostname, listen # (socket is then only opened for localhost) while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and \ (not shared.config.getboolean('bitmessagesettings', 'sockslisten') and \ ".onion" not in shared.config.get('bitmessagesettings', 'onionhostname')) and \ shared.shutdown == 0: self.stop.wait(5) logger.info('Listening for incoming connections.') # First try listening on an IPv6 socket. This should also be # able to accept connections on IPv4. If that's not available # we'll fall back to IPv4-only. try: sock = self._createListenSocket(socket.AF_INET6) except socket.error, e: if (isinstance(e.args, tuple) and e.args[0] in (errno.EAFNOSUPPORT, errno.EPFNOSUPPORT, errno.EADDRNOTAVAIL, errno.ENOPROTOOPT)): sock = self._createListenSocket(socket.AF_INET) else: raise
def run(self): # If there is a trusted peer then we don't want to accept # incoming connections so we'll just abandon the thread if shared.trustedPeer: return while shared.safeConfigGetBoolean("bitmessagesettings", "dontconnect"): time.sleep(1) helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get("bitmessagesettings", "socksproxytype")[ 0:5 ] == "SOCKS" and not shared.config.getboolean("bitmessagesettings", "sockslisten"): time.sleep(5) with shared.printLock: print "Listening for incoming connections." # First try listening on an IPv6 socket. This should also be # able to accept connections on IPv4. If that's not available # we'll fall back to IPv4-only. try: sock = self._createListenSocket(socket.AF_INET6) except socket.error, e: if isinstance(e.args, tuple) and e.args[0] in (errno.EAFNOSUPPORT, errno.EPFNOSUPPORT, errno.ENOPROTOOPT): sock = self._createListenSocket(socket.AF_INET) else: raise
def run(self): # If there is a trusted peer then we don't want to accept # incoming connections so we'll just abandon the thread if shared.trustedPeer: return helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get( 'bitmessagesettings', 'socksproxytype' )[0:5] == 'SOCKS' and not shared.config.getboolean( 'bitmessagesettings', 'sockslisten'): time.sleep(5) # First try listening on an IPv6 socket. This should also be # able to accept connections on IPv4. If that's not available # we'll fall back to IPv4-only. try: sock = self._createListenSocket(socket.AF_INET6) except socket.error, e: if (isinstance(e.args, tuple) and e.args[0] in (errno.EAFNOSUPPORT, errno.EPFNOSUPPORT, errno.ENOPROTOOPT)): sock = self._createListenSocket(socket.AF_INET) else: raise
def run(self): while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): time.sleep(1) helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): time.sleep(5) logger.info('Listening for incoming connections.') HOST = '' # Symbolic name meaning all available interfaces PORT = shared.config.getint('bitmessagesettings', 'port') sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # This option apparently avoids the TIME_WAIT state so that we can # rebind faster sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((HOST, PORT)) sock.listen(2) while True: # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): time.sleep(10) while len(shared.connectedHostsList) > 220: logger.info('We are connected to too many people. Not accepting further incoming connections for ten seconds.') time.sleep(10) a, (HOST, PORT) = sock.accept() # The following code will, unfortunately, block an incoming # connection if someone else on the same LAN is already connected # because the two computers will share the same external IP. This # is here to prevent connection flooding. while HOST in shared.connectedHostsList: logger.info('We are already connected to %s . Ignoring connection.'%HOST) a.close() a, (HOST, PORT) = sock.accept() someObjectsOfWhichThisRemoteNodeIsAlreadyAware = {} # This is not necessairly a complete list; we clear it from time to time to save memory. a.settimeout(20) sd = sendDataThread() sd.setup( a, HOST, PORT, -1, someObjectsOfWhichThisRemoteNodeIsAlreadyAware) sd.start() rd = receiveDataThread() rd.daemon = True # close the main program even if there are threads left rd.setup( a, HOST, PORT, -1, someObjectsOfWhichThisRemoteNodeIsAlreadyAware, self.selfInitiatedConnections) rd.start() logger.info('%s connected to %s during INCOMING request.'%(self,HOST))
def cleanupKnownNodes(): """ Cleanup knownnodes: remove old nodes and nodes with low rating """ now = int(time.time()) needToWriteKnownNodesToDisk = False dns_done = False spawnConnections = not BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'dontconnect') and BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'sendoutgoingconnections') with knownNodesLock: for stream in knownNodes: if stream not in state.streamsInWhichIAmParticipating: continue keys = knownNodes[stream].keys() if len(keys) <= 1: # leave at least one node if not dns_done and spawnConnections: dns() dns_done = True continue for node in keys: try: # scrap old nodes if (now - knownNodes[stream][node]["lastseen"] > 2419200): # 28 days needToWriteKnownNodesToDisk = True del knownNodes[stream][node] continue # scrap old nodes with low rating if (now - knownNodes[stream][node]["lastseen"] > 10800 and knownNodes[stream][node]["rating"] <= knownNodesForgetRating): needToWriteKnownNodesToDisk = True del knownNodes[stream][node] continue except TypeError: logger.warning('Error in %s', node) keys = [] # Let us write out the knowNodes to disk # if there is anything new to write out. if needToWriteKnownNodesToDisk: saveKnownNodes()
shared.networkDefaultProofOfWorkNonceTrialsPerByte = int( shared.networkDefaultProofOfWorkNonceTrialsPerByte / 16) shared.networkDefaultPayloadLengthExtraBytes = int( shared.networkDefaultPayloadLengthExtraBytes / 7000) if __name__ == "__main__": # is the application already running? If yes then exit. thisapp = singleton.singleinstance() signal.signal(signal.SIGINT, helper_generic.signal_handler) # signal.signal(signal.SIGINT, signal.SIG_DFL) helper_startup.loadConfig() helper_bootstrap.knownNodes() helper_bootstrap.dns() # Start the address generation thread addressGeneratorThread = addressGenerator() addressGeneratorThread.daemon = True # close the main program even if there are threads left addressGeneratorThread.start() # Start the thread that calculates POWs singleWorkerThread = singleWorker() singleWorkerThread.daemon = True # close the main program even if there are threads left singleWorkerThread.start() # Start the SQL thread sqlLookup = sqlThread() sqlLookup.daemon = False # DON'T close the main program even if there are threads left. The closeEvent should command this thread to exit gracefully. sqlLookup.start()
def run(self): # If there is a trusted peer then we don't want to accept # incoming connections so we'll just abandon the thread if state.trustedPeer: return while BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'dontconnect') and state.shutdown == 0: self.stop.wait(1) helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. But if on SOCKS and have an onionhostname, listen # (socket is then only opened for localhost) while BMConfigParser().get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and \ (not BMConfigParser().getboolean('bitmessagesettings', 'sockslisten') and \ ".onion" not in BMConfigParser().get('bitmessagesettings', 'onionhostname')) and \ state.shutdown == 0: self.stop.wait(5) logger.info('Listening for incoming connections.') # First try listening on an IPv6 socket. This should also be # able to accept connections on IPv4. If that's not available # we'll fall back to IPv4-only. try: sock = self._createListenSocket(socket.AF_INET6) except socket.error as e: if (isinstance(e.args, tuple) and e.args[0] in (errno.EAFNOSUPPORT, errno.EPFNOSUPPORT, errno.EADDRNOTAVAIL, errno.ENOPROTOOPT, errno.EINVAL)): sock = self._createListenSocket(socket.AF_INET) else: raise # regexp to match an IPv4-mapped IPv6 address mappedAddressRegexp = re.compile( r'^::ffff:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$') while state.shutdown == 0: # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while BMConfigParser().get( 'bitmessagesettings', 'socksproxytype' )[0:5] == 'SOCKS' and not BMConfigParser().getboolean( 'bitmessagesettings', 'sockslisten') and ".onion" not in BMConfigParser().get( 'bitmessagesettings', 'onionhostname') and state.shutdown == 0: self.stop.wait(10) while len(shared.connectedHostsList) > \ BMConfigParser().safeGetInt("bitmessagesettings", "maxtotalconnections", 200) + \ BMConfigParser().safeGetInt("bitmessagesettings", "maxbootstrapconnections", 20) \ and state.shutdown == 0: logger.info( 'We are connected to too many people. Not accepting further incoming connections for ten seconds.' ) self.stop.wait(10) while state.shutdown == 0: try: socketObject, sockaddr = sock.accept() except socket.error as e: if isinstance(e.args, tuple) and \ e.args[0] in (errno.EINTR,): continue time.wait(1) continue (HOST, PORT) = sockaddr[0:2] # If the address is an IPv4-mapped IPv6 address then # convert it to just the IPv4 representation md = mappedAddressRegexp.match(HOST) if md != None: HOST = md.group(1) # The following code will, unfortunately, block an # incoming connection if someone else on the same LAN # is already connected because the two computers will # share the same external IP. This is here to prevent # connection flooding. # permit repeated connections from Tor if HOST in shared.connectedHostsList and \ (".onion" not in BMConfigParser().get('bitmessagesettings', 'onionhostname') or not protocol.checkSocksIP(HOST)): socketObject.close() logger.info('We are already connected to ' + str(HOST) + '. Ignoring connection.') else: break sendDataThreadQueue = Queue.Queue( ) # Used to submit information to the send data thread for this connection. socketObject.settimeout(20) sd = sendDataThread(sendDataThreadQueue) sd.setup(socketObject, HOST, PORT, -1) sd.start() rd = receiveDataThread() rd.daemon = True # close the main program even if there are threads left rd.setup(socketObject, HOST, PORT, -1, self.selfInitiatedConnections, sendDataThreadQueue, sd.objectHashHolderInstance) rd.start() logger.info('connected to ' + HOST + ' during INCOMING request.')
def loop(self): # 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 if BMConfigParser().get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and \ (not BMConfigParser().getboolean('bitmessagesettings', 'sockslisten') and \ ".onion" not in BMConfigParser().get('bitmessagesettings', 'onionhostname')): acceptConnections = False if spawnConnections: if not self.bootstrapped: helper_bootstrap.dns() 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 BMConfigParser().get("network", "onionsocksproxytype").startswith("SOCKS"): raise NoOptionError Proxy.onionproxy = (BMConfigParser().get("network", "onionsockshostname"), BMConfigParser().getint("network", "onionsocksport")) except (NoOptionError, NoSectionError): Proxy.onionproxy = 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 = chooseConnection(random.choice(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 #for c in self.outboundConnections: # if chosen == c.destination: # continue #for c in self.inboundConnections: # if chosen.host == c.destination.host: # continue try: if chosen.host.endswith(".onion") and Proxy.onionproxy is not None: if BMConfigParser().get("network", "onionsocksproxytype") == "SOCKS5": self.addConnection(Socks5BMConnection(chosen)) elif BMConfigParser().get("network", "onionsocksproxytype") == "SOCKS4a": self.addConnection(Socks4aBMConnection(chosen)) elif BMConfigParser().safeGet("bitmessagesettings", "socksproxytype") == "SOCKS5": self.addConnection(Socks5BMConnection(chosen)) elif BMConfigParser().safeGet("bitmessagesettings", "socksproxytype") == "SOCKS4a": self.addConnection(Socks4aBMConnection(chosen)) else: self.addConnection(TCPConnection(chosen)) except socket.error as e: if e.errno == errno.ENETUNREACH: continue except (NoSectionError, NoOptionError): # shouldn't happen pass self.lastSpawned = time.time() else: for i in ( self.inboundConnections.values() + self.outboundConnections.values() ): i.set_state("close") # 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("[^\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("[^\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.inboundConnections.values() + self.outboundConnections.values(): 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.inboundConnections.values() + self.outboundConnections.values() + 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)
def run(self): # If there is a trusted peer then we don't want to accept # incoming connections so we'll just abandon the thread if state.trustedPeer: return while BMConfigParser().safeGetBoolean('bitmessagesettings', 'dontconnect') and state.shutdown == 0: self.stop.wait(1) helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. But if on SOCKS and have an onionhostname, listen # (socket is then only opened for localhost) while BMConfigParser().get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and \ (not BMConfigParser().getboolean('bitmessagesettings', 'sockslisten') and \ ".onion" not in BMConfigParser().get('bitmessagesettings', 'onionhostname')) and \ state.shutdown == 0: self.stop.wait(5) logger.info('Listening for incoming connections.') # First try listening on an IPv6 socket. This should also be # able to accept connections on IPv4. If that's not available # we'll fall back to IPv4-only. try: sock = self._createListenSocket(socket.AF_INET6) except socket.error as e: if (isinstance(e.args, tuple) and e.args[0] in (errno.EAFNOSUPPORT, errno.EPFNOSUPPORT, errno.EADDRNOTAVAIL, errno.ENOPROTOOPT, errno.EINVAL)): sock = self._createListenSocket(socket.AF_INET) else: raise # regexp to match an IPv4-mapped IPv6 address mappedAddressRegexp = re.compile(r'^::ffff:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$') while state.shutdown == 0: # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while BMConfigParser().get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not BMConfigParser().getboolean('bitmessagesettings', 'sockslisten') and ".onion" not in BMConfigParser().get('bitmessagesettings', 'onionhostname') and state.shutdown == 0: self.stop.wait(10) while len(shared.connectedHostsList) > \ BMConfigParser().safeGetInt("bitmessagesettings", "maxtotalconnections", 200) + \ BMConfigParser().safeGetInt("bitmessagesettings", "maxbootstrapconnections", 20) \ and state.shutdown == 0: logger.info('We are connected to too many people. Not accepting further incoming connections for ten seconds.') self.stop.wait(10) while state.shutdown == 0: try: socketObject, sockaddr = sock.accept() except socket.error as e: if isinstance(e.args, tuple) and \ e.args[0] in (errno.EINTR,): continue time.wait(1) continue (HOST, PORT) = sockaddr[0:2] # If the address is an IPv4-mapped IPv6 address then # convert it to just the IPv4 representation md = mappedAddressRegexp.match(HOST) if md != None: HOST = md.group(1) # The following code will, unfortunately, block an # incoming connection if someone else on the same LAN # is already connected because the two computers will # share the same external IP. This is here to prevent # connection flooding. # permit repeated connections from Tor if HOST in shared.connectedHostsList and \ (".onion" not in BMConfigParser().get('bitmessagesettings', 'onionhostname') or not protocol.checkSocksIP(HOST)): socketObject.close() logger.info('We are already connected to ' + str(HOST) + '. Ignoring connection.') else: break sendDataThreadQueue = Queue.Queue() # Used to submit information to the send data thread for this connection. socketObject.settimeout(20) sd = sendDataThread(sendDataThreadQueue) sd.setup( socketObject, HOST, PORT, -1) sd.start() rd = receiveDataThread() rd.daemon = True # close the main program even if there are threads left rd.setup( socketObject, HOST, PORT, -1, self.selfInitiatedConnections, sendDataThreadQueue, sd.objectHashHolderInstance) rd.start() logger.info('connected to ' + HOST + ' during INCOMING request.')
def run(self): while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): time.sleep(1) helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get( 'bitmessagesettings', 'socksproxytype' )[0:5] == 'SOCKS' and not shared.config.getboolean( 'bitmessagesettings', 'sockslisten'): time.sleep(5) with shared.printLock: print 'Listening for incoming connections.' HOST = '' # Symbolic name meaning all available interfaces PORT = shared.config.getint('bitmessagesettings', 'port') sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # This option apparently avoids the TIME_WAIT state so that we can # rebind faster sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((HOST, PORT)) sock.listen(2) while True: # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get( 'bitmessagesettings', 'socksproxytype' )[0:5] == 'SOCKS' and not shared.config.getboolean( 'bitmessagesettings', 'sockslisten'): time.sleep(10) while len(shared.connectedHostsList) > 220: with shared.printLock: print 'We are connected to too many people. Not accepting further incoming connections for ten seconds.' time.sleep(10) a, (HOST, PORT) = sock.accept() # The following code will, unfortunately, block an incoming # connection if someone else on the same LAN is already connected # because the two computers will share the same external IP. This # is here to prevent connection flooding. while HOST in shared.connectedHostsList: with shared.printLock: print 'We are already connected to', HOST + '. Ignoring connection.' a.close() a, (HOST, PORT) = sock.accept() someObjectsOfWhichThisRemoteNodeIsAlreadyAware = { } # This is not necessairly a complete list; we clear it from time to time to save memory. a.settimeout(20) sd = sendDataThread() sd.setup(a, HOST, PORT, -1, someObjectsOfWhichThisRemoteNodeIsAlreadyAware) sd.start() rd = receiveDataThread() rd.daemon = True # close the main program even if there are threads left rd.setup(a, HOST, PORT, -1, someObjectsOfWhichThisRemoteNodeIsAlreadyAware, self.selfInitiatedConnections) rd.start() with shared.printLock: print self, 'connected to', HOST, 'during INCOMING request.'