示例#1
0
    def _client_respond(self, client, their_ts):
        l = protocol.PTP(data=[])
        l.data = []
        t = protocol.TLV(type=protocol.PTP_TYPE_SERVERVER, data=protocol.UInt(size=1, data=PTP_SERVERVER))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_SEQUENCE, data=protocol.UInt(size=4, data=self.server_seq))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_UUID, data=protocol.String(data=client['uuid']))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_YOURTS, data=protocol.UInt(size=8, data=their_ts))
        l.data.append(t)

        packet = l.pack()
        if len(packet) > protocol.PTP_MTU: # bad
            self.ui.log("Ignoring attempt to send ts %d bytes to client %s. MTU is %d" % \
                    (len(packet), str(client['sin']), protocol.PTP_MTU))
            return

        if self.args.debug:
            self.ui.log("Sending ts %d bytes to client %s" % (len(packet), str(client['sin'])))
            self.ui.log("%s" % repr(protocol.PTP(packet)), indent='  ')
            if self.args.hexdump:
                self.ui.log(hexdump.hexdump(result='return', data=packet))

        self.sock.sendto(packet, client['sin'])
        self.server_seq += 1L
示例#2
0
    def _server_beacons(self, shutdown=False):
        # Tell the server about ourself
        l = protocol.PTP(data=[])
        l.data = []

        t = protocol.TLV(type=protocol.PTP_TYPE_CLIENTVER,
                         data=protocol.UInt(size=1, data=PTP_CLIENTVER))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_SEQUENCE,
                         data=protocol.UInt(size=4, data=self.server_seq))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_UUID,
                         data=protocol.String(data=self.uuid))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_PTPADDR,
                         data=protocol.Address(data=(self.addr, self.port)))
        l.data.append(t)
        if shutdown:
            t = protocol.TLV(type=protocol.PTP_TYPE_SHUTDOWN,
                             data=protocol.UInt(size=1, data=1))
            l.data.append(t)
        else:
            t = protocol.TLV(type=protocol.PTP_TYPE_MYTS,
                             data=protocol.UInt(size=8,
                                                data=int(time.time() * 2**32)))
            l.data.append(t)

        tmp = copy.deepcopy(self.servers)
        for k in tmp:
            if 'uuid' in tmp[k]:
                del (tmp[k]['uuid'])
        t = protocol.TLV(type=protocol.PTP_TYPE_META,
                         data=protocol.JSON(data=tmp))
        l.data.append(t)

        packet = l.pack()
        if len(packet) > protocol.PTP_MTU:  # bad
            self.ui.log(
                "Ignoring attempt to send %d bytes to servers. MTU is %d" %
                (len(packet), protocol.PTP_MTU))
            return

        if self.args.debug:
            self.ui.log("Sending %d bytes to servers:" % len(packet))
            self.ui.log("%s" % repr(protocol.PTP(packet)), indent='  ')
            if self.args.hexdump:
                self.ui.log(hexdump.hexdump(result='return', data=packet))

        with self._slock:
            for k in self.servers:
                server = self.servers[k]
                server['stats']['sent'] += 1
                self.sock.sendto(packet, server['sin'])
                self.ui.peer_update('server', server['sin'], server['stats'])

        self.server_seq += 1L
