Beispiel #1
0
    def callRemote(self, methname, *args, **kwargs):
        # this is ideally a Membrane, but that's too hard. We do a shallow
        # wrapping of inbound arguments, and per-methodname wrapping of
        # selected return values.
        def wrap(a):
            if isinstance(a, Referenceable):
                return LocalWrapper(a)
            else:
                return a

        args = tuple([wrap(a) for a in args])
        kwargs = dict([(k, wrap(kwargs[k])) for k in kwargs])

        def _really_call():
            meth = getattr(self.original, "remote_" + methname)
            return meth(*args, **kwargs)

        def _call():
            if self.broken:
                raise IntentionalError("I was asked to break")
            if self.hung_until:
                d2 = defer.Deferred()
                self.hung_until.addCallback(lambda ign: _really_call())
                self.hung_until.addCallback(lambda res: d2.callback(res))

                def _err(res):
                    d2.errback(res)
                    return res

                self.hung_until.addErrback(_err)
                return d2
            return _really_call()

        d = fireEventually()
        d.addCallback(lambda res: _call())

        def _wrap_exception(f):
            return Failure(RemoteException(f))

        d.addErrback(_wrap_exception)

        def _return_membrane(res):
            # rather than complete the difficult task of building a
            # fully-general Membrane (which would locate all Referenceable
            # objects that cross the simulated wire and replace them with
            # wrappers), we special-case certain methods that we happen to
            # know will return Referenceables.
            if methname == "allocate_buckets":
                (alreadygot, allocated) = res
                for shnum in allocated:
                    allocated[shnum] = LocalWrapper(allocated[shnum])
            if methname == "get_buckets":
                for shnum in res:
                    res[shnum] = LocalWrapper(res[shnum])
            return res

        d.addCallback(_return_membrane)
        if self.post_call_notifier:
            d.addCallback(self.post_call_notifier, self, methname)
        return d
Beispiel #2
0
 def loop(self):
     d = fireEventually(None) # avoid #237 recursion limit problem
     d.addCallback(lambda ign: self._activate_enough_peers())
     d.addCallback(lambda ign: self._download_current_segment())
     # when we're done, _download_current_segment will call _done. If we
     # aren't, it will call loop() again.
     d.addErrback(self._error)
Beispiel #3
0
    def test_welcome(self):
        basedir = "web.IntroducerWeb.test_welcome"
        os.mkdir(basedir)
        cfg = "\n".join([
            "[node]",
            "tub.location = 127.0.0.1:1",
            "web.port = tcp:0",
        ]) + "\n"
        fileutil.write(os.path.join(basedir, "tahoe.cfg"), cfg)
        self.node = IntroducerNode(basedir)
        self.ws = self.node.getServiceNamed("webish")

        d = fireEventually(None)
        d.addCallback(lambda ign: self.node.startService())

        d.addCallback(lambda ign: self.GET("/"))

        def _check(res):
            self.failUnlessIn('Welcome to the Tahoe-LAFS Introducer', res)
            self.failUnlessIn(FAVICON_MARKUP, res)
            self.failUnlessIn('Page rendered at', res)
            self.failUnlessIn('Tahoe-LAFS code imported from:', res)

        d.addCallback(_check)
        return d
Beispiel #4
0
 def run(self, target_furl):
     target_tubid = SturdyRef(target_furl).getTubRef().getTubID()
     d = fireEventually(target_furl)
     d.addCallback(self.start, target_tubid)
     d.addErrback(self._error)
     print("starting..")
     reactor.run()
Beispiel #5
0
 def run(self, target_furl):
     target_tubid = SturdyRef(target_furl).getTubRef().getTubID()
     d = fireEventually(target_furl)
     d.addCallback(self.start, target_tubid)
     d.addErrback(self._error)
     print "starting.."
     reactor.run()
Beispiel #6
0
def create_introducer_webish(reactor, port_assigner, basedir):
    """
    Create and start an introducer node and return it and its ``WebishServer``
    service.

    :param reactor: The reactor to use to allow the introducer node to use to
        listen for connections.

    :param SameProcessStreamEndpointAssigner port_assigner: The assigner to
        use to assign a listening port for the introducer node.

    :param bytes basedir: A non-existant path where the introducer node will
        be created.

    :return Deferred[(_IntroducerNode, WebishServer)]: A Deferred that fires
        with the node and its webish service.
    """
    node.create_node_dir(basedir, "testing")
    _, port_endpoint = port_assigner.assign(reactor)
    with open(join(basedir, "tahoe.cfg"), "w") as f:
        f.write("[node]\n"
                "tub.location = 127.0.0.1:1\n" +
                "web.port = {}\n".format(port_endpoint))

    intro_node = yield create_introducer(basedir)
    ws = intro_node.getServiceNamed("webish")

    yield fireEventually(None)
    intro_node.startService()

    defer.returnValue((intro_node, ws))
Beispiel #7
0
    def run(self):
        framelog = os.path.join(self.basedir, "driver.log")
        log.startLogging(open(framelog, "a"), setStdout=False)
        log.msg("CHECK_MEMORY(mode=%s) STARTING" % self.mode)
        #logfile = open(os.path.join(self.testdir, "log"), "w")
        #flo = log.FileLogObserver(logfile)
        #log.startLoggingWithObserver(flo.emit, setStdout=False)
        d = fireEventually()
        d.addCallback(lambda res: self.setUp())
        d.addCallback(lambda res: self.record_initial_memusage())
        d.addCallback(lambda res: self.make_nodes())
        d.addCallback(lambda res: self.wait_for_client_connected())
        d.addCallback(lambda res: self.do_test())
        d.addBoth(self.tearDown)

        def _err(err):
            self.failed = err
            log.err(err)
            print(err)

        d.addErrback(_err)

        def _done(res):
            reactor.stop()
            return res

        d.addBoth(_done)
        reactor.run()
        if self.failed:
            # raiseException doesn't work for CopiedFailures
            self.failed.raiseException()
Beispiel #8
0
 def loop(self):
     d = fireEventually(None)  # avoid #237 recursion limit problem
     d.addCallback(lambda ign: self._activate_enough_servers())
     d.addCallback(lambda ign: self._download_current_segment())
     # when we're done, _download_current_segment will call _done. If we
     # aren't, it will call loop() again.
     d.addErrback(self._error)
Beispiel #9
0
 def run(self):
     framelog = os.path.join(self.basedir, "driver.log")
     log.startLogging(open(framelog, "a"), setStdout=False)
     log.msg("CHECK_MEMORY(mode=%s) STARTING" % self.mode)
     #logfile = open(os.path.join(self.testdir, "log"), "w")
     #flo = log.FileLogObserver(logfile)
     #log.startLoggingWithObserver(flo.emit, setStdout=False)
     d = fireEventually()
     d.addCallback(lambda res: self.setUp())
     d.addCallback(lambda res: self.record_initial_memusage())
     d.addCallback(lambda res: self.make_nodes())
     d.addCallback(lambda res: self.wait_for_client_connected())
     d.addCallback(lambda res: self.do_test())
     d.addBoth(self.tearDown)
     def _err(err):
         self.failed = err
         log.err(err)
         print err
     d.addErrback(_err)
     def _done(res):
         reactor.stop()
         return res
     d.addBoth(_done)
     reactor.run()
     if self.failed:
         # raiseException doesn't work for CopiedFailures
         self.failed.raiseException()
