示例#1
0
    def __init__(self, main, parent_n):
        self.main = main
        self.parent_n = parent_n
        self.blocks = {}  # {hash: [None | data]}
        self.hashlist = []
        self.status_pktnum = None

        self.topic_flag = False

        self.moderated = False

        self.last_assembled_pktnum = None
        self.nicks = {}  # {nick: NickNode()}
        self.bans = {}  # {(ip,mask): Ban()}

        # Tuple of info strings; indices match up with the nick modes
        self.infostrings = ()

        self.req_blocks = RandSet()
        self.requestBlocks_dcall = None

        # Register me in BridgeClientManager
        self.main.osm.bcm.bridges.add(self)
示例#2
0
    def __init__(self, main, parent_n):
        self.main = main
        self.parent_n = parent_n
        self.blocks = {}   # {hash: [None | data]}
        self.hashlist = []
        self.status_pktnum = None

        self.topic_flag = False
        
        self.moderated = False

        self.last_assembled_pktnum = None
        self.nicks = {} # {nick: NickNode()}
        self.bans = {}  # {(ip,mask): Ban()}

        # Tuple of info strings; indices match up with the nick modes
        self.infostrings = ()

        self.req_blocks = RandSet()
        self.requestBlocks_dcall = None

        # Register me in BridgeClientManager
        self.main.osm.bcm.bridges.add(self)
示例#3
0
class BridgeNodeData(object):

    class Ban(object):
        def __init__(self, ipmask, enable, pktnum):
            self.ipmask = ipmask
            self.enable = enable
            self.pktnum = pktnum


    def __init__(self, main, parent_n):
        self.main = main
        self.parent_n = parent_n
        self.blocks = {}   # {hash: [None | data]}
        self.hashlist = []
        self.status_pktnum = None

        self.topic_flag = False
        
        self.moderated = False

        self.last_assembled_pktnum = None
        self.nicks = {} # {nick: NickNode()}
        self.bans = {}  # {(ip,mask): Ban()}

        # Tuple of info strings; indices match up with the nick modes
        self.infostrings = ()

        self.req_blocks = RandSet()
        self.requestBlocks_dcall = None

        # Register me in BridgeClientManager
        self.main.osm.bcm.bridges.add(self)


    def setHashList(self, hashlist, do_request):
       
        self.hashlist = hashlist
        
        self.blocks = dict.fromkeys(self.hashlist, None)

        bcm = self.main.osm.bcm

        # Start with no requested blocks
        self.req_blocks.clear()

        for bhash in self.blocks:
            try:
                bk = bcm.unclaimed_blocks.pop((self.parent_n.ipp, bhash))
            except KeyError:
                # If we're requesting blocks, then add this to the list
                if do_request:
                    self.req_blocks.add(bhash)
            else:
                bk.expire_dcall.cancel()
                self.blocks[bhash] = bk.data

        self.assembleBlocks()

        # Start requesting blocks (if any)
        self.scheduleRequestBlocks()


    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)


    def addDataBlock(self, bhash, data):
        # Return True if the block was accepted, False otherwise

        if bhash not in self.blocks:
            return False

        # If we're requesting blocks, then mark this one off
        # and possibly ask for more.
        
        if bhash in self.req_blocks:
            self.req_blocks.discard(bhash)
            self.scheduleRequestBlocks()

        # Record the block data, and check if it's time to assemble
        # all the blocks together.

        if self.blocks[bhash] is None:
            self.blocks[bhash] = data
            self.assembleBlocks()

        return True


    def assembleBlocks(self):

        osm = self.main.osm

        # DEBUG
        i=0
        for bk in self.blocks.itervalues():
            if bk is None:
                i+=1

        # Check if all the blocks exist yet
        if None in self.blocks.itervalues():
            return
        
        data = ''.join([self.blocks[bhash] for bhash in self.hashlist])

        self.hashlist = []
        self.blocks = {}

        # This will be toggled back to True if the topic is set
        self.topic_flag = False

        # Default to disabled
        self.moderated = False

        try:
            self.processChunks(data, self.status_pktnum)
        except ChunkError, e:
            self.main.logPacket("Couldn't assemble blocks: %s" % e)

        # Remove any nicks who aren't mentioned in this update
        dead_nicks = []

        for n in self.nicks.values():
            if n.pktnum < self.status_pktnum:
                del self.nicks[n.nick]
                if n.mode != 0xFF:
                    dead_nicks.append(n)

        # Report all the nicks that we deleted
        dead_nicks.sort()
        for n in dead_nicks:
            osm.nkm.removeNode(n, "Dead")

        # Remove any bans which aren't mentioned in this update
        for b in self.bans.values():
            if b.pktnum < self.status_pktnum:
                del self.bans[b.ipmask]

        # If not topic was set, release control of it
        if not self.topic_flag:
            osm.tm.checkLeavingNode(self.parent_n)

        self.last_assembled_pktnum = self.status_pktnum
