Пример #1
0
    def startConnecting(self):
        # This fires when the DC client connects and wants to be online

        dcall_discard(self, 'reconnect_dcall')

        # Only continue if the UDP port is ready
        if not self.bindUDPPort():
            return

        # Any reason to be online?
        if not self.reconnectDesired():
            return

        if self.icm or self.osm:
            # Already in progress; return description.
            return self.login_text

        # Get config from DNS
        def dns_cb():
            try:
                # 2011-08-21: New nodes ignore the value of 'when'.
                when, ipps = self.state.dns_ipcache
            except ValueError:
                pass
            else:
                random.shuffle(ipps)
                for ipp in ipps:
                    ad = Ad().setRawIPPort(ipp)
                    self.state.refreshPeer(ad, 0)

            self.startInitialContact()

        self.dcfg.getDynamicConfig(dns_cb)
Пример #2
0
    def startConnecting(self):
        # This fires when the DC client connects and wants to be online

        dcall_discard(self, 'reconnect_dcall')

        # Only continue if the UDP port is ready
        if not self.bindUDPPort():
            return

        # Any reason to be online?
        if not self.reconnectDesired():
            return

        if self.icm or self.osm:
            # Already in progress; return description.
            return self.login_text

        # Get config from DNS
        def dns_cb():
            try:
                # 2011-08-21: New nodes ignore the value of 'when'.
                when, ipps = self.state.dns_ipcache
            except ValueError:
                pass
            else:
                random.shuffle(ipps)
                for ipp in ipps:
                    ad = Ad().setRawIPPort(ipp)
                    self.state.refreshPeer(ad, 0)

            self.startInitialContact()

        self.dcfg.getDynamicConfig(dns_cb)
Пример #3
0
    def doRejoin(self):
        if self.state != 'invisible':
            return

        dcall_discard(self, 'autoRejoin_dcall')

        self.state = 'ready'

        # This can trigger an event_DtellaUp()
        self.main.stateChange_ObserverUp()
Пример #4
0
Файл: dc.py Проект: LiPeK/dtella
    def doRejoin(self):
        if self.state != 'invisible':
            return

        dcall_discard(self, 'autoRejoin_dcall')

        self.state = 'ready'

        # This can trigger an event_DtellaUp()
        self.main.stateChange_ObserverUp()
Пример #5
0
    def d_MyNick(self, nick):
        # This is a fake RevConnect that we should terminate.

        dcall_discard(self, 'init_dcall')

        if self.state != 'login_1':
            self.fatalError("$MyNick not expected.")
            return

        if not self.main.abort_nick:
            self.transport.loseConnection()
            return

        # Transfer my state to the connection abort handler
        AbortTransfer_In(self.main.abort_nick, self)
        self.main.abort_nick = None
Пример #6
0
Файл: dc.py Проект: LiPeK/dtella
    def d_MyNick(self, nick):
        # This is a fake RevConnect that we should terminate.
        
        dcall_discard(self, 'init_dcall')
        
        if self.state != 'login_1':
            self.fatalError("$MyNick not expected.")
            return

        if not self.main.abort_nick:
            self.transport.loseConnection()
            return

        # Transfer my state to the connection abort handler
        AbortTransfer_In(self.main.abort_nick, self)
        self.main.abort_nick = None
Пример #7
0
    def removeDCHandler(self, dch):
        # DC client has left.

        if self.pending_dch is dch:
            self.pending_dch = None
            return
        elif self.dch is not dch:
            return

        self.dch = None
        self.abort_nick = None

        # Announce the DC client's departure.
        if dch.state == 'ready':
            self.stateChange_ObserverDown()

        # If another handler is waiting, let it on.
        if self.pending_dch:
            self.pending_dch.attachMeToDtella()
            self.pending_dch = None
            return

        # Maybe forget about reconnecting
        if not self.reconnectDesired():
            dcall_discard(self, 'reconnect_dcall')

        # Maybe skip the disconnect
        if self.state.persistent or not (self.icm or self.osm):
            return

        # Client left, so shut down in a while
        when = core.NO_CLIENT_TIMEOUT

        if self.disconnect_dcall:
            self.disconnect_dcall.reset(when)
            return

        def cb():
            self.disconnect_dcall = None
            self.shutdown(reconnect='no')

        self.disconnect_dcall = reactor.callLater(when, cb)