Beispiel #10
0
 def callRemote(self, methname, *args, **kwargs):
     self.queries += 1
     def _call():
         meth = getattr(self, methname)
         return meth(*args, **kwargs)
     d = fireEventually()
     d.addCallback(lambda res: _call())
     return d
Beispiel #11
0
 def callRemote(self, methname, *args, **kwargs):
     self.queries += 1
     def _call():
         meth = getattr(self, methname)
         return meth(*args, **kwargs)
     d = fireEventually()
     d.addCallback(lambda res: _call())
     return d
def wait_a_few_turns(ignored=None):
    d = fireEventually()
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    return d
Beispiel #13
0
def wait_a_few_turns(ignored=None):
    d = fireEventually()
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    d.addCallback(fireEventually)
    return d
Beispiel #14
0
    def _turn_barrier(self, res):
        # putting this method in a Deferred chain imposes a guaranteed
        # reactor turn between the pre- and post- portions of that chain.
        # This can be useful to limit memory consumption: since Deferreds do
        # not do tail recursion, code which uses defer.succeed(result) for
        # consistency will cause objects to live for longer than you might
        # normally expect.

        return fireEventually(res)
Beispiel #15
0
    def _turn_barrier(self, res):
        # putting this method in a Deferred chain imposes a guaranteed
        # reactor turn between the pre- and post- portions of that chain.
        # This can be useful to limit memory consumption: since Deferreds do
        # not do tail recursion, code which uses defer.succeed(result) for
        # consistency will cause objects to live for longer than you might
        # normally expect.

        return fireEventually(res)
Beispiel #16
0
    def callRemote(self, methname, *args, **kwargs):
        # this is ideally a Membrane, but that's too hard. We do a shallow
        # wrapping of inbound arguments, and per-methodname wrapping of
        # selected return values.
        def wrap(a):
            if isinstance(a, Referenceable):
                return LocalWrapper(a)
            else:
                return a
        args = tuple([wrap(a) for a in args])
        kwargs = dict([(k,wrap(kwargs[k])) for k in kwargs])

        def _really_call():
            def incr(d, k): d[k] = d.setdefault(k, 0) + 1
            incr(self.counter_by_methname, methname)
            meth = getattr(self.original, "remote_" + methname)
            return meth(*args, **kwargs)

        def _call():
            if self.broken:
                if self.broken is not True: # a counter, not boolean
                    self.broken -= 1
                raise IntentionalError("I was asked to break")
            if self.hung_until:
                d2 = defer.Deferred()
                self.hung_until.addCallback(lambda ign: _really_call())
                self.hung_until.addCallback(lambda res: d2.callback(res))
                def _err(res):
                    d2.errback(res)
                    return res
                self.hung_until.addErrback(_err)
                return d2
            return _really_call()

        d = fireEventually()
        d.addCallback(lambda res: _call())
        def _wrap_exception(f):
            return Failure(RemoteException(f))
        d.addErrback(_wrap_exception)
        def _return_membrane(res):
            # rather than complete the difficult task of building a
            # fully-general Membrane (which would locate all Referenceable
            # objects that cross the simulated wire and replace them with
            # wrappers), we special-case certain methods that we happen to
            # know will return Referenceables.
            if methname == "allocate_buckets":
                (alreadygot, allocated) = res
                for shnum in allocated:
                    allocated[shnum] = LocalWrapper(allocated[shnum])
            if methname == "get_buckets":
                for shnum in res:
                    res[shnum] = LocalWrapper(res[shnum])
            return res
        d.addCallback(_return_membrane)
        if self.post_call_notifier:
            d.addCallback(self.post_call_notifier, self, methname)
        return d
Beispiel #17
0
    def setUp(self):
        self.parent = service.MultiService()
        self.parent.startService()

        self.tub = t = Tub()
        t.setOption("expose-remote-exception-types", False)
        t.setServiceParent(self.parent)
        t.listenOn("tcp:0")
        t.setLocationAutomatically()
        return fireEventually()
Beispiel #18
0
 def _then2(ign):
     self.failUnlessEqual(len(announcements), 1)
     self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 2)
     self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
     self.failUnlessEqual(ic._debug_counts["update"], 0)
     self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 1)
     # and a replacement announcement: same FURL, new other stuff.
     # Clients should be notified.
     ca.remote_announce([ann1b])
     return fireEventually()
Beispiel #19
0
    def setUp(self):
        self.parent = service.MultiService()
        self.parent.startService()

        self.tub = t = Tub()
        t.setOption("expose-remote-exception-types", False)
        t.setServiceParent(self.parent)
        t.listenOn("tcp:0")
        t.setLocationAutomatically()
        return fireEventually()
Beispiel #20
0
 def test_loadable(self):
     basedir = "introducer.IntroducerNode.test_loadable"
     os.mkdir(basedir)
     q = IntroducerNode(basedir)
     d = fireEventually(None)
     d.addCallback(lambda res: q.startService())
     d.addCallback(lambda res: q.when_tub_ready())
     d.addCallback(lambda res: q.stopService())
     d.addCallback(flushEventualQueue)
     return d
Beispiel #21
0
 def _then2(ign):
     self.failUnlessEqual(len(announcements), 1)
     self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 2)
     self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
     self.failUnlessEqual(ic._debug_counts["update"], 0)
     self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 1)
     # and a replacement announcement: same FURL, new other stuff.
     # Clients should be notified.
     ca.remote_announce([ann1b])
     return fireEventually()
 def test_loadable(self):
     basedir = "introducer.IntroducerNode.test_loadable"
     os.mkdir(basedir)
     q = IntroducerNode(basedir)
     d = fireEventually(None)
     d.addCallback(lambda res: q.startService())
     d.addCallback(lambda res: q.when_tub_ready())
     d.addCallback(lambda res: q.stopService())
     d.addCallback(flushEventualQueue)
     return d
Beispiel #23
0
 def put_block(self, segmentnum, data):
     if self.mode == "lost-early":
         f = Failure(LostPeerError("I went away early"))
         return fireEventually(f)
     def _try():
         assert not self.closed
         assert segmentnum not in self.blocks
         if self.mode == "lost" and segmentnum >= 1:
             raise LostPeerError("I'm going away now")
         self.blocks[segmentnum] = data
     return defer.maybeDeferred(_try)
Beispiel #24
0
def run_flappclient(argv=None, run_by_human=True, stdio=StandardIO):
    if run_by_human:
        stdout = sys.stdout
        stderr = sys.stderr
    else:
        stdout = io.StringIO()
        stderr = io.StringIO()

    if argv:
        command_name, argv = argv[0], argv[1:]
    else:
        command_name = sys.argv[0]

    d = fireEventually()
    d.addCallback(
        lambda _ign: parse_options(command_name, argv, stdio, stdout, stderr))
    d.addCallback(run_command)

    if run_by_human:
        # we need to spin up our own reactor
        from twisted.internet import reactor
        stash_rc = []

        def good(rc):
            stash_rc.append(rc)
            reactor.stop()

        def oops(f):
            if f.check(SystemExit):
                stash_rc.append(f.value.args[0])
            else:
                print("flappclient command failed:", file=stderr)
                print(f, file=stderr)
                stash_rc.append(-1)
            reactor.stop()

        d.addCallbacks(good, oops)

        reactor.run()

        sys.exit(stash_rc[0] if stash_rc else 1)

    else:

        @d.addErrback
        def _convert_system_exit(f):
            f.trap(SystemExit)
            return f.value.args[0]

        @d.addCallback
        def done(rc):
            return (rc, stdout.getvalue(), stderr.getvalue())

        return d
