Tusia se tagata NTP faigofie

Talofa, Habrausers. O le asō ou te fia talanoa e uiga i le auala e tusi ai lau lava NTP client faigofie. O le mea moni, o le talanoaga o le a liliu atu i le fausaga o le afifi ma le auala e faʻatautaia ai le tali mai le NTP server. O le code o le a tusia i le Python, aua e foliga mai ia te aʻu e leai se gagana sili atu mo ia mea. Connoisseurs o le a matauina le tutusa o le code ma le ntplib code - na "musuia" aʻu.

O le a tonu la le NTP? O le NTP o se faʻasalalauga mo fegalegaleaiga ma saʻo taimi saʻo. O lo'o fa'aogaina lenei fa'atonuga i le tele o masini fa'aonaponei. Mo se faʻataʻitaʻiga, o le w32tm service in windows.

E 5 fa'asologa o le NTP protocol i le aofa'i. Muamua, version 0 (1985, RFC958)), ua manatu nei ua le toe aoga. O lea la ua fa'aogaina mea fou, 1st (1988, RFC1059), 2nd (1989, RFC1119), 3rd (1992, RFC1305) ma le 4th (1996, RFC2030). Fa'aliliuga 1-4 e fetaui ma le tasi ma le isi; e ese'ese na'o le fa'agaioia o fa'agaioiga a le server.

Fa'asologa o afifi

Tusia se tagata NTP faigofie