示例#4
0
class BridgeNodeData(object):
    class Ban(object):
        def __init__(self, ipmask, enable, pktnum):
            self.ipmask = ipmask
            self.enable = enable
            self.pktnum = pktnum

    def __init__(self, main, parent_n):
        self.main = main
        self.parent_n = parent_n
        self.blocks = {}  # {hash: [None | data]}
        self.hashlist = []
        self.status_pktnum = None

        self.topic_flag = False

        self.moderated = False

        self.last_assembled_pktnum = None
        self.nicks = {}  # {nick: NickNode()}
        self.bans = {}  # {(ip,mask): Ban()}

        # Tuple of info strings; indices match up with the nick modes
        self.infostrings = ()

        self.req_blocks = RandSet()
        self.requestBlocks_dcall = None

        # Register me in BridgeClientManager
        self.main.osm.bcm.bridges.add(self)

    def setHashList(self, hashlist, do_request):

        self.hashlist = hashlist

        self.blocks = dict.fromkeys(self.hashlist, None)

        bcm = self.main.osm.bcm

        # Start with no requested blocks
        self.req_blocks.clear()

        for bhash in self.blocks:
            try:
                bk = bcm.unclaimed_blocks.pop((self.parent_n.ipp, bhash))
            except KeyError:
                # If we're requesting blocks, then add this to the list
                if do_request:
                    self.req_blocks.add(bhash)
            else:
                bk.expire_dcall.cancel()
                self.blocks[bhash] = bk.data

        self.assembleBlocks()

        # Start requesting blocks (if any)
        self.scheduleRequestBlocks()

    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)

    def addDataBlock(self, bhash, data):
        # Return True if the block was accepted, False otherwise

        if bhash not in self.blocks:
            return False

        # If we're requesting blocks, then mark this one off
        # and possibly ask for more.

        if bhash in self.req_blocks:
            self.req_blocks.discard(bhash)
            self.scheduleRequestBlocks()

        # Record the block data, and check if it's time to assemble
        # all the blocks together.

        if self.blocks[bhash] is None:
            self.blocks[bhash] = data
            self.assembleBlocks()

        return True

    def assembleBlocks(self):

        osm = self.main.osm

        # DEBUG
        i = 0
        for bk in self.blocks.itervalues():
            if bk is None:
                i += 1

        # Check if all the blocks exist yet
        if None in self.blocks.itervalues():
            return

        data = ''.join([self.blocks[bhash] for bhash in self.hashlist])

        self.hashlist = []
        self.blocks = {}

        # This will be toggled back to True if the topic is set
        self.topic_flag = False

        # Default to disabled
        self.moderated = False

        try:
            self.processChunks(data, self.status_pktnum)
        except ChunkError, e:
            self.main.logPacket("Couldn't assemble blocks: %s" % e)

        # Remove any nicks who aren't mentioned in this update
        dead_nicks = []

        for n in self.nicks.values():
            if n.pktnum < self.status_pktnum:
                del self.nicks[n.nick]
                if n.mode != 0xFF:
                    dead_nicks.append(n)

        # Report all the nicks that we deleted
        dead_nicks.sort()
        for n in dead_nicks:
            osm.nkm.removeNode(n, "Dead")

        # Remove any bans which aren't mentioned in this update
        for b in self.bans.values():
            if b.pktnum < self.status_pktnum:
                del self.bans[b.ipmask]

        # If not topic was set, release control of it
        if not self.topic_flag:
            osm.tm.checkLeavingNode(self.parent_n)

        self.last_assembled_pktnum = self.status_pktnum