Beispiel #25
0
    def start(self):
        """ Returns a Deferred that will fire with the verify cap (an instance of
        uri.CHKFileVerifierURI)."""
        self.log("%s starting" % (self, ))
        #paddedsize = self._size + mathutil.pad_size(self._size, self.needed_shares)
        assert self._codec
        self._crypttext_hasher = hashutil.crypttext_hasher()
        self._crypttext_hashes = []
        self.segment_num = 0
        self.block_hashes = [[] for x in range(self.num_shares)]
        # block_hashes[i] is a list that will be accumulated and then send
        # to landlord[i]. This list contains a hash of each segment_share
        # that we sent to that landlord.
        self.share_root_hashes = [None] * self.num_shares

        self._times = {
            "cumulative_encoding": 0.0,
            "cumulative_sending": 0.0,
            "hashes_and_close": 0.0,
            "total_encode_and_push": 0.0,
        }
        self._start_total_timestamp = time.time()

        d = fireEventually()

        d.addCallback(lambda res: self.start_all_shareholders())

        for i in range(self.num_segments - 1):
            # note to self: this form doesn't work, because lambda only
            # captures the slot, not the value
            #d.addCallback(lambda res: self.do_segment(i))
            # use this form instead:
            d.addCallback(
                lambda res, i=i: self._encode_segment(i, is_tail=False))
            d.addCallback(self._send_segment, i)
            d.addCallback(self._turn_barrier)
        last_segnum = self.num_segments - 1
        d.addCallback(
            lambda res: self._encode_segment(last_segnum, is_tail=True))
        d.addCallback(self._send_segment, last_segnum)
        d.addCallback(self._turn_barrier)

        d.addCallback(lambda res: self.finish_hashing())

        d.addCallback(
            lambda res: self.send_crypttext_hash_tree_to_all_shareholders())
        d.addCallback(lambda res: self.send_all_block_hash_trees())
        d.addCallback(lambda res: self.send_all_share_hash_trees())
        d.addCallback(
            lambda res: self.send_uri_extension_to_all_shareholders())

        d.addCallback(lambda res: self.close_all_shareholders())
        d.addCallbacks(self.done, self.err)
        return d
Beispiel #26
0
 def _then(ign):
     self.failUnlessEqual(len(announcements), 1)
     self.failUnlessEqual(announcements[0]["nickname"], u"nick1")
     self.failUnlessEqual(announcements[0]["my-version"], "ver23")
     self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 1)
     self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
     self.failUnlessEqual(ic._debug_counts["update"], 0)
     self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 0)
     # now send a duplicate announcement: this should not notify clients
     ca.remote_announce([ann1])
     return fireEventually()
Beispiel #27
0
 def _then(ign):
     self.failUnlessEqual(len(announcements), 1)
     self.failUnlessEqual(announcements[0]["nickname"], u"nick1")
     self.failUnlessEqual(announcements[0]["my-version"], "ver23")
     self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 1)
     self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
     self.failUnlessEqual(ic._debug_counts["update"], 0)
     self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 0)
     # now send a duplicate announcement: this should not notify clients
     ca.remote_announce([ann1])
     return fireEventually()
Beispiel #28
0
 def _then(ign):
     # first announcement has been processed
     self.failUnlessEqual(len(announcements), 1)
     self.failUnlessEqual(announcements[0]["anonymous-storage-FURL"],
                          furl1)
     # now submit a second one, with a tubid that happens to look just
     # like the pubkey-based serverid we just processed. They should
     # not overlap.
     ann2 = (furl2, "storage", "RIStorage", "nick1", "ver23", "ver0")
     ca = WrapV2ClientInV1Interface(ic)
     ca.remote_announce([ann2])
     return fireEventually()
Beispiel #29
0
    def test_duplicate_receive_v1(self):
        ic = IntroducerClient(None, "introducer.furl", u"my_nickname",
                              "my_version", "oldest_version", {})
        announcements = []
        ic.subscribe_to("storage",
                        lambda key_s, ann: announcements.append(ann))
        furl1 = "pb://[email protected]:36106/gydnpigj2ja2qr2srq4ikjwnl7xfgbra"
        ann1 = (furl1, "storage", "RIStorage", "nick1", "ver23", "ver0")
        ann1b = (furl1, "storage", "RIStorage", "nick1", "ver24", "ver0")
        ca = WrapV2ClientInV1Interface(ic)

        ca.remote_announce([ann1])
        d = fireEventually()

        def _then(ign):
            self.failUnlessEqual(len(announcements), 1)
            self.failUnlessEqual(announcements[0]["nickname"], u"nick1")
            self.failUnlessEqual(announcements[0]["my-version"], "ver23")
            self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["update"], 0)
            self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 0)
            # now send a duplicate announcement: this should not notify clients
            ca.remote_announce([ann1])
            return fireEventually()

        d.addCallback(_then)

        def _then2(ign):
            self.failUnlessEqual(len(announcements), 1)
            self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 2)
            self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["update"], 0)
            self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 1)
            # and a replacement announcement: same FURL, new other stuff.
            # Clients should be notified.
            ca.remote_announce([ann1b])
            return fireEventually()

        d.addCallback(_then2)

        def _then3(ign):
            self.failUnlessEqual(len(announcements), 2)
            self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 3)
            self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["update"], 1)
            self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 1)
            # test that the other stuff changed
            self.failUnlessEqual(announcements[-1]["nickname"], u"nick1")
            self.failUnlessEqual(announcements[-1]["my-version"], "ver24")

        d.addCallback(_then3)
        return d
Beispiel #30
0
 def _then(ign):
     # first announcement has been processed
     self.failUnlessEqual(len(announcements), 1)
     self.failUnlessEqual(announcements[0]["anonymous-storage-FURL"],
                          furl1)
     # now submit a second one, with a tubid that happens to look just
     # like the pubkey-based serverid we just processed. They should
     # not overlap.
     ann2 = (furl2, "storage", "RIStorage", "nick1", "ver23", "ver0")
     ca = WrapV2ClientInV1Interface(ic)
     ca.remote_announce([ann2])
     return fireEventually()
Beispiel #31
0
def run_flappclient(argv=None, run_by_human=True, stdio=StandardIO):
    if run_by_human:
        stdout = wrap_in_binary_mode(sys.stdout)
        stderr = wrap_in_binary_mode(sys.stderr)
    else:
        stdout = BytesIO()
        stderr = BytesIO()
    if argv:
        command_name, argv = argv[0], argv[1:]
    else:
        command_name = sys.argv[0]

    d = fireEventually()
    d.addCallback(
        lambda _ign: parse_options(command_name, argv, stdio, stdout, stderr))
    d.addCallback(run_command)

    if run_by_human:
        # we need to spin up our own reactor
        from twisted.internet import reactor
        stash_rc = []

        def good(rc):
            stash_rc.append(rc)
            reactor.stop()

        def oops(f):
            if f.check(SystemExit):
                stash_rc.append(f.value.args[0])
            else:
                stderr.write(b"flappclient command failed:\n")
                stderr.write(six.ensure_binary("%s\n" % (f, )))
                stash_rc.append(-1)
            reactor.stop()

        d.addCallbacks(good, oops)
        reactor.run()
        sys.exit(stash_rc[0])
    else:

        def _convert_system_exit(f):
            f.trap(SystemExit)
            return f.value.args[0]

        d.addErrback(_convert_system_exit)

        def done(rc):
            return (rc, stdout.getvalue(), stderr.getvalue())

        d.addCallback(done)
        return d
