Beispiel #1
0
 def got_interested(self, stream):
     if self.connector_side and self.state != SENT_NOT_INTERESTED:
         raise RuntimeError("INTERESTED when state != SENT_NOT_INTERESTED")
     if not self.connector_side and self.state != INITIAL:
         raise RuntimeError("INTERESTED when state != INITIAL")
     LOG.start("BitTorrent: uploading")
     self.state = UPLOADING
     stream.send_unchoke()
Beispiel #2
0
    def connect_uri(self, uri=None, count=None):
        if not uri:
            address = self.conf["bittorrent.address"]
            port = self.conf["bittorrent.negotiate.port"]
            uri = "http://%s:%s/" % (address, port)

        LOG.start("BitTorrent: connecting to %s" % uri)

        ClientHTTP.connect_uri(self, uri, 1)
Beispiel #3
0
 def connect(self, endpoint, count=1):
     self.connector_side = True
     #
     # In Neubot the listener does not have an infohash
     # and handshakes, including connector infohash, after
     # it receives the connector handshake.
     #
     self.infohash = self.conf["bittorrent.infohash"]
     LOG.start("BitTorrent: connecting to %s" % str(endpoint))
     StreamHandler.connect(self, endpoint, count)
Beispiel #4
0
 def got_unchoke(self, stream):
     if self.state != SENT_INTERESTED:
         raise RuntimeError("UNCHOKE when state != SENT_INTERESTED")
     else:
         self.state = DOWNLOADING
         LOG.start("BitTorrent: downloading %d bytes" % self.target_bytes)
         burst = self.sched_req.next()
         for index, begin, length in burst:
             stream.send_request(index, begin, length)
             self.inflight += 1
Beispiel #5
0
    def connect_uri(self, uri=None, count=None):
        self._task = None

        if not uri:
            uri = "http://%s:9773/rendezvous" % CONFIG["agent.master"]

        LOG.start("* Rendezvous with %s" % uri)
        STATE.update("rendezvous")

        # We need to make just one connection
        ClientHTTP.connect_uri(self, uri, 1)
Beispiel #6
0
    def connection_ready(self, stream):
        LOG.complete()

        STATE.update("negotiate")
        LOG.start("BitTorrent: negotiating")

        request = Message()
        body = json.dumps({"target_bytes": self.conf["bittorrent.bytes.up"]})
        request.compose(method="GET", pathquery="/negotiate/bittorrent",
          host=self.host_header, body=body, mimetype="application/json")
        request["authorization"] = self.conf.get("_authorization", "")
        stream.send_request(request)
Beispiel #7
0
    def connect_uri(self, uri=None, count=None):
        self._task = None

        if not privacy.allowed_to_run():
            _open_browser_on_windows("privacy.html")
            privacy.complain()
            self._schedule()
            return

        if not uri:
            uri = "http://%s:9773/rendezvous" % CONFIG["agent.master"]

        LOG.start("* Rendezvous with %s" % uri)
        STATE.update("rendezvous")

        # We need to make just one connection
        ClientHTTP.connect_uri(self, uri, 1)
Beispiel #8
0
    def peer_test_complete(self, stream, download_speed, rtt, target_bytes):
        self.success = True
        stream = self.http_stream

        # Update the downstream channel estimate
        estimate.DOWNLOAD = target_bytes

        self.my_side = {
            # The server will override our timestamp
            "timestamp": utils.timestamp(),
            "uuid": self.conf.get("uuid"),
            "internal_address": stream.myname[0],
            "real_address": self.conf.get("_real_address", ""),
            "remote_address": stream.peername[0],

            "privacy_informed": self.conf.get("privacy.informed", 0),
            "privacy_can_collect": self.conf.get("privacy.can_collect", 0),
            "privacy_can_publish": self.conf.get("privacy.can_publish", 0),

            # Upload speed measured at the server
            "connect_time": rtt,
            "download_speed": download_speed,

            # OS and version info
            "neubot_version": LibVersion.to_numeric("0.4.6-rc3"),
            "platform": sys.platform,
        }

        LOG.start("BitTorrent: collecting")
        STATE.update("collect")

        s = json.dumps(self.my_side)
        stringio = StringIO.StringIO(s)

        request = Message()
        request.compose(method="POST", pathquery="/collect/bittorrent",
          body=stringio, mimetype="application/json", host=self.host_header)
        request["authorization"] = self.conf.get("_authorization", "")

        stream.send_request(request)
Beispiel #9
0
import logging
import sys

if __name__ == "__main__":
    sys.path.insert(0, ".")

from neubot.log import LOG
from neubot.log import _log_info
from neubot import compat

if __name__ == "__main__":
    # Make sure the hackish name substitution works
    assert(logging.info == _log_info)

    LOG.start("Testing the in-progress feature")
    LOG.progress("...")
    LOG.progress()
    LOG.complete("success!")

    logging.info("INFO w/ logging.info")
    # The following should work because it should not interpolate
    logging.debug("DEBUG w/ logging.debug", "ciao")
    logging.warning("WARNING w/ logging.warning")
    logging.error("ERROR w/ logging.error")

    LOG.verbose()

    logging.info("INFO w/ logging.info")
    logging.debug("DEBUG w/ logging.debug")
    logging.warning("WARNING w/ logging.warning")
