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
Beispiel #2
0
    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.')
Beispiel #9
0
    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.'