Beispiel #32
0
    def start(self):
        """ Returns a Deferred that will fire with the verify cap (an instance of
        uri.CHKFileVerifierURI)."""
        self.log("%s starting" % (self,))
        #paddedsize = self._size + mathutil.pad_size(self._size, self.needed_shares)
        assert self._codec
        self._crypttext_hasher = hashutil.crypttext_hasher()
        self._crypttext_hashes = []
        self.segment_num = 0
        self.block_hashes = [[] for x in range(self.num_shares)]
        # block_hashes[i] is a list that will be accumulated and then send
        # to landlord[i]. This list contains a hash of each segment_share
        # that we sent to that landlord.
        self.share_root_hashes = [None] * self.num_shares

        self._times = {
            "cumulative_encoding": 0.0,
            "cumulative_sending": 0.0,
            "hashes_and_close": 0.0,
            "total_encode_and_push": 0.0,
            }
        self._start_total_timestamp = time.time()

        d = fireEventually()

        d.addCallback(lambda res: self.start_all_shareholders())

        for i in range(self.num_segments-1):
            # note to self: this form doesn't work, because lambda only
            # captures the slot, not the value
            #d.addCallback(lambda res: self.do_segment(i))
            # use this form instead:
            d.addCallback(lambda res, i=i: self._encode_segment(i))
            d.addCallback(self._send_segment, i)
            d.addCallback(self._turn_barrier)
        last_segnum = self.num_segments - 1
        d.addCallback(lambda res: self._encode_tail_segment(last_segnum))
        d.addCallback(self._send_segment, last_segnum)
        d.addCallback(self._turn_barrier)

        d.addCallback(lambda res: self.finish_hashing())

        d.addCallback(lambda res:
                      self.send_crypttext_hash_tree_to_all_shareholders())
        d.addCallback(lambda res: self.send_all_block_hash_trees())
        d.addCallback(lambda res: self.send_all_share_hash_trees())
        d.addCallback(lambda res: self.send_uri_extension_to_all_shareholders())

        d.addCallback(lambda res: self.close_all_shareholders())
        d.addCallbacks(self.done, self.err)
        return d
Beispiel #33
0
def run_flappclient(argv=None, run_by_human=True, stdio=StandardIO):
    if run_by_human:
        stdout = sys.stdout
        stderr = sys.stderr
    else:
        stdout = StringIO()
        stderr = StringIO()
    if argv:
        command_name, argv = argv[0], argv[1:]
    else:
        command_name = sys.argv[0]

    d = fireEventually()
    d.addCallback(lambda _ign: parse_options(command_name, argv, stdio, stdout, stderr))
    d.addCallback(run_command)

    if run_by_human:
        # we need to spin up our own reactor
        from twisted.internet import reactor

        stash_rc = []

        def good(rc):
            stash_rc.append(rc)
            reactor.stop()

        def oops(f):
            if f.check(SystemExit):
                stash_rc.append(f.value.args[0])
            else:
                print >> stderr, "flappclient command failed:"
                print >> stderr, f
                stash_rc.append(-1)
            reactor.stop()

        d.addCallbacks(good, oops)
        reactor.run()
        sys.exit(stash_rc[0])
    else:

        def _convert_system_exit(f):
            f.trap(SystemExit)
            return f.value.args[0]

        d.addErrback(_convert_system_exit)

        def done(rc):
            return (rc, stdout.getvalue(), stderr.getvalue())

        d.addCallback(done)
        return d
Beispiel #34
0
    def test_duplicate_receive_v1(self):
        ic = IntroducerClient(None,
                              "introducer.furl", u"my_nickname",
                              "my_version", "oldest_version", {})
        announcements = []
        ic.subscribe_to("storage",
                        lambda key_s,ann: announcements.append(ann))
        furl1 = "pb://[email protected]:36106/gydnpigj2ja2qr2srq4ikjwnl7xfgbra"
        ann1 = (furl1, "storage", "RIStorage", "nick1", "ver23", "ver0")
        ann1b = (furl1, "storage", "RIStorage", "nick1", "ver24", "ver0")
        ca = WrapV2ClientInV1Interface(ic)

        ca.remote_announce([ann1])
        d = fireEventually()
        def _then(ign):
            self.failUnlessEqual(len(announcements), 1)
            self.failUnlessEqual(announcements[0]["nickname"], u"nick1")
            self.failUnlessEqual(announcements[0]["my-version"], "ver23")
            self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["update"], 0)
            self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 0)
            # now send a duplicate announcement: this should not notify clients
            ca.remote_announce([ann1])
            return fireEventually()
        d.addCallback(_then)
        def _then2(ign):
            self.failUnlessEqual(len(announcements), 1)
            self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 2)
            self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["update"], 0)
            self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 1)
            # and a replacement announcement: same FURL, new other stuff.
            # Clients should be notified.
            ca.remote_announce([ann1b])
            return fireEventually()
        d.addCallback(_then2)
        def _then3(ign):
            self.failUnlessEqual(len(announcements), 2)
            self.failUnlessEqual(ic._debug_counts["inbound_announcement"], 3)
            self.failUnlessEqual(ic._debug_counts["new_announcement"], 1)
            self.failUnlessEqual(ic._debug_counts["update"], 1)
            self.failUnlessEqual(ic._debug_counts["duplicate_announcement"], 1)
            # test that the other stuff changed
            self.failUnlessEqual(announcements[-1]["nickname"], u"nick1")
            self.failUnlessEqual(announcements[-1]["my-version"], "ver24")
        d.addCallback(_then3)
        return d
Beispiel #35
0
 def slot_testv_and_readv_and_writev(self, storage_index, secrets,
                                     tw_vectors, read_vector):
     # always-pass: parrot the test vectors back to them.
     readv = {}
     for shnum, (testv, writev, new_length) in tw_vectors.items():
         for (offset, length, op, specimen) in testv:
             assert op in ("le", "eq", "ge")
         # TODO: this isn't right, the read is controlled by read_vector,
         # not by testv
         readv[shnum] = [
             specimen for (offset, length, op, specimen) in testv
         ]
         for (offset, data) in writev:
             self.storage.write(self.peerid, storage_index, shnum, offset,
                                data)
     answer = (True, readv)
     return fireEventually(answer)
Beispiel #36
0
 def slot_testv_and_readv_and_writev(self, storage_index, secrets,
                                     tw_vectors, read_vector):
     # always-pass: parrot the test vectors back to them.
     readv = {}
     for shnum, (testv, writev, new_length) in tw_vectors.items():
         for (offset, length, op, specimen) in testv:
             assert op in ("le", "eq", "ge")
         # TODO: this isn't right, the read is controlled by read_vector,
         # not by testv
         readv[shnum] = [ specimen
                          for (offset, length, op, specimen)
                          in testv ]
         for (offset, data) in writev:
             self.storage.write(self.peerid, storage_index, shnum,
                                offset, data)
     answer = (True, readv)
     return fireEventually(answer)