Пример #8
0
    def removeDCHandler(self, dch):
        # DC client has left.

        if self.pending_dch is dch:
            self.pending_dch = None
            return
        elif self.dch is not dch:
            return

        self.dch = None
        self.abort_nick = None

        # Announce the DC client's departure.
        if dch.state == 'ready':
            self.stateChange_ObserverDown()

        # If another handler is waiting, let it on.
        if self.pending_dch:
            self.pending_dch.attachMeToDtella()
            self.pending_dch = None
            return

        # Maybe forget about reconnecting
        if not self.reconnectDesired():
            dcall_discard(self, 'reconnect_dcall')

        # Maybe skip the disconnect
        if self.state.persistent or not (self.icm or self.osm):
            return

        # Client left, so shut down in a while
        when = core.NO_CLIENT_TIMEOUT

        if self.disconnect_dcall:
            self.disconnect_dcall.reset(when)
            return

        def cb():
            self.disconnect_dcall = None
            self.shutdown(reconnect='no')

        self.disconnect_dcall = reactor.callLater(when, cb)
Пример #9
0
    def scheduleRequestBlocks(self):

        # After we receive a sync reply from the bridge, individually
        # request the full data for each block hash.

        dcall_discard(self, 'requestBlocks_dcall')

        if not self.req_blocks:
            return

        def cb(timeout):
            self.requestBlocks_dcall = None

            # Pick one of the hashes randomly
            try:
                bhash = self.req_blocks.peek()
            except KeyError:
                return

            # Build request packet
            packet = ['bQ']
            packet.append(self.main.osm.me.ipp)
            packet.append(bhash)

            # Send to bridge
            ad = Ad().setRawIPPort(self.parent_n.ipp)
            self.main.ph.sendPacket(''.join(packet), ad.getAddrTuple())

            # Too many failures, just give up
            if timeout > 30.0:
                self.req_blocks.clear()
                return

            # Schedule next request.
            # This will become immediate if a reply arrives.
            when = random.uniform(0.9, 1.1) * timeout
            timeout *= 1.2
            self.requestBlocks_dcall = reactor.callLater(when, cb, timeout)

        self.requestBlocks_dcall = reactor.callLater(0, cb, 1.0)
Пример #10
0
Файл: dc.py Проект: LiPeK/dtella
    def connectionLost(self, reason):

        self.main.removeDCHandler(self)

        dcall_discard(self, 'init_dcall')
        dcall_discard(self, 'chatRate_dcall')
        dcall_discard(self, 'autoRejoin_dcall')
Пример #11
0
    def connectionLost(self, reason):

        self.main.removeDCHandler(self)

        dcall_discard(self, 'init_dcall')
        dcall_discard(self, 'chatRate_dcall')
        dcall_discard(self, 'autoRejoin_dcall')
Пример #12
0
    def scheduleRequestBlocks(self):

        # After we receive a sync reply from the bridge, individually
        # request the full data for each block hash.

        dcall_discard(self, 'requestBlocks_dcall')

        if not self.req_blocks:
            return

        def cb(timeout):
            self.requestBlocks_dcall = None

            # Pick one of the hashes randomly
            try:
                bhash = self.req_blocks.peek()
            except KeyError:
                return

            # Build request packet
            packet = ['bQ']
            packet.append(self.main.osm.me.ipp)
            packet.append(bhash)

            # Send to bridge
            ad = Ad().setRawIPPort(self.parent_n.ipp)
            self.main.ph.sendPacket(''.join(packet), ad.getAddrTuple())

            # Too many failures, just give up
            if timeout > 30.0:
                self.req_blocks.clear()
                return

            # Schedule next request.
            # This will become immediate if a reply arrives.
            when = random.uniform(0.9, 1.1) * timeout
            timeout *= 1.2
            self.requestBlocks_dcall = reactor.callLater(when, cb, timeout)

        self.requestBlocks_dcall = reactor.callLater(0, cb, 1.0)
Пример #13
0
    def d_ValidateNick(self, nick):

        dcall_discard(self, 'init_dcall')

        if self.state != 'login_1':
            self.fatalError("$ValidateNick not expected.")
            return

        # Next, we expect $GetNickList+$MyINFO
        self.state = 'login_2'

        reason = validateNick(nick)

        if reason:
            self.pushStatus("Your nick is invalid: %s" % reason)
            self.pushStatus("Please fix it and reconnect.  Goodbye.")
            self.transport.loseConnection()
            return

        self.nick = nick

        self.pushHello(self.nick)