示例#3
0
    def _client_beacon(self, k, client):
        # We need a list of TLVs and then form a PTP fron them
        l = protocol.PTP(data=[])
        l.data = []

        t = protocol.TLV(type=protocol.PTP_TYPE_SERVERVER, data=protocol.UInt(size=1, data=PTP_SERVERVER))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_SEQUENCE, data=protocol.UInt(size=4, data=self.server_seq))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_UUID, data=protocol.String(data=client['uuid']))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_MYTS, data=protocol.UInt(size=8, data=int(time.time()*2**32)))
        l.data.append(t)
        t = protocol.TLV(type=protocol.PTP_TYPE_YOURADDR, data=protocol.Address(data=client['sin']))
        l.data.append(t)

        # Now add the list of known clients
        count = 0
        for sk in self.clients:
            if sk == k: continue  # skip the client we're sending this to
            sc = self.clients[sk]
            t = protocol.TLV(type=protocol.PTP_TYPE_CLIENTLIST_EXT,
                    data=protocol.Address(data=sc['sin']))
            l.data.append(t)
            count += 1

            # If this client address matches the address we're sending this packet to then we
            # also send its local address - the clients can then try to talk locally
            if sc['sin'][0] == client['sin'][0]:
                t = protocol.TLV(type=protocol.PTP_TYPE_CLIENTLIST_INT,
                        data=protocol.Address(data=sc['ptpaddr']))
                l.data.append(t)

        t = protocol.TLV(type=protocol.PTP_TYPE_CLIENTLEN, data=protocol.UInt(size=1, data=count))
        l.data.append(t)

        packet = l.pack()
        if len(packet) > protocol.PTP_MTU: # bad
            self.ui.log("Ignoring attempt to send %d bytes to client %s. MTU is %d" % \
                    (len(packet), str(client['sin']), protocol.PTP_MTU))
            return

        if self.args.debug:
            self.ui.log("Sending %d bytes to client %s" % (len(packet), str(client['sin'])))
            self.ui.log("%s" % repr(protocol.PTP(packet)), indent='  ')
            if self.args.hexdump:
                self.ui.log(hexdump.hexdump(result='return', data=packet))

        self.sock.sendto(packet, client['sin'])
        client['stats']['sent'] += 1
        self.server_seq += 1L
        self.ui.peer_update('client', client['sin'], client['stats'])
示例#4
0
    def _client_parse(self, buf, sin, client):
        l = protocol.PTP(buf)
        if l is None:
            self.ui.log("Client packet from %s failed to parse!" % repr(sin))
            return False
        if l.buf_csum is None or l.buf_csum != l.csum:
            self.ui.log("Client packet from %s has a bad checksum!" %
                        repr(sin))
            return False

        client['ts'] = time.time()
        client['stats']['rcvd'] += 1

        if self.args.debug: self.ui.log(repr(l))

        for tlv in l.data:
            p = tlv.data
            if p.ptp_type == protocol.PTP_TYPE_CLIENTVER:
                client['clientver'] = p.data
            elif p.ptp_type == protocol.PTP_TYPE_SEQUENCE:
                client['sequence'] = p.data
            elif p.ptp_type == protocol.PTP_TYPE_UUID:
                client['uuid'] = p.data
            elif p.ptp_type == protocol.PTP_TYPE_MYTS:
                self._client_respond(client, p.data)
                client['myts'] = float(p.data) / float(2**32)
            elif p.ptp_type == protocol.PTP_TYPE_YOURTS:
                ts = float(p.data) / float(2**32)
                rtt = client['ts'] - ts
                client['stats']['rtt'] = rtt
                client['stats']['ackd'] += 1
                self.ui.log("ACK from client %s; RTT %fs" % (str(sin), rtt))

        self.ui.peer_update('client', client['sin'], client['stats'])
        return True
示例#5
0
    def _client_beacons(self):
        with self._clock:
            for k in self.clients:
                client = self.clients[k]
                if not 'myseq' in client or not 'sin' in client: continue
                if 'uuid' in client and client['uuid'] == self.uuid:
                    continue  # self!

                l = protocol.PTP(data=[])
                l.data = []

                t = protocol.TLV(type=protocol.PTP_TYPE_CLIENTVER,
                                 data=protocol.UInt(size=1,
                                                    data=PTP_CLIENTVER))
                l.data.append(t)
                t = protocol.TLV(type=protocol.PTP_TYPE_SEQUENCE,
                                 data=protocol.UInt(size=4,
                                                    data=client['myseq']))
                l.data.append(t)
                t = protocol.TLV(type=protocol.PTP_TYPE_UUID,
                                 data=protocol.String(data=self.uuid))
                l.data.append(t)
                t = protocol.TLV(type=protocol.PTP_TYPE_MYTS,
                                 data=protocol.UInt(size=8,
                                                    data=int(time.time() *
                                                             2**32)))
                l.data.append(t)

                packet = l.pack()
                if len(packet) > protocol.PTP_MTU:  # bad
                    self.ui.log("Ignoring attempt to send ts %d bytes to client %s. MTU is %d" % \
                            (len(packet), str(client['sin']), protocol.PTP_MTU))
                    return

                if self.args.debug:
                    self.ui.log("Sending ts %d bytes to client %s" %
                                (len(packet), str(client['sin'])))
                    self.ui.log("%s" % repr(protocol.PTP(packet)), indent='  ')
                    if self.args.hexdump:
                        self.ui.log(
                            hexdump.hexdump(result='return', data=packet))

                self.sock.sendto(packet, client['sin'])
                client['stats']['sent'] += 1
                client['myseq'] += 1
                self.ui.peer_update('client', client['sin'], client['stats'])