Beispiel #37
0
    def test_welcome(self):
        config = ("[node]\n"
                  "tub.location = 127.0.0.1:1\n"
                  "web.port = tcp:0\n")
        from allmydata.node import config_from_string
        self.node = IntroducerNode(
            config_from_string(config, portnumfile="introducer.port"), )
        self.ws = self.node.getServiceNamed("webish")

        yield fireEventually(None)
        self.node.startService()

        url = "http://localhost:%d/" % self.ws.getPortnum()
        res = yield do_http("get", url)
        self.failUnlessIn('Welcome to the Tahoe-LAFS Introducer', res)
        self.failUnlessIn(FAVICON_MARKUP, res)
        self.failUnlessIn('Page rendered at', res)
        self.failUnlessIn('Tahoe-LAFS code imported from:', res)
Beispiel #38
0
 def _good(children):
     # Deferreds don't optimize out tail recursion, and the way
     # Nevow's flattener handles Deferreds doesn't take this into
     # account. As a result, large lists of Deferreds that fire in the
     # same turn (i.e. the output of defer.succeed) will cause a stack
     # overflow. To work around this, we insert a turn break after
     # every 100 items, using foolscap's fireEventually(). This gives
     # the stack a chance to be popped. It would also work to put
     # every item in its own turn, but that'd be a lot more
     # inefficient. This addresses ticket #237, for which I was never
     # able to create a failing unit test.
     output = []
     for i,item in enumerate(sorted(children.items())):
         if i % 100 == 0:
             output.append(fireEventually(item))
         else:
             output.append(item)
     self.dirnode_children = output
     return ctx
Beispiel #39
0
 def _good(children):
     # Deferreds don't optimize out tail recursion, and the way
     # Nevow's flattener handles Deferreds doesn't take this into
     # account. As a result, large lists of Deferreds that fire in the
     # same turn (i.e. the output of defer.succeed) will cause a stack
     # overflow. To work around this, we insert a turn break after
     # every 100 items, using foolscap's fireEventually(). This gives
     # the stack a chance to be popped. It would also work to put
     # every item in its own turn, but that'd be a lot more
     # inefficient. This addresses ticket #237, for which I was never
     # able to create a failing unit test.
     output = []
     for i,item in enumerate(sorted(children.items())):
         if i % 100 == 0:
             output.append(fireEventually(item))
         else:
             output.append(item)
     self.dirnode_children = output
     return ctx
Beispiel #40
0
    def run(self, options):
        basedir = options.basedir
        stdout = options.stdout
        stderr = options.stderr
        if os.path.exists(basedir):
            print >> stderr, "Refusing to touch pre-existing directory %s" % basedir
            return 1

        os.makedirs(basedir)
        os.makedirs(os.path.join(basedir, "services"))
        os.chmod(basedir, 0700)

        # start the server and let it run briefly. This lets the Tub spin up,
        # create the key, decide upon a port, and auto-determine its location
        # (if one was not provided with --location=). The base FURL will be
        # written to a file so that subsequent 'add' and 'list' can compute
        # FURLs without needing to run the Tub (which might already be
        # running).

        f = open(os.path.join(basedir, "port"), "w")
        f.write("%s\n" % options["port"])
        f.close()
        # we'll overwrite BASEDIR/port if necessary

        f = open(os.path.join(basedir, "location"), "w")
        f.write("%s\n" % options["location"])
        f.close()

        f = open(os.path.join(basedir, "umask"), "w")
        f.write("%04o\n" % options["umask"])
        f.close()

        save_service_data(basedir, {"version": 1, "services": {}})

        self.server = None
        d = fireEventually(basedir)
        d.addCallback(AppServer, stdout)
        d.addCallback(self.stash_and_start_appserver)
        d.addCallback(self.appserver_ready, options)
        d.addBoth(self.stop_appserver)
        d.addCallback(lambda ign: 0)
        return d
Beispiel #41
0
    def run(self, options):
        basedir = options.basedir
        stdout = options.stdout
        stderr = options.stderr
        if os.path.exists(basedir):
            print >> stderr, "Refusing to touch pre-existing directory %s" % basedir
            return 1

        os.makedirs(basedir)
        os.makedirs(os.path.join(basedir, "services"))
        os.chmod(basedir, 0700)

        # start the server and let it run briefly. This lets the Tub spin up,
        # create the key, decide upon a port, and auto-determine its location
        # (if one was not provided with --location=). The base FURL will be
        # written to a file so that subsequent 'add' and 'list' can compute
        # FURLs without needing to run the Tub (which might already be
        # running).

        f = open(os.path.join(basedir, "port"), "w")
        f.write("%s\n" % options["port"])
        f.close()
        # we'll overwrite BASEDIR/port if necessary

        f = open(os.path.join(basedir, "location"), "w")
        f.write("%s\n" % options["location"])
        f.close()

        f = open(os.path.join(basedir, "umask"), "w")
        f.write("%04o\n" % options["umask"])
        f.close()

        save_service_data(basedir, {"version": 1, "services": {}})

        self.server = None
        d = fireEventually(basedir)
        d.addCallback(AppServer, stdout)
        d.addCallback(self.stash_and_start_appserver)
        d.addCallback(self.appserver_ready, options)
        d.addBoth(self.stop_appserver)
        d.addCallback(lambda ign: 0)
        return d
Beispiel #42
0
 def run(self):
     print("STARTING")
     d = fireEventually()
     d.addCallback(lambda res: self.setUp())
     d.addCallback(lambda res: self.do_test())
     d.addBoth(self.tearDown)
     def _err(err):
         self.failed = err
         log.err(err)
         print(err)
     d.addErrback(_err)
     def _done(res):
         reactor.stop()
         return res
     d.addBoth(_done)
     reactor.run()
     if self.failed:
         print("EXCEPTION")
         print(self.failed)
         sys.exit(1)
Beispiel #43
0
 def _deep_traverse_dirnode_children(self, children, parent, path,
                                     walker, monitor, found):
     monitor.raise_if_cancelled()
     d = defer.maybeDeferred(walker.enter_directory, parent, children)
     # we process file-like children first, so we can drop their FileNode
     # objects as quickly as possible. Tests suggest that a FileNode (held
     # in the client's nodecache) consumes about 2440 bytes. dirnodes (not
     # in the nodecache) seem to consume about 2000 bytes.
     dirkids = []
     filekids = []
     for name, (child, metadata) in sorted(children.iteritems()):
         childpath = path + [name]
         if isinstance(child, UnknownNode):
             walker.add_node(child, childpath)
             continue
         verifier = child.get_verify_cap()
         # allow LIT files (for which verifier==None) to be processed
         if (verifier is not None) and (verifier in found):
             continue
         found.add(verifier)
         if IDirectoryNode.providedBy(child):
             dirkids.append( (child, childpath) )
         else:
             filekids.append( (child, childpath) )
     for i, (child, childpath) in enumerate(filekids):
         d.addCallback(lambda ignored, child=child, childpath=childpath:
                       walker.add_node(child, childpath))
         # to work around the Deferred tail-recursion problem
         # (specifically the defer.succeed flavor) requires us to avoid
         # doing more than 158 LIT files in a row. We insert a turn break
         # once every 100 files (LIT or CHK) to preserve some stack space
         # for other code. This is a different expression of the same
         # Twisted problem as in #237.
         if i % 100 == 99:
             d.addCallback(lambda ignored: fireEventually())
     for (child, childpath) in dirkids:
         d.addCallback(lambda ignored, child=child, childpath=childpath:
                       self._deep_traverse_dirnode(child, childpath,
                                                   walker, monitor,
                                                   found))
     return d