Пример #14
0
Файл: dc.py Проект: LiPeK/dtella
    def d_ValidateNick(self, nick):

        dcall_discard(self, 'init_dcall')

        if self.state != 'login_1':
            self.fatalError("$ValidateNick not expected.")
            return

        # Next, we expect $GetNickList+$MyINFO
        self.state = 'login_2'

        reason = validateNick(nick)

        if reason:
            self.pushStatus("Your nick is invalid: %s" % reason)
            self.pushStatus("Please fix it and reconnect.  Goodbye.")
            self.transport.loseConnection()
            return

        self.nick = nick

        self.pushHello(self.nick)
Пример #15
0
    def attachMeToDtella(self):

        CHECK(self.main.dch is None)

        if self.state == 'queued':
            self.queued_dcall.cancel()
            self.queued_dcall = None
            self.pushStatus(
                "The other client left.  Resuming normal connection.")

        dcall_discard(self, 'queued_dcall')

        # Add the post-login handlers
        self.addDispatch('$ConnectToMe', 2, self.d_ConnectToMe)
        self.addDispatch('$RevConnectToMe', 2, self.d_RevConnectToMe)
        self.addDispatch('$Search', -2, self.d_Search)
        self.addDispatch('$To:', -5, self.d_PrivateMsg)
        self.addDispatch("<%s>" % self.nick, -1, self.d_PublicMsg)

        # Announce my presence.
        # If Dtella's online too, this will trigger an event_DtellaUp.
        self.state = 'ready'
        self.main.addDCHandler(self)
Пример #16
0
    def addDCHandler(self, dch):

        CHECK(not self.dch)
        CHECK(dch.state == 'ready')

        self.dch = dch

        # Cancel the disconnect timeout
        dcall_discard(self, 'disconnect_dcall')

        # Start connecting, or get status of current connection
        text = self.startConnecting()
        if text:
            # We must already be connecting/online.
            # Show the last status message.
            LOG.debug(text)
            dch.pushStatus(text)

            # Send a message if there's a newer version
            self.dcfg.resetReportedVersion()
            self.dcfg.reportNewVersion()

        self.stateChange_ObserverUp()
Пример #17
0
Файл: dc.py Проект: LiPeK/dtella
    def attachMeToDtella(self):

        CHECK(self.main.dch is None)

        if self.state == 'queued':
            self.queued_dcall.cancel()
            self.queued_dcall = None
            self.pushStatus(
                "The other client left.  Resuming normal connection.")

        dcall_discard(self, 'queued_dcall')

        # Add the post-login handlers
        self.addDispatch('$ConnectToMe',      2, self.d_ConnectToMe)
        self.addDispatch('$RevConnectToMe',   2, self.d_RevConnectToMe)
        self.addDispatch('$Search',          -2, self.d_Search)
        self.addDispatch('$To:',             -5, self.d_PrivateMsg)
        self.addDispatch("<%s>" % self.nick, -1, self.d_PublicMsg)

        # Announce my presence.
        # If Dtella's online too, this will trigger an event_DtellaUp.
        self.state = 'ready'
        self.main.addDCHandler(self)
Пример #18
0
    def addDCHandler(self, dch):

        CHECK(not self.dch)
        CHECK(dch.state == 'ready')

        self.dch = dch

        # Cancel the disconnect timeout
        dcall_discard(self, 'disconnect_dcall')

        # Start connecting, or get status of current connection
        text = self.startConnecting()
        if text:
            # We must already be connecting/online.
            # Show the last status message.
            LOG.debug(text)
            dch.pushStatus(text)

            # Send a message if there's a newer version
            self.dcfg.resetReportedVersion()
            self.dcfg.reportNewVersion()

        self.stateChange_ObserverUp()
Пример #19
0
    def sendState(self):
        dcall_discard(self, 'sendState_dcall')

        def cb():
            self.sendState_dcall = None

            osm = self.main.osm

            CHECK(osm and osm.syncd)

            # Decide when to retransmit next
            when = 60 * 5
            self.sendState_dcall = reactor.callLater(when, cb)

            # Broadcast header
            packet = osm.mrm.broadcastHeader('BS', osm.me.ipp)

            # The meat
            block_hashes, blocks = self.getStateData(packet)

            # Signature
            self.signPacket(packet, broadcast=True)

            # Broadcast status message
            osm.mrm.newMessage(''.join(packet), tries=8)

            # Broadcast data blocks
            # This could potentially be a bottleneck for slow connections
            for b in blocks:
                packet = osm.mrm.broadcastHeader('BB', osm.me.ipp)
                packet.append(self.nextPktNum())
                packet.append(struct.pack("!H", len(b)))
                packet.append(b)
                osm.mrm.newMessage(''.join(packet), tries=4)

        # The first time, send state immediately.
        cb()
