-
Notifications
You must be signed in to change notification settings - Fork 1
/
tcp_time.repy
123 lines (86 loc) · 3.37 KB
/
tcp_time.repy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""
Author: Zachary Boka
tcp_time.repy
Start Date:
3 May 2009
Amended 5 July, 2009 to be an extension to time.repy
Description:
This module is an implementation of time_interface.repy
Contacts a server running time_server.repy to get the current time from an
NTP because only the server can communicate with an NTP.
To use this module, make one call to time_updatetime() to get the
time from the server. This function also implicitly sets the time. Then
call time_gettime() every time the current time is needed.
"""
include time_interface.repy
include advertise.repy
include random.repy
include sockettimeout.repy
# This function contacts the server to get the time from a NTP
def tcp_time_updatetime(localport):
"""
<Purpose>
Opens a connection with a server hosting time_server.repy, which obtains the
current time via a NTP, then calls time_settime(float(currenttime)) to set
the current time to the received value form the server.
<Arguments>
localport:
The local port which may be used in contacting NTP servers. It is
currently not used in this function, but must be present as an argument
for compatibility issues with time.repy.
<Exceptions>
Exception raised if advertise_lookup("time_server") fails after
ten tries.
Exception raised when a connection is not able to be established with any of
the servers running time_server.repy.
<Side Effects>
time_settime(float(currenttime)) is called to set the time.
<Returns>
Returns the server ip:port that it managed to successfully connect to
"""
# Get the ips and ports of servers hosting time_server.repy, retrying nine
# times if there is an exception.
gotval = False
attemptretrieval = 0
while attemptretrieval < 2:
try:
serveraddresses = advertise_lookup("time_server")
except Exception:
attemptretrieval = attemptretrieval + 1
sleep(2) # Look up the value again in 10 seconds
else:
if serveraddresses != [] and serveraddresses[0] != '':
gotval = True # Successfully obtained the value
break
else:
attemptretrieval = attemptretrieval + 1
if not gotval:
raise Exception("Unable to locate any servers running time_server.repy")
timelength = 25 # Max length of string, representing the time, to be received
shuffledserveraddresses = random_sample(serveraddresses,min(len(serveraddresses),5))
# Open a connection with a random server hosting time_server.repy
timeobtained = False
serverindex = 0
while serverindex < len(shuffledserveraddresses):
remoteaddress = shuffledserveraddresses[serverindex].split(':')
remoteip = remoteaddress[0]
remoteport = int(remoteaddress[1])
try:
sockobject = timeout_openconn(remoteip,remoteport)
except Exception:
serverindex +=1
else:
timeobtained = True
break
if not timeobtained:
raise Exception("Unable to open connection with any of the ",len(shuffledserveraddresses),"servers running time_server.repy.")
currenttime =''
while '$' not in currenttime:
currenttime += sockobject.recv(20)
sockobject.close()
currenttime = float(currenttime[:-1])
# finally, set the time
time_settime(currenttime)
return shuffledserveraddresses[serverindex]
#register the update method
time_register_method('tcp',tcp_time_updatetime)