Beispiel #44
0
 def _deep_traverse_dirnode_children(self, children, parent, path,
                                     walker, monitor, found):
     monitor.raise_if_cancelled()
     d = defer.maybeDeferred(walker.enter_directory, parent, children)
     # we process file-like children first, so we can drop their FileNode
     # objects as quickly as possible. Tests suggest that a FileNode (held
     # in the client's nodecache) consumes about 2440 bytes. dirnodes (not
     # in the nodecache) seem to consume about 2000 bytes.
     dirkids = []
     filekids = []
     for name, (child, metadata) in sorted(children.iteritems()):
         childpath = path + [name]
         if isinstance(child, UnknownNode):
             walker.add_node(child, childpath)
             continue
         verifier = child.get_verify_cap()
         # allow LIT files (for which verifier==None) to be processed
         if (verifier is not None) and (verifier in found):
             continue
         found.add(verifier)
         if IDirectoryNode.providedBy(child):
             dirkids.append( (child, childpath) )
         else:
             filekids.append( (child, childpath) )
     for i, (child, childpath) in enumerate(filekids):
         d.addCallback(lambda ignored, child=child, childpath=childpath:
                       walker.add_node(child, childpath))
         # to work around the Deferred tail-recursion problem
         # (specifically the defer.succeed flavor) requires us to avoid
         # doing more than 158 LIT files in a row. We insert a turn break
         # once every 100 files (LIT or CHK) to preserve some stack space
         # for other code. This is a different expression of the same
         # Twisted problem as in #237.
         if i % 100 == 99:
             d.addCallback(lambda ignored: fireEventually())
     for (child, childpath) in dirkids:
         d.addCallback(lambda ignored, child=child, childpath=childpath:
                       self._deep_traverse_dirnode(child, childpath,
                                                   walker, monitor,
                                                   found))
     return d
Beispiel #45
0
    def test_welcome(self):
        basedir = "web.IntroducerWeb.test_welcome"
        os.mkdir(basedir)
        cfg = "\n".join([
            "[node]",
            "tub.location = 127.0.0.1:1",
            "web.port = tcp:0",
        ]) + "\n"
        fileutil.write(os.path.join(basedir, "tahoe.cfg"), cfg)
        self.node = IntroducerNode(basedir)
        self.ws = self.node.getServiceNamed("webish")

        yield fireEventually(None)
        self.node.startService()

        url = "http://localhost:%d/" % self.ws.getPortnum()
        res = yield do_http("get", url)
        self.failUnlessIn('Welcome to the Tahoe-LAFS Introducer', res)
        self.failUnlessIn(FAVICON_MARKUP, res)
        self.failUnlessIn('Page rendered at', res)
        self.failUnlessIn('Tahoe-LAFS code imported from:', res)
Beispiel #46
0
    def test_id_collision(self):
        # test replacement case where tubid equals a keyid (one should
        # not replace the other)
        ic = IntroducerClient(None, "introducer.furl", u"my_nickname",
                              "my_version", "oldest_version", {})
        announcements = []
        ic.subscribe_to("storage",
                        lambda key_s, ann: announcements.append(ann))
        sk_s, vk_s = keyutil.make_keypair()
        sk, _ignored = keyutil.parse_privkey(sk_s)
        keyid = keyutil.remove_prefix(vk_s, "pub-v0-")
        furl1 = "pb://[email protected]:123/short"  # base32("short")
        furl2 = "pb://%[email protected]:36106/swissnum" % keyid
        ann_t = ic.create_announcement("storage", make_ann(furl1), sk)
        ic.remote_announce_v2([ann_t])
        d = fireEventually()

        def _then(ign):
            # first announcement has been processed
            self.failUnlessEqual(len(announcements), 1)
            self.failUnlessEqual(announcements[0]["anonymous-storage-FURL"],
                                 furl1)
            # now submit a second one, with a tubid that happens to look just
            # like the pubkey-based serverid we just processed. They should
            # not overlap.
            ann2 = (furl2, "storage", "RIStorage", "nick1", "ver23", "ver0")
            ca = WrapV2ClientInV1Interface(ic)
            ca.remote_announce([ann2])
            return fireEventually()

        d.addCallback(_then)

        def _then2(ign):
            # if they overlapped, the second announcement would be ignored
            self.failUnlessEqual(len(announcements), 2)
            self.failUnlessEqual(announcements[1]["anonymous-storage-FURL"],
                                 furl2)

        d.addCallback(_then2)
        return d
Beispiel #47
0
    def test_welcome(self):
        basedir = self.mktemp()
        node.create_node_dir(basedir, "testing")
        with open(join(basedir, "tahoe.cfg"), "w") as f:
            f.write(
                "[node]\n"
                "tub.location = 127.0.0.1:1\n"
                "web.port = tcp:0\n"
            )

        self.node = yield create_introducer(basedir)
        self.ws = self.node.getServiceNamed("webish")

        yield fireEventually(None)
        self.node.startService()

        url = "http://localhost:%d/" % self.ws.getPortnum()
        res = yield do_http("get", url)
        self.failUnlessIn('Welcome to the Tahoe-LAFS Introducer', res)
        self.failUnlessIn(FAVICON_MARKUP, res)
        self.failUnlessIn('Page rendered at', res)
        self.failUnlessIn('Tahoe-LAFS code imported from:', res)
Beispiel #48
0
    def test_welcome(self):
        basedir = "web.IntroducerWeb.test_welcome"
        os.mkdir(basedir)
        cfg = "\n".join(["[node]",
                         "tub.location = 127.0.0.1:1",
                         "web.port = tcp:0",
                         ]) + "\n"
        fileutil.write(os.path.join(basedir, "tahoe.cfg"), cfg)
        self.node = IntroducerNode(basedir)
        self.ws = self.node.getServiceNamed("webish")

        d = fireEventually(None)
        d.addCallback(lambda ign: self.node.startService())

        d.addCallback(lambda ign: self.GET("/"))
        def _check(res):
            self.failUnlessIn('Welcome to the Tahoe-LAFS Introducer', res)
            self.failUnlessIn(FAVICON_MARKUP, res)
            self.failUnlessIn('Page rendered at', res)
            self.failUnlessIn('Tahoe-LAFS code imported from:', res)
        d.addCallback(_check)
        return d
    def test_welcome(self):
        basedir = self.mktemp()
        node.create_node_dir(basedir, "testing")
        _, port_endpoint = self.port_assigner.assign(reactor)
        with open(join(basedir, "tahoe.cfg"), "w") as f:
            f.write(
                "[node]\n"
                "tub.location = 127.0.0.1:1\n" +
                "web.port = {}\n".format(port_endpoint)
            )

        self.node = yield create_introducer(basedir)
        self.ws = self.node.getServiceNamed("webish")

        yield fireEventually(None)
        self.node.startService()

        url = "http://localhost:%d/" % self.ws.getPortnum()
        res = yield do_http("get", url)
        self.failUnlessIn('Welcome to the Tahoe-LAFS Introducer', res)
        self.failUnlessIn(FAVICON_MARKUP, res)
        self.failUnlessIn('Page rendered at', res)
        self.failUnlessIn('Tahoe-LAFS code imported from:', res)