Пример #20
0
    def sendState(self):
        dcall_discard(self, 'sendState_dcall')

        def cb():
            self.sendState_dcall = None

            osm = self.main.osm

            CHECK(osm and osm.syncd)

            # Decide when to retransmit next
            when = 60 * 5
            self.sendState_dcall = reactor.callLater(when, cb)

            # Broadcast header
            packet = osm.mrm.broadcastHeader('BS', osm.me.ipp)

            # The meat
            block_hashes, blocks = self.getStateData(packet)

            # Signature
            self.signPacket(packet, broadcast=True)

            # Broadcast status message
            osm.mrm.newMessage(''.join(packet), tries=8)

            # Broadcast data blocks
            # This could potentially be a bottleneck for slow connections
            for b in blocks:
                packet = osm.mrm.broadcastHeader('BB', osm.me.ipp)
                packet.append(self.nextPktNum())
                packet.append(struct.pack("!H", len(b)))
                packet.append(b)
                osm.mrm.newMessage(''.join(packet), tries=4)

        # The first time, send state immediately.
        cb()
Пример #21
0
    def saveState(self):
        # Save the state file every few minutes

        def cb():
            when = random.uniform(5 * 60, 6 * 60)
            self.saveState_dcall = reactor.callLater(when, cb)

            d = {}

            # Store all state data to dictionary
            for ls in self.loadsavers:
                ls.save(self, d)

            # Write to file
            try:
                f = file(self.filename, "wb")

                keys = d.keys()
                keys.sort()

                f.write(struct.pack("!6sI", "DTELLA", len(keys)))

                for k in keys:
                    v = d[k]
                    f.write(struct.pack("!I", len(k)))
                    f.write(k)
                    f.write(struct.pack("!I", len(v)))
                    f.write(v)

                f.close()

            except:
                twisted.python.log.err()

        dcall_discard(self, 'saveState_dcall')

        cb()
Пример #22
0
    def saveState(self):
        # Save the state file every few minutes
        
        def cb():
            when = random.uniform(5*60, 6*60)
            self.saveState_dcall = reactor.callLater(when, cb)

            d = {}

            # Store all state data to dictionary
            for ls in self.loadsavers:
                ls.save(self, d)

            # Write to file
            try:
                f = file(self.filename, "wb")

                keys = d.keys()
                keys.sort()

                f.write(struct.pack("!6sI", "DTELLA", len(keys)))

                for k in keys:
                    v = d[k]
                    f.write(struct.pack("!I", len(k)))
                    f.write(k)
                    f.write(struct.pack("!I", len(v)))
                    f.write(v)

                f.close()
                
            except:
                twisted.python.log.err()

        dcall_discard(self, 'saveState_dcall')

        cb()
Пример #23
0
 def dtellaShutdown(self):
     dcall_discard(self, 'cfgRefresh_dcall')
     self.cfg_cb = None
Пример #24
0
 def dtellaShutdown(self):
     dcall_discard(self, 'cfgRefresh_dcall')
     self.cfg_cb = None
Пример #25
0
 def shutdown(self):
     dcall_discard(self, 'requestBlocks_dcall')
Пример #26
0
    def shutdown(self):
        dcall_discard(self, 'sendState_dcall')

        for b in self.cached_blocks.itervalues():
            dcall_discard(b, 'expire_dcall')
Пример #27
0
 def connectionLost(self, reason):
     dcall_discard(self, 'timeout_dcall')
Пример #28
0
 def shutdown(self):
     dcall_discard(self, 'requestBlocks_dcall')
Пример #29
0
Файл: dc.py Проект: LiPeK/dtella
 def connectionLost(self, reason):
     dcall_discard(self, 'timeout_dcall')
Пример #30
0
    def shutdown(self):
        dcall_discard(self, 'sendState_dcall')

        for b in self.cached_blocks.itervalues():
            dcall_discard(b, 'expire_dcall')