Faailoga oso (fa'ailoga fa'asa'oga) - o se numera e fa'aalia ai se lapataiga e uiga i le fa'amaopoopo lona lua. Uiga:

  • 0 – leai se faasa’oga
  • 1 – o le minute mulimuli o le aso e iai le 61 sekone
  • 2 – o le minute mulimuli o le aso e iai le 59 sekone
  • 3 - faʻaletonu le server (e le o faʻatasi le taimi)

Numera numera (numera fa'aliliuga) – NTP protocol version number (1-4).

āʻega (mode) - faiga fa'agaioiga a le tagata e auina atu pepa. Tau mai le 0 i le 7, sili ona taatele:

  • 3 – tagata o tausia
  • 4 – server
  • 5 – ala fa'asalalau

stratum (tulaga faʻapipiʻi) - o le numera o le vaeluagalemu i le va o le 'auʻaunaga ma le uati faʻasino (1 - e ave saʻo e le 'auʻaunaga faʻamaumauga mai le uati faʻasino, 2 - e ave e le 'auʻaunaga faʻamaumauga mai se 'auʻaunaga ma le layer 1, ma isi).
vaitāʻele ose numera saini e fai ma sui o le va maualuga i le va o fe'au soso'o. O le NTP client o lo'o fa'amaoti mai iinei le va'aiga lea e fa'amoemoe e su'esu'e ai le 'au'aunaga, ae fa'amaoti mai e le NTP server le va'aiga e fa'amoemoe e su'eina ai. O le tau e tutusa ma le binary logarithm o sekone.
matuā saʻo (saʻo) o se numera saini e fai ma sui o le saʻo o le uati faiga. O le tau e tutusa ma le binary logarithm o sekone.
Fa'atuai a'a (fa'atuai o le server) - o le taimi e alu ai le faitau o le uati e o'o atu i le NTP server, o se numera fa'amautu o sekone.
Ta'ape a'a (server spread) - fa'asalalauina o faitauga o le uati a le server NTP e pei o se numera o sekone ma se fa'amaumau.
Ref id (puna fa'ailoa) - uati id. Afai o le server e iai le stratum 1, o le ref id o le igoa o le uati atomic (4 ASCII mataitusi). Afai e fa'aogaina e le 'au'aunaga se isi 'au'aunaga, ona iai lea i le ref id le tuatusi o lenei 'au'aunaga.
O fanua mulimuli e 4 o loʻo faʻatusalia ai le taimi - 32 bits - o le vaega numera, 32 bits - o le vaega vaevaega.
Tusitaiala - o faitauga lata mai uati i luga o le server.
Amataga – taimi na lafo atu ai le pepa (faatumu e le server - sili atu i lalo ifo).
Talia – taimi na maua ai e le server le afifi.
faʻasalalau – taimi e lafo ai le pepa mai le server i le kalani (faatumu e le kalani, sili atu i lalo ifo).

O le a tatou le iloiloina vaega mulimuli e lua.

Tatou tusi la tatou afifi:

Fa'ailoga o le afifi

class NTPPacket:
    _FORMAT = "!B B b b 11I"

    def __init__(self, version_number=2, mode=3, transmit=0):
        # Necessary of enter leap second (2 bits)
        self.leap_indicator = 0
        # Version of protocol (3 bits)
        self.version_number = version_number
        # Mode of sender (3 bits)
        self.mode = mode
        # The level of "layering" reading time (1 byte)
        self.stratum = 0
        # Interval between requests (1 byte)
        self.pool = 0
        # Precision (log2) (1 byte)
        self.precision = 0
        # Interval for the clock reach NTP server (4 bytes)
        self.root_delay = 0
        # Scatter the clock NTP-server (4 bytes)
        self.root_dispersion = 0
        # Indicator of clocks (4 bytes)
        self.ref_id = 0
        # Last update time on server (8 bytes)
        self.reference = 0
        # Time of sending packet from local machine (8 bytes)
        self.originate = 0
        # Time of receipt on server (8 bytes)
        self.receive = 0
        # Time of sending answer from server (8 bytes)
        self.transmit = transmit

Ina ia lafo (ma maua) se afifi i le 'au'aunaga, e tatau ona mafai ona tatou fa'aliliuina i se laina byte.
Mo lenei (ma fesuiaʻi) gaioiga, o le a matou tusia ni galuega se lua - pack() ma le unpack():

galuega fa'apipi'i

def pack(self):
        return struct.pack(NTPPacket._FORMAT,
                (self.leap_indicator << 6) + 
                    (self.version_number << 3) + self.mode,
                self.stratum,
                self.pool,
                self.precision,
                int(self.root_delay) + get_fraction(self.root_delay, 16),
                int(self.root_dispersion) + 
                    get_fraction(self.root_dispersion, 16),
                self.ref_id,
                int(self.reference),
                get_fraction(self.reference, 32),
                int(self.originate),
                get_fraction(self.originate, 32),
                int(self.receive),
                get_fraction(self.receive, 32),
                int(self.transmit),
                get_fraction(self.transmit, 32))

tatala galuega

def unpack(self, data: bytes):
        unpacked_data = struct.unpack(NTPPacket._FORMAT, data)

        self.leap_indicator = unpacked_data[0] >> 6  # 2 bits
        self.version_number = unpacked_data[0] >> 3 & 0b111  # 3 bits
        self.mode = unpacked_data[0] & 0b111  # 3 bits

        self.stratum = unpacked_data[1]  # 1 byte
        self.pool = unpacked_data[2]  # 1 byte
        self.precision = unpacked_data[3]  # 1 byte

        # 2 bytes | 2 bytes
        self.root_delay = (unpacked_data[4] >> 16) +
            (unpacked_data[4] & 0xFFFF) / 2 ** 16
         # 2 bytes | 2 bytes
        self.root_dispersion = (unpacked_data[5] >> 16) +
            (unpacked_data[5] & 0xFFFF) / 2 ** 16 

        # 4 bytes
        self.ref_id = str((unpacked_data[6] >> 24) & 0xFF) + " " + 
                      str((unpacked_data[6] >> 16) & 0xFF) + " " +  
                      str((unpacked_data[6] >> 8) & 0xFF) + " " +  
                      str(unpacked_data[6] & 0xFF)

        self.reference = unpacked_data[7] + unpacked_data[8] / 2 ** 32  # 8 bytes
        self.originate = unpacked_data[9] + unpacked_data[10] / 2 ** 32  # 8 bytes
        self.receive = unpacked_data[11] + unpacked_data[12] / 2 ** 32  # 8 bytes
        self.transmit = unpacked_data[13] + unpacked_data[14] / 2 ** 32  # 8 bytes

        return self

Mo tagata paie, o se talosaga - code lea e liliu ai se afifi i se manoa matagofie

def to_display(self):
        return "Leap indicator: {0.leap_indicator}n" 
                "Version number: {0.version_number}n" 
                "Mode: {0.mode}n" 
                "Stratum: {0.stratum}n" 
                "Pool: {0.pool}n" 
                "Precision: {0.precision}n" 
                "Root delay: {0.root_delay}n" 
                "Root dispersion: {0.root_dispersion}n" 
                "Ref id: {0.ref_id}n" 
                "Reference: {0.reference}n" 
                "Originate: {0.originate}n" 
                "Receive: {0.receive}n" 
                "Transmit: {0.transmit}"
                .format(self)

Tuuina atu o se afifi i le server

E tatau ona lafo i le 'au'aunaga se pepa o lo'o fa'atumu uma fanua faʻamatalaga, āʻega и faʻasalalau. le faʻasalalau e tatau ona e faʻamaonia le taimi nei i luga o le masini i le lotoifale (le numera o sekone talu mai Ianuari 1, 1900), faʻamatalaga - soʻo se 1-4, mode - 3 (tagata faʻatau).

O le server, i le taliaina o le talosaga, faʻatumu uma fanua i totonu o le NTP packet, kopi i totonu o le fanua Amataga taua mai faʻasalalau, lea na sau i le talosaga. Ose mea lilo ia te a'u pe aisea e le mafai ai e le kalani ona vave faatumu le taua o lona taimi i le fanua Amataga. O le iʻuga, pe a toe foʻi mai le afifi, e 4 taimi faʻatauga a le kalani - o le taimi na lafoina ai le talosaga (Amataga), taimi na maua ai e le server le talosaga (Talia), taimi na auina atu ai e le server le tali (faʻasalalau) ma le taimi na maua ai e le kalani le tali - Taunuu (e le oi totonu o le afifi). O le faʻaaogaina o nei tau e mafai ona tatou setiina le taimi saʻo.

Fa'ailoga o le lafo ma le mauaina o pusa

# Time difference between 1970 and 1900, seconds
FORMAT_DIFF = (datetime.date(1970, 1, 1) - datetime.date(1900, 1, 1)).days * 24 * 3600
# Waiting time for recv (seconds)
WAITING_TIME = 5
server = "pool.ntp.org"
port = 123
    
packet = NTPPacket(version_number=2, mode=3, transmit=time.time() + FORMAT_DIFF)
answer = NTPPacket()
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
    s.settimeout(WAITING_TIME)
    s.sendto(packet.pack(), (server, port))
    data = s.recv(48)
    arrive_time = time.time() + FORMAT_DIFF
    answer.unpack(data)

Fa'atonuina fa'amaumauga mai le 'au'aunaga

O le fa'agaioia o fa'amaumauga mai le 'au'aunaga e talitutusa lava ma gaioiga a le ali'i Peretania mai le fa'afitauli tuai a Raymond M. Smullyan (1978): “O se tasi tagata e leai sana uati tapulima, ae sa i ai se uati puipui sa'o i le fale, lea na galo i nisi taimi. e matagi. I se tasi aso, ua galo ai ona toe viliina lana uati, na alu ai e asi lana uo, ma faaalu le afiafi faatasi ma ia, ma ina ua toe foi i le fale, sa mafai ona ia setiina le uati saʻo. Na faapefea ona ia faia lenei mea pe afai e leʻi iloa muamua le taimi o le malaga? O le tali: “Pe a alu ese mai le fale, e vili e se tagata lana uati ma manatua le tulaga o loo i ai lima. Ina ua sau i se uo ma tuua le au valaaulia, na ia matauina le taimi o lona taunuu mai ma le alu ese. O lenei mea e mafai ai e ia ona iloa le umi na ia asiasi ai. Toe foi i le fale ma tilotilo i le uati, e fuafua e se tagata le umi o lona toesea. E ala i le toesea mai lea taimi o le taimi na ia faaaluina e asiasi atu ai, e iloa ai e se tagata le taimi na alu ai e malaga ai iina ma toe foi mai. E ala i le faaopoopo atu o le afa o le taimi i luga o le auala i le taimi e tuua ai mālō, na te maua ai le avanoa e iloa ai le taimi e taunuu ai i le fale ma fetuutuunai lima o lana uati e tusa ai.”

Su'e le taimi o lo'o galue ai le server ile talosaga:

  1. Su'e le taimi femalagaa'i o le afifi mai le kalani i le server: ((Taunuu – Afua mai) – (Faasalalau – Maua)) / 2
  2. Su'e le eseesega i le va o le tagata o tausia ma le taimi o le server:
    Maua - Maua - ((Tauu - Afua) - (Auina - Maua)) / 2 =
    2 * Maua – 2 * Amata – Taunuu + Amata + Tuuina atu – Maua =
    Maua – Amata – Taunuu + Faasalalau

Tatou te faaopoopo le tau aogā i le taimi o le atunuu ma olioli ai i le olaga.

Tulaga o le taunuuga

time_different = answer.get_time_different(arrive_time)
result = "Time difference: {}nServer time: {}n{}".format(
    time_different,
    datetime.datetime.fromtimestamp(time.time() + time_different).strftime("%c"),
    answer.to_display())
print(result)

E aoga ссылка.

puna: www.habr.com

Faaopoopo i ai se faamatalaga