Beispiel #50
0
    def test_welcome(self):
        basedir = self.mktemp()
        node.create_node_dir(basedir, "testing")
        _, port_endpoint = self.port_assigner.assign(reactor)
        with open(join(basedir, "tahoe.cfg"), "w") as f:
            f.write("[node]\n"
                    "tub.location = 127.0.0.1:1\n" +
                    "web.port = {}\n".format(port_endpoint))

        self.node = yield create_introducer(basedir)
        self.ws = self.node.getServiceNamed("webish")

        yield fireEventually(None)
        self.node.startService()

        url = "http://localhost:%d/" % self.ws.getPortnum()
        res = yield do_http("get", url)
        soup = BeautifulSoup(res, 'html5lib')
        assert_soup_has_text(self, soup,
                             u'Welcome to the Tahoe-LAFS Introducer')
        assert_soup_has_favicon(self, soup)
        assert_soup_has_text(self, soup, u'Page rendered at')
        assert_soup_has_text(self, soup, u'Tahoe-LAFS code imported from:')
Beispiel #51
0
 def test_id_collision(self):
     # test replacement case where tubid equals a keyid (one should
     # not replace the other)
     ic = IntroducerClient(None,
                           "introducer.furl", u"my_nickname",
                           "my_version", "oldest_version", {})
     announcements = []
     ic.subscribe_to("storage",
                     lambda key_s,ann: announcements.append(ann))
     sk_s, vk_s = keyutil.make_keypair()
     sk, _ignored = keyutil.parse_privkey(sk_s)
     keyid = keyutil.remove_prefix(vk_s, "pub-v0-")
     furl1 = "pb://[email protected]:123/short" # base32("short")
     furl2 = "pb://%[email protected]:36106/swissnum" % keyid
     ann_t = ic.create_announcement("storage", make_ann(furl1), sk)
     ic.remote_announce_v2([ann_t])
     d = fireEventually()
     def _then(ign):
         # first announcement has been processed
         self.failUnlessEqual(len(announcements), 1)
         self.failUnlessEqual(announcements[0]["anonymous-storage-FURL"],
                              furl1)
         # now submit a second one, with a tubid that happens to look just
         # like the pubkey-based serverid we just processed. They should
         # not overlap.
         ann2 = (furl2, "storage", "RIStorage", "nick1", "ver23", "ver0")
         ca = WrapV2ClientInV1Interface(ic)
         ca.remote_announce([ann2])
         return fireEventually()
     d.addCallback(_then)
     def _then2(ign):
         # if they overlapped, the second announcement would be ignored
         self.failUnlessEqual(len(announcements), 2)
         self.failUnlessEqual(announcements[1]["anonymous-storage-FURL"],
                              furl2)
     d.addCallback(_then2)
     return d
Beispiel #52
0
    def run(self):
        print "STARTING"
        d = fireEventually()
        d.addCallback(lambda res: self.setUp())
        d.addCallback(lambda res: self.do_test())
        d.addBoth(self.tearDown)

        def _err(err):
            self.failed = err
            log.err(err)
            print err

        d.addErrback(_err)

        def _done(res):
            reactor.stop()
            return res

        d.addBoth(_done)
        reactor.run()
        if self.failed:
            print "EXCEPTION"
            print self.failed
            sys.exit(1)
Beispiel #53
0
    def get_data(self, shnum, peerid):
        self.log(format="sending sh#%(shnum)d request to [%(peerid)s]",
                 shnum=shnum,
                 peerid=idlib.shortnodeid_b2a(peerid),
                 level=log.NOISY)
        ss = self.servermap.connections[peerid]
        started = time.time()
        (seqnum, root_hash, IV, segsize, datalength, k, N, prefix,
         offsets_tuple) = self.verinfo
        offsets = dict(offsets_tuple)

        # we read the checkstring, to make sure that the data we grab is from
        # the right version.
        readv = [ (0, struct.calcsize(SIGNED_PREFIX)) ]

        # We also read the data, and the hashes necessary to validate them
        # (share_hash_chain, block_hash_tree, share_data). We don't read the
        # signature or the pubkey, since that was handled during the
        # servermap phase, and we'll be comparing the share hash chain
        # against the roothash that was validated back then.

        readv.append( (offsets['share_hash_chain'],
                       offsets['enc_privkey'] - offsets['share_hash_chain'] ) )

        # if we need the private key (for repair), we also fetch that
        if self._need_privkey:
            readv.append( (offsets['enc_privkey'],
                           offsets['EOF'] - offsets['enc_privkey']) )

        m = Marker()
        self._outstanding_queries[m] = (peerid, shnum, started)

        # ask the cache first
        got_from_cache = False
        datavs = []
        for (offset, length) in readv:
            (data, timestamp) = self._node._read_from_cache(self.verinfo, shnum,
                                                            offset, length)
            if data is not None:
                datavs.append(data)
        if len(datavs) == len(readv):
            self.log("got data from cache")
            got_from_cache = True
            d = fireEventually({shnum: datavs})
            # datavs is a dict mapping shnum to a pair of strings
        else:
            d = self._do_read(ss, peerid, self._storage_index, [shnum], readv)
        self.remaining_sharemap.discard(shnum, peerid)

        d.addCallback(self._got_results, m, peerid, started, got_from_cache)
        d.addErrback(self._query_failed, m, peerid)
        # errors that aren't handled by _query_failed (and errors caused by
        # _query_failed) get logged, but we still want to check for doneness.
        def _oops(f):
            self.log(format="problem in _query_failed for sh#%(shnum)d to %(peerid)s",
                     shnum=shnum,
                     peerid=idlib.shortnodeid_b2a(peerid),
                     failure=f,
                     level=log.WEIRD, umid="W0xnQA")
        d.addErrback(_oops)
        d.addBoth(self._check_for_done)
        # any error during _check_for_done means the download fails. If the
        # download is successful, _check_for_done will fire _done by itself.
        d.addErrback(self._done)
        d.addErrback(log.err)
        return d # purely for testing convenience
Beispiel #54
0
 def flush(self):
     self.connected = False
     return fireEventually()
Beispiel #55
0
 def _start(self):
     if self.mode == "lost-early":
         f = Failure(LostPeerError("I went away early"))
         return fireEventually(f)
     return defer.succeed(self)