示例#6
0
    def _server_parse(self, buf, sin, server):
        l = protocol.PTP(buf)
        if l is None:
            self.ui.log("Server packet from %s failed to parse!" % repr(sin))
            return False
        if l.buf_csum is None or l.buf_csum != l.csum:
            self.ui.log("Server packet from %s has a bad checksum!" %
                        repr(sin))
            return False

        server['ts'] = time.time()
        server['stats']['rcvd'] += 1

        if self.args.debug: self.ui.log(repr(l))

        new_clients = []
        num_clients = None

        for tlv in l.data:
            p = tlv.data
            if p.ptp_type == protocol.PTP_TYPE_SERVERVER:
                server['serverver'] = p.data
            elif p.ptp_type == protocol.PTP_TYPE_SEQUENCE:
                server['sequence'] = p.data
            elif p.ptp_type == protocol.PTP_TYPE_UUID:
                server['uuid'] = p.data
            elif p.ptp_type == protocol.PTP_TYPE_MYTS:
                self._server_respond(server, p.data)
                server['myts'] = float(p.data) / float(2**32)
            elif p.ptp_type == protocol.PTP_TYPE_YOURTS:
                ts = float(p.data) / float(2**32)
                rtt = server['ts'] - ts
                server['stats']['rtt'] = rtt
                server['stats']['ackd'] += 1
                self.ui.log("ACK from server %s; RTT %fs" % (str(sin), rtt))
            elif p.ptp_type == protocol.PTP_TYPE_CLIENTLEN:
                num_clients = p.data
            elif p.ptp_type == protocol.PTP_TYPE_CLIENTLIST_EXT:
                new_clients.append(p.data)  # should be a sockaddr
            elif p.ptp_type == protocol.PTP_TYPE_CLIENTLIST_INT:
                # server thinks the previous address may be on the same
                # network as us, so has sent us a clients internal address
                # This is crude, but we just overwrite the previous address for now
                new_clients[-1] = p.data
            elif p.ptp_type == protocol.PTP_TYPE_YOURADDR:
                self.ui.log("Server sees us as %s" % repr(p.data))
                self.ui.set_address(p.data[0], p.data[1])

        self.ui.peer_update('server', server['sin'], server['stats'])

        if num_clients is not None:
            if num_clients == len(new_clients):
                with self._clock:
                    # Sync the client list
                    delete = []
                    for k in self.clients:
                        if not self.clients[k]['sin'] in new_clients:  # old
                            delete.append(k)
                    for k in delete:
                        if self.args.debug:
                            self.ui.log("Removing old client %s" %
                                        str(self.clients[k]['sin']))
                        self.ui.peer_del(group='client',
                                         sin=self.clients[k]['sin'])
                        del (self.clients[k])
                    for sin in new_clients:
                        k = _mkey(sin[0], sin[1])
                        if k not in self.clients:  # new
                            if self.args.debug:
                                self.ui.log("Adding new client %s" % str(sin))
                            self.clients[k] = {
                                'sin': sin,
                                'ts': time.time(),
                                'myseq': 0L,
                                'stats': {
                                    'sent': 0,
                                    'rcvd': 0,
                                    'ackd': 0,
                                    'rtt': 0,
                                },
                            }
                            self.ui.peer_add(group='client', sin=sin)
                    if self.args.debug:
                        self.ui.log("Client count: %d" % len(self.clients))