Beispiel #10
0
    def update(self):
        if self.finished:
            return

        #
        # Decide whether we can transition to the next phase of
        # the speedtest or not.  Fall through to next request if
        # needed, or return to the caller and rewind the stack.
        #

        ostate = self.state

        if not self.state:
            self.state = "negotiate"
            del QUEUE_HISTORY[:]

        elif self.state == "negotiate":
            if self.conf.get("speedtest.client.unchoked", False):
                LOG.complete("authorized to take the test\n")
                self.state = "latency"
            elif "speedtest.client.queuepos" in self.conf:
                queuepos = self.conf["speedtest.client.queuepos"]
                LOG.complete("waiting in queue, pos %s\n" % queuepos)
                STATE.update("negotiate", {"queue_pos": queuepos})
                QUEUE_HISTORY.append(queuepos)

        elif self.state == "latency":
            tries = self.conf.get("speedtest.client.latency_tries", 10)
            if tries == 0:
                # Calculate average latency
                latency = self.conf["speedtest.client.latency"]
                latency = sum(latency) / len(latency)
                self.conf["speedtest.client.latency"] = latency
                # Advertise the result
                STATE.update("test_latency", utils.time_formatter(latency))
                LOG.complete("done, %s\n" % utils.time_formatter(latency))
                self.state = "download"
            else:
                self.conf["speedtest.client.latency_tries"] = tries - 1

        elif self.state in ("download", "upload"):
            if len(self.streams) == self.conf.get("speedtest.client.nconn", 1):

                # Calculate average speed
                speed = self.conf["speedtest.client.%s" % self.state]
                elapsed = (max(map(lambda t: t[1], speed)) -
                  min(map(lambda t: t[0], speed)))
                speed = sum(map(lambda t: t[2], speed)) / elapsed
                LOG.progress(".[%s,%s]." % (utils.time_formatter(elapsed),
                       utils.speed_formatter(speed)))

                #
                # O(N) loopless adaptation to the channel w/ memory
                # TODO bittorrent/peer.py implements an enhanced version
                # of this algorithm, with a cap to the max number of
                # subsequent tests.  In addition to that, the bittorrent
                # code also anticipates the update of target_bytes.
                #
                if elapsed > LO_THRESH:
                    ESTIMATE[self.state] *= TARGET/elapsed
                    self.conf["speedtest.client.%s" % self.state] = speed
                    # Advertise
                    STATE.update("test_%s" % self.state,
                      utils.speed_formatter(speed))
                    LOG.complete("done, %s\n" % utils.speed_formatter(speed))
                    if self.state == "download":
                        self.state = "upload"
                    else:
                        self.state = "collect"
                elif elapsed > LO_THRESH/3:
                    del self.conf["speedtest.client.%s" % self.state]
                    ESTIMATE[self.state] *= TARGET/elapsed
                else:
                    del self.conf["speedtest.client.%s" % self.state]
                    ESTIMATE[self.state] *= 2

            else:
                # Wait for all pending requests to complete
                return

        elif self.state == "collect":
            LOG.complete()
            self.cleanup()
            return

        else:
            raise RuntimeError("Invalid state")

        #
        # Perform state transition and run the next phase of the
        # speedtest.  Not all phases need to employ all the connection
        # with the upstream server.
        #

        if self.state == "negotiate":
            ctor, justone = ClientNegotiate, True
        elif self.state == "latency":
            ctor, justone = ClientLatency, True
        elif self.state == "download":
            ctor, justone = ClientDownload, False
        elif self.state == "upload":
            ctor, justone = ClientUpload, False
        elif self.state == "collect":
            ctor, justone = ClientCollect, True
        else:
            raise RuntimeError("Invalid state")

        if ostate != self.state:
            self.child = ctor(self.poller)
            self.child.configure(self.conf)
            self.child.host_header = self.host_header
            if self.state not in ("negotiate", "collect"):
                if ostate == "negotiate" and self.state == "latency":
                    STATE.update("test_latency", "---", publish=False)
                    STATE.update("test_download", "---", publish=False)
                    STATE.update("test_upload", "---", publish=False)
                    STATE.update("test", "speedtest")
            else:
                STATE.update(self.state)
            LOG.start("* speedtest: %s" % self.state)
        elif self.state == "negotiate":
            LOG.start("* speedtest: %s" % self.state)

        while self.streams:
            #
            # Override child Time-To-Connect (TTC) with our TTC
            # so for the child it's like it really performed the
            # connect(), not us.
            #
            self.child.rtts = self.rtts
            self.child.connection_ready(self.streams.popleft())
            if justone:
                break
Beispiel #11
0
 def connection_ready(self, stream):
     stream.send_bitfield(str(self.bitfield))
     LOG.start("BitTorrent: receiving bitfield")
     if self.connector_side:
         self.state = SENT_INTERESTED
         stream.send_interested()