Beispiel #56
0
    def test_key_gen_service(self):
        def p(junk, msg):
            #import time
            #print time.asctime(), msg
            return junk

        #print 'starting key generator service'
        keysize = TEST_RSA_KEY_SIZE
        kgs = key_generator.KeyGeneratorService(display_furl=False, default_key_size=keysize, basedir="key_generator_service")
        kgs.key_generator.verbose = True
        kgs.setServiceParent(self.parent)
        kgs.key_generator.pool_size = 8

        def keypool_full():
            return len(kgs.key_generator.keypool) == kgs.key_generator.pool_size

        # first wait for key gen pool to fill up
        d = fireEventually()
        d.addCallback(p, 'waiting for pool to fill up')
        d.addCallback(lambda junk: self.poll(keypool_full))

        d.addCallback(p, 'grabbing a few keys')
        # grab a few keys, check that pool size shrinks
        def get_key(junk=None):
            d = self.tub.getReference(kgs.keygen_furl)
            d.addCallback(lambda kg: kg.callRemote('get_rsa_key_pair', keysize))
            return d

        def check_poolsize(junk, size):
            self.failUnlessEqual(len(kgs.key_generator.keypool), size)

        n_keys_to_waste = 4
        for i in range(n_keys_to_waste):
            d.addCallback(get_key)
        d.addCallback(check_poolsize, kgs.key_generator.pool_size - n_keys_to_waste)

        d.addCallback(p, 'checking a key works')
        # check that a retrieved key is actually useful
        d.addCallback(get_key)
        def check_key_works(keys):
            verifying_key, signing_key = keys
            v = rsa.create_verifying_key_from_string(verifying_key)
            s = rsa.create_signing_key_from_string(signing_key)
            junk = os.urandom(42)
            sig = s.sign(junk)
            self.failUnless(v.verify(junk, sig))
        d.addCallback(check_key_works)

        d.addCallback(p, 'checking pool exhaustion')
        # exhaust the pool
        for i in range(kgs.key_generator.pool_size):
            d.addCallback(get_key)
        d.addCallback(check_poolsize, 0)

        # and check it still works (will gen key synchronously on demand)
        d.addCallback(get_key)
        d.addCallback(check_key_works)

        d.addCallback(p, 'checking pool replenishment')
        # check that the pool will refill
        d.addCallback(lambda junk: self.poll(keypool_full))

        return d
    def test_duplicate_receive_v2(self):
        ic1 = IntroducerClient(None,
                               "introducer.furl", u"my_nickname",
                               "ver23", "oldest_version", {}, fakeseq,
                               FilePath(self.mktemp()))
        # we use a second client just to create a different-looking
        # announcement
        ic2 = IntroducerClient(None,
                               "introducer.furl", u"my_nickname",
                               "ver24","oldest_version",{}, fakeseq,
                               FilePath(self.mktemp()))
        announcements = []
        def _received(key_s, ann):
            announcements.append( (key_s, ann) )
        ic1.subscribe_to("storage", _received)
        furl1 = "pb://[email protected]:36106/gydnp"
        furl1a = "pb://[email protected]:7777/gydnp"
        furl2 = "pb://[email protected]:36106/ttwwoo"

        privkey_s, pubkey_vs = keyutil.make_keypair()
        privkey, _ignored = keyutil.parse_privkey(privkey_s)
        pubkey_s = keyutil.remove_prefix(pubkey_vs, "pub-")

        # ann1: ic1, furl1
        # ann1a: ic1, furl1a (same SturdyRef, different connection hints)
        # ann1b: ic2, furl1
        # ann2: ic2, furl2

        self.ann1 = make_ann_t(ic1, furl1, privkey, seqnum=10)
        self.ann1old = make_ann_t(ic1, furl1, privkey, seqnum=9)
        self.ann1noseqnum = make_ann_t(ic1, furl1, privkey, seqnum=None)
        self.ann1b = make_ann_t(ic2, furl1, privkey, seqnum=11)
        self.ann1a = make_ann_t(ic1, furl1a, privkey, seqnum=12)
        self.ann2 = make_ann_t(ic2, furl2, privkey, seqnum=13)

        ic1.remote_announce_v2([self.ann1]) # queues eventual-send
        d = fireEventually()
        def _then1(ign):
            self.failUnlessEqual(len(announcements), 1)
            key_s,ann = announcements[0]
            self.failUnlessEqual(key_s, pubkey_s)
            self.failUnlessEqual(ann["anonymous-storage-FURL"], furl1)
            self.failUnlessEqual(ann["my-version"], "ver23")
        d.addCallback(_then1)

        # now send a duplicate announcement. This should not fire the
        # subscriber
        d.addCallback(lambda ign: ic1.remote_announce_v2([self.ann1]))
        d.addCallback(fireEventually)
        def _then2(ign):
            self.failUnlessEqual(len(announcements), 1)
        d.addCallback(_then2)

        # an older announcement shouldn't fire the subscriber either
        d.addCallback(lambda ign: ic1.remote_announce_v2([self.ann1old]))
        d.addCallback(fireEventually)
        def _then2a(ign):
            self.failUnlessEqual(len(announcements), 1)
        d.addCallback(_then2a)

        # announcement with no seqnum cannot replace one with-seqnum
        d.addCallback(lambda ign: ic1.remote_announce_v2([self.ann1noseqnum]))
        d.addCallback(fireEventually)
        def _then2b(ign):
            self.failUnlessEqual(len(announcements), 1)
        d.addCallback(_then2b)

        # and a replacement announcement: same FURL, new other stuff. The
        # subscriber *should* be fired.
        d.addCallback(lambda ign: ic1.remote_announce_v2([self.ann1b]))
        d.addCallback(fireEventually)
        def _then3(ign):
            self.failUnlessEqual(len(announcements), 2)
            key_s,ann = announcements[-1]
            self.failUnlessEqual(key_s, pubkey_s)
            self.failUnlessEqual(ann["anonymous-storage-FURL"], furl1)
            self.failUnlessEqual(ann["my-version"], "ver24")
        d.addCallback(_then3)

        # and a replacement announcement with a different FURL (it uses
        # different connection hints)
        d.addCallback(lambda ign: ic1.remote_announce_v2([self.ann1a]))
        d.addCallback(fireEventually)
        def _then4(ign):
            self.failUnlessEqual(len(announcements), 3)
            key_s,ann = announcements[-1]
            self.failUnlessEqual(key_s, pubkey_s)
            self.failUnlessEqual(ann["anonymous-storage-FURL"], furl1a)
            self.failUnlessEqual(ann["my-version"], "ver23")
        d.addCallback(_then4)

        # now add a new subscription, which should be called with the
        # backlog. The introducer only records one announcement per index, so
        # the backlog will only have the latest message.
        announcements2 = []
        def _received2(key_s, ann):
            announcements2.append( (key_s, ann) )
        d.addCallback(lambda ign: ic1.subscribe_to("storage", _received2))
        d.addCallback(fireEventually)
        def _then5(ign):
            self.failUnlessEqual(len(announcements2), 1)
            key_s,ann = announcements2[-1]
            self.failUnlessEqual(key_s, pubkey_s)
            self.failUnlessEqual(ann["anonymous-storage-FURL"], furl1a)
            self.failUnlessEqual(ann["my-version"], "ver23")
        d.addCallback(_then5)
        return d
Beispiel #58
0
 def _maybe_iterate(res):
     if res:
         d4 = fireEventually()
         d4.addCallback(_iterate)
         return d4
     return False
Beispiel #59
0
 def _start(self):
     if self.mode == "lost-early":
         f = Failure(LostPeerError("I went away early"))
         return fireEventually(f)
     return defer.succeed(self)