forked from SeattleTestbed/tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathallpairsping.r2py
More file actions
197 lines (151 loc) · 6.22 KB
/
allpairsping.r2py
File metadata and controls
197 lines (151 loc) · 6.22 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
"""
<Author>
Urvashi Soni
<Description>
gives the connectivity graph and latency information of all nodes in a group.
"""
# send a probe message to each neighbor
def probe_neighbors_forever():
# Call me again in 10 seconds
while True:
for neighborip in mycontext["neighborlist"]:
mycontext['sendtime'][neighborip] = getruntime()
if neighborip == mycontext['myip']:
#skip if ip address in neighboriplist matches the local ip because in repy we cann't have same localip and dest ip
continue
sendmessage(neighborip, mycontext['port'], 'ping',mycontext['myip'],mycontext['port'])
sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext['myip'],mycontext["neighborlist"],mycontext['latency'].copy()),mycontext['myip'],mycontext['port'])
sleep(0.5)
#sleep for 10 sec and start from while loop again
sleep(10)
# Handle an incoming message
def got_message(srcip,srcport,mess):
if mess == 'ping':
sendmessage(srcip,srcport,'pong',mycontext['myip'], pingport)
elif mess == 'pong':
# elapsed time is now - time when I sent the ping
mycontext['latency'][srcip] = getruntime() - mycontext['sendtime'][srcip]
elif mess.startswith('share'):
mycontext['row'][srcip] = mess[len('share'):]
def encode_row(rowip, neighborlist, latencylist):
retstring = "<tr><td>"+rowip+"</td>"
for neighborip in neighborlist:
if neighborip in latencylist:
retstring = retstring + "<td>"+str(latencylist[neighborip])[:4]+"s</td>"
else:
retstring = retstring + "<td>Unknown</td>"
retstring = retstring + "</tr>"
return retstring
# Generates a HTML page that represents the current status of the program
def generate_status_page():
webpage = "<html><head><title>Latency Information</title></head><body><h1>Latency information from "+mycontext['myip']+' </h1><table border="1">'
webpage = webpage + "<tr><td></td><td>"+ "</td><td>".join(mycontext['neighborlist'])+"</td></tr>"
for nodeip in mycontext['neighborlist']:
if nodeip in mycontext['row']:
webpage = webpage + mycontext['row'][nodeip]+'\n'
else:
webpage = webpage + '<tr><td>'+nodeip+'</td><td>No Data Reported</td></tr>\n'
# now the footer...
webpage = webpage + '</table></html>'
return webpage
# Displays a web page with the latency information
def handle_http_request(srcip,srcport,connobj):
log('received request from',srcip,'\n')
# Get the header
total_data = ''
# The HTTP header ends once we see the char combination '\n\n', which
# is an empty string.
while '\n\n' not in total_data:
# Receive in chunks to avoid reading too much data
try:
data = connobj.recv(4096)
except SocketWouldBlockError:
# retry if they haven't completed sending the header
sleep(.05)
continue
except SocketClosedRemote:
log('client from',srcip,'aborted before sending HTTP header...\n')
return
total_data += data
total_data = total_data.replace('\r\n', '\n')
header, overflow = total_data.split('\n\n', 1)
# Get the request path, which is inbetween the HTTP action keyword and the
# HTTP version number.
# The http action keyword is the first word with no whitespace.
everything_after_httpaction = header.split(None, 1)[1]
# Following the path is the HTTP/[VERSION_NUMBER].
# We can use that as a delimiter to extract the path.
request_path = everything_after_httpaction.split(" HTTP/")[0]
# Generate the data to send back
# Don't respond with anything if they have something in the request path.
# This include favicons. We don't want to generate the webpage needlessly.
if request_path != '/':
data = 'HTTP/1.1 404 Not Found\n\n'
else:
webpage = generate_status_page()
# combine everything into one unit for sending
data = 'HTTP/1.1 200 OK\nContent-Type: text/html\nContent-Length: '+str(len(webpage))+'\nServer: Seattle Testbed\n\n'+webpage
# send the response
sent = 0
while sent < len(data):
try:
sent += connobj.send(data[sent:])
except SocketWouldBlockError:
# retry if response hasn't been sent yet
sleep(.05)
continue
except SocketClosedRemote:
log('client from',srcip,'aborted before response could be sent...\n')
return
# and we're done, so let's close this connection...
connobj.close()
def handle_message_forever():
while True:
try:
srcip, srcport, mess = udpserversocket.getmessage()
except SocketWouldBlockError:
sleep(0.1)
continue
got_message(srcip, srcport, mess)
def handle_connection_forever():
while True:
try:
ret_ip, ret_port, ret_socket = connobj.getconnection()
except SocketWouldBlockError:
sleep(0.1)
continue
handle_http_request(ret_ip, ret_port, ret_socket)
if callfunc == 'initialize':
#check if user has provided port number as call argument
if len(callargs) != 1:
raise Exception("Must specify the port to use")
pingport = int(callargs[0])
mycontext['port'] = pingport
# this holds the response information (i.e. when nodes responded)
mycontext['latency'] = {}
mycontext['myip'] = getmyip()
# this remembers when we sent a probe
mycontext['sendtime'] = {}
# this remembers row data from the other nodes
mycontext['row'] = {}
# get the nodes to probe
mycontext['neighborlist'] = []
try:
fileobject = openfile('neighboriplist.txt',False)
except FileNotFoundError, e:
#raise error if file doesn't exists
raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.")
filecontent = fileobject.readat(None,0)
neighbor_array = filecontent.splitlines()
for line in neighbor_array:
if line == '':
#skip if file contains any blank line
continue
mycontext['neighborlist'].append(line.strip())
#listen for a new message and call handle_message in new thread
udpserversocket = listenformessage(mycontext['myip'], mycontext['port'])
createthread(handle_message_forever)
createthread(probe_neighbors_forever)
#listen for connection and call handle_http_request once a connection is got
connobj = listenforconnection(mycontext['myip'],mycontext['port'])
createthread(handle_connection_forever)