forked from SeattleTestbed/seattlelib_v2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcp_time.r2py
124 lines (89 loc) · 3.86 KB
/
tcp_time.r2py
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
124
"""
Author: Zachary Boka
tcp_time.r2py
Start Date:
3 May 2009
Amended 5 July, 2009 to be an extension to time.r2py
Description:
This module is an implementation of time_interface.r2py
Contacts a server running time_server.r2py 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.
"""
time_interface = dy_import_module('time_interface.r2py')
advertise = dy_import_module('advertise.r2py')
random = dy_import_module('random.r2py')
sockettimeout = dy_import_module('sockettimeout.r2py')
# 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.r2py, 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.r2py.
<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.r2py.
<Side Effects>
time_settime(float(currenttime)) is called to set the time.
<Returns>
None.
"""
# Get the ips and ports of servers hosting time_server.r2py.
# Retry if there is an exception.
# We raise the following string if lookups succeeded but only
# return empty lists. (In this case, there are no exceptions we
# could inform the caller of.)
exceptionslist = ["advertise_lookup did not reveal any node advertising 'time_server'"]
for attempt in range(2):
try:
serveraddresses = advertise.advertise_lookup("time_server")
except Exception, e:
# Log and retry
exceptionslist.append((type(e), str(e)))
sleep(2)
else:
if serveraddresses != [] and serveraddresses[0] != '':
break
else:
# We never broke out of the for loop. This indicates a problem.
raise time_interface.TimeError("tcp_time could not find any servers running time_server.r2py using advertise_lookup. Errors: " + str(exceptionslist))
timelength = 25 # Max length of string, representing the time, to be received
# XXX Shuffling takes excessively long (10s on a list of 20 servers)!
shuffledserveraddresses = random.random_sample(serveraddresses,min(len(serveraddresses),5))
# Try to obtain a timestamp from one of at most five
# random servers hosting time_server.r2py
exceptionslist = []
serverindex = 0
for server_ip_and_port in shuffledserveraddresses:
remoteaddress = server_ip_and_port.split(':')
remoteip = remoteaddress[0]
remoteport = int(remoteaddress[1])
try:
sockobject = sockettimeout.timeout_openconnection(remoteip, remoteport,
getmyip(), localport, timeout=10)
except Exception, e:
exceptionslist.append((server_ip_and_port, type(e), str(e)))
else:
break
else:
# Didn't break out of the loop. Tried all time servers to no avail.
raise time_interface.TimeError("tcp_time could not contact any of the ",len(shuffledserveraddresses)," servers running time_server.r2py. Errors encountered: " + str(exceptionslist))
currenttime = ''
while '$' not in currenttime:
currenttime += sockobject.recv(20)
sockobject.close()
currenttime = float(currenttime[:-1])
# finally, set the time
time_interface.time_settime(currenttime)
#register the update method
time_interface.time_register_method('tcp', tcp_time_updatetime)