From a1bf14350e1a24f6daa2cf873d9bb91ed66d6997 Mon Sep 17 00:00:00 2001 From: Urvashi Soni Date: Mon, 4 Aug 2014 22:28:41 -0400 Subject: [PATCH 01/59] r2py version of allpairsping.repy --- allpairsping.r2py | 165 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 allpairsping.r2py diff --git a/allpairsping.r2py b/allpairsping.r2py new file mode 100644 index 0000000..e7a8d8a --- /dev/null +++ b/allpairsping.r2py @@ -0,0 +1,165 @@ +# send a probe message to each neighbor +def probe_neighbors(port): + + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + sendmessage(neighborip, port, 'ping',getmyip(),port) + + sendmessage(neighborip, port,'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy())) + # sleep in between messages to prevent us from getting a huge number of + # responses all at once... + sleep(.5) + + # Call me again in 10 seconds + while True: + try: + settimer(10,probe_neighbors,(port,)) + return + except Exception, e: + if "Resource 'events'" in str(e): + # there are too many events scheduled, I should wait and try again + sleep(.5) + continue + raise + + + +# Handle an incoming message +def got_message(srcip,srcport,mess,ch): + if mess == 'ping': + sendmessage(srcip,srcport,'pong') + 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 = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + webpage = "Latency Information

Latency information from "+getmyip()+'

' + + webpage = webpage + "" + + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + + return webpage + + + +# Displays a web page with the latency information +def handle_http_request(srcip,srcport,connobj, ch, mainch): + # Get the header + try: + total_data = '' + # We use a separate string to store the received data so that we don't have to + # re-check the beginning parts of the string multiple times + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + # This is because Windows uses \r\n, Linux/Macs use \n. + # By doing this, we avoid having to program special cases for + # the different endline formats. + new_data = data.replace('\r\n', '\n') + total_data += new_data + + # keep everything after the first '\n\n' intact, just incase there is + # more content after the header that we may need + # Potential Bug?: We ignore the overflow data + header, overflow = total_data.split('\n\n', 1) + + except Exception, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + # 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 + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except Exception, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + + +if callfunc == 'initialize': + + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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'] = [] + for line in file("neighboriplist.txt"): + mycontext['neighborlist'].append(line.strip()) + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + + # call gotmessage whenever receiving a message + recvmess(ip,pingport,got_message) + + probe_neighbors(pingport) + + # we want to register a function to show a status webpage (TCP port) + pageport = int(callargs[0]) + waitforconn(ip,pageport,handle_http_request) + From 3e48b5c2839b120a3f4ea632ba0bb0b6d007b1ae Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 6 Aug 2014 22:46:58 -0400 Subject: [PATCH 02/59] Update allpairsping.r2py --- allpairsping.r2py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index e7a8d8a..9b02238 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -13,7 +13,9 @@ def probe_neighbors(port): # Call me again in 10 seconds while True: try: - settimer(10,probe_neighbors,(port,)) + #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality + sleep(10) + createthread(probe_neighbors(port,)) return except Exception, e: if "Resource 'events'" in str(e): @@ -25,7 +27,7 @@ def probe_neighbors(port): # Handle an incoming message -def got_message(srcip,srcport,mess,ch): +def got_message(srcip,srcport,mess): if mess == 'ping': sendmessage(srcip,srcport,'pong') elif mess == 'pong': @@ -71,7 +73,7 @@ def generate_status_page(): # Displays a web page with the latency information -def handle_http_request(srcip,srcport,connobj, ch, mainch): +def handle_http_request(srcip,srcport,connobj): # Get the header try: total_data = '' @@ -94,7 +96,7 @@ def handle_http_request(srcip,srcport,connobj, ch, mainch): # Potential Bug?: We ignore the overflow data header, overflow = total_data.split('\n\n', 1) - except Exception, e: + except SocketClosedRemote, e: if "Socket closed" in str(e): # We can't do anything if the socket is closed return @@ -125,7 +127,7 @@ def handle_http_request(srcip,srcport,connobj, ch, mainch): sent += connobj.send(data[sent:]) # and we're done, so let's close this connection... connobj.close() - except Exception, e: + except SocketClosedRemote, e: if "Socket closed" in str(e): # We can't do anything if the socket is closed return @@ -155,11 +157,26 @@ if callfunc == 'initialize': pingport = int(callargs[0]) # call gotmessage whenever receiving a message - recvmess(ip,pingport,got_message) + # recvmess(ip,pingport,got_message) repyV1 call, not valid in RepyV2 + udpserversocket = listenformessage(ip, pingport) #waits for new UDP message + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + probe_neighbors(pingport) # we want to register a function to show a status webpage (TCP port) pageport = int(callargs[0]) - waitforconn(ip,pageport,handle_http_request) + #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 + connobj = listenforconnection(ip,pageport) + while true: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + From 04967900ea9a9fa3a2eef2ecc410229549c3a463 Mon Sep 17 00:00:00 2001 From: us341 Date: Fri, 8 Aug 2014 23:26:04 -0400 Subject: [PATCH 03/59] Update allpairsping.r2py --- allpairsping.r2py | 65 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 9b02238..5812a1c 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -1,11 +1,13 @@ # send a probe message to each neighbor def probe_neighbors(port): - + log ("inside probe") + log (getthreadname) for neighborip in mycontext["neighborlist"]: mycontext['sendtime'][neighborip] = getruntime() sendmessage(neighborip, port, 'ping',getmyip(),port) - - sendmessage(neighborip, port,'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy())) + log ("first sendmessage is done") + sendmessage(neighborip, port,'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), port) + log ("second sendmessage is done") # sleep in between messages to prevent us from getting a huge number of # responses all at once... sleep(.5) @@ -13,23 +15,26 @@ def probe_neighbors(port): # Call me again in 10 seconds while True: try: + log ("entering while loop") #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality sleep(10) - createthread(probe_neighbors(port,)) + createthread(probe_neighbors(port)) + log ("also working in while loop") return except Exception, e: - if "Resource 'events'" in str(e): - # there are too many events scheduled, I should wait and try again - sleep(.5) - continue - raise + # there are too many events scheduled, I should wait and try again + log ("*********oops**************") + sleep(.5) + continue + # Handle an incoming message def got_message(srcip,srcport,mess): if mess == 'ping': - sendmessage(srcip,srcport,'pong') + log ("\n is it coming here in got message") + sendmessage(srcip,srcport,'pong',getmyip(), pingport) elif mess == 'pong': # elapsed time is now - time when I sent the ping mycontext['latency'][srcip] = getruntime() - mycontext['sendtime'][srcip] @@ -136,7 +141,7 @@ def handle_http_request(srcip,srcport,connobj): if callfunc == 'initialize': - + # this holds the response information (i.e. when nodes responded) mycontext['latency'] = {} @@ -145,36 +150,60 @@ if callfunc == 'initialize': # this remembers row data from the other nodes mycontext['row'] = {} - + log ("hi working") # get the nodes to probe mycontext['neighborlist'] = [] - for line in file("neighboriplist.txt"): - mycontext['neighborlist'].append(line.strip()) + try: + fileobject = openfile('neighboriplist.txt',True) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + log ("file is opened correctly") + except RepyArgumentError, e1: + log ("exception in reading from file"+ str(e1)) + except FileInUseError, e2: + log ("exception in reading from file"+ str(e2)) + except ResourceExhaustedError, e3: + log ("exception in reading from file"+ str(e3)) + except FileNotFoundError, e4: + log ("exception in reading from file"+ str(e4)) ip = getmyip() + log (ip) if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) + log (pingport) # call gotmessage whenever receiving a message # recvmess(ip,pingport,got_message) repyV1 call, not valid in RepyV2 + + log ("working till message listening") udpserversocket = listenformessage(ip, pingport) #waits for new UDP message + log ("listening still") try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) + srcip, srcport, mess = udpserversocket.getmessage() + log ("got message") + got_message(srcip, srcport, mess) + log ("done") except SocketWouldBlockError: sleep(0.1) + - + log ("calling pingport") probe_neighbors(pingport) # we want to register a function to show a status webpage (TCP port) pageport = int(callargs[0]) + log ("working after pageport") #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 connobj = listenforconnection(ip,pageport) - while true: + log ("listened a new connection") + while True: try: ret_ip, ret_port, ret_socket = connobj.getconnection() + log ("got connection") handle_http_request(ret_ip, ret_port, ret_socket) except SocketWouldBlockError: sleep(0.1) From 1819bf9bb19040d73b852f82bdac1c0b9e1abcd1 Mon Sep 17 00:00:00 2001 From: us341 Date: Fri, 8 Aug 2014 23:44:35 -0400 Subject: [PATCH 04/59] Update allpairsping.r2py --- allpairsping.r2py | 42 +++++++++++------------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 5812a1c..c169aca 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -1,13 +1,9 @@ # send a probe message to each neighbor -def probe_neighbors(port): - log ("inside probe") - log (getthreadname) +def probe_neighbors(): for neighborip in mycontext["neighborlist"]: mycontext['sendtime'][neighborip] = getruntime() - sendmessage(neighborip, port, 'ping',getmyip(),port) - log ("first sendmessage is done") - sendmessage(neighborip, port,'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), port) - log ("second sendmessage is done") + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) # sleep in between messages to prevent us from getting a huge number of # responses all at once... sleep(.5) @@ -15,17 +11,16 @@ def probe_neighbors(port): # Call me again in 10 seconds while True: try: - log ("entering while loop") #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality sleep(10) - createthread(probe_neighbors(port)) - log ("also working in while loop") + createthread(probe_neighbors) return except Exception, e: - # there are too many events scheduled, I should wait and try again - log ("*********oops**************") - sleep(.5) - continue + if "Resource 'events'" in str(e): + # there are too many events scheduled, I should wait and try again + sleep(.5) + continue + raise @@ -33,7 +28,6 @@ def probe_neighbors(port): # Handle an incoming message def got_message(srcip,srcport,mess): if mess == 'ping': - log ("\n is it coming here in got message") sendmessage(srcip,srcport,'pong',getmyip(), pingport) elif mess == 'pong': # elapsed time is now - time when I sent the ping @@ -45,7 +39,6 @@ def got_message(srcip,srcport,mess): def encode_row(rowip, neighborlist, latencylist): - retstring = ""+rowip+"" for neighborip in neighborlist: if neighborip in latencylist: @@ -150,7 +143,6 @@ if callfunc == 'initialize': # this remembers row data from the other nodes mycontext['row'] = {} - log ("hi working") # get the nodes to probe mycontext['neighborlist'] = [] try: @@ -170,40 +162,28 @@ if callfunc == 'initialize': log ("exception in reading from file"+ str(e4)) ip = getmyip() - log (ip) if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) - log (pingport) - - # call gotmessage whenever receiving a message + mycontext['port'] = pingport # recvmess(ip,pingport,got_message) repyV1 call, not valid in RepyV2 - log ("working till message listening") udpserversocket = listenformessage(ip, pingport) #waits for new UDP message - log ("listening still") try: srcip, srcport, mess = udpserversocket.getmessage() - log ("got message") got_message(srcip, srcport, mess) - log ("done") except SocketWouldBlockError: sleep(0.1) - - log ("calling pingport") - probe_neighbors(pingport) + probe_neighbors() # we want to register a function to show a status webpage (TCP port) pageport = int(callargs[0]) - log ("working after pageport") #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 connobj = listenforconnection(ip,pageport) - log ("listened a new connection") while True: try: ret_ip, ret_port, ret_socket = connobj.getconnection() - log ("got connection") handle_http_request(ret_ip, ret_port, ret_socket) except SocketWouldBlockError: sleep(0.1) From dc6e74ce75d67d14b480d22608868473a6d20001 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 12 Aug 2014 15:05:39 -0400 Subject: [PATCH 05/59] Create allpairspingmap.mix --- allpairspingmap.mix | 524 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 524 insertions(+) create mode 100644 allpairspingmap.mix diff --git a/allpairspingmap.mix b/allpairspingmap.mix new file mode 100644 index 0000000..6477723 --- /dev/null +++ b/allpairspingmap.mix @@ -0,0 +1,524 @@ +''' + + allpairspingmap.r2py + + + This program gives a visual representation of the vessels that a user has + acquired. It includes a map that contains markers on where the vessels are + reported to be, according to the geoip client. + + + A file containing the ip addresses of all the vessels to contact must be + uploaded. This file should be named 'neighboriplist.txt'. Each line should + contain one vessel. This file can be prepared within seash by issuing the + following command within a group: + show ip to neighboriplist.txt + + Additionally, the following files (which are provided) need to be uploaded to + the vessels: + jquerygmaps.js + style.css + map_marker_icon.png + + Once this is set up, you need to pass your Clearinghouse port to the program + as an argument: + username@group> run allpairspingmap.r2py [port number] + +''' + +include geoip_client.r2py + + +class InvalidRequestError(Exception): + ''' The user made a request for a nonexistent file. ''' + + +# These are the paths that the web server will serve files for. +# This is to prevent clients from seeing anything else that we might not want +# them to be able to see. +# +# '': +# Index file. We generate a webpage representing the current program status +# +# style.css: +# Stylesheet that controls how the webpage is formatted. Without this, +# the map will not render correctly. +# +# jquerygmaps.js: +# Contains code that interfaces against google's MapV2 API. +# +# map_marker_icon.png: +# This image is used as a marker for where the vessels are, on the map. + +mycontext['RECOGNIZED_FILES'] = ( + '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png') + + +# When responding to HTTP requests, we need to include a MIME type, identifying +# the type of file that we are serving to the HTTP client. This dictionary +# maps a file extension to its common MIME type. +mycontext['MIME_TYPES'] = { + '.js': 'text/javascript', + '.css': 'text/css', + '.png': 'image/png' + } + + + +def probe_neighbors(): + ''' + + Send a probe message to each neighbor + + + port: The clearinghouse port assigned to the current user. + + + Starts the ping loop to calculate the latency between the local node + and neighboring nodes. We also send our latency data to each node. + + + None + + + None + ''' + + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip, mycontext['port'],'share'+encode_row( mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) + # sleep in between messages to prevent us from getting a huge number of + # responses all at once... + sleep(.5) + + # Call me again in 10 seconds + while True: + try: + #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality + sleep(10) + createthread(probe_neighbors) + return + except Exception, e: + if "Resource 'events'" in str(e): + # there are too many events scheduled, I should wait and try again + sleep(.5) + continue + raise + + + + + # Handle an incoming message +def got_message(srcip,srcport,mess): + ''' + + Handle an incoming message from a neighboring node. + + + See documentation for recvmess(). + + + If we receive a ping message, we respond with a pong message. + If we receive a pong message, we take the difference between when we sent + this neighbor a ping message and record that as the latency. + If we receive a share message, we record the neighbor's neighbor row + information. + + + None + + + None + ''' + + + if mess == 'ping': + sendmessage(srcip,srcport,'pong',getmyip(), 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(neighborlist, latencylist): + ''' + + Prepares the local node's latency information into a format that is + recognizable by the other nodes. + + + neighborlist: The IP addresses of all our neighbors. + latencylist: The list of latencies associated with the neighbors. + + + None + + + None + + + A string representing a HTML row containing the latency information + between this node and the other neighbor nodes. + ''' + + retstring = "" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring += ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring += "Unknown" + return retstring + + +def generate_node_list(): + """ + + Generates an HTMl string of an unsorted list of nodes. + + + None. + + + None. + + + None. + + + HTML string of unsorted list of nodes. + """ + + # Is there a specific reason why we sort these keys? I'm leaving these + # intact since the original version sorted them. + nodeiplist = mycontext['neighborlist'] + nodeiplist.sort() + + nodelist_str = '
    ' + for nodeip in nodeiplist: + # Print node list element + nodelist_str += ('
  • ' + + str(nodeip) + '') + + if nodeip in mycontext['locationdata']: + nodelocdict = mycontext['locationdata'][nodeip] + if nodelocdict is not None: + nodelist_str += ('' + str(nodelocdict['longitude']) + + '' + str(nodelocdict['latitude']) + + '' + geoip_location_str(nodelocdict) + '') + # We didn't perform the lookup yet. This is used to tell the client to + # refresh the page. + else: + nodelist_str += "" + nodelist_str += '
  • ' + nodelist_str += '
' + return nodelist_str + + + + + +def generate_status_page(): + ''' + + Generates a HTML page that represents the current status of the program + + + None + + + The webpage returned may cause a client's browser to make additional + requests to the current program, or other machines. + + + None + + + A string representing a HTML webpage containing the current status of the + program. + ''' + + webpage = "Latency Information" + + webpage += '' + webpage += '' + + # Include our script/stylesheet for the webpage + webpage += '' + webpage += '' + + # Begin displaying body content; Lets start with the map. + webpage += "
" + + # Display the latency information as a table + webpage += "

Latency information from "+getmyip()+'

' + + # Create a column in the table for each vessel + webpage += "" + + # Create a row in the table for each vessel + for nodeip in mycontext['neighborlist']: + # Show ip and location data, if present + webpage += '' + + # Add latency information + if nodeip in mycontext['row']: + webpage += mycontext['row'][nodeip] + else: + webpage += '' + webpage += '\n' + + webpage += '
"+ "".join(mycontext['neighborlist'])+"
' +nodeip+'
\n' + + # Was there a geoip lookup yet? + if nodeip in mycontext['locationdata']: + # Did the geoip lookup succeed? + if mycontext['locationdata'][nodeip] is not None: + nodelocation = mycontext['locationdata'][nodeip] + webpage += nodelocation['city'] + ', ' + nodelocation['country_code'] + # The lookup failed + else: + webpage += "No location data available" + + # We haven't done a geoip lookup yet. Let the user know. + else: + webpage += "Location data not yet retrieved" + webpage += '
No Data Reported
' + + # We need this for the map data to work + webpage += generate_node_list() + log ("dsbvkskvnsdlnvls") + # now the footer... + webpage += '' + + return webpage + + + + +def handle_http_request(srcip,srcport,connobj): + ''' + + waitforconn() callback. Responds to a user's http request. + + + See the Repy documentation for waitforconn() callbacks. + + + If no file is requested, we send a web page with the latency information. + If a recognized file is requested, and the file exists, we send the file's + contents to the user. + Otherwise, we send a 404 error message. + + + None + + + None + ''' + + # Get the header + try: + total_data = '' + # We use a separate string to store the received data so that we don't have to + # re-check the beginning parts of the string multiple times + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + # This is because Windows uses \r\n, Linux/Macs use \n. + # By doing this, we avoid having to program special cases for + # the different endline formats. + new_data = data.replace('\r\n', '\n') + total_data += new_data + + # keep everything after the first '\n\n' intact, just incase there is + # more content after the header that we may need + # Potential Bug?: We ignore the overflow data + header, overflow = total_data.split('\n\n', 1) + + except Exception, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + # 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. + requested_file = everything_after_httpaction.split(" HTTP/")[0] + + # Get rid of the leading '/' because its useless to us + requested_file = requested_file.lstrip('/') + + # Generate the data to send back. + try: + # We default to this content type. + content_type = 'text/html' + # Don't respond with anything if they have something in the request path. + + if requested_file not in mycontext['RECOGNIZED_FILES']: + raise InvalidRequestError("Unrecognized file:" + requested_file) + + # Generate the index page if the request field is empty. + elif not requested_file: + contents = generate_status_page() + + # This is a file that we recognize. Send its contents to the client. + else: + # PNGs are binary files. Plaintext files still work when read in + # binary mode. + contents = openfile(requested_file, True).readat(None,0) + + # Figure out the MIME type to send to the client + for extension in mycontext['MIME_TYPES']: + if requested_file.endswith(extension): + content_type = mycontext['MIME_TYPES'][extension] + break + else: + content_type = 'text/plain' + + # combine everything into one unit for sending + data = 'HTTP/1.1 200 OK\nContent-Type: '+content_type+'\nContent-Length: '+str(len(contents))+'\nServer: Seattle Testbed\n\n'+contents + + except InvalidRequestError: + data = 'HTTP/1.1 404 Not Found\n\n' + + + # send the response + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except Exception, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + + +def lookup_geoip_info(): + ''' + + Acquires the geoip information for all the vessels specified in the + neighbor ip table. + + + None + + + The geoip data recorded will be stored in mycontext['locationdata'][neighborip]. + If the lookup was successful, then the looked up data will be stored. + Otherwise, we put + + + None + + + None + ''' + + geoip_init_client() + for neighbor in mycontext['neighborlist']: + try: + locationdict = geoip_record_by_addr(neighbor) + if locationdict is not None: + # Sometimes we don't get a city name. + if 'city' not in locationdict: + locationdict['city'] = "Unknown" + mycontext['locationdata'][neighbor] = locationdict + + # The lookup failed + else: + mycontext['locationdata'][neighbor] = None + + except Exception, e: + if not "Unable to contact the geoip server" in str(e): + raise + # We use this to indicate that no location data is available. + mycontext['locationdata'][neighbor] = None + + +if callfunc == 'initialize': + + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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',True) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + log ("file is opened correctly") + except RepyArgumentError, e1: + log ("exception in reading from file"+ str(e1)) + except FileInUseError, e2: + log ("exception in reading from file"+ str(e2)) + except ResourceExhaustedError, e3: + log ("exception in reading from file"+ str(e3)) + except FileNotFoundError, e4: + log ("exception in reading from file"+ str(e4)) + + # Contains the dictionaries for node location information. + mycontext['locationdata'] = {} + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + log (pingport ) + mycontext['port'] = pingport + + # call gotmessage whenever receiving a message + #recvmess(ip,pingport,got_message) #doesn't work in r2py. + udpserversocket = listenformessage(ip, pingport) #waits for new UDP message + + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + + except SocketWouldBlockError: + sleep(0.1) + + probe_neighbors() + + # we want to register a function to show a status webpage (TCP port) + pageport = int(callargs[0]) + log (pageport) + #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 + log ("till msg listening") + + connobj = listenforconnection(ip,pageport) + log (" its here") + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + log (" \n *****got a new connection*******") + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + log (" \n *****inside error") + + # Getting geoip data takes a while, in the meanwhile we allow the user to + # see a status webpage and display a notice there. + lookup_geoip_info() From 968563f602235aa3f9f6729e5965c0f4901dd04d Mon Sep 17 00:00:00 2001 From: us341 Date: Thu, 14 Aug 2014 08:18:13 -0400 Subject: [PATCH 06/59] Create allpairping_new.r2py --- allpairping_new.r2py | 204 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 allpairping_new.r2py diff --git a/allpairping_new.r2py b/allpairping_new.r2py new file mode 100644 index 0000000..9fb2900 --- /dev/null +++ b/allpairping_new.r2py @@ -0,0 +1,204 @@ +# send a probe message to each neighbor +def probe_neighbors(): + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) + # sleep in between messages to prevent us from getting a huge number of + # responses all at once... + sleep(.5) + + # Call me again in 10 seconds + while True: + try: + #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality + sleep(10) + createthread(probe_neighbors) + return + except Exception, e: + if "Resource 'events'" in str(e): + # there are too many events scheduled, I should wait and try again + sleep(.5) + continue + raise + + + + +# Handle an incoming message +def got_message(srcip,srcport,mess): + if mess == 'ping': + sendmessage(srcip,srcport,'pong',getmyip(), 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 = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + webpage = "Latency Information

Latency information from "+getmyip()+'

' + + webpage = webpage + "" + log (mycontext['row']) + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + log ("outside no data reported") + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + + return webpage + + + +# Displays a web page with the latency information +def handle_http_request(srcip,srcport,connobj): + # Get the header + + try: + log ("inside http request") + total_data = '' + # We use a separate string to store the received data so that we don't have to + # re-check the beginning parts of the string multiple times + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + log ("recieved data") + # This is because Windows uses \r\n, Linux/Macs use \n. + # By doing this, we avoid having to program special cases for + # the different endline formats. + new_data = data.replace('\r\n', '\n') + total_data += new_data + + # keep everything after the first '\n\n' intact, just incase there is + # more content after the header that we may need + # Potential Bug?: We ignore the overflow data + header, overflow = total_data.split('\n\n', 1) + + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + # 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 + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + +def handle_message(): + while True: + try: + log ("\n waiting for new message") + srcip, srcport, mess = udpserversocket.getmessage() + log ("\n ***********got a new message*******") + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(1) + continue + + +if callfunc == 'initialize': + log ("********if it gets printed") + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + log ("file is opened correctly") + #except RepyArgumentError, FileInUseError, ResourceExhaustedError, e1: + #log ("exception in reading from file"+ str(e1)) + except FileNotFoundError, e4: + log ("neighboriplist.txt file doesn't exist.") + + ip = getmyip() + log (ip) + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + + # recvmess(ip,pingport,got_message) repyV1 call, not valid in RepyV2 + udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) + createthread(handle_message) + + + + probe_neighbors() + + # we want to register a function to show a status webpage (TCP port) + pageport = int(callargs[0]) + #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 + connobj = listenforconnection(ip,pageport) + while True: + try: + log ("\n waiting for new connection") + ret_ip, ret_port, ret_socket = connobj.getconnection() + log ("got a new connection") + handle_http_request(ret_ip, ret_port, ret_socket) + log ("http request completed") + except SocketWouldBlockError: + sleep(0.1) + + From 8bf53c1616d3d1457654b98c6729c64d983e935b Mon Sep 17 00:00:00 2001 From: us341 Date: Thu, 14 Aug 2014 13:52:11 -0400 Subject: [PATCH 07/59] Create allpairsping.r2py --- latest/allpairsping.r2py | 198 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 latest/allpairsping.r2py diff --git a/latest/allpairsping.r2py b/latest/allpairsping.r2py new file mode 100644 index 0000000..3cc59ad --- /dev/null +++ b/latest/allpairsping.r2py @@ -0,0 +1,198 @@ +# send a probe message to each neighbor +def probe_neighbors(): + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) + # sleep in between messages to prevent us from getting a huge number of + # responses all at once... + sleep(.5) + + # Call me again in 10 seconds + while True: + try: + sleep(10) + createthread(probe_neighbors) + return + except ResourceExhaustedError, e: + # there are too many events scheduled, I should wait and try again + sleep(.5) + continue + + + + + +# Handle an incoming message +def got_message(srcip,srcport,mess): + if mess == 'ping': + sendmessage(srcip,srcport,'pong',getmyip(), 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 = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + log ("inside generate status page") + webpage = "Latency Information

Latency information from "+getmyip()+'

' + + webpage = webpage + "" + log (mycontext['row']) + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + log ("outside no data reported") + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + + return webpage + + + +# Displays a web page with the latency information +def handle_http_request(srcip,srcport,connobj): + # Get the header + + try: + log ("inside http request") + total_data = '' + # We use a separate string to store the received data so that we don't have to + # re-check the beginning parts of the string multiple times + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + log ("recieved data") + # This is because Windows uses \r\n, Linux/Macs use \n. + # By doing this, we avoid having to program special cases for + # the different endline formats. + new_data = data.replace('\r\n', '\n') + total_data += new_data + + # keep everything after the first '\n\n' intact, just incase there is + # more content after the header that we may need + # Potential Bug?: We ignore the overflow data + header, overflow = total_data.split('\n\n', 1) + + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + # 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 + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + +def handle_message(): + while True: + try: + log ("\n waiting for new message") + srcip, srcport, mess = udpserversocket.getmessage() + log ("\n ***********got a new message*******") + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + continue + + +if callfunc == 'initialize': + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + log ("file is opened correctly") + except FileNotFoundError, e4: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") + + ip = getmyip() + log (ip) + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) + createthread(handle_message) + + + + probe_neighbors() + + # we want to register a function to show a status webpage (TCP port) + pageport = int(callargs[0]) + + #listen for connection and call handle_http_request once a connection is got + connobj = listenforconnection(ip,pageport) + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + + From 22b4c0750a28faa9ba145ae855f77e7d8453c801 Mon Sep 17 00:00:00 2001 From: Urvashi Soni Date: Fri, 15 Aug 2014 21:21:02 -0400 Subject: [PATCH 08/59] this is latest --- example/allpairsping.r2py | 200 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 example/allpairsping.r2py diff --git a/example/allpairsping.r2py b/example/allpairsping.r2py new file mode 100644 index 0000000..2716935 --- /dev/null +++ b/example/allpairsping.r2py @@ -0,0 +1,200 @@ +""" + + Urvashi Soni + + + gives the connectivity graph and latency information of all nodes in a group. + +""" + + +# send a probe message to each neighbor +def probe_neighbors(): + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip == getmyip(): + #do nothing. local/destination ip and port can't be same in r2py + else: + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) + # sleep in between messages to prevent us from getting a huge number of + # responses all at once... + sleep(.5) + + # Call me again in 10 seconds + while True: + try: + sleep(10) + createthread(probe_neighbors) + return + except ResourceExhaustedError, e: + # there are too many events scheduled, I should wait and try again + sleep(.5) + continue + + + + + +# Handle an incoming message +def got_message(srcip,srcport,mess): + if mess == 'ping': + sendmessage(srcip,srcport,'pong',getmyip(), 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 = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + log ("inside generate status page") + webpage = "Latency Information

Latency information from "+getmyip()+'

' + webpage = webpage + "" + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + + return webpage + + + +# Displays a web page with the latency information +def handle_http_request(srcip,srcport,connobj): + # Get the header + try: + total_data = '' + # We use a separate string to store the received data so that we don't have to + # re-check the beginning parts of the string multiple times + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + # This is because Windows uses \r\n, Linux/Macs use \n. + # By doing this, we avoid having to program special cases for + # the different endline formats. + new_data = data.replace('\r\n', '\n') + total_data += new_data + + # keep everything after the first '\n\n' intact, just incase there is + # more content after the header that we may need + # Potential Bug?: We ignore the overflow data + header, overflow = total_data.split('\n\n', 1) + + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + # 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 + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + +def handle_message(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + continue + + +if callfunc == 'initialize': + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + except FileNotFoundError, e4: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) + createthread(handle_message) + + + + probe_neighbors() + + # we want to register a function to show a status webpage (TCP port) + pageport = int(callargs[0]) + + #listen for connection and call handle_http_request once a connection is got + connobj = listenforconnection(ip,pageport) + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + + From df21954e08b63f23679a47d54b22e13bb7f73277 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 20 Aug 2014 20:06:22 -0400 Subject: [PATCH 09/59] Update allpairsping.r2py --- allpairsping.r2py | 108 ++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index c169aca..208ae5f 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -1,27 +1,28 @@ -# send a probe message to each neighbor -def probe_neighbors(): - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) - # sleep in between messages to prevent us from getting a huge number of - # responses all at once... - sleep(.5) +""" + + Urvashi Soni + + + 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: try: - #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality - sleep(10) - createthread(probe_neighbors) - return - except Exception, e: - if "Resource 'events'" in str(e): - # there are too many events scheduled, I should wait and try again - sleep(.5) - continue - raise - + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip != getmyip(): + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) + sleep(10) + except ResourceExhaustedError, e: + # there are too many events scheduled, I should wait and try again + sleep(.5) + continue @@ -32,7 +33,6 @@ def got_message(srcip,srcport,mess): 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'):] @@ -54,9 +54,7 @@ def encode_row(rowip, neighborlist, latencylist): # Generates a HTML page that represents the current status of the program def generate_status_page(): webpage = "Latency Information

Latency information from "+getmyip()+'

' - webpage = webpage + "" - for nodeip in mycontext['neighborlist']: if nodeip in mycontext['row']: webpage = webpage + mycontext['row'][nodeip]+'\n' @@ -65,7 +63,6 @@ def generate_status_page(): # now the footer... webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
' - return webpage @@ -129,12 +126,27 @@ def handle_http_request(srcip,srcport,connobj): if "Socket closed" in str(e): # We can't do anything if the socket is closed return - raise + raise +def handle_message_forever(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + continue + +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) if callfunc == 'initialize': - # this holds the response information (i.e. when nodes responded) mycontext['latency'] = {} @@ -146,46 +158,30 @@ if callfunc == 'initialize': # get the nodes to probe mycontext['neighborlist'] = [] try: - fileobject = openfile('neighboriplist.txt',True) + fileobject = openfile('neighboriplist.txt',False) filecontent = fileobject.readat(None,0) neighbor_array = filecontent.splitlines() for line in neighbor_array: mycontext['neighborlist'].append(line.strip()) - log ("file is opened correctly") - except RepyArgumentError, e1: - log ("exception in reading from file"+ str(e1)) - except FileInUseError, e2: - log ("exception in reading from file"+ str(e2)) - except ResourceExhaustedError, e3: - log ("exception in reading from file"+ str(e3)) - except FileNotFoundError, e4: - log ("exception in reading from file"+ str(e4)) + except FileNotFoundError, e: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") ip = getmyip() if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) mycontext['port'] = pingport - # recvmess(ip,pingport,got_message) repyV1 call, not valid in RepyV2 - - udpserversocket = listenformessage(ip, pingport) #waits for new UDP message - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - - probe_neighbors() + mycontext['ip'] = ip - # we want to register a function to show a status webpage (TCP port) - pageport = int(callargs[0]) - #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 - connobj = listenforconnection(ip,pageport) - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) + createthread(handle_connection_forever) + From e5d5d846e8a7ef30812fcc56676b77e4e0709798 Mon Sep 17 00:00:00 2001 From: Urvashi Soni Date: Thu, 21 Aug 2014 11:02:01 -0400 Subject: [PATCH 10/59] latest --- allpairsping.r2py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 208ae5f..43c15b0 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -18,7 +18,8 @@ def probe_neighbors_forever(): if neighborip != getmyip(): sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) - sleep(10) + sleep(0.5) + sleep(10) except ResourceExhaustedError, e: # there are too many events scheduled, I should wait and try again sleep(.5) @@ -181,6 +182,7 @@ if callfunc == 'initialize': #listen for connection and call handle_http_request once a connection is got connobj = listenforconnection(ip,mycontext['port']) + log("changed") createthread(handle_connection_forever) From 45cbe13237aa778200f07ae674b2d93e358deb92 Mon Sep 17 00:00:00 2001 From: us341 Date: Thu, 21 Aug 2014 11:18:36 -0400 Subject: [PATCH 11/59] Update allpairsping.r2py --- allpairsping.r2py | 1 - 1 file changed, 1 deletion(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 43c15b0..eac5470 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -182,7 +182,6 @@ if callfunc == 'initialize': #listen for connection and call handle_http_request once a connection is got connobj = listenforconnection(ip,mycontext['port']) - log("changed") createthread(handle_connection_forever) From 5adceb4baa268bac449a6336d34272464fb7a21e Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Thu, 21 Aug 2014 11:59:27 -0400 Subject: [PATCH 12/59] after sleep update --- allpairsping.r2py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 43c15b0..640d167 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -15,12 +15,15 @@ def probe_neighbors_forever(): try: for neighborip in mycontext["neighborlist"]: mycontext['sendtime'][neighborip] = getruntime() - if neighborip != getmyip(): + if neighborip == getmyip(): + #do nothing + continue + else: sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) sleep(0.5) sleep(10) - except ResourceExhaustedError, e: + except AlreadyListeningError, e: # there are too many events scheduled, I should wait and try again sleep(.5) continue @@ -182,7 +185,6 @@ if callfunc == 'initialize': #listen for connection and call handle_http_request once a connection is got connobj = listenforconnection(ip,mycontext['port']) - log("changed") createthread(handle_connection_forever) From 20c51ce769e2567559bccb8015f40f6527de3212 Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Thu, 21 Aug 2014 12:10:17 -0400 Subject: [PATCH 13/59] after sleep update --- allpairsping.r2py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 640d167..e5495e8 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -12,21 +12,18 @@ def probe_neighbors_forever(): # Call me again in 10 seconds while True: - try: - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - if neighborip == getmyip(): - #do nothing - continue - else: + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip == getmyip(): + #do nothing + continue + else: sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) sleep(0.5) - sleep(10) - except AlreadyListeningError, e: - # there are too many events scheduled, I should wait and try again - sleep(.5) - continue + #sleep for 10 sec and start from while loop again + sleep(10) + From 6d74aa0d90991b812a46fc62be6f4d806d1b7b86 Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Thu, 21 Aug 2014 17:40:46 -0400 Subject: [PATCH 14/59] these are for infosec --- samplesecurity.r2py | 95 +++++++++++++++++++++++++++++++++++++++++ samplesecuritytest.r2py | 13 ++++++ 2 files changed, 108 insertions(+) create mode 100644 samplesecurity.r2py create mode 100644 samplesecuritytest.r2py diff --git a/samplesecurity.r2py b/samplesecurity.r2py new file mode 100644 index 0000000..54600c3 --- /dev/null +++ b/samplesecurity.r2py @@ -0,0 +1,95 @@ +""" +This security layer interposes on a textfile and gives it read, write, or append access. +A user can only read, write, or append to that file when that specific mode is enabled for that file. Multiple files can be be simultaneously opened and have different modes. + +Read-only: You may read the contents of a file, but not write or append. +If you attempt to read when read mode is disabled, a ValueError is raised. + +Write-only: You may overwrite the contents of a file, but not append to the file. +If you attempt to do so, the file should be overwritten to the length of the file, and then writing stops. + +Append-only: You may append data to the end of the file, but not overwrite +anything that is already written. If a write starts before the end of the +file, but continues afterward, only the data after the current end of +file should be written. + +More than one mode may be enabled at once, e.g. Write and Append allows you to overwrite existing file data and append data to the end of the file. + +writeat must return a ValueError if and only if both write and append are +blocked. readat must return a value error if and only if read is blocked. + +For efficiency purposes, you *MUST NOT* call readat inside of writeat. It +is fine to call readat during file open if desired. + + +Extra credit (?): remember permissions for files after they are closed and +reopened. This would include situations where your security layer is itself +closed and reopened (for example, if the system restarts). You can assume +that all reads must go through your security layer and so you can add an +additional file or modify the file format. + +Note: + This security layer uses encasementlib.r2py, restrictions.default, repy.py and Python + Also you need to give it an application to run. + This security layer never runs explicitly but instead interposes functions + from above layers. + + """ + + +TYPE="type" +ARGS="args" +RETURN="return" +EXCP="exceptions" +TARGET="target" +FUNC="func" +OBJC="objc" + +class SecureFile(): + def __init__(self,file): + # globals + mycontext['debug'] = False + mycontext['read'] = False + mycontext['write'] = False + mycontext['append'] = False + mycontext['size'] = 0 + # local (per object) reference to the underlying file + self.file = file + + def setread(self,enabled): + mycontext['read'] = enabled + + def setwrite(self,enabled): + mycontext['write'] = enabled + + def setmaxfilesize(self,size): + mycontext['size'] = size + + def writeat(self,data,offset): + datalen = len(data) + filesize_after_datawriting = datalen + offset + if size_after_data != mycontext['size']: + raise ValueError + else: + self.file.writeat(data,offset) + + def close(self): + return self.file.close() + +sec_file_def = {"obj-type":SecureFile, + "name":"SecureFile", + "setread":{TYPE:FUNC,ARGS:[bool],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setread}, + "setwrite":{TYPE:FUNC,ARGS:[bool],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setwrite}, + "setappend":{TYPE:FUNC,ARGS:[bool],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setappend}, + "setmaxfilesize":{TYPE:FUNC,ARGS:[int],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setmaxfilesize}, + "writeat":{TYPE:FUNC,ARGS:(str,(int,long)),EXCP:Exception,RETURN:(int,type(None)),TARGET:SecureFile.writeat}, + "close":{TYPE:FUNC,ARGS:None,EXCP:None,RETURN:(bool,type(None)),TARGET:SecureFile.close} + } + +def secure_openfile(filename, create): + f = openfile(filename,create) + return SecureFile(f) + +CHILD_CONTEXT_DEF["openfile"] = {TYPE:OBJC,ARGS:(str,bool),EXCP:Exception,RETURN:sec_file_def,TARGET:secure_openfile} + +secure_dispatch_module() diff --git a/samplesecuritytest.r2py b/samplesecuritytest.r2py new file mode 100644 index 0000000..5de9ff1 --- /dev/null +++ b/samplesecuritytest.r2py @@ -0,0 +1,13 @@ +if "look.txt" in listfiles(): + removefile("look.txt") +myfile=openfile("look.txt",True) #Open a file + + +#set maximum file size allowed +myfile.setmaxfilesize(10) + +#the following writeat should give error as data size is greater than allowed max size +myfile.writeat("abcdegsrtfcdy",0) + +#Close the file +myfile.close() \ No newline at end of file From 9170b89250e0bfbc7e494195ccafec34dc53965a Mon Sep 17 00:00:00 2001 From: us341 Date: Thu, 21 Aug 2014 17:44:31 -0400 Subject: [PATCH 15/59] Update samplesecurity.r2py --- samplesecurity.r2py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samplesecurity.r2py b/samplesecurity.r2py index 54600c3..930992e 100644 --- a/samplesecurity.r2py +++ b/samplesecurity.r2py @@ -67,7 +67,7 @@ class SecureFile(): def writeat(self,data,offset): datalen = len(data) - filesize_after_datawriting = datalen + offset + size_after_data = datalen + offset if size_after_data != mycontext['size']: raise ValueError else: From a29c102fdc0b00d61f5cbee6b31b2bc6ffc0c8b0 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 26 Aug 2014 15:18:58 -0400 Subject: [PATCH 16/59] Update allpairspingmap.mix --- allpairspingmap.mix | 137 ++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 68 deletions(-) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index 6477723..f08c462 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -26,7 +26,7 @@ ''' -include geoip_client.r2py +dy_import_module_symbols('geoip_client.r2py') class InvalidRequestError(Exception): @@ -65,7 +65,7 @@ mycontext['MIME_TYPES'] = { -def probe_neighbors(): +def probe_neighbors_forever(): ''' Send a probe message to each neighbor @@ -83,28 +83,19 @@ def probe_neighbors(): None ''' - - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip, mycontext['port'],'share'+encode_row( mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) - # sleep in between messages to prevent us from getting a huge number of - # responses all at once... - sleep(.5) - - # Call me again in 10 seconds while True: - try: - #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality - sleep(10) - createthread(probe_neighbors) - return - except Exception, e: - if "Resource 'events'" in str(e): - # there are too many events scheduled, I should wait and try again - sleep(.5) + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip == getmyip(): + #do nothing continue - raise + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + + sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) + log("sent message") + sleep(0.5) + #sleep for 10 sec and start from while loop again + sleep(10) @@ -191,7 +182,7 @@ def generate_node_list(): HTML string of unsorted list of nodes. """ - + log("\ninside generate_node_list\n") # Is there a specific reason why we sort these keys? I'm leaving these # intact since the original version sorted them. nodeiplist = mycontext['neighborlist'] @@ -240,12 +231,12 @@ def generate_status_page(): A string representing a HTML webpage containing the current status of the program. ''' - + log("\ninside generate_status_page\n") webpage = "Latency Information" webpage += '' webpage += '' - + log("\njavascript added") # Include our script/stylesheet for the webpage webpage += '' webpage += '' @@ -319,7 +310,7 @@ def handle_http_request(srcip,srcport,connobj): None ''' - + log("inside http_request") # Get the header try: total_data = '' @@ -330,23 +321,25 @@ def handle_http_request(srcip,srcport,connobj): # is an empty string. while '\n\n' not in new_data: # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - # This is because Windows uses \r\n, Linux/Macs use \n. - # By doing this, we avoid having to program special cases for - # the different endline formats. - new_data = data.replace('\r\n', '\n') - total_data += new_data + log("inside while loop") + try: + data = connobj.recv(4096) + # This is because Windows uses \r\n, Linux/Macs use \n. + # By doing this, we avoid having to program special cases for + # the different endline formats. + new_data = data.replace('\r\n', '\n') + total_data += new_data + except Exception,e: + log("inside error\n") + continue # keep everything after the first '\n\n' intact, just incase there is # more content after the header that we may need # Potential Bug?: We ignore the overflow data header, overflow = total_data.split('\n\n', 1) - except Exception, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise + + # Get the request path, which is inbetween the HTTP action keyword and the # HTTP version number. @@ -354,6 +347,7 @@ def handle_http_request(srcip,srcport,connobj): 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. + log("splitting") requested_file = everything_after_httpaction.split(" HTTP/")[0] # Get rid of the leading '/' because its useless to us @@ -367,9 +361,9 @@ def handle_http_request(srcip,srcport,connobj): if requested_file not in mycontext['RECOGNIZED_FILES']: raise InvalidRequestError("Unrecognized file:" + requested_file) - # Generate the index page if the request field is empty. elif not requested_file: + contents = generate_status_page() # This is a file that we recognize. Send its contents to the client. @@ -403,6 +397,7 @@ def handle_http_request(srcip,srcport,connobj): except Exception, e: if "Socket closed" in str(e): # We can't do anything if the socket is closed + log ("why its happening") return raise @@ -449,6 +444,24 @@ def lookup_geoip_info(): # We use this to indicate that no location data is available. mycontext['locationdata'][neighbor] = None +def handle_message_forever(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + log("got a new message\n") + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + continue + +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + log("got a new connection") + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) if callfunc == 'initialize': @@ -464,7 +477,7 @@ if callfunc == 'initialize': # get the nodes to probe mycontext['neighborlist'] = [] try: - fileobject = openfile('neighboriplist.txt',True) + fileobject = openfile('neighboriplist.txt',False) filecontent = fileobject.readat(None,0) neighbor_array = filecontent.splitlines() for line in neighbor_array: @@ -483,42 +496,30 @@ if callfunc == 'initialize': mycontext['locationdata'] = {} ip = getmyip() + log (ip) + log ("isss") if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) log (pingport ) + mycontext['port'] = pingport + mycontext['ip'] = ip mycontext['port'] = pingport - # call gotmessage whenever receiving a message - #recvmess(ip,pingport,got_message) #doesn't work in r2py. - udpserversocket = listenformessage(ip, pingport) #waits for new UDP message - - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - - except SocketWouldBlockError: - sleep(0.1) - - probe_neighbors() - - # we want to register a function to show a status webpage (TCP port) - pageport = int(callargs[0]) - log (pageport) - #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 - log ("till msg listening") - connobj = listenforconnection(ip,pageport) - log (" its here") - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - log (" \n *****got a new connection*******") - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - log (" \n *****inside error") + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) + createthread(handle_connection_forever) + # Getting geoip data takes a while, in the meanwhile we allow the user to # see a status webpage and display a notice there. - lookup_geoip_info() + log ("*****************check if it ever gets here****************") + #lookup_geoip_info() + From 9deaad658de1fa6adebde8e3c09c8557d5b18546 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 26 Aug 2014 16:43:53 -0400 Subject: [PATCH 17/59] Update allpairsping.r2py --- allpairsping.r2py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/allpairsping.r2py b/allpairsping.r2py index e5495e8..f7ae2bb 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -80,7 +80,9 @@ def handle_http_request(srcip,srcport,connobj): # is an empty string. while '\n\n' not in new_data: # Receive in chunks to avoid reading too much data + log("inside while of http_handle_request") data = connobj.recv(4096) + log(data) # This is because Windows uses \r\n, Linux/Macs use \n. # By doing this, we avoid having to program special cases for # the different endline formats. @@ -168,6 +170,7 @@ if callfunc == 'initialize': raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") ip = getmyip() + log(ip) if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) From 428917d784b6e2965e13104473ef94c337c1d3e6 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 12:45:01 -0400 Subject: [PATCH 18/59] Update allpairsping.r2py --- allpairsping.r2py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index f7ae2bb..00551fc 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -94,12 +94,16 @@ def handle_http_request(srcip,srcport,connobj): # Potential Bug?: We ignore the overflow data header, overflow = total_data.split('\n\n', 1) - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed + #except SocketClosedRemote, e: + #if "Socket closed" in str(e): + ## We can't do anything if the socket is closed + #return + #raise + + except SocketWouldBlockError, e: + log(e) return - raise - + # 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. From b702b54ffbe4732e036927e36e5fae09a296d34c Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 13:14:32 -0400 Subject: [PATCH 19/59] Update allpairping_new.r2py --- allpairping_new.r2py | 141 ++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 82 deletions(-) diff --git a/allpairping_new.r2py b/allpairping_new.r2py index 9fb2900..a11614e 100644 --- a/allpairping_new.r2py +++ b/allpairping_new.r2py @@ -1,27 +1,29 @@ -# send a probe message to each neighbor -def probe_neighbors(): - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) - # sleep in between messages to prevent us from getting a huge number of - # responses all at once... - sleep(.5) +""" + + Urvashi Soni + + + 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: - try: - #settimer(10,probe_neighbors,(port,)) RepyV1 call, not Valid in RepyV2. Will use sleep and createthread() to achieve this functionality - sleep(10) - createthread(probe_neighbors) - return - except Exception, e: - if "Resource 'events'" in str(e): - # there are too many events scheduled, I should wait and try again - sleep(.5) + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip == getmyip(): + #do nothing continue - raise - + else: + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) + sleep(0.5) + #sleep for 10 sec and start from while loop again + sleep(10) + @@ -32,7 +34,6 @@ def got_message(srcip,srcport,mess): 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'):] @@ -54,19 +55,15 @@ def encode_row(rowip, neighborlist, latencylist): # Generates a HTML page that represents the current status of the program def generate_status_page(): webpage = "Latency Information

Latency information from "+getmyip()+'

' - webpage = webpage + "" - log (mycontext['row']) for nodeip in mycontext['neighborlist']: if nodeip in mycontext['row']: - log ("outside no data reported") webpage = webpage + mycontext['row'][nodeip]+'\n' else: webpage = webpage + '\n' # now the footer... webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' - return webpage @@ -74,39 +71,28 @@ def generate_status_page(): # Displays a web page with the latency information def handle_http_request(srcip,srcport,connobj): # Get the header - - try: - log ("inside http request") - total_data = '' - # We use a separate string to store the received data so that we don't have to - # re-check the beginning parts of the string multiple times - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + log("inside while of http_handle_request") + try: data = connobj.recv(4096) - log ("recieved data") - # This is because Windows uses \r\n, Linux/Macs use \n. - # By doing this, we avoid having to program special cases for - # the different endline formats. - new_data = data.replace('\r\n', '\n') - total_data += new_data - - # keep everything after the first '\n\n' intact, just incase there is - # more content after the header that we may need - # Potential Bug?: We ignore the overflow data - header, overflow = total_data.split('\n\n', 1) - - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed + log(data) + except SocketWouldBlockError, e: + log(e) return - raise + new_data = data.replace('\r\n', '\n') + total_data += new_data + 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. + log("is it coming here") 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. @@ -135,20 +121,25 @@ def handle_http_request(srcip,srcport,connobj): return raise -def handle_message(): +def handle_message_forever(): while True: try: - log ("\n waiting for new message") srcip, srcport, mess = udpserversocket.getmessage() - log ("\n ***********got a new message*******") got_message(srcip, srcport, mess) except SocketWouldBlockError: - sleep(1) + sleep(0.1) continue +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + if callfunc == 'initialize': - log ("********if it gets printed") # this holds the response information (i.e. when nodes responded) mycontext['latency'] = {} @@ -165,40 +156,26 @@ if callfunc == 'initialize': neighbor_array = filecontent.splitlines() for line in neighbor_array: mycontext['neighborlist'].append(line.strip()) - log ("file is opened correctly") - #except RepyArgumentError, FileInUseError, ResourceExhaustedError, e1: - #log ("exception in reading from file"+ str(e1)) - except FileNotFoundError, e4: - log ("neighboriplist.txt file doesn't exist.") + except FileNotFoundError, e: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") ip = getmyip() - log (ip) + log(ip) if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) mycontext['port'] = pingport mycontext['ip'] = ip - # recvmess(ip,pingport,got_message) repyV1 call, not valid in RepyV2 + #listen for a new message and call handle_message in new thread udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) - createthread(handle_message) + createthread(handle_message_forever) + + createthread(probe_neighbors_forever) + + #listen for connection and call handle_http_request once a connection is got + connobj = listenforconnection(ip,mycontext['port']) + createthread(handle_connection_forever) - - - probe_neighbors() - - # we want to register a function to show a status webpage (TCP port) - pageport = int(callargs[0]) - #waitforconn(ip,pageport,handle_http_request) repyV1 call, not valid in RepyV2 - connobj = listenforconnection(ip,pageport) - while True: - try: - log ("\n waiting for new connection") - ret_ip, ret_port, ret_socket = connobj.getconnection() - log ("got a new connection") - handle_http_request(ret_ip, ret_port, ret_socket) - log ("http request completed") - except SocketWouldBlockError: - sleep(0.1) From 0852695b333af6110450687ba58afbb3ee2f81d0 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 14:06:54 -0400 Subject: [PATCH 20/59] Update allpairspingmap.mix --- allpairspingmap.mix | 54 +++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index f08c462..658f966 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -86,13 +86,9 @@ def probe_neighbors_forever(): while True: for neighborip in mycontext["neighborlist"]: mycontext['sendtime'][neighborip] = getruntime() - if neighborip == getmyip(): - #do nothing - continue sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - - sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) log("sent message") + sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) sleep(0.5) #sleep for 10 sec and start from while loop again sleep(10) @@ -310,40 +306,29 @@ def handle_http_request(srcip,srcport,connobj): None ''' - log("inside http_request") + def handle_http_request(srcip,srcport,connobj): # Get the header - try: - total_data = '' - # We use a separate string to store the received data so that we don't have to - # re-check the beginning parts of the string multiple times - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - log("inside while loop") - try: - data = connobj.recv(4096) - # This is because Windows uses \r\n, Linux/Macs use \n. - # By doing this, we avoid having to program special cases for - # the different endline formats. - new_data = data.replace('\r\n', '\n') - total_data += new_data - except Exception,e: - log("inside error\n") - continue - - # keep everything after the first '\n\n' intact, just incase there is - # more content after the header that we may need - # Potential Bug?: We ignore the overflow data - header, overflow = total_data.split('\n\n', 1) - - - + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + log("inside while of http_handle_request") + try: + data = connobj.recv(4096) + log(data) + except SocketWouldBlockError, e: + log(e) + return + new_data = data.replace('\r\n', '\n') + total_data += new_data + 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. + log("splitting1") 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. @@ -361,6 +346,7 @@ def handle_http_request(srcip,srcport,connobj): if requested_file not in mycontext['RECOGNIZED_FILES']: raise InvalidRequestError("Unrecognized file:" + requested_file) + # Generate the index page if the request field is empty. elif not requested_file: From 52b3d6322b5cd5737cea1bda29eb7c5de25aa944 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 14:14:11 -0400 Subject: [PATCH 21/59] Update allpairspingmap.mix --- allpairspingmap.mix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index 658f966..228720a 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -85,7 +85,11 @@ def probe_neighbors_forever(): ''' while True: for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip == getmyip(): + #do nothing + continue sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) log("sent message") sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) From 4acbb7d464900ee220ccbd799ff9cfb984492480 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 14:19:11 -0400 Subject: [PATCH 22/59] Update allpairspingmap.mix --- allpairspingmap.mix | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index 228720a..841010e 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -85,11 +85,7 @@ def probe_neighbors_forever(): ''' while True: for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - if neighborip == getmyip(): - #do nothing - continue sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) log("sent message") sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) @@ -288,29 +284,7 @@ def generate_status_page(): return webpage - - def handle_http_request(srcip,srcport,connobj): - ''' - - waitforconn() callback. Responds to a user's http request. - - - See the Repy documentation for waitforconn() callbacks. - - - If no file is requested, we send a web page with the latency information. - If a recognized file is requested, and the file exists, we send the file's - contents to the user. - Otherwise, we send a 404 error message. - - - None - - - None - ''' - def handle_http_request(srcip,srcport,connobj): # Get the header total_data = '' new_data = '' From 56a9d24105f6b6f81bc2d154bc7ea0ef4ce6e9f8 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 14:20:05 -0400 Subject: [PATCH 23/59] Update allpairspingmap.mix --- allpairspingmap.mix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index 841010e..6c728be 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -485,5 +485,5 @@ if callfunc == 'initialize': # Getting geoip data takes a while, in the meanwhile we allow the user to # see a status webpage and display a notice there. log ("*****************check if it ever gets here****************") - #lookup_geoip_info() + lookup_geoip_info() From 5e010e3357046915c3b4946a56336433f7471b0a Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 14:24:59 -0400 Subject: [PATCH 24/59] Update allpairspingmap.mix --- allpairspingmap.mix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index 6c728be..7500e78 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -86,6 +86,9 @@ def probe_neighbors_forever(): while True: for neighborip in mycontext["neighborlist"]: mycontext['sendtime'][neighborip] = getruntime() + if neighborip == getmyip(): + #do nothing + continue sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) log("sent message") sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) @@ -96,7 +99,7 @@ def probe_neighbors_forever(): - # Handle an incoming message +# Handle an incoming message def got_message(srcip,srcport,mess): ''' From 9b631fb0803465628dc42775e4708f6f48fcdf5b Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 15:16:56 -0400 Subject: [PATCH 25/59] Update allpairsping.r2py --- allpairsping.r2py | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 00551fc..391f1ae 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -71,42 +71,23 @@ def generate_status_page(): # Displays a web page with the latency information def handle_http_request(srcip,srcport,connobj): # Get the header - try: - total_data = '' - # We use a separate string to store the received data so that we don't have to - # re-check the beginning parts of the string multiple times - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - log("inside while of http_handle_request") - data = connobj.recv(4096) - log(data) - # This is because Windows uses \r\n, Linux/Macs use \n. - # By doing this, we avoid having to program special cases for - # the different endline formats. - new_data = data.replace('\r\n', '\n') - total_data += new_data - - # keep everything after the first '\n\n' intact, just incase there is - # more content after the header that we may need - # Potential Bug?: We ignore the overflow data - header, overflow = total_data.split('\n\n', 1) - - #except SocketClosedRemote, e: - #if "Socket closed" in str(e): - ## We can't do anything if the socket is closed - #return - #raise + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + log("inside while of http_handle_request") + data = connobj.recv(4096) + new_data = data.replace('\r\n', '\n') + total_data += new_data + header, overflow = total_data.split('\n\n', 1) - except SocketWouldBlockError, e: - log(e) - return - + # 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. + log("is it coming here") 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. From e8461d064889ca2825c3b8af83830a33892fe396 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 15:50:24 -0400 Subject: [PATCH 26/59] Update allpairspingmap.mix --- allpairspingmap.mix | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index 7500e78..704fe28 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -237,9 +237,9 @@ def generate_status_page(): webpage += '' log("\njavascript added") # Include our script/stylesheet for the webpage - webpage += '' - webpage += '' - + webpage += '' + webpage += '' + # Begin displaying body content; Lets start with the map. webpage += "
" @@ -296,12 +296,7 @@ def handle_http_request(srcip,srcport,connobj): while '\n\n' not in new_data: # Receive in chunks to avoid reading too much data log("inside while of http_handle_request") - try: - data = connobj.recv(4096) - log(data) - except SocketWouldBlockError, e: - log(e) - return + data = connobj.recv(4096) new_data = data.replace('\r\n', '\n') total_data += new_data header, overflow = total_data.split('\n\n', 1) From 228d0ede6a744284eb69bf8ae6321da246658ab8 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 27 Aug 2014 21:19:18 -0400 Subject: [PATCH 27/59] Update allpairspingmap.mix --- allpairspingmap.mix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/allpairspingmap.mix b/allpairspingmap.mix index 704fe28..c7ec3cd 100644 --- a/allpairspingmap.mix +++ b/allpairspingmap.mix @@ -235,10 +235,9 @@ def generate_status_page(): webpage += '' webpage += '' - log("\njavascript added") # Include our script/stylesheet for the webpage - webpage += '' - webpage += '' + webpage += '' + webpage += '' # Begin displaying body content; Lets start with the map. webpage += "
" From 1cf2d51054052b4bbda0751fa829468f3465716b Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Thu, 28 Aug 2014 13:29:12 -0400 Subject: [PATCH 28/59] running version of allpairspingmap --- allpairspingmap.r2py | 466 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100644 allpairspingmap.r2py diff --git a/allpairspingmap.r2py b/allpairspingmap.r2py new file mode 100644 index 0000000..da10d83 --- /dev/null +++ b/allpairspingmap.r2py @@ -0,0 +1,466 @@ +''' + + allpairspingmap.r2py + + + This program gives a visual representation of the vessels that a user has + acquired. It includes a map that contains markers on where the vessels are + reported to be, according to the geoip client. + + + A file containing the ip addresses of all the vessels to contact must be + uploaded. This file should be named 'neighboriplist.txt'. Each line should + contain one vessel. This file can be prepared within seash by issuing the + following command within a group: + show ip to neighboriplist.txt + + Additionally, the following files (which are provided) need to be uploaded to + the vessels: + jquerygmaps.js + style.css + map_marker_icon.png + + Once this is set up, you need to pass your Clearinghouse port to the program + as an argument: + username@group> run allpairspingmap.r2py [port number] + +''' + +dy_import_module_symbols('geoip_client.r2py') + + +class InvalidRequestError(Exception): + ''' The user made a request for a nonexistent file. ''' + + +# These are the paths that the web server will serve files for. +# This is to prevent clients from seeing anything else that we might not want +# them to be able to see. +# +# '': +# Index file. We generate a webpage representing the current program status +# +# style.css: +# Stylesheet that controls how the webpage is formatted. Without this, +# the map will not render correctly. +# +# jquerygmaps.js: +# Contains code that interfaces against google's MapV2 API. +# +# map_marker_icon.png: +# This image is used as a marker for where the vessels are, on the map. + +mycontext['RECOGNIZED_FILES'] = ( + '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png') + + +# When responding to HTTP requests, we need to include a MIME type, identifying +# the type of file that we are serving to the HTTP client. This dictionary +# maps a file extension to its common MIME type. +mycontext['MIME_TYPES'] = { + '.js': 'text/javascript', + '.css': 'text/css', + '.png': 'image/png' + } + + + +def probe_neighbors_forever(): + ''' + + Send a probe message to each neighbor + + + port: The clearinghouse port assigned to the current user. + + + Starts the ping loop to calculate the latency between the local node + and neighboring nodes. We also send our latency data to each node. + + + None + + + None + ''' + while True: + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip == mycontext['ip']: + #skip if local and destination ip addresses and port match because we can't send message if local/dest ip and port match in repy v2 + continue + sendmessage(neighborip, mycontext['port'], 'ping',mycontext['ip'],mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),mycontext['ip'],mycontext['port']) + sleep(0.5) + #sleep for 10 sec and start from while loop again to avoid so many responses at the same time + sleep(10) + + + + +# Handle an incoming message +def got_message(srcip,srcport,mess): + ''' + + Handle an incoming message from a neighboring node. + + + See documentation for recvmess(). + + + If we receive a ping message, we respond with a pong message. + If we receive a pong message, we take the difference between when we sent + this neighbor a ping message and record that as the latency. + If we receive a share message, we record the neighbor's neighbor row + information. + + + None + + + None + ''' + + + if mess == 'ping': + sendmessage(srcip,srcport,'pong',getmyip(), 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(neighborlist, latencylist): + ''' + + Prepares the local node's latency information into a format that is + recognizable by the other nodes. + + + neighborlist: The IP addresses of all our neighbors. + latencylist: The list of latencies associated with the neighbors. + + + None + + + None + + + A string representing a HTML row containing the latency information + between this node and the other neighbor nodes. + ''' + + retstring = "" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring += ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring += "Unknown" + return retstring + + +def generate_node_list(): + """ + + Generates an HTMl string of an unsorted list of nodes. + + + None. + + + None. + + + None. + + + HTML string of unsorted list of nodes. + """ + # Is there a specific reason why we sort these keys? I'm leaving these + # intact since the original version sorted them. + nodeiplist = mycontext['neighborlist'] + nodeiplist.sort() + + nodelist_str = '
    ' + for nodeip in nodeiplist: + # Print node list element + nodelist_str += ('
  • ' + + str(nodeip) + '') + + if nodeip in mycontext['locationdata']: + nodelocdict = mycontext['locationdata'][nodeip] + if nodelocdict is not None: + nodelist_str += ('' + str(nodelocdict['longitude']) + + '' + str(nodelocdict['latitude']) + + '' + geoip_location_str(nodelocdict) + '') + # We didn't perform the lookup yet. This is used to tell the client to + # refresh the page. + else: + nodelist_str += "" + nodelist_str += '
  • ' + nodelist_str += '
' + return nodelist_str + + + + + +def generate_status_page(): + ''' + + Generates a HTML page that represents the current status of the program + + + None + + + The webpage returned may cause a client's browser to make additional + requests to the current program, or other machines. + + + None + + + A string representing a HTML webpage containing the current status of the + program. + ''' + webpage = "Latency Information" + + webpage += '' + webpage += '' + # Include our script/stylesheet for the webpage + webpage += '' + webpage += '' + + # Begin displaying body content; Lets start with the map. + webpage += "
" + + # Display the latency information as a table + webpage += "

Latency information from "+getmyip()+'

' + + # Create a column in the table for each vessel + webpage += "" + + # Create a row in the table for each vessel + for nodeip in mycontext['neighborlist']: + # Show ip and location data, if present + webpage += '' + + # Add latency information + if nodeip in mycontext['row']: + webpage += mycontext['row'][nodeip] + else: + webpage += '' + webpage += '\n' + + webpage += '
"+ "".join(mycontext['neighborlist'])+"
' +nodeip+'
\n' + + # Was there a geoip lookup yet? + if nodeip in mycontext['locationdata']: + # Did the geoip lookup succeed? + if mycontext['locationdata'][nodeip] is not None: + nodelocation = mycontext['locationdata'][nodeip] + webpage += nodelocation['city'] + ', ' + nodelocation['country_code'] + # The lookup failed + else: + webpage += "No location data available" + + # We haven't done a geoip lookup yet. Let the user know. + else: + webpage += "Location data not yet retrieved" + webpage += '
No Data Reported
' + + # We need this for the map data to work + webpage += generate_node_list() + # now the footer... + webpage += '' + + return webpage + + +def handle_http_request(srcip,srcport,connobj): + # Get the header + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + new_data = data.replace('\r\n', '\n') + total_data += new_data + 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. + requested_file = everything_after_httpaction.split(" HTTP/")[0] + + # Get rid of the leading '/' because its useless to us + requested_file = requested_file.lstrip('/') + + # Generate the data to send back. + try: + # We default to this content type. + content_type = 'text/html' + # Don't respond with anything if they have something in the request path. + + if requested_file not in mycontext['RECOGNIZED_FILES']: + raise InvalidRequestError("Unrecognized file:" + requested_file) + + # Generate the index page if the request field is empty. + elif not requested_file: + + contents = generate_status_page() + + # This is a file that we recognize. Send its contents to the client. + else: + # PNGs are binary files. Plaintext files still work when read in + # binary mode. + contents = openfile(requested_file, True).readat(None,0) + + # Figure out the MIME type to send to the client + for extension in mycontext['MIME_TYPES']: + if requested_file.endswith(extension): + content_type = mycontext['MIME_TYPES'][extension] + break + else: + content_type = 'text/plain' + + # combine everything into one unit for sending + data = 'HTTP/1.1 200 OK\nContent-Type: '+content_type+'\nContent-Length: '+str(len(contents))+'\nServer: Seattle Testbed\n\n'+contents + + except InvalidRequestError: + data = 'HTTP/1.1 404 Not Found\n\n' + + + # send the response + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except Exception, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + + +def lookup_geoip_info(): + ''' + + Acquires the geoip information for all the vessels specified in the + neighbor ip table. + + + None + + + The geoip data recorded will be stored in mycontext['locationdata'][neighborip]. + If the lookup was successful, then the looked up data will be stored. + Otherwise, we put + + + None + + + None + ''' + + geoip_init_client() + for neighbor in mycontext['neighborlist']: + try: + locationdict = geoip_record_by_addr(neighbor) + if locationdict is not None: + # Sometimes we don't get a city name. + if 'city' not in locationdict: + locationdict['city'] = "Unknown" + mycontext['locationdata'][neighbor] = locationdict + + # The lookup failed + else: + mycontext['locationdata'][neighbor] = None + + except Exception, e: + if not "Unable to contact the geoip server" in str(e): + raise + # We use this to indicate that no location data is available. + mycontext['locationdata'][neighbor] = None + +def handle_message_forever(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + + +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + + + +if callfunc == 'initialize': + + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + except FileNotFoundError, e: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") + + # Contains the dictionaries for node location information. + mycontext['locationdata'] = {} + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + log(mycontext['ip']) + + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], 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['ip'],mycontext['port']) + createthread(handle_connection_forever) + + + # Getting geoip data takes a while, in the meanwhile we allow the user to + # see a status webpage and display a notice there. + lookup_geoip_info() + From 6efb17f2cfe03b0785e573bf948e2603ca18ccfc Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 3 Sep 2014 12:55:42 -0400 Subject: [PATCH 29/59] Update allpairspingmap.r2py --- allpairspingmap.r2py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/allpairspingmap.r2py b/allpairspingmap.r2py index da10d83..48247f7 100644 --- a/allpairspingmap.r2py +++ b/allpairspingmap.r2py @@ -19,6 +19,7 @@ jquerygmaps.js style.css map_marker_icon.png + map_marker_icon_blue.png Once this is set up, you need to pass your Clearinghouse port to the program as an argument: @@ -51,7 +52,7 @@ class InvalidRequestError(Exception): # This image is used as a marker for where the vessels are, on the map. mycontext['RECOGNIZED_FILES'] = ( - '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png') + '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png', 'map_marker_icon_blue.png') # When responding to HTTP requests, we need to include a MIME type, identifying From 190d739b4903d85c3f3da8862e6bedbb614424a6 Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Wed, 3 Sep 2014 13:00:03 -0400 Subject: [PATCH 30/59] java script for allpairspingmap.r2py --- jquerygmaps.js | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 jquerygmaps.js diff --git a/jquerygmaps.js b/jquerygmaps.js new file mode 100644 index 0000000..1f07b6f --- /dev/null +++ b/jquerygmaps.js @@ -0,0 +1,91 @@ +// Function to run at page load +$(document).ready(function() { + function initialize_map() { + // Initialize map inside #map div element + var map = new GMap2(document.getElementById('map')); + map.setUIToDefault(); + + // Set up points for Seattle nodes + var markers = []; + $("ul#coords li").each(function(i) { + var latitude = $(this).children(".latitude").text(); + var longitude = $(this).children(".longitude").text(); + if(!latitude && !longitude){ + var point = new GLatLng(85,0); + marker = new GMarker(point); + map.addOverlay(marker); + marker.setImage("map_marker_icon_blue.png"); + map.setCenter(point, 2); + markers[i] = marker; + }else{ + var point = new GLatLng(latitude, longitude); + marker = new GMarker(point); + map.addOverlay(marker); + marker.setImage("map_marker_icon.png"); + map.setCenter(point, 2); + markers[i] = marker; + } + }); + + // Pan to point when clicked + $(markers).each(function(i, marker) { + GEvent.addListener(marker, "click", function(){ + displayPoint(marker, i); + }); + }); + return map; + } + + // Whenever a marker is clicked, pan to it and move/populate the tooltip div + function displayPoint(marker, i) { + map.panTo(marker.getPoint()); + var markerOffset = map.fromLatLngToDivPixel(marker.getPoint()); + + // Get node information from adjacency table + var nodeip = $("#node" + i).children(".nodeip").text(); + var nodelocation = $("#node" + i).children(".locationname").text(); + var nodelat = $("#node" + i).children(".latitude").text(); + var nodelong = $("#node" + i).children(".longitude").text(); + + // Populate #message div with node information + $("#message").empty().append("Node IP: " + nodeip + "
Location: " + nodelocation + "
Lat/Long: " + nodelat + "/" + nodelong + "
Select this node"); + + // If a node bas been selected to base latencies on... + if (typeof(selected_node) != "undefined") { + // Remove any existing lines + if (typeof(line) != "undefined") { + map.removeOverlay(line); + } + + // Draw new line between selected node and clicked node + line = new GPolyline([selected_marker.getLatLng(), marker.getLatLng()]); + map.addOverlay(line); + + // Populate #message div with latency info + var latency = $("td." + selected_node + "_" + i).text(); + $("#message a").before("Latency to " + selected_location + ": " + latency + ((latency != 'N/A') ? " s" : "") + "
"); + } + + // Function to select node as latency hub on click + $("#message").children("a").click(function() { + if (typeof(selected_marker) != "undefined") { + selected_marker.setImage("map_marker_icon.png"); + } + selected_marker = marker; + selected_node = i; + selected_location = nodelocation.split(",")[0]; + marker.setImage("map_marker_sel_icon.png"); + }); + + // Finally, display the #message div tooltip + $("#message").show().css({ top:markerOffset.y, left:markerOffset.x }); + } + + + var map = initialize_map(); + $("#message").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE)); + var selected_node; + var selected_marker; + var selected_location; + var line; +}); From 20886da806a9acb4e970cc3f3775d5c194098a37 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 3 Sep 2014 14:01:26 -0400 Subject: [PATCH 31/59] Update allpairsping.r2py --- allpairsping.r2py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index 391f1ae..3241319 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -17,10 +17,9 @@ def probe_neighbors_forever(): if neighborip == getmyip(): #do nothing continue - else: - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) - sleep(0.5) + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) + sleep(0.5) #sleep for 10 sec and start from while loop again sleep(10) @@ -77,7 +76,6 @@ def handle_http_request(srcip,srcport,connobj): # is an empty string. while '\n\n' not in new_data: # Receive in chunks to avoid reading too much data - log("inside while of http_handle_request") data = connobj.recv(4096) new_data = data.replace('\r\n', '\n') total_data += new_data @@ -87,7 +85,6 @@ def handle_http_request(srcip,srcport,connobj): # 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. - log("is it coming here") 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. @@ -123,7 +120,7 @@ def handle_message_forever(): got_message(srcip, srcport, mess) except SocketWouldBlockError: sleep(0.1) - continue + def handle_connection_forever(): while True: @@ -155,7 +152,6 @@ if callfunc == 'initialize': raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") ip = getmyip() - log(ip) if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) From b22f82053e9347da517622a393c9f4805e8df31a Mon Sep 17 00:00:00 2001 From: us341 Date: Thu, 4 Sep 2014 18:38:20 -0400 Subject: [PATCH 32/59] Update samplesecurity.r2py --- samplesecurity.r2py | 94 +++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/samplesecurity.r2py b/samplesecurity.r2py index 930992e..d52fa19 100644 --- a/samplesecurity.r2py +++ b/samplesecurity.r2py @@ -1,33 +1,17 @@ """ -This security layer interposes on a textfile and gives it read, write, or append access. -A user can only read, write, or append to that file when that specific mode is enabled for that file. Multiple files can be be simultaneously opened and have different modes. +This security layer interposes size restrictions on a textfile. +The security layer comes into play when a user tries to write data on a text file. There are three cases here: -Read-only: You may read the contents of a file, but not write or append. -If you attempt to read when read mode is disabled, a ValueError is raised. +- If data on file goes beyond the permitted file size, then extra data would be truncated and remaining would be written on file +- If data to be written is less than the size specified, then "0"s would be written till file is of specified size +- If someone tries to write at the place of specified size, an error would be raised. For example if the permitted file size is 10 and someone tries to write on file with offset 10 or larger then it will raise an error -Write-only: You may overwrite the contents of a file, but not append to the file. -If you attempt to do so, the file should be overwritten to the length of the file, and then writing stops. -Append-only: You may append data to the end of the file, but not overwrite -anything that is already written. If a write starts before the end of the -file, but continues afterward, only the data after the current end of -file should be written. - -More than one mode may be enabled at once, e.g. Write and Append allows you to overwrite existing file data and append data to the end of the file. - -writeat must return a ValueError if and only if both write and append are -blocked. readat must return a value error if and only if read is blocked. For efficiency purposes, you *MUST NOT* call readat inside of writeat. It is fine to call readat during file open if desired. -Extra credit (?): remember permissions for files after they are closed and -reopened. This would include situations where your security layer is itself -closed and reopened (for example, if the system restarts). You can assume -that all reads must go through your security layer and so you can add an -additional file or modify the file format. - Note: This security layer uses encasementlib.r2py, restrictions.default, repy.py and Python Also you need to give it an application to run. @@ -49,40 +33,76 @@ class SecureFile(): def __init__(self,file): # globals mycontext['debug'] = False - mycontext['read'] = False - mycontext['write'] = False - mycontext['append'] = False mycontext['size'] = 0 + mycontext['filesizesetflag'] = False # local (per object) reference to the underlying file self.file = file - def setread(self,enabled): - mycontext['read'] = enabled + def setmaxfilesize(self,size): - def setwrite(self,enabled): - mycontext['write'] = enabled + #raise value error if specified size is negative + if size<0: + raise ValueError - def setmaxfilesize(self,size): + #truncate if file size is already more than specifies size. + data = self.file.readat(None,0) + if len(data)>size: + self.close() + removefile("look.txt") + file = self.openfile("look.txt",True) + self.__init__(file) + extra_size = len(data) - size + data = data[0:-extra_size] + self.file.writeat(data,0) mycontext['size'] = size + mycontext['filesizesetflag'] = True def writeat(self,data,offset): - datalen = len(data) - size_after_data = datalen + offset - if size_after_data != mycontext['size']: - raise ValueError - else: + # check if setmaxfilesize() has been called before or not. Will act upon file size actions only if the fla for setmaxfilesize is set. + if mycontext['filesizesetflag'] != True: self.file.writeat(data,offset) + else: + datalen = len(data) + size_after_data = datalen + offset + size_diff = abs(size_after_data - mycontext['size']) + + #raise error if user try to write beyond permitted file size + if offset >= mycontext['size']: + raise ValueError + + #truncate data if its starting position is within size but data goes beyond permitted file size + elif size_after_data > mycontext['size']: + data = data [0:-size_diff] + self.file.writeat(data,offset) + + #fill out the remaining places with zeros to make file of required size + elif size_after_data < mycontext['size']: + self.file.writeat(data,offset) + while size_after_data < mycontext['size']: + self.file.writeat("0",size_after_data) + size_after_data = size_after_data+1 + + def readat(self,bytes,offset): + return self.file.readat(bytes,offset) + + def openfile(self,filename,create): + file = openfile(filename,create) + return file + + + def removefile(filename): + removefile(filename) def close(self): return self.file.close() sec_file_def = {"obj-type":SecureFile, "name":"SecureFile", - "setread":{TYPE:FUNC,ARGS:[bool],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setread}, - "setwrite":{TYPE:FUNC,ARGS:[bool],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setwrite}, - "setappend":{TYPE:FUNC,ARGS:[bool],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setappend}, "setmaxfilesize":{TYPE:FUNC,ARGS:[int],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setmaxfilesize}, + "removefile":{TYPE:FUNC,ARGS:(str),EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.removefile}, + "openfile":{TYPE:FUNC,ARGS:(str,bool),EXCP:Exception,RETURN:(type(file)),TARGET:SecureFile.openfile}, "writeat":{TYPE:FUNC,ARGS:(str,(int,long)),EXCP:Exception,RETURN:(int,type(None)),TARGET:SecureFile.writeat}, + "readat":{TYPE:FUNC,ARGS:((int,long,type(None)),(int,long)),EXCP:Exception,RETURN:str,TARGET:SecureFile.readat}, "close":{TYPE:FUNC,ARGS:None,EXCP:None,RETURN:(bool,type(None)),TARGET:SecureFile.close} } From cbfd80645c92a21644006e896a5feb9b02377afc Mon Sep 17 00:00:00 2001 From: us341 Date: Thu, 4 Sep 2014 18:38:47 -0400 Subject: [PATCH 33/59] Update samplesecuritytest.r2py --- samplesecuritytest.r2py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/samplesecuritytest.r2py b/samplesecuritytest.r2py index 5de9ff1..8c75489 100644 --- a/samplesecuritytest.r2py +++ b/samplesecuritytest.r2py @@ -2,12 +2,27 @@ if "look.txt" in listfiles(): removefile("look.txt") myfile=openfile("look.txt",True) #Open a file +myfile.writeat("abc",0) +data = myfile.readat(None,0) +log("data on file after first write should be test : " + data + "\n") -#set maximum file size allowed -myfile.setmaxfilesize(10) +#set maximum file size allowed to 10 +myfile.setmaxfilesize(2) +data = myfile.readat(None,0) +log("data on file should be ab : " + data + "\n") -#the following writeat should give error as data size is greater than allowed max size -myfile.writeat("abcdegsrtfcdy",0) +# this should write "test" to file and fill zero till file size +myfile.writeat("t",0) +data = myfile.readat(None,0) +log("data on file should be t0: " + data + "\n") + + +#the following writeat should write data till file size is 2 and truncate the remaining data because data size is greater than allowed max size +myfile.writeat("abcdnvnlvfjdkgjfdlkj",1) +data = myfile.readat(None,0) +log("data on file now should be ta : " + data + "\n") + +#if we set the offset to 10 then it should raise error. User can try that too #Close the file -myfile.close() \ No newline at end of file +myfile.close() From 08c5ead88864a436b1fe3d809cd5ee35520a6825 Mon Sep 17 00:00:00 2001 From: us341 Date: Thu, 4 Sep 2014 19:40:51 -0400 Subject: [PATCH 34/59] Update samplesecuritytest.r2py --- samplesecuritytest.r2py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samplesecuritytest.r2py b/samplesecuritytest.r2py index 8c75489..3256784 100644 --- a/samplesecuritytest.r2py +++ b/samplesecuritytest.r2py @@ -4,7 +4,7 @@ myfile=openfile("look.txt",True) #Open a file myfile.writeat("abc",0) data = myfile.readat(None,0) -log("data on file after first write should be test : " + data + "\n") +log("data on file after first write should be abc : " + data + "\n") #set maximum file size allowed to 10 myfile.setmaxfilesize(2) From b26f8bbce590173adb270647de30a1e91e270c97 Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:18:46 -0400 Subject: [PATCH 35/59] Delete samplesecurity.r2py --- samplesecurity.r2py | 115 -------------------------------------------- 1 file changed, 115 deletions(-) delete mode 100644 samplesecurity.r2py diff --git a/samplesecurity.r2py b/samplesecurity.r2py deleted file mode 100644 index d52fa19..0000000 --- a/samplesecurity.r2py +++ /dev/null @@ -1,115 +0,0 @@ -""" -This security layer interposes size restrictions on a textfile. -The security layer comes into play when a user tries to write data on a text file. There are three cases here: - -- If data on file goes beyond the permitted file size, then extra data would be truncated and remaining would be written on file -- If data to be written is less than the size specified, then "0"s would be written till file is of specified size -- If someone tries to write at the place of specified size, an error would be raised. For example if the permitted file size is 10 and someone tries to write on file with offset 10 or larger then it will raise an error - - - -For efficiency purposes, you *MUST NOT* call readat inside of writeat. It -is fine to call readat during file open if desired. - - -Note: - This security layer uses encasementlib.r2py, restrictions.default, repy.py and Python - Also you need to give it an application to run. - This security layer never runs explicitly but instead interposes functions - from above layers. - - """ - - -TYPE="type" -ARGS="args" -RETURN="return" -EXCP="exceptions" -TARGET="target" -FUNC="func" -OBJC="objc" - -class SecureFile(): - def __init__(self,file): - # globals - mycontext['debug'] = False - mycontext['size'] = 0 - mycontext['filesizesetflag'] = False - # local (per object) reference to the underlying file - self.file = file - - def setmaxfilesize(self,size): - - #raise value error if specified size is negative - if size<0: - raise ValueError - - #truncate if file size is already more than specifies size. - data = self.file.readat(None,0) - if len(data)>size: - self.close() - removefile("look.txt") - file = self.openfile("look.txt",True) - self.__init__(file) - extra_size = len(data) - size - data = data[0:-extra_size] - self.file.writeat(data,0) - mycontext['size'] = size - mycontext['filesizesetflag'] = True - - def writeat(self,data,offset): - # check if setmaxfilesize() has been called before or not. Will act upon file size actions only if the fla for setmaxfilesize is set. - if mycontext['filesizesetflag'] != True: - self.file.writeat(data,offset) - else: - datalen = len(data) - size_after_data = datalen + offset - size_diff = abs(size_after_data - mycontext['size']) - - #raise error if user try to write beyond permitted file size - if offset >= mycontext['size']: - raise ValueError - - #truncate data if its starting position is within size but data goes beyond permitted file size - elif size_after_data > mycontext['size']: - data = data [0:-size_diff] - self.file.writeat(data,offset) - - #fill out the remaining places with zeros to make file of required size - elif size_after_data < mycontext['size']: - self.file.writeat(data,offset) - while size_after_data < mycontext['size']: - self.file.writeat("0",size_after_data) - size_after_data = size_after_data+1 - - def readat(self,bytes,offset): - return self.file.readat(bytes,offset) - - def openfile(self,filename,create): - file = openfile(filename,create) - return file - - - def removefile(filename): - removefile(filename) - - def close(self): - return self.file.close() - -sec_file_def = {"obj-type":SecureFile, - "name":"SecureFile", - "setmaxfilesize":{TYPE:FUNC,ARGS:[int],EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.setmaxfilesize}, - "removefile":{TYPE:FUNC,ARGS:(str),EXCP:Exception,RETURN:(type(None)),TARGET:SecureFile.removefile}, - "openfile":{TYPE:FUNC,ARGS:(str,bool),EXCP:Exception,RETURN:(type(file)),TARGET:SecureFile.openfile}, - "writeat":{TYPE:FUNC,ARGS:(str,(int,long)),EXCP:Exception,RETURN:(int,type(None)),TARGET:SecureFile.writeat}, - "readat":{TYPE:FUNC,ARGS:((int,long,type(None)),(int,long)),EXCP:Exception,RETURN:str,TARGET:SecureFile.readat}, - "close":{TYPE:FUNC,ARGS:None,EXCP:None,RETURN:(bool,type(None)),TARGET:SecureFile.close} - } - -def secure_openfile(filename, create): - f = openfile(filename,create) - return SecureFile(f) - -CHILD_CONTEXT_DEF["openfile"] = {TYPE:OBJC,ARGS:(str,bool),EXCP:Exception,RETURN:sec_file_def,TARGET:secure_openfile} - -secure_dispatch_module() From f79599b37129dbac14e5453752286d206c9b81fe Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:20:24 -0400 Subject: [PATCH 36/59] Delete samplesecuritytest.r2py --- samplesecuritytest.r2py | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 samplesecuritytest.r2py diff --git a/samplesecuritytest.r2py b/samplesecuritytest.r2py deleted file mode 100644 index 3256784..0000000 --- a/samplesecuritytest.r2py +++ /dev/null @@ -1,28 +0,0 @@ -if "look.txt" in listfiles(): - removefile("look.txt") -myfile=openfile("look.txt",True) #Open a file - -myfile.writeat("abc",0) -data = myfile.readat(None,0) -log("data on file after first write should be abc : " + data + "\n") - -#set maximum file size allowed to 10 -myfile.setmaxfilesize(2) -data = myfile.readat(None,0) -log("data on file should be ab : " + data + "\n") - -# this should write "test" to file and fill zero till file size -myfile.writeat("t",0) -data = myfile.readat(None,0) -log("data on file should be t0: " + data + "\n") - - -#the following writeat should write data till file size is 2 and truncate the remaining data because data size is greater than allowed max size -myfile.writeat("abcdnvnlvfjdkgjfdlkj",1) -data = myfile.readat(None,0) -log("data on file now should be ta : " + data + "\n") - -#if we set the offset to 10 then it should raise error. User can try that too - -#Close the file -myfile.close() From 4740d3c843bac0212ccbd83f98da796ceb817cbf Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:20:49 -0400 Subject: [PATCH 37/59] Delete allpairsping.r2py --- example/allpairsping.r2py | 200 -------------------------------------- 1 file changed, 200 deletions(-) delete mode 100644 example/allpairsping.r2py diff --git a/example/allpairsping.r2py b/example/allpairsping.r2py deleted file mode 100644 index 2716935..0000000 --- a/example/allpairsping.r2py +++ /dev/null @@ -1,200 +0,0 @@ -""" - - Urvashi Soni - - - gives the connectivity graph and latency information of all nodes in a group. - -""" - - -# send a probe message to each neighbor -def probe_neighbors(): - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - if neighborip == getmyip(): - #do nothing. local/destination ip and port can't be same in r2py - else: - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) - # sleep in between messages to prevent us from getting a huge number of - # responses all at once... - sleep(.5) - - # Call me again in 10 seconds - while True: - try: - sleep(10) - createthread(probe_neighbors) - return - except ResourceExhaustedError, e: - # there are too many events scheduled, I should wait and try again - sleep(.5) - continue - - - - - -# Handle an incoming message -def got_message(srcip,srcport,mess): - if mess == 'ping': - sendmessage(srcip,srcport,'pong',getmyip(), 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 = ""+rowip+"" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring = retstring + "Unknown" - - retstring = retstring + "" - return retstring - - - -# Generates a HTML page that represents the current status of the program -def generate_status_page(): - log ("inside generate status page") - webpage = "Latency Information

Latency information from "+getmyip()+'

' - webpage = webpage + "" - for nodeip in mycontext['neighborlist']: - if nodeip in mycontext['row']: - webpage = webpage + mycontext['row'][nodeip]+'\n' - else: - webpage = webpage + '\n' - - # now the footer... - webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' - - return webpage - - - -# Displays a web page with the latency information -def handle_http_request(srcip,srcport,connobj): - # Get the header - try: - total_data = '' - # We use a separate string to store the received data so that we don't have to - # re-check the beginning parts of the string multiple times - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - # This is because Windows uses \r\n, Linux/Macs use \n. - # By doing this, we avoid having to program special cases for - # the different endline formats. - new_data = data.replace('\r\n', '\n') - total_data += new_data - - # keep everything after the first '\n\n' intact, just incase there is - # more content after the header that we may need - # Potential Bug?: We ignore the overflow data - header, overflow = total_data.split('\n\n', 1) - - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - - # 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 - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - -def handle_message(): - while True: - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - continue - - -if callfunc == 'initialize': - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - except FileNotFoundError, e4: - raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - - ip = getmyip() - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) - createthread(handle_message) - - - - probe_neighbors() - - # we want to register a function to show a status webpage (TCP port) - pageport = int(callargs[0]) - - #listen for connection and call handle_http_request once a connection is got - connobj = listenforconnection(ip,pageport) - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - - From d7568e99cd4989b5cfd45f6e207da6e6780c60cd Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:21:08 -0400 Subject: [PATCH 38/59] Delete allpairsping.r2py --- latest/allpairsping.r2py | 198 --------------------------------------- 1 file changed, 198 deletions(-) delete mode 100644 latest/allpairsping.r2py diff --git a/latest/allpairsping.r2py b/latest/allpairsping.r2py deleted file mode 100644 index 3cc59ad..0000000 --- a/latest/allpairsping.r2py +++ /dev/null @@ -1,198 +0,0 @@ -# send a probe message to each neighbor -def probe_neighbors(): - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip, mycontext['port'],'share'+encode_row(getmyip(), mycontext["neighborlist"], mycontext['latency'].copy()), getmyip(), mycontext['port']) - # sleep in between messages to prevent us from getting a huge number of - # responses all at once... - sleep(.5) - - # Call me again in 10 seconds - while True: - try: - sleep(10) - createthread(probe_neighbors) - return - except ResourceExhaustedError, e: - # there are too many events scheduled, I should wait and try again - sleep(.5) - continue - - - - - -# Handle an incoming message -def got_message(srcip,srcport,mess): - if mess == 'ping': - sendmessage(srcip,srcport,'pong',getmyip(), 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 = ""+rowip+"" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring = retstring + "Unknown" - - retstring = retstring + "" - return retstring - - - -# Generates a HTML page that represents the current status of the program -def generate_status_page(): - log ("inside generate status page") - webpage = "Latency Information

Latency information from "+getmyip()+'

' - - webpage = webpage + "" - log (mycontext['row']) - for nodeip in mycontext['neighborlist']: - if nodeip in mycontext['row']: - log ("outside no data reported") - webpage = webpage + mycontext['row'][nodeip]+'\n' - else: - webpage = webpage + '\n' - - # now the footer... - webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' - - return webpage - - - -# Displays a web page with the latency information -def handle_http_request(srcip,srcport,connobj): - # Get the header - - try: - log ("inside http request") - total_data = '' - # We use a separate string to store the received data so that we don't have to - # re-check the beginning parts of the string multiple times - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - log ("recieved data") - # This is because Windows uses \r\n, Linux/Macs use \n. - # By doing this, we avoid having to program special cases for - # the different endline formats. - new_data = data.replace('\r\n', '\n') - total_data += new_data - - # keep everything after the first '\n\n' intact, just incase there is - # more content after the header that we may need - # Potential Bug?: We ignore the overflow data - header, overflow = total_data.split('\n\n', 1) - - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - - # 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 - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - -def handle_message(): - while True: - try: - log ("\n waiting for new message") - srcip, srcport, mess = udpserversocket.getmessage() - log ("\n ***********got a new message*******") - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - continue - - -if callfunc == 'initialize': - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - log ("file is opened correctly") - except FileNotFoundError, e4: - raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - - ip = getmyip() - log (ip) - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) - createthread(handle_message) - - - - probe_neighbors() - - # we want to register a function to show a status webpage (TCP port) - pageport = int(callargs[0]) - - #listen for connection and call handle_http_request once a connection is got - connobj = listenforconnection(ip,pageport) - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - - From 4065c2758aaa3a1d1927e0045fa0636c4080bdd9 Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:22:12 -0400 Subject: [PATCH 39/59] Delete allpairping_new.r2py --- allpairping_new.r2py | 181 ------------------------------------------- 1 file changed, 181 deletions(-) delete mode 100644 allpairping_new.r2py diff --git a/allpairping_new.r2py b/allpairping_new.r2py deleted file mode 100644 index a11614e..0000000 --- a/allpairping_new.r2py +++ /dev/null @@ -1,181 +0,0 @@ -""" - - Urvashi Soni - - - 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 == getmyip(): - #do nothing - continue - else: - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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',getmyip(), 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 = ""+rowip+"" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring = retstring + "Unknown" - - retstring = retstring + "" - return retstring - - - -# Generates a HTML page that represents the current status of the program -def generate_status_page(): - webpage = "Latency Information

Latency information from "+getmyip()+'

' - webpage = webpage + "" - for nodeip in mycontext['neighborlist']: - if nodeip in mycontext['row']: - webpage = webpage + mycontext['row'][nodeip]+'\n' - else: - webpage = webpage + '\n' - - # now the footer... - webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' - return webpage - - - -# Displays a web page with the latency information -def handle_http_request(srcip,srcport,connobj): - # Get the header - total_data = '' - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - log("inside while of http_handle_request") - try: - data = connobj.recv(4096) - log(data) - except SocketWouldBlockError, e: - log(e) - return - new_data = data.replace('\r\n', '\n') - total_data += new_data - 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. - log("is it coming here") - 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 - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - -def handle_message_forever(): - while True: - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - continue - -def handle_connection_forever(): - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - - -if callfunc == 'initialize': - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - except FileNotFoundError, e: - raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - - ip = getmyip() - log(ip) - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) - createthread(handle_connection_forever) - - - From 1d45182b435eaa5cada907e63719a104f938c7e3 Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:22:25 -0400 Subject: [PATCH 40/59] Delete allpairspingmap.mix --- allpairspingmap.mix | 486 -------------------------------------------- 1 file changed, 486 deletions(-) delete mode 100644 allpairspingmap.mix diff --git a/allpairspingmap.mix b/allpairspingmap.mix deleted file mode 100644 index c7ec3cd..0000000 --- a/allpairspingmap.mix +++ /dev/null @@ -1,486 +0,0 @@ -''' - - allpairspingmap.r2py - - - This program gives a visual representation of the vessels that a user has - acquired. It includes a map that contains markers on where the vessels are - reported to be, according to the geoip client. - - - A file containing the ip addresses of all the vessels to contact must be - uploaded. This file should be named 'neighboriplist.txt'. Each line should - contain one vessel. This file can be prepared within seash by issuing the - following command within a group: - show ip to neighboriplist.txt - - Additionally, the following files (which are provided) need to be uploaded to - the vessels: - jquerygmaps.js - style.css - map_marker_icon.png - - Once this is set up, you need to pass your Clearinghouse port to the program - as an argument: - username@group> run allpairspingmap.r2py [port number] - -''' - -dy_import_module_symbols('geoip_client.r2py') - - -class InvalidRequestError(Exception): - ''' The user made a request for a nonexistent file. ''' - - -# These are the paths that the web server will serve files for. -# This is to prevent clients from seeing anything else that we might not want -# them to be able to see. -# -# '': -# Index file. We generate a webpage representing the current program status -# -# style.css: -# Stylesheet that controls how the webpage is formatted. Without this, -# the map will not render correctly. -# -# jquerygmaps.js: -# Contains code that interfaces against google's MapV2 API. -# -# map_marker_icon.png: -# This image is used as a marker for where the vessels are, on the map. - -mycontext['RECOGNIZED_FILES'] = ( - '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png') - - -# When responding to HTTP requests, we need to include a MIME type, identifying -# the type of file that we are serving to the HTTP client. This dictionary -# maps a file extension to its common MIME type. -mycontext['MIME_TYPES'] = { - '.js': 'text/javascript', - '.css': 'text/css', - '.png': 'image/png' - } - - - -def probe_neighbors_forever(): - ''' - - Send a probe message to each neighbor - - - port: The clearinghouse port assigned to the current user. - - - Starts the ping loop to calculate the latency between the local node - and neighboring nodes. We also send our latency data to each node. - - - None - - - None - ''' - while True: - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - if neighborip == getmyip(): - #do nothing - continue - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - log("sent message") - sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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): - ''' - - Handle an incoming message from a neighboring node. - - - See documentation for recvmess(). - - - If we receive a ping message, we respond with a pong message. - If we receive a pong message, we take the difference between when we sent - this neighbor a ping message and record that as the latency. - If we receive a share message, we record the neighbor's neighbor row - information. - - - None - - - None - ''' - - - if mess == 'ping': - sendmessage(srcip,srcport,'pong',getmyip(), 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(neighborlist, latencylist): - ''' - - Prepares the local node's latency information into a format that is - recognizable by the other nodes. - - - neighborlist: The IP addresses of all our neighbors. - latencylist: The list of latencies associated with the neighbors. - - - None - - - None - - - A string representing a HTML row containing the latency information - between this node and the other neighbor nodes. - ''' - - retstring = "" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring += ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring += "Unknown" - return retstring - - -def generate_node_list(): - """ - - Generates an HTMl string of an unsorted list of nodes. - - - None. - - - None. - - - None. - - - HTML string of unsorted list of nodes. - """ - log("\ninside generate_node_list\n") - # Is there a specific reason why we sort these keys? I'm leaving these - # intact since the original version sorted them. - nodeiplist = mycontext['neighborlist'] - nodeiplist.sort() - - nodelist_str = '
    ' - for nodeip in nodeiplist: - # Print node list element - nodelist_str += ('
  • ' + - str(nodeip) + '') - - if nodeip in mycontext['locationdata']: - nodelocdict = mycontext['locationdata'][nodeip] - if nodelocdict is not None: - nodelist_str += ('' + str(nodelocdict['longitude']) + - '' + str(nodelocdict['latitude']) + - '' + geoip_location_str(nodelocdict) + '') - # We didn't perform the lookup yet. This is used to tell the client to - # refresh the page. - else: - nodelist_str += "" - nodelist_str += '
  • ' - nodelist_str += '
' - return nodelist_str - - - - - -def generate_status_page(): - ''' - - Generates a HTML page that represents the current status of the program - - - None - - - The webpage returned may cause a client's browser to make additional - requests to the current program, or other machines. - - - None - - - A string representing a HTML webpage containing the current status of the - program. - ''' - log("\ninside generate_status_page\n") - webpage = "Latency Information" - - webpage += '' - webpage += '' - # Include our script/stylesheet for the webpage - webpage += '' - webpage += '' - - # Begin displaying body content; Lets start with the map. - webpage += "
" - - # Display the latency information as a table - webpage += "

Latency information from "+getmyip()+'

' - - # Create a column in the table for each vessel - webpage += "" - - # Create a row in the table for each vessel - for nodeip in mycontext['neighborlist']: - # Show ip and location data, if present - webpage += '' - - # Add latency information - if nodeip in mycontext['row']: - webpage += mycontext['row'][nodeip] - else: - webpage += '' - webpage += '\n' - - webpage += '
"+ "".join(mycontext['neighborlist'])+"
' +nodeip+'
\n' - - # Was there a geoip lookup yet? - if nodeip in mycontext['locationdata']: - # Did the geoip lookup succeed? - if mycontext['locationdata'][nodeip] is not None: - nodelocation = mycontext['locationdata'][nodeip] - webpage += nodelocation['city'] + ', ' + nodelocation['country_code'] - # The lookup failed - else: - webpage += "No location data available" - - # We haven't done a geoip lookup yet. Let the user know. - else: - webpage += "Location data not yet retrieved" - webpage += '
No Data Reported
' - - # We need this for the map data to work - webpage += generate_node_list() - log ("dsbvkskvnsdlnvls") - # now the footer... - webpage += '' - - return webpage - - -def handle_http_request(srcip,srcport,connobj): - # Get the header - total_data = '' - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - log("inside while of http_handle_request") - data = connobj.recv(4096) - new_data = data.replace('\r\n', '\n') - total_data += new_data - 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. - log("splitting1") - 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. - log("splitting") - requested_file = everything_after_httpaction.split(" HTTP/")[0] - - # Get rid of the leading '/' because its useless to us - requested_file = requested_file.lstrip('/') - - # Generate the data to send back. - try: - # We default to this content type. - content_type = 'text/html' - # Don't respond with anything if they have something in the request path. - - if requested_file not in mycontext['RECOGNIZED_FILES']: - raise InvalidRequestError("Unrecognized file:" + requested_file) - - # Generate the index page if the request field is empty. - elif not requested_file: - - contents = generate_status_page() - - # This is a file that we recognize. Send its contents to the client. - else: - # PNGs are binary files. Plaintext files still work when read in - # binary mode. - contents = openfile(requested_file, True).readat(None,0) - - # Figure out the MIME type to send to the client - for extension in mycontext['MIME_TYPES']: - if requested_file.endswith(extension): - content_type = mycontext['MIME_TYPES'][extension] - break - else: - content_type = 'text/plain' - - # combine everything into one unit for sending - data = 'HTTP/1.1 200 OK\nContent-Type: '+content_type+'\nContent-Length: '+str(len(contents))+'\nServer: Seattle Testbed\n\n'+contents - - except InvalidRequestError: - data = 'HTTP/1.1 404 Not Found\n\n' - - - # send the response - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except Exception, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - log ("why its happening") - return - raise - - - -def lookup_geoip_info(): - ''' - - Acquires the geoip information for all the vessels specified in the - neighbor ip table. - - - None - - - The geoip data recorded will be stored in mycontext['locationdata'][neighborip]. - If the lookup was successful, then the looked up data will be stored. - Otherwise, we put - - - None - - - None - ''' - - geoip_init_client() - for neighbor in mycontext['neighborlist']: - try: - locationdict = geoip_record_by_addr(neighbor) - if locationdict is not None: - # Sometimes we don't get a city name. - if 'city' not in locationdict: - locationdict['city'] = "Unknown" - mycontext['locationdata'][neighbor] = locationdict - - # The lookup failed - else: - mycontext['locationdata'][neighbor] = None - - except Exception, e: - if not "Unable to contact the geoip server" in str(e): - raise - # We use this to indicate that no location data is available. - mycontext['locationdata'][neighbor] = None - -def handle_message_forever(): - while True: - try: - srcip, srcport, mess = udpserversocket.getmessage() - log("got a new message\n") - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - continue - -def handle_connection_forever(): - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - log("got a new connection") - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - -if callfunc == 'initialize': - - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - log ("file is opened correctly") - except RepyArgumentError, e1: - log ("exception in reading from file"+ str(e1)) - except FileInUseError, e2: - log ("exception in reading from file"+ str(e2)) - except ResourceExhaustedError, e3: - log ("exception in reading from file"+ str(e3)) - except FileNotFoundError, e4: - log ("exception in reading from file"+ str(e4)) - - # Contains the dictionaries for node location information. - mycontext['locationdata'] = {} - - ip = getmyip() - log (ip) - log ("isss") - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - log (pingport ) - mycontext['port'] = pingport - mycontext['ip'] = ip - mycontext['port'] = pingport - - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) - createthread(handle_connection_forever) - - - # Getting geoip data takes a while, in the meanwhile we allow the user to - # see a status webpage and display a notice there. - log ("*****************check if it ever gets here****************") - lookup_geoip_info() - From 1c3541392a68446e560de0450950be6e72eaddb1 Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:24:08 -0400 Subject: [PATCH 41/59] Create allpairsping.r2py --- apps/allpairsping/allpairsping.r2py | 172 ++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 apps/allpairsping/allpairsping.r2py diff --git a/apps/allpairsping/allpairsping.r2py b/apps/allpairsping/allpairsping.r2py new file mode 100644 index 0000000..3241319 --- /dev/null +++ b/apps/allpairsping/allpairsping.r2py @@ -0,0 +1,172 @@ +""" + + Urvashi Soni + + + 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 == getmyip(): + #do nothing + continue + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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',getmyip(), 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 = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + webpage = "Latency Information

Latency information from "+getmyip()+'

' + webpage = webpage + "" + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + return webpage + + + +# Displays a web page with the latency information +def handle_http_request(srcip,srcport,connobj): + # Get the header + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + new_data = data.replace('\r\n', '\n') + total_data += new_data + 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 + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + +def handle_message_forever(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + + +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + + +if callfunc == 'initialize': + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + except FileNotFoundError, e: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) + createthread(handle_connection_forever) + + + From 560908c7be4dbcf5420de005d05190d67433a69a Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:26:13 -0400 Subject: [PATCH 42/59] Delete allpairsping.r2py --- allpairsping.r2py | 172 ---------------------------------------------- 1 file changed, 172 deletions(-) delete mode 100644 allpairsping.r2py diff --git a/allpairsping.r2py b/allpairsping.r2py deleted file mode 100644 index 3241319..0000000 --- a/allpairsping.r2py +++ /dev/null @@ -1,172 +0,0 @@ -""" - - Urvashi Soni - - - 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 == getmyip(): - #do nothing - continue - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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',getmyip(), 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 = ""+rowip+"" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring = retstring + "Unknown" - - retstring = retstring + "" - return retstring - - - -# Generates a HTML page that represents the current status of the program -def generate_status_page(): - webpage = "Latency Information

Latency information from "+getmyip()+'

' - webpage = webpage + "" - for nodeip in mycontext['neighborlist']: - if nodeip in mycontext['row']: - webpage = webpage + mycontext['row'][nodeip]+'\n' - else: - webpage = webpage + '\n' - - # now the footer... - webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' - return webpage - - - -# Displays a web page with the latency information -def handle_http_request(srcip,srcport,connobj): - # Get the header - total_data = '' - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - new_data = data.replace('\r\n', '\n') - total_data += new_data - 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 - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - -def handle_message_forever(): - while True: - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - - -def handle_connection_forever(): - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - - -if callfunc == 'initialize': - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - except FileNotFoundError, e: - raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - - ip = getmyip() - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) - createthread(handle_connection_forever) - - - From f5c248a796e786097ee993f3b40fc5f597e0cf7b Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:26:30 -0400 Subject: [PATCH 43/59] Delete allpairspingmap.r2py --- allpairspingmap.r2py | 467 ------------------------------------------- 1 file changed, 467 deletions(-) delete mode 100644 allpairspingmap.r2py diff --git a/allpairspingmap.r2py b/allpairspingmap.r2py deleted file mode 100644 index 48247f7..0000000 --- a/allpairspingmap.r2py +++ /dev/null @@ -1,467 +0,0 @@ -''' - - allpairspingmap.r2py - - - This program gives a visual representation of the vessels that a user has - acquired. It includes a map that contains markers on where the vessels are - reported to be, according to the geoip client. - - - A file containing the ip addresses of all the vessels to contact must be - uploaded. This file should be named 'neighboriplist.txt'. Each line should - contain one vessel. This file can be prepared within seash by issuing the - following command within a group: - show ip to neighboriplist.txt - - Additionally, the following files (which are provided) need to be uploaded to - the vessels: - jquerygmaps.js - style.css - map_marker_icon.png - map_marker_icon_blue.png - - Once this is set up, you need to pass your Clearinghouse port to the program - as an argument: - username@group> run allpairspingmap.r2py [port number] - -''' - -dy_import_module_symbols('geoip_client.r2py') - - -class InvalidRequestError(Exception): - ''' The user made a request for a nonexistent file. ''' - - -# These are the paths that the web server will serve files for. -# This is to prevent clients from seeing anything else that we might not want -# them to be able to see. -# -# '': -# Index file. We generate a webpage representing the current program status -# -# style.css: -# Stylesheet that controls how the webpage is formatted. Without this, -# the map will not render correctly. -# -# jquerygmaps.js: -# Contains code that interfaces against google's MapV2 API. -# -# map_marker_icon.png: -# This image is used as a marker for where the vessels are, on the map. - -mycontext['RECOGNIZED_FILES'] = ( - '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png', 'map_marker_icon_blue.png') - - -# When responding to HTTP requests, we need to include a MIME type, identifying -# the type of file that we are serving to the HTTP client. This dictionary -# maps a file extension to its common MIME type. -mycontext['MIME_TYPES'] = { - '.js': 'text/javascript', - '.css': 'text/css', - '.png': 'image/png' - } - - - -def probe_neighbors_forever(): - ''' - - Send a probe message to each neighbor - - - port: The clearinghouse port assigned to the current user. - - - Starts the ping loop to calculate the latency between the local node - and neighboring nodes. We also send our latency data to each node. - - - None - - - None - ''' - while True: - for neighborip in mycontext["neighborlist"]: - mycontext['sendtime'][neighborip] = getruntime() - if neighborip == mycontext['ip']: - #skip if local and destination ip addresses and port match because we can't send message if local/dest ip and port match in repy v2 - continue - sendmessage(neighborip, mycontext['port'], 'ping',mycontext['ip'],mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),mycontext['ip'],mycontext['port']) - sleep(0.5) - #sleep for 10 sec and start from while loop again to avoid so many responses at the same time - sleep(10) - - - - -# Handle an incoming message -def got_message(srcip,srcport,mess): - ''' - - Handle an incoming message from a neighboring node. - - - See documentation for recvmess(). - - - If we receive a ping message, we respond with a pong message. - If we receive a pong message, we take the difference between when we sent - this neighbor a ping message and record that as the latency. - If we receive a share message, we record the neighbor's neighbor row - information. - - - None - - - None - ''' - - - if mess == 'ping': - sendmessage(srcip,srcport,'pong',getmyip(), 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(neighborlist, latencylist): - ''' - - Prepares the local node's latency information into a format that is - recognizable by the other nodes. - - - neighborlist: The IP addresses of all our neighbors. - latencylist: The list of latencies associated with the neighbors. - - - None - - - None - - - A string representing a HTML row containing the latency information - between this node and the other neighbor nodes. - ''' - - retstring = "" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring += ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring += "Unknown" - return retstring - - -def generate_node_list(): - """ - - Generates an HTMl string of an unsorted list of nodes. - - - None. - - - None. - - - None. - - - HTML string of unsorted list of nodes. - """ - # Is there a specific reason why we sort these keys? I'm leaving these - # intact since the original version sorted them. - nodeiplist = mycontext['neighborlist'] - nodeiplist.sort() - - nodelist_str = '
    ' - for nodeip in nodeiplist: - # Print node list element - nodelist_str += ('
  • ' + - str(nodeip) + '') - - if nodeip in mycontext['locationdata']: - nodelocdict = mycontext['locationdata'][nodeip] - if nodelocdict is not None: - nodelist_str += ('' + str(nodelocdict['longitude']) + - '' + str(nodelocdict['latitude']) + - '' + geoip_location_str(nodelocdict) + '') - # We didn't perform the lookup yet. This is used to tell the client to - # refresh the page. - else: - nodelist_str += "" - nodelist_str += '
  • ' - nodelist_str += '
' - return nodelist_str - - - - - -def generate_status_page(): - ''' - - Generates a HTML page that represents the current status of the program - - - None - - - The webpage returned may cause a client's browser to make additional - requests to the current program, or other machines. - - - None - - - A string representing a HTML webpage containing the current status of the - program. - ''' - webpage = "Latency Information" - - webpage += '' - webpage += '' - # Include our script/stylesheet for the webpage - webpage += '' - webpage += '' - - # Begin displaying body content; Lets start with the map. - webpage += "
" - - # Display the latency information as a table - webpage += "

Latency information from "+getmyip()+'

' - - # Create a column in the table for each vessel - webpage += "" - - # Create a row in the table for each vessel - for nodeip in mycontext['neighborlist']: - # Show ip and location data, if present - webpage += '' - - # Add latency information - if nodeip in mycontext['row']: - webpage += mycontext['row'][nodeip] - else: - webpage += '' - webpage += '\n' - - webpage += '
"+ "".join(mycontext['neighborlist'])+"
' +nodeip+'
\n' - - # Was there a geoip lookup yet? - if nodeip in mycontext['locationdata']: - # Did the geoip lookup succeed? - if mycontext['locationdata'][nodeip] is not None: - nodelocation = mycontext['locationdata'][nodeip] - webpage += nodelocation['city'] + ', ' + nodelocation['country_code'] - # The lookup failed - else: - webpage += "No location data available" - - # We haven't done a geoip lookup yet. Let the user know. - else: - webpage += "Location data not yet retrieved" - webpage += '
No Data Reported
' - - # We need this for the map data to work - webpage += generate_node_list() - # now the footer... - webpage += '' - - return webpage - - -def handle_http_request(srcip,srcport,connobj): - # Get the header - total_data = '' - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - new_data = data.replace('\r\n', '\n') - total_data += new_data - 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. - requested_file = everything_after_httpaction.split(" HTTP/")[0] - - # Get rid of the leading '/' because its useless to us - requested_file = requested_file.lstrip('/') - - # Generate the data to send back. - try: - # We default to this content type. - content_type = 'text/html' - # Don't respond with anything if they have something in the request path. - - if requested_file not in mycontext['RECOGNIZED_FILES']: - raise InvalidRequestError("Unrecognized file:" + requested_file) - - # Generate the index page if the request field is empty. - elif not requested_file: - - contents = generate_status_page() - - # This is a file that we recognize. Send its contents to the client. - else: - # PNGs are binary files. Plaintext files still work when read in - # binary mode. - contents = openfile(requested_file, True).readat(None,0) - - # Figure out the MIME type to send to the client - for extension in mycontext['MIME_TYPES']: - if requested_file.endswith(extension): - content_type = mycontext['MIME_TYPES'][extension] - break - else: - content_type = 'text/plain' - - # combine everything into one unit for sending - data = 'HTTP/1.1 200 OK\nContent-Type: '+content_type+'\nContent-Length: '+str(len(contents))+'\nServer: Seattle Testbed\n\n'+contents - - except InvalidRequestError: - data = 'HTTP/1.1 404 Not Found\n\n' - - - # send the response - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except Exception, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - - - -def lookup_geoip_info(): - ''' - - Acquires the geoip information for all the vessels specified in the - neighbor ip table. - - - None - - - The geoip data recorded will be stored in mycontext['locationdata'][neighborip]. - If the lookup was successful, then the looked up data will be stored. - Otherwise, we put - - - None - - - None - ''' - - geoip_init_client() - for neighbor in mycontext['neighborlist']: - try: - locationdict = geoip_record_by_addr(neighbor) - if locationdict is not None: - # Sometimes we don't get a city name. - if 'city' not in locationdict: - locationdict['city'] = "Unknown" - mycontext['locationdata'][neighbor] = locationdict - - # The lookup failed - else: - mycontext['locationdata'][neighbor] = None - - except Exception, e: - if not "Unable to contact the geoip server" in str(e): - raise - # We use this to indicate that no location data is available. - mycontext['locationdata'][neighbor] = None - -def handle_message_forever(): - while True: - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - - -def handle_connection_forever(): - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - - - -if callfunc == 'initialize': - - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - except FileNotFoundError, e: - raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - - # Contains the dictionaries for node location information. - mycontext['locationdata'] = {} - - ip = getmyip() - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - log(mycontext['ip']) - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], 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['ip'],mycontext['port']) - createthread(handle_connection_forever) - - - # Getting geoip data takes a while, in the meanwhile we allow the user to - # see a status webpage and display a notice there. - lookup_geoip_info() - From 620a66c5f28b2eef254abdcfb134872054b77ae2 Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:26:42 -0400 Subject: [PATCH 44/59] Delete jquerygmaps.js --- jquerygmaps.js | 91 -------------------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 jquerygmaps.js diff --git a/jquerygmaps.js b/jquerygmaps.js deleted file mode 100644 index 1f07b6f..0000000 --- a/jquerygmaps.js +++ /dev/null @@ -1,91 +0,0 @@ -// Function to run at page load -$(document).ready(function() { - function initialize_map() { - // Initialize map inside #map div element - var map = new GMap2(document.getElementById('map')); - map.setUIToDefault(); - - // Set up points for Seattle nodes - var markers = []; - $("ul#coords li").each(function(i) { - var latitude = $(this).children(".latitude").text(); - var longitude = $(this).children(".longitude").text(); - if(!latitude && !longitude){ - var point = new GLatLng(85,0); - marker = new GMarker(point); - map.addOverlay(marker); - marker.setImage("map_marker_icon_blue.png"); - map.setCenter(point, 2); - markers[i] = marker; - }else{ - var point = new GLatLng(latitude, longitude); - marker = new GMarker(point); - map.addOverlay(marker); - marker.setImage("map_marker_icon.png"); - map.setCenter(point, 2); - markers[i] = marker; - } - }); - - // Pan to point when clicked - $(markers).each(function(i, marker) { - GEvent.addListener(marker, "click", function(){ - displayPoint(marker, i); - }); - }); - return map; - } - - // Whenever a marker is clicked, pan to it and move/populate the tooltip div - function displayPoint(marker, i) { - map.panTo(marker.getPoint()); - var markerOffset = map.fromLatLngToDivPixel(marker.getPoint()); - - // Get node information from adjacency table - var nodeip = $("#node" + i).children(".nodeip").text(); - var nodelocation = $("#node" + i).children(".locationname").text(); - var nodelat = $("#node" + i).children(".latitude").text(); - var nodelong = $("#node" + i).children(".longitude").text(); - - // Populate #message div with node information - $("#message").empty().append("Node IP: " + nodeip + "
Location: " + nodelocation + "
Lat/Long: " + nodelat + "/" + nodelong + "
Select this node"); - - // If a node bas been selected to base latencies on... - if (typeof(selected_node) != "undefined") { - // Remove any existing lines - if (typeof(line) != "undefined") { - map.removeOverlay(line); - } - - // Draw new line between selected node and clicked node - line = new GPolyline([selected_marker.getLatLng(), marker.getLatLng()]); - map.addOverlay(line); - - // Populate #message div with latency info - var latency = $("td." + selected_node + "_" + i).text(); - $("#message a").before("Latency to " + selected_location + ": " + latency + ((latency != 'N/A') ? " s" : "") + "
"); - } - - // Function to select node as latency hub on click - $("#message").children("a").click(function() { - if (typeof(selected_marker) != "undefined") { - selected_marker.setImage("map_marker_icon.png"); - } - selected_marker = marker; - selected_node = i; - selected_location = nodelocation.split(",")[0]; - marker.setImage("map_marker_sel_icon.png"); - }); - - // Finally, display the #message div tooltip - $("#message").show().css({ top:markerOffset.y, left:markerOffset.x }); - } - - - var map = initialize_map(); - $("#message").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE)); - var selected_node; - var selected_marker; - var selected_location; - var line; -}); From 0aaf98df33eb0cf10f2ea3722efbb7d26ecea9ea Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 8 Sep 2014 10:27:49 -0400 Subject: [PATCH 45/59] Delete allpairsping.r2py --- apps/allpairsping/allpairsping.r2py | 172 ---------------------------- 1 file changed, 172 deletions(-) delete mode 100644 apps/allpairsping/allpairsping.r2py diff --git a/apps/allpairsping/allpairsping.r2py b/apps/allpairsping/allpairsping.r2py deleted file mode 100644 index 3241319..0000000 --- a/apps/allpairsping/allpairsping.r2py +++ /dev/null @@ -1,172 +0,0 @@ -""" - - Urvashi Soni - - - 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 == getmyip(): - #do nothing - continue - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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',getmyip(), 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 = ""+rowip+"" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring = retstring + "Unknown" - - retstring = retstring + "" - return retstring - - - -# Generates a HTML page that represents the current status of the program -def generate_status_page(): - webpage = "Latency Information

Latency information from "+getmyip()+'

' - webpage = webpage + "" - for nodeip in mycontext['neighborlist']: - if nodeip in mycontext['row']: - webpage = webpage + mycontext['row'][nodeip]+'\n' - else: - webpage = webpage + '\n' - - # now the footer... - webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' - return webpage - - - -# Displays a web page with the latency information -def handle_http_request(srcip,srcport,connobj): - # Get the header - total_data = '' - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - new_data = data.replace('\r\n', '\n') - total_data += new_data - 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 - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - -def handle_message_forever(): - while True: - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - - -def handle_connection_forever(): - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - - -if callfunc == 'initialize': - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - except FileNotFoundError, e: - raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - - ip = getmyip() - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) - createthread(handle_connection_forever) - - - From 4635ac3e2b377ad3920425a5b0b0d5e85d2b3cfb Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Mon, 8 Sep 2014 10:37:41 -0400 Subject: [PATCH 46/59] allpairsping is added to apps --- apps/allapirsping/allpairsping.r2py | 172 ++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 apps/allapirsping/allpairsping.r2py diff --git a/apps/allapirsping/allpairsping.r2py b/apps/allapirsping/allpairsping.r2py new file mode 100644 index 0000000..3241319 --- /dev/null +++ b/apps/allapirsping/allpairsping.r2py @@ -0,0 +1,172 @@ +""" + + Urvashi Soni + + + 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 == getmyip(): + #do nothing + continue + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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',getmyip(), 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 = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + webpage = "Latency Information

Latency information from "+getmyip()+'

' + webpage = webpage + "" + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + return webpage + + + +# Displays a web page with the latency information +def handle_http_request(srcip,srcport,connobj): + # Get the header + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + new_data = data.replace('\r\n', '\n') + total_data += new_data + 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 + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + +def handle_message_forever(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + + +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + + +if callfunc == 'initialize': + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + except FileNotFoundError, e: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) + createthread(handle_connection_forever) + + + From c623c44e4524af47b8207552a38caae40f688fcd Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Mon, 8 Sep 2014 10:40:09 -0400 Subject: [PATCH 47/59] allpairspingmap added --- apps/allpairspingmap/allpairspingmap.r2py | 467 ++++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 apps/allpairspingmap/allpairspingmap.r2py diff --git a/apps/allpairspingmap/allpairspingmap.r2py b/apps/allpairspingmap/allpairspingmap.r2py new file mode 100644 index 0000000..48247f7 --- /dev/null +++ b/apps/allpairspingmap/allpairspingmap.r2py @@ -0,0 +1,467 @@ +''' + + allpairspingmap.r2py + + + This program gives a visual representation of the vessels that a user has + acquired. It includes a map that contains markers on where the vessels are + reported to be, according to the geoip client. + + + A file containing the ip addresses of all the vessels to contact must be + uploaded. This file should be named 'neighboriplist.txt'. Each line should + contain one vessel. This file can be prepared within seash by issuing the + following command within a group: + show ip to neighboriplist.txt + + Additionally, the following files (which are provided) need to be uploaded to + the vessels: + jquerygmaps.js + style.css + map_marker_icon.png + map_marker_icon_blue.png + + Once this is set up, you need to pass your Clearinghouse port to the program + as an argument: + username@group> run allpairspingmap.r2py [port number] + +''' + +dy_import_module_symbols('geoip_client.r2py') + + +class InvalidRequestError(Exception): + ''' The user made a request for a nonexistent file. ''' + + +# These are the paths that the web server will serve files for. +# This is to prevent clients from seeing anything else that we might not want +# them to be able to see. +# +# '': +# Index file. We generate a webpage representing the current program status +# +# style.css: +# Stylesheet that controls how the webpage is formatted. Without this, +# the map will not render correctly. +# +# jquerygmaps.js: +# Contains code that interfaces against google's MapV2 API. +# +# map_marker_icon.png: +# This image is used as a marker for where the vessels are, on the map. + +mycontext['RECOGNIZED_FILES'] = ( + '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png', 'map_marker_icon_blue.png') + + +# When responding to HTTP requests, we need to include a MIME type, identifying +# the type of file that we are serving to the HTTP client. This dictionary +# maps a file extension to its common MIME type. +mycontext['MIME_TYPES'] = { + '.js': 'text/javascript', + '.css': 'text/css', + '.png': 'image/png' + } + + + +def probe_neighbors_forever(): + ''' + + Send a probe message to each neighbor + + + port: The clearinghouse port assigned to the current user. + + + Starts the ping loop to calculate the latency between the local node + and neighboring nodes. We also send our latency data to each node. + + + None + + + None + ''' + while True: + for neighborip in mycontext["neighborlist"]: + mycontext['sendtime'][neighborip] = getruntime() + if neighborip == mycontext['ip']: + #skip if local and destination ip addresses and port match because we can't send message if local/dest ip and port match in repy v2 + continue + sendmessage(neighborip, mycontext['port'], 'ping',mycontext['ip'],mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),mycontext['ip'],mycontext['port']) + sleep(0.5) + #sleep for 10 sec and start from while loop again to avoid so many responses at the same time + sleep(10) + + + + +# Handle an incoming message +def got_message(srcip,srcport,mess): + ''' + + Handle an incoming message from a neighboring node. + + + See documentation for recvmess(). + + + If we receive a ping message, we respond with a pong message. + If we receive a pong message, we take the difference between when we sent + this neighbor a ping message and record that as the latency. + If we receive a share message, we record the neighbor's neighbor row + information. + + + None + + + None + ''' + + + if mess == 'ping': + sendmessage(srcip,srcport,'pong',getmyip(), 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(neighborlist, latencylist): + ''' + + Prepares the local node's latency information into a format that is + recognizable by the other nodes. + + + neighborlist: The IP addresses of all our neighbors. + latencylist: The list of latencies associated with the neighbors. + + + None + + + None + + + A string representing a HTML row containing the latency information + between this node and the other neighbor nodes. + ''' + + retstring = "" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring += ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring += "Unknown" + return retstring + + +def generate_node_list(): + """ + + Generates an HTMl string of an unsorted list of nodes. + + + None. + + + None. + + + None. + + + HTML string of unsorted list of nodes. + """ + # Is there a specific reason why we sort these keys? I'm leaving these + # intact since the original version sorted them. + nodeiplist = mycontext['neighborlist'] + nodeiplist.sort() + + nodelist_str = '
    ' + for nodeip in nodeiplist: + # Print node list element + nodelist_str += ('
  • ' + + str(nodeip) + '') + + if nodeip in mycontext['locationdata']: + nodelocdict = mycontext['locationdata'][nodeip] + if nodelocdict is not None: + nodelist_str += ('' + str(nodelocdict['longitude']) + + '' + str(nodelocdict['latitude']) + + '' + geoip_location_str(nodelocdict) + '') + # We didn't perform the lookup yet. This is used to tell the client to + # refresh the page. + else: + nodelist_str += "" + nodelist_str += '
  • ' + nodelist_str += '
' + return nodelist_str + + + + + +def generate_status_page(): + ''' + + Generates a HTML page that represents the current status of the program + + + None + + + The webpage returned may cause a client's browser to make additional + requests to the current program, or other machines. + + + None + + + A string representing a HTML webpage containing the current status of the + program. + ''' + webpage = "Latency Information" + + webpage += '' + webpage += '' + # Include our script/stylesheet for the webpage + webpage += '' + webpage += '' + + # Begin displaying body content; Lets start with the map. + webpage += "
" + + # Display the latency information as a table + webpage += "

Latency information from "+getmyip()+'

' + + # Create a column in the table for each vessel + webpage += "" + + # Create a row in the table for each vessel + for nodeip in mycontext['neighborlist']: + # Show ip and location data, if present + webpage += '' + + # Add latency information + if nodeip in mycontext['row']: + webpage += mycontext['row'][nodeip] + else: + webpage += '' + webpage += '\n' + + webpage += '
"+ "".join(mycontext['neighborlist'])+"
' +nodeip+'
\n' + + # Was there a geoip lookup yet? + if nodeip in mycontext['locationdata']: + # Did the geoip lookup succeed? + if mycontext['locationdata'][nodeip] is not None: + nodelocation = mycontext['locationdata'][nodeip] + webpage += nodelocation['city'] + ', ' + nodelocation['country_code'] + # The lookup failed + else: + webpage += "No location data available" + + # We haven't done a geoip lookup yet. Let the user know. + else: + webpage += "Location data not yet retrieved" + webpage += '
No Data Reported
' + + # We need this for the map data to work + webpage += generate_node_list() + # now the footer... + webpage += '' + + return webpage + + +def handle_http_request(srcip,srcport,connobj): + # Get the header + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + new_data = data.replace('\r\n', '\n') + total_data += new_data + 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. + requested_file = everything_after_httpaction.split(" HTTP/")[0] + + # Get rid of the leading '/' because its useless to us + requested_file = requested_file.lstrip('/') + + # Generate the data to send back. + try: + # We default to this content type. + content_type = 'text/html' + # Don't respond with anything if they have something in the request path. + + if requested_file not in mycontext['RECOGNIZED_FILES']: + raise InvalidRequestError("Unrecognized file:" + requested_file) + + # Generate the index page if the request field is empty. + elif not requested_file: + + contents = generate_status_page() + + # This is a file that we recognize. Send its contents to the client. + else: + # PNGs are binary files. Plaintext files still work when read in + # binary mode. + contents = openfile(requested_file, True).readat(None,0) + + # Figure out the MIME type to send to the client + for extension in mycontext['MIME_TYPES']: + if requested_file.endswith(extension): + content_type = mycontext['MIME_TYPES'][extension] + break + else: + content_type = 'text/plain' + + # combine everything into one unit for sending + data = 'HTTP/1.1 200 OK\nContent-Type: '+content_type+'\nContent-Length: '+str(len(contents))+'\nServer: Seattle Testbed\n\n'+contents + + except InvalidRequestError: + data = 'HTTP/1.1 404 Not Found\n\n' + + + # send the response + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except Exception, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + + + +def lookup_geoip_info(): + ''' + + Acquires the geoip information for all the vessels specified in the + neighbor ip table. + + + None + + + The geoip data recorded will be stored in mycontext['locationdata'][neighborip]. + If the lookup was successful, then the looked up data will be stored. + Otherwise, we put + + + None + + + None + ''' + + geoip_init_client() + for neighbor in mycontext['neighborlist']: + try: + locationdict = geoip_record_by_addr(neighbor) + if locationdict is not None: + # Sometimes we don't get a city name. + if 'city' not in locationdict: + locationdict['city'] = "Unknown" + mycontext['locationdata'][neighbor] = locationdict + + # The lookup failed + else: + mycontext['locationdata'][neighbor] = None + + except Exception, e: + if not "Unable to contact the geoip server" in str(e): + raise + # We use this to indicate that no location data is available. + mycontext['locationdata'][neighbor] = None + +def handle_message_forever(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + + +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + + + +if callfunc == 'initialize': + + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + except FileNotFoundError, e: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") + + # Contains the dictionaries for node location information. + mycontext['locationdata'] = {} + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + log(mycontext['ip']) + + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], 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['ip'],mycontext['port']) + createthread(handle_connection_forever) + + + # Getting geoip data takes a while, in the meanwhile we allow the user to + # see a status webpage and display a notice there. + lookup_geoip_info() + From 7a6cc9fdc7b771e7d0557f4d08065134faee8a12 Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Mon, 8 Sep 2014 10:44:45 -0400 Subject: [PATCH 48/59] allpairsping and allpairspingmap added with required files --- apps/allpairspingmap/jquerygmaps.js | 91 ++++++++++++++++++ apps/allpairspingmap/map_marker_icon.png | Bin 0 -> 3554 bytes apps/allpairspingmap/map_marker_icon_blue.png | Bin 0 -> 1340 bytes apps/allpairspingmap/style.css | 58 +++++++++++ 4 files changed, 149 insertions(+) create mode 100644 apps/allpairspingmap/jquerygmaps.js create mode 100644 apps/allpairspingmap/map_marker_icon.png create mode 100644 apps/allpairspingmap/map_marker_icon_blue.png create mode 100644 apps/allpairspingmap/style.css diff --git a/apps/allpairspingmap/jquerygmaps.js b/apps/allpairspingmap/jquerygmaps.js new file mode 100644 index 0000000..1f07b6f --- /dev/null +++ b/apps/allpairspingmap/jquerygmaps.js @@ -0,0 +1,91 @@ +// Function to run at page load +$(document).ready(function() { + function initialize_map() { + // Initialize map inside #map div element + var map = new GMap2(document.getElementById('map')); + map.setUIToDefault(); + + // Set up points for Seattle nodes + var markers = []; + $("ul#coords li").each(function(i) { + var latitude = $(this).children(".latitude").text(); + var longitude = $(this).children(".longitude").text(); + if(!latitude && !longitude){ + var point = new GLatLng(85,0); + marker = new GMarker(point); + map.addOverlay(marker); + marker.setImage("map_marker_icon_blue.png"); + map.setCenter(point, 2); + markers[i] = marker; + }else{ + var point = new GLatLng(latitude, longitude); + marker = new GMarker(point); + map.addOverlay(marker); + marker.setImage("map_marker_icon.png"); + map.setCenter(point, 2); + markers[i] = marker; + } + }); + + // Pan to point when clicked + $(markers).each(function(i, marker) { + GEvent.addListener(marker, "click", function(){ + displayPoint(marker, i); + }); + }); + return map; + } + + // Whenever a marker is clicked, pan to it and move/populate the tooltip div + function displayPoint(marker, i) { + map.panTo(marker.getPoint()); + var markerOffset = map.fromLatLngToDivPixel(marker.getPoint()); + + // Get node information from adjacency table + var nodeip = $("#node" + i).children(".nodeip").text(); + var nodelocation = $("#node" + i).children(".locationname").text(); + var nodelat = $("#node" + i).children(".latitude").text(); + var nodelong = $("#node" + i).children(".longitude").text(); + + // Populate #message div with node information + $("#message").empty().append("Node IP: " + nodeip + "
Location: " + nodelocation + "
Lat/Long: " + nodelat + "/" + nodelong + "
Select this node"); + + // If a node bas been selected to base latencies on... + if (typeof(selected_node) != "undefined") { + // Remove any existing lines + if (typeof(line) != "undefined") { + map.removeOverlay(line); + } + + // Draw new line between selected node and clicked node + line = new GPolyline([selected_marker.getLatLng(), marker.getLatLng()]); + map.addOverlay(line); + + // Populate #message div with latency info + var latency = $("td." + selected_node + "_" + i).text(); + $("#message a").before("Latency to " + selected_location + ": " + latency + ((latency != 'N/A') ? " s" : "") + "
"); + } + + // Function to select node as latency hub on click + $("#message").children("a").click(function() { + if (typeof(selected_marker) != "undefined") { + selected_marker.setImage("map_marker_icon.png"); + } + selected_marker = marker; + selected_node = i; + selected_location = nodelocation.split(",")[0]; + marker.setImage("map_marker_sel_icon.png"); + }); + + // Finally, display the #message div tooltip + $("#message").show().css({ top:markerOffset.y, left:markerOffset.x }); + } + + + var map = initialize_map(); + $("#message").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE)); + var selected_node; + var selected_marker; + var selected_location; + var line; +}); diff --git a/apps/allpairspingmap/map_marker_icon.png b/apps/allpairspingmap/map_marker_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a0ff05f7a169b9e84151016f2ea0762e90ff1696 GIT binary patch literal 3554 zcmV<84IT1{P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0009GNkl2!+&i;nzpt*E}SVznkFgu!NAP9 z-}&ad=iGZ|l!)*00u;4e2tJ&>J;#o$K`52+1$LN+%$&6;m>E? z?kB))5qY*MWH`C>^1_8b9F2|Js;P-TnVdb*)zt@F7m;y`QIigj%hg`32!Nxpahu2G zY6m)$Qkypc&hu?;moFYYx_6_UYObrRNoBJ;ClU$26=-#8T5U1uTQ0|7D1;t~0N~U# zPTTF&+iV3qr>50*d%dkzpyg0Q!S{Jpm*H^u^OdJhdw{zZV;4u? zM58ks5y>ttE}eC||1mc2g4wn1PF?>unaRvoD|B;gECP&}Cx8V&L{@-%_X2@fH6rs% zOUu_rMnb^#{Pvr8eD(SB{}+~*S1Jkh1%nCTasJ`9DkLHqVCc~=Qd!&>9gPEziWg)) zdT))5#mk9!?)B z`|)GR47~XG@e81f$hWG6L?j0c_T?>wuD5SX7P*om0MFn3{h<{RnNFwY2Hw5%i-@o4 zPj;TGm{RJ^a5#K$JQhorb7Ll~djW^f?Azx9o&YuFxYi0UnN&(m0#hQA-O%4i3G@R0 cRU-Wy0A3oNG9Z=1od5s;07*qoM6N<$g2!y2cmMzZ literal 0 HcmV?d00001 diff --git a/apps/allpairspingmap/map_marker_icon_blue.png b/apps/allpairspingmap/map_marker_icon_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..98b280d3019757279bb80abd14f4a3a2adfc6aad GIT binary patch literal 1340 zcmV-C1;hG@P)-@5d&O@+y=v9-|K^FiI%`J9+Z;@$aT*^}F(FOt$%0OpFpX;CSx0q(J*s z*_}4|<;(qgzjOch+;h*lmjD3a!_xCBDek>aOkI~qR_$q$Qv5QBH4F)Z<7?F3vd~_E zKrliGIZB`2vXE_oF{P>T#=W8x%P84U^8qn+{>Xh#?YJ6)LjFxaVb^7%Z~BD9X#3+O zK7OY}BKKLDUp#~+*2B8>9T2K&0NEN9;QKj=k77J3vq!CKIKv75PXt(ysEn=m<7{UF zqAXx+`xdN&^H8-L?3C}AhrCVSL6Fjl7Rl_o)Q4K_-`|OV(*7Beko!cPKtMok8HK7n z02M<3R@*$3ZJ%AhHpjiE|EHF|25xR{pwtbv(eIfBn7gl#%<2;=9Q=l+_$XBG1srT{ z>A+6RK@Ijxv%X0^F`s6AE8X0El}$iS>p9}9h&|t`!`Ur6P7(Vr5yVgbWDLz=nm0Y+j5u$NEPvq`6`s0F~`{(nm@%| zPzxRs8TX`Z$EBb#u_{1KyRcjx(f#ibNtiwC&i324tA3o*Eiq6)+l> z)W{ifG)`x}SO9JF3Ah*Y1hvB?0HgmpD{F@fy$xV+XXZLjcs3oK;Sl?VBD9+BtYME7QK-E zDgu?ec(R`>&|7rb{347vd)1g8>jIO2BFtdu+EAgp__|VOTXr&{{V;uFIu`w*YxpR# zsQVggE%=R;VJ_Dczof@Vo=(hvhIdCe2A>A8yKcc};~=DM3c;~e`>E)no?l4O)}J|;1Qa}c(T=I}5-EJ-C!vpg?PPFVrIQzEJ6hWZVh`UR z@;04cSSy_E35Bp^n&-32zH)DIF5iTwM>jBdC~BKuvH|Ew&9ddNJ&3!4CK zze{2bJBg1h4POsoz1O zv-(`}zX-rP!vUHVy`{m&@#sbHTILca0ZFC;0$2Q#fWHBQKnRo|Jc1tp0000 Date: Wed, 10 Sep 2014 23:03:06 -0400 Subject: [PATCH 49/59] Delete allpairsping.r2py --- apps/allapirsping/allpairsping.r2py | 172 ---------------------------- 1 file changed, 172 deletions(-) delete mode 100644 apps/allapirsping/allpairsping.r2py diff --git a/apps/allapirsping/allpairsping.r2py b/apps/allapirsping/allpairsping.r2py deleted file mode 100644 index 3241319..0000000 --- a/apps/allapirsping/allpairsping.r2py +++ /dev/null @@ -1,172 +0,0 @@ -""" - - Urvashi Soni - - - 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 == getmyip(): - #do nothing - continue - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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',getmyip(), 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 = ""+rowip+"" - for neighborip in neighborlist: - if neighborip in latencylist: - retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" - else: - retstring = retstring + "Unknown" - - retstring = retstring + "" - return retstring - - - -# Generates a HTML page that represents the current status of the program -def generate_status_page(): - webpage = "Latency Information

Latency information from "+getmyip()+'

' - webpage = webpage + "" - for nodeip in mycontext['neighborlist']: - if nodeip in mycontext['row']: - webpage = webpage + mycontext['row'][nodeip]+'\n' - else: - webpage = webpage + '\n' - - # now the footer... - webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' - return webpage - - - -# Displays a web page with the latency information -def handle_http_request(srcip,srcport,connobj): - # Get the header - total_data = '' - new_data = '' - # The HTTP header ends once we see the char combination '\n\n', which - # is an empty string. - while '\n\n' not in new_data: - # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - new_data = data.replace('\r\n', '\n') - total_data += new_data - 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 - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise - -def handle_message_forever(): - while True: - try: - srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) - except SocketWouldBlockError: - sleep(0.1) - - -def handle_connection_forever(): - while True: - try: - ret_ip, ret_port, ret_socket = connobj.getconnection() - handle_http_request(ret_ip, ret_port, ret_socket) - except SocketWouldBlockError: - sleep(0.1) - - -if callfunc == 'initialize': - # this holds the response information (i.e. when nodes responded) - mycontext['latency'] = {} - - # 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) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) - except FileNotFoundError, e: - raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - - ip = getmyip() - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) - createthread(handle_connection_forever) - - - From 0604f52a317037937086cfdb785e632f16c5f574 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 10 Sep 2014 23:03:28 -0400 Subject: [PATCH 50/59] Create allpairsping.r2py --- apps/allpairsping/allpairsping.r2py | 172 ++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 apps/allpairsping/allpairsping.r2py diff --git a/apps/allpairsping/allpairsping.r2py b/apps/allpairsping/allpairsping.r2py new file mode 100644 index 0000000..3241319 --- /dev/null +++ b/apps/allpairsping/allpairsping.r2py @@ -0,0 +1,172 @@ +""" + + Urvashi Soni + + + 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 == getmyip(): + #do nothing + continue + sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) + sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),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',getmyip(), 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 = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + webpage = "Latency Information

Latency information from "+getmyip()+'

' + webpage = webpage + "" + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + return webpage + + + +# Displays a web page with the latency information +def handle_http_request(srcip,srcport,connobj): + # Get the header + total_data = '' + new_data = '' + # The HTTP header ends once we see the char combination '\n\n', which + # is an empty string. + while '\n\n' not in new_data: + # Receive in chunks to avoid reading too much data + data = connobj.recv(4096) + new_data = data.replace('\r\n', '\n') + total_data += new_data + 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 + try: + sent = 0 + while sent < len(data): + sent += connobj.send(data[sent:]) + # and we're done, so let's close this connection... + connobj.close() + except SocketClosedRemote, e: + if "Socket closed" in str(e): + # We can't do anything if the socket is closed + return + raise + +def handle_message_forever(): + while True: + try: + srcip, srcport, mess = udpserversocket.getmessage() + got_message(srcip, srcport, mess) + except SocketWouldBlockError: + sleep(0.1) + + +def handle_connection_forever(): + while True: + try: + ret_ip, ret_port, ret_socket = connobj.getconnection() + handle_http_request(ret_ip, ret_port, ret_socket) + except SocketWouldBlockError: + sleep(0.1) + + +if callfunc == 'initialize': + # this holds the response information (i.e. when nodes responded) + mycontext['latency'] = {} + + # 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) + filecontent = fileobject.readat(None,0) + neighbor_array = filecontent.splitlines() + for line in neighbor_array: + mycontext['neighborlist'].append(line.strip()) + except FileNotFoundError, e: + raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") + + ip = getmyip() + if len(callargs) != 1: + raise Exception, "Must specify the port to use" + pingport = int(callargs[0]) + mycontext['port'] = pingport + mycontext['ip'] = ip + + #listen for a new message and call handle_message in new thread + udpserversocket = listenformessage(mycontext['ip'], 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(ip,mycontext['port']) + createthread(handle_connection_forever) + + + From f573788f3a5def0a1747a73cb643453b133476e8 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 16 Sep 2014 16:00:41 -0400 Subject: [PATCH 51/59] Update allpairsping.r2py --- apps/allpairsping/allpairsping.r2py | 60 +++++++++++++++++------------ 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/apps/allpairsping/allpairsping.r2py b/apps/allpairsping/allpairsping.r2py index 3241319..90ad619 100644 --- a/apps/allpairsping/allpairsping.r2py +++ b/apps/allpairsping/allpairsping.r2py @@ -7,18 +7,17 @@ """ - # 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 == getmyip(): + if neighborip == mycontext['myip']: #do nothing continue - sendmessage(neighborip, mycontext['port'], 'ping',getmyip(),mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(getmyip(),mycontext["neighborlist"],mycontext['latency'].copy()),getmyip(),mycontext['port']) + 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) @@ -29,7 +28,7 @@ def probe_neighbors_forever(): # Handle an incoming message def got_message(srcip,srcport,mess): if mess == 'ping': - sendmessage(srcip,srcport,'pong',getmyip(), pingport) + 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] @@ -53,7 +52,7 @@ def encode_row(rowip, neighborlist, latencylist): # Generates a HTML page that represents the current status of the program def generate_status_page(): - webpage = "Latency Information

Latency information from "+getmyip()+'

' + webpage = "Latency Information

Latency information from "+mycontext['myip']+'

' webpage = webpage + "" for nodeip in mycontext['neighborlist']: if nodeip in mycontext['row']: @@ -69,16 +68,26 @@ def generate_status_page(): # 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 = '' - new_data = '' # The HTTP header ends once we see the char combination '\n\n', which # is an empty string. - while '\n\n' not in new_data: + while '\n\n' not in total_data: # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - new_data = data.replace('\r\n', '\n') - total_data += new_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) @@ -101,17 +110,20 @@ def handle_http_request(srcip,srcport,connobj): data = 'HTTP/1.1 200 OK\nContent-Type: text/html\nContent-Length: '+str(len(webpage))+'\nServer: Seattle Testbed\n\n'+webpage # send the response - try: + sent = 0 while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except SocketClosedRemote, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed - return - raise + 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: @@ -134,6 +146,8 @@ def handle_connection_forever(): if callfunc == 'initialize': # this holds the response information (i.e. when nodes responded) mycontext['latency'] = {} + mycontext['myip'] = getmyip() + log(mycontext['myip']) # this remembers when we sent a probe mycontext['sendtime'] = {} @@ -151,21 +165,19 @@ if callfunc == 'initialize': except FileNotFoundError, e: raise FileNotFoundError("neighboriplist.txt file doesn't exist. Please provide the required file in same directory.") - ip = getmyip() if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) mycontext['port'] = pingport - mycontext['ip'] = ip #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) + 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(ip,mycontext['port']) + connobj = listenforconnection(mycontext['myip'],mycontext['port']) createthread(handle_connection_forever) From 293ea8c1c4e5279fd4fd5042cb14d11b12418eb5 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 16 Sep 2014 16:46:02 -0400 Subject: [PATCH 52/59] Update allpairsping.r2py --- apps/allpairsping/allpairsping.r2py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/allpairsping/allpairsping.r2py b/apps/allpairsping/allpairsping.r2py index 90ad619..265a6c8 100644 --- a/apps/allpairsping/allpairsping.r2py +++ b/apps/allpairsping/allpairsping.r2py @@ -156,15 +156,20 @@ if callfunc == 'initialize': mycontext['row'] = {} # get the nodes to probe mycontext['neighborlist'] = [] + try: fileobject = openfile('neighboriplist.txt',False) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) except FileNotFoundError, e: 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()) + if len(callargs) != 1: raise Exception, "Must specify the port to use" pingport = int(callargs[0]) From 26f66b2972d873c5b483e7755c265d10990340b2 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 16 Sep 2014 16:52:23 -0400 Subject: [PATCH 53/59] Update allpairsping.r2py --- apps/allpairsping/allpairsping.r2py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/allpairsping/allpairsping.r2py b/apps/allpairsping/allpairsping.r2py index 265a6c8..760aef8 100644 --- a/apps/allpairsping/allpairsping.r2py +++ b/apps/allpairsping/allpairsping.r2py @@ -14,7 +14,7 @@ def probe_neighbors_forever(): for neighborip in mycontext["neighborlist"]: mycontext['sendtime'][neighborip] = getruntime() if neighborip == mycontext['myip']: - #do nothing + #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']) @@ -156,7 +156,7 @@ if callfunc == 'initialize': mycontext['row'] = {} # get the nodes to probe mycontext['neighborlist'] = [] - + try: fileobject = openfile('neighboriplist.txt',False) except FileNotFoundError, e: From eced32816d0d758fe8007d8d9e871ff2d7b88c22 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 16 Sep 2014 17:10:19 -0400 Subject: [PATCH 54/59] Update allpairsping.r2py --- apps/allpairsping/allpairsping.r2py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/allpairsping/allpairsping.r2py b/apps/allpairsping/allpairsping.r2py index 760aef8..22f85ff 100644 --- a/apps/allpairsping/allpairsping.r2py +++ b/apps/allpairsping/allpairsping.r2py @@ -144,6 +144,13 @@ def handle_connection_forever(): 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() @@ -160,6 +167,7 @@ if callfunc == 'initialize': 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) @@ -170,10 +178,7 @@ if callfunc == 'initialize': continue mycontext['neighborlist'].append(line.strip()) - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport + #listen for a new message and call handle_message in new thread udpserversocket = listenformessage(mycontext['myip'], mycontext['port']) From 82196d00e3eabab7946d299614a7050b7a0e2dd5 Mon Sep 17 00:00:00 2001 From: "us341@nyu.edu" Date: Fri, 19 Sep 2014 20:37:22 -0400 Subject: [PATCH 55/59] improved:blank lines in neighboriplist.txt are skipped without error --- allpairsping.r2py | 197 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 allpairsping.r2py diff --git a/allpairsping.r2py b/allpairsping.r2py new file mode 100644 index 0000000..c49f758 --- /dev/null +++ b/allpairsping.r2py @@ -0,0 +1,197 @@ +""" + + Urvashi Soni + + + 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 = "" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + "" + else: + retstring = retstring + "" + + retstring = retstring + "" + return retstring + + + +# Generates a HTML page that represents the current status of the program +def generate_status_page(): + webpage = "Latency Information

Latency information from "+mycontext['myip']+'

"+ "".join(mycontext['neighborlist'])+"
"+rowip+""+str(latencylist[neighborip])[:4]+"sUnknown
' + webpage = webpage + "" + for nodeip in mycontext['neighborlist']: + if nodeip in mycontext['row']: + webpage = webpage + mycontext['row'][nodeip]+'\n' + else: + webpage = webpage + '\n' + + # now the footer... + webpage = webpage + '
"+ "".join(mycontext['neighborlist'])+"
'+nodeip+'No Data Reported
' + 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) + + + From 9d164778aff93f0aef318205f0d0b02e763470c3 Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 22 Sep 2014 11:37:13 -0400 Subject: [PATCH 56/59] Create allpairspingmap_new,r2py --- apps/allpairspingmap/allpairspingmap_new,r2py | 487 ++++++++++++++++++ 1 file changed, 487 insertions(+) create mode 100644 apps/allpairspingmap/allpairspingmap_new,r2py diff --git a/apps/allpairspingmap/allpairspingmap_new,r2py b/apps/allpairspingmap/allpairspingmap_new,r2py new file mode 100644 index 0000000..a0d8b3e --- /dev/null +++ b/apps/allpairspingmap/allpairspingmap_new,r2py @@ -0,0 +1,487 @@ +''' + + allpairspingmap.r2py + + + This program gives a visual representation of the vessels that a user has + acquired. It includes a map that contains markers on where the vessels are + reported to be, according to the geoip client. + + + A file containing the ip addresses of all the vessels to contact must be + uploaded. This file should be named 'neighboriplist.txt'. Each line should + contain one vessel. This file can be prepared within seash by issuing the + following command within a group: + show ip to neighboriplist.txt + + Additionally, the following files (which are provided) need to be uploaded to + the vessels: + jquerygmaps.js + style.css + map_marker_icon.png + map_marker_icon_blue.png + + Once this is set up, you need to pass your Clearinghouse port to the program + as an argument: + username@group> run allpairspingmap.r2py [port number] + +''' + +dy_import_module_symbols('geoip_client.r2py') + + +class InvalidRequestError(Exception): + ''' The user made a request for a nonexistent file. ''' + + +# These are the paths that the web server will serve files for. +# This is to prevent clients from seeing anything else that we might not want +# them to be able to see. +# +# '': +# Index file. We generate a webpage representing the current program status +# +# style.css: +# Stylesheet that controls how the webpage is formatted. Without this, +# the map will not render correctly. +# +# jquerygmaps.js: +# Contains code that interfaces against google's MapV2 API. +# +# map_marker_icon.png: +# This image is used as a marker for where the vessels are, on the map. + +mycontext['RECOGNIZED_FILES'] = ( + '', 'style.css', 'jquerygmaps.js', 'map_marker_icon.png', 'map_marker_icon_blue.png') + + +# When responding to HTTP requests, we need to include a MIME type, identifying +# the type of file that we are serving to the HTTP client. This dictionary +# maps a file extension to its common MIME type. +mycontext['MIME_TYPES'] = { + '.js': 'text/javascript', + '.css': 'text/css', + '.png': 'image/png' + } + + + +def probe_neighbors_forever(): + ''' + + Send a probe message to each neighbor + + + port: The clearinghouse port assigned to the current user. + + + Starts the ping loop to calculate the latency between the local node + and neighboring nodes. We also send our latency data to each node. + + + None + + + None + ''' + 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): + ''' + + Handle an incoming message from a neighboring node. + + + See documentation for recvmess(). + + + If we receive a ping message, we respond with a pong message. + If we receive a pong message, we take the difference between when we sent + this neighbor a ping message and record that as the latency. + If we receive a share message, we record the neighbor's neighbor row + information. + + + None + + + None + ''' + + + if mess == 'ping': + sendmessage(srcip,srcport,'pong',getmyip(), 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): + ''' + + Prepares the local node's latency information into a format that is + recognizable by the other nodes. + + + neighborlist: The IP addresses of all our neighbors. + latencylist: The list of latencies associated with the neighbors. + + + None + + + None + + + A string representing a HTML row containing the latency information + between this node and the other neighbor nodes. + ''' + + + retstring = ""+rowip+"" + for neighborip in neighborlist: + if neighborip in latencylist: + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" + else: + retstring = retstring + "Unknown" + + retstring = retstring + "" + return retstring + + +def generate_node_list(): + """ + + Generates an HTMl string of an unsorted list of nodes. + + + None. + + + None. + + + None. + + + HTML string of unsorted list of nodes. + """ + # Is there a specific reason why we sort these keys? I'm leaving these + # intact since the original version sorted them. + nodeiplist = mycontext['neighborlist'] + nodeiplist.sort() + + nodelist_str = '
    ' + for nodeip in nodeiplist: + # Print node list element + nodelist_str += ('
  • ' + + str(nodeip) + '') + + if nodeip in mycontext['locationdata']: + nodelocdict = mycontext['locationdata'][nodeip] + if nodelocdict is not None: + nodelist_str += ('' + str(nodelocdict['longitude']) + + '' + str(nodelocdict['latitude']) + + '' + geoip_location_str(nodelocdict) + '') + # We didn't perform the lookup yet. This is used to tell the client to + # refresh the page. + else: + nodelist_str += "" + nodelist_str += '
  • ' + nodelist_str += '
' + return nodelist_str + + + + + +def generate_status_page(): + ''' + + Generates a HTML page that represents the current status of the program + + + None + + + The webpage returned may cause a client's browser to make additional + requests to the current program, or other machines. + + + None + + + A string representing a HTML webpage containing the current status of the + program. + ''' + webpage = "Latency Information" + + webpage += '' + webpage += '' + # Include our script/stylesheet for the webpage + webpage += '' + webpage += '' + + # Begin displaying body content; Lets start with the map. + webpage += "
" + + # Display the latency information as a table + webpage += "

Latency information from "+getmyip()+'

' + + # Create a column in the table for each vessel + webpage += "" + + # Create a row in the table for each vessel + for nodeip in mycontext['neighborlist']: + # Show ip and location data, if present + webpage += '' + + # Add latency information + if nodeip in mycontext['row']: + webpage += mycontext['row'][nodeip] + else: + webpage += '' + webpage += '\n' + + webpage += '
"+ "".join(mycontext['neighborlist'])+"
' +nodeip+'
\n' + + # Was there a geoip lookup yet? + if nodeip in mycontext['locationdata']: + # Did the geoip lookup succeed? + if mycontext['locationdata'][nodeip] is not None: + nodelocation = mycontext['locationdata'][nodeip] + webpage += nodelocation['city'] + ', ' + nodelocation['country_code'] + # The lookup failed + else: + webpage += "No location data available" + + # We haven't done a geoip lookup yet. Let the user know. + else: + webpage += "Location data not yet retrieved" + webpage += '
No Data Reported
' + + # We need this for the map data to work + webpage += generate_node_list() + # now the footer... + webpage += '' + + return webpage + + +def handle_http_request(srcip,srcport,connobj): + # 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. + requested_file = everything_after_httpaction.split(" HTTP/")[0] + + # Get rid of the leading '/' because its useless to us + requested_file = requested_file.lstrip('/') + + # Generate the data to send back. + try: + # We default to this content type. + content_type = 'text/html' + # Don't respond with anything if they have something in the request path. + + if requested_file not in mycontext['RECOGNIZED_FILES']: + raise InvalidRequestError("Unrecognized file:" + requested_file) + + # Generate the index page if the request field is empty. + elif not requested_file: + + contents = generate_status_page() + + # This is a file that we recognize. Send its contents to the client. + else: + # PNGs are binary files. Plaintext files still work when read in + # binary mode. + contents = openfile(requested_file, True).readat(None,0) + + # Figure out the MIME type to send to the client + for extension in mycontext['MIME_TYPES']: + if requested_file.endswith(extension): + content_type = mycontext['MIME_TYPES'][extension] + break + else: + content_type = 'text/plain' + + # combine everything into one unit for sending + data = 'HTTP/1.1 200 OK\nContent-Type: '+content_type+'\nContent-Length: '+str(len(contents))+'\nServer: Seattle Testbed\n\n'+contents + + except InvalidRequestError: + data = 'HTTP/1.1 404 Not Found\n\n' + + + # 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 lookup_geoip_info(): + ''' + + Acquires the geoip information for all the vessels specified in the + neighbor ip table. + + + None + + + The geoip data recorded will be stored in mycontext['locationdata'][neighborip]. + If the lookup was successful, then the looked up data will be stored. + Otherwise, we put + + + None + + + None + ''' + + geoip_init_client() + for neighbor in mycontext['neighborlist']: + try: + locationdict = geoip_record_by_addr(neighbor) + if locationdict is not None: + # Sometimes we don't get a city name. + if 'city' not in locationdict: + locationdict['city'] = "Unknown" + mycontext['locationdata'][neighbor] = locationdict + + # The lookup failed + else: + mycontext['locationdata'][neighbor] = None + + except Exception, e: + if not "Unable to contact the geoip server" in str(e): + raise + # We use this to indicate that no location data is available. + mycontext['locationdata'][neighbor] = None + +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'] = [] + + mycontext['locationdata'] = {} + 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) + + # Getting geoip data takes a while, in the meanwhile we allow the user to + # see a status webpage and display a notice there. + lookup_geoip_info() + From d71004f801212caf4d6170e2deeab66cc81ae5c2 Mon Sep 17 00:00:00 2001 From: us341 Date: Mon, 22 Sep 2014 11:37:59 -0400 Subject: [PATCH 57/59] Update allpairsping.r2py --- allpairsping.r2py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/allpairsping.r2py b/allpairsping.r2py index c49f758..4259d42 100644 --- a/allpairsping.r2py +++ b/allpairsping.r2py @@ -123,7 +123,7 @@ def handle_http_request(srcip,srcport,connobj): log('client from',srcip,'aborted before response could be sent...\n') return # and we're done, so let's close this connection... - connobj.close() + connobj.close() def handle_message_forever(): while True: From ad3f05796fd8623cd326f039cb8263a9f94101d0 Mon Sep 17 00:00:00 2001 From: us341 Date: Tue, 30 Sep 2014 11:55:05 -0400 Subject: [PATCH 58/59] Create httpserver.r2py --- httpserver.r2py | 937 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 937 insertions(+) create mode 100644 httpserver.r2py diff --git a/httpserver.r2py b/httpserver.r2py new file mode 100644 index 0000000..baf72e2 --- /dev/null +++ b/httpserver.r2py @@ -0,0 +1,937 @@ +""" + + httpserver.r2py + + + July 29, 2009 + + + Conrad Meyer + + + This is a library that abstracts away the details of the HTTP protocol, + instead calling a user-supplied function on each request. The return + value of the user-supplied function determines the response that is sent + to the HTTP client. + +""" + + + +dy_import_module_symbols("librepy.r2py") +dy_import_module_symbols("urllib.r2py") +dy_import_module_symbols("urlparse.r2py") +dy_import_module_symbols("uniqueid.r2py") +dy_import_module_symbols("sockettimeout.r2py") +dy_import_module_symbols("httpretrieve.r2py") + + + + +class _httpserver_ClientClosedSockEarly(Exception): + # Raised internally when the client unexpectedly closes the socket. The + # correct behavior in this instance is to clean up that handler and + # continue. + pass + + + + +class _httpserver_BadRequest(Exception): + # Raised internally when the client's request is malformed. + pass + + + + +class _httpserver_ServerError(Exception): + # Raised internally when the callback function unexpectedly raises an + # exception. + pass + + + + +class _httpserver_BadTransferCoding(Exception): + # Raised internally when the request's encoding is something we can't + # handle (most everything at the time of writing). + pass + + + + +# This global dictionary is used to keep track of open HTTP callbacks. +# The 'lock' entry is used to serialize changes to the other entries. +# The 'handles' dictionary maps numeric ids we hand out in +# httpserver_registercallback() and take in httpserver_stopcallback() +# to ids returned and used by waitforconn(). The 'cbfuncs' entry +# maps httpserver numeric ids to the callback function associated +# with them. +_httpserver_context = { + 'handles': {}, + 'cbfuncs': {}, + 'lock': createlock()} + + + +def httpserver_registercallback(addresstuple, cbfunc): + """ + + Registers a callback function on the (host, port). + + + addresstuple: + An address 2-tuple to bind to: ('host', port). + + cbfunc: + The callback function to process requests. It takes one argument, + which is a dictionary describing the HTTP request. It looks like + this (just an example): + { + 'verb': 'HEAD', + 'path': '/', + 'querystr': 'foo=bar&baz', + 'querydict': { 'foo': 'bar', 'baz': None } + 'version': '0.9', + 'datastream': object with a file-like read() method, + 'headers': { 'Content-Type': 'application/x-xmlrpc-data'}, + 'httpdid': 17, + 'remoteipstr': '10.0.0.4', + 'remoteportnum': 54001 + } + ('datastream' is a stream of any HTTP message body data sent by the + client.) + + It is expected that this callback function returns a dictionary of: + { + 'version': '0.9' or '1.0' or '1.1', + 'statuscode': any integer from 100 to 599, + 'statusmsg' (optional): an arbitrary string without newlines, + 'headers': { 'X-Header-Foo': 'Bar' }, + 'message': arbitrary string + } + + + TypeError, ValueError, KeyError, IndexError if arguments to this + function are malformed. + + Raises any exception waitforconn() will raise if the (hostname, port) + tuple is restricted, already taken, etc. + + + Starts a listener on the given host and port. + + + A handle for the listener (an httpdid). This can be used to stop the + server. + + """ + + _httpserver_context['lock'].acquire(True) + + try: + newhttpdid = uniqueid_getid() + + # Keep track of this server's id in a closure: + def _httpserver_cbclosure(remoteip, remoteport, sock, ch, listench): + # Do the actual processing on the request. + _httpserver_socketcb(remoteip, remoteport, sock, ch, listench, \ + newhttpdid) + + # Close the socket afterwards. + try: + sock.close() + except Exception, e: + if "socket" not in str(e).lower(): + raise + pass # Best effort. + + + _httpserver_context['handles'][newhttpdid] = \ + waitforconn(addresstuple[0], addresstuple[1], _httpserver_cbclosure) + _httpserver_context['cbfuncs'][newhttpdid] = cbfunc + + return newhttpdid + finally: + _httpserver_context['lock'].release() + + + + +def _httpserver_socketcb(remoteip, remoteport, sock, ch, listench, httpdid): + # This function gets invoked each time a client connects to our socket. + + # It proceeds in a loop -- reading in requests, handing them off to the + # callback function, and sending the result to the client. If errors are + # encountered, it sends an error message (we choose HTTP/1.0 for + # compatibility and because we don't always know what version the client + # wants) and closes the connection. Additionally, if the response + # generated by the callback requests protocol version 0.9 or 1.0, or is + # 1.1 but includes the Connection: close header, the connection is closed + # and the loop broken. + + _httpserver_context['lock'].acquire(True) + try: + cbfunc = _httpserver_context['cbfuncs'][httpdid] + finally: + _httpserver_context['lock'].release() + + extradata = "" + + # HTTP/1.0 and HTTP/1.1 Connection: close requests break out of this + # loop immediately; HTTP/1.1 clients can keep sending requests and + # receiving responses in this loop indefinitely. + while True: + try: + # Reads request headers, parses them, lets callback handle headers + # and possible request body, sends the response that the callback + # function tells it to send. On error, may raise one of many + # exceptions, which we deal with here: + closeconn, extradata = \ + _httpserver_process_single_request(sock, cbfunc, extradata, \ + httpdid, remoteip, remoteport) + + if closeconn: + break + + except _httpserver_BadRequest, br: + # There was some sort of flaw in the client's request. + response = "HTTP/1.0 400 Bad Request\r\n" + \ + "Content-Type: text/plain\r\n\r\n" + str(br) + "\r\n" + _httpserver_sendAll(sock, response, besteffort=True) + break + + except _httpserver_ServerError, se: + # The callback function raised an exception or returned some object + # we didn't expect. + response = "HTTP/1.0 500 Internal Server Error\r\n" + \ + "Content-Type: text/plain\r\n\r\n" + str(se) + "\r\n" + _httpserver_sendAll(sock, response, besteffort=True) + break + + except _httpserver_BadTransferCoding, bte: + # The HTTP/1.1 client sent us something with a Transport-Encoding we + # can't handle. + response = "HTTP/1.1 501 Not Implemented\r\n" + \ + ("Content-Length: %d\r\n" % (len(str(bte)) + 2)) + \ + "Connection: close\r\n" + \ + "Content-Type: text/plain\r\n\r\n" + str(bte) + "\r\n" + _httpserver_sendAll(sock, response, besteffort=True) + break + + except _httpserver_ClientClosedSockEarly: + # Not much else we can do. + break + + except Exception, e: + if "Socket closed" in str(e): + break + + # We shouldn't encounter these, other than 'Socket closed' ones. They + # represent a bug in our code somewhere. However, not raising the + # exception makes HTTP server software incredibly unintuitive to + # debug. + raise + + + + +def _httpserver_readHTTPheader(sock, data): + # Reads data from the socket in 4k chunks, replacing \r\n newlines with + # \n newlines. When it encounters a (decoded) \n\n sequence, it returns + # (data_before, data_after). + + headers = [] + command = True + while True: + line, data = _httpserver_getline(sock, data) + if len(line) == 0: + raise _httpserver_ClientClosedSockEarly() + + # Be a well-behaved server, and handle normal newlines and telnet-style + # newlines in the same fashion. + line = line.rstrip("\r") + if command: + splitln = line.split(" ") + if len(splitln) != 3: + raise _httpserver_BadRequest("HTTP/0.9 or malformed request.") + if not splitln[2].lower().startswith("http/1."): + raise _httpserver_BadRequest("Malformed request.") + command = False + + if len(line) == 0: + break + + headers.append(line) + + return (headers, data) + + + + +def _httpserver_parseHTTPheader(headerdatalist): + lineslist = headerdatalist + commandstr = lineslist[0] + otherheaderslist = lineslist[1:] + + infodict = {} + + verbstr, rawpathstr, versionstr = commandstr.split(" ", 2) + + infodict['verb'] = verbstr + + if len(versionstr) != len("HTTP/1.1"): + raise _httpserver_BadRequest("Bad HTTP command") + versionstr = versionstr.upper() + if versionstr == "HTTP/1.0": + infodict['version'] = '1.0' + elif versionstr == "HTTP/1.1": + infodict['version'] = '1.1' + else: + raise _httpserver_BadRequest("Unrecognized HTTP version") + + if rawpathstr.find("?") != -1: + infodict['path'], infodict['querystr'] = rawpathstr.split("?", 1) + else: + infodict['path'] = rawpathstr + infodict['querystr'] = None + + try: + infodict['headers'] = _httpretrieve_parse_responseheaders(otherheaderslist) + except HttpBrokenServerError: + raise _httpserver_BadRequest("Request headers are misformed.") + + try: + infodict['querydict'] = urllib_unquote_parameters(infodict['querystr']) + except (ValueError, AttributeError, TypeError): + infodict['querydict'] = None + + return infodict + + + + + +def _httpserver_sendAll(sock, datastr, besteffort=False): + # Sends all the data in datastr to sock. If besteffort is True, + # we don't care if it fails or not. + #try: + #while len(datastr) > 0: + #datastr = datastr[sock.send(datastr):] + #except Exception, e: + #if "socket" not in str(e).lower(): + #raise + + # If the caller didn't want this function to raise an exception for + # any reason, we don't, and instead return silently. If they are ok + # with exceptions, we re-raise. + #if not besteffort: + #raise + + sent = 0 + while sent < len(datastr): + try: + sent += sock.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 + + + + + +def _httpserver_getline(sock, datastr): + # Reads a line out of datastr (if possible), or failing that, gets more from + # the socket. Returns (line, extra) + newdatastr = "" + while True: + endloc = datastr.find("\n", -len(newdatastr)) + if endloc != -1: + return (datastr[:endloc], datastr[endloc+1:]) + try: + newdatastr = sock.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 + datastr += newdatastr + + + + + +def _httpserver_getblock(blocksize, sock, datastr): + # Reads a block of size blocksize out of datastr (if possible), or failing + # that, gets more from the socket. Returns (block, extra). + + try: + while len(datastr) < blocksize: + datastr += sock.recv(4096) + + return (datastr[:blocksize], datastr[blocksize:]) + except Exception, e: + if "Socket closed" in str(e) and len(datastr) != 0: + return (datastr, "") + raise + + + + +def httpserver_stopcallback(callbackid): + """ + + Removes an existing callback function. + + + callbackid: + The id returned by httpserver_registercallback(). + + + IndexError, KeyError if the id is invalid or has already been deleted. + + + Removes this listener from the registry, deletes the listening socket. + + + Nothing. + + """ + _httpserver_context['lock'].acquire(True) + try: + stopcomm(_httpserver_context['handles'][callbackid]) + del _httpserver_context['handles'][callbackid] + del _httpserver_context['cbfuncs'][callbackid] + finally: + _httpserver_context['lock'].release() + + + + +class _httpserver_bodystream: + """ + _httpserver_bodystream is a helper class passed as the 'datastream' entry + in the dictionary sent to user callback functions. It has a read() method + that behaves very similarly to file.read(). Other than that, this object + is nothing like Python's file. + + """ + + # Reads the rest of the HTTP request from the socket, erroring + # appropriately. Understands transfer-coding. Returns chunks + # at a time. + + def __init__(self, sock, data, verb, headers): + # The socket object for communicating with the client: + self._sock = sock + # And any data we have already read off the socket, but has not been + # consumed (we read data in 4 kilobyte chunks and keep the extra + # around for later use). + self._rawdata = data + + # The HTTP request verb (GET, POST, etc); a string. + self._verb = verb + + # A dictionary of the client's request headers, as parsed by + # _httpretrieve_parse_responseheaders() (this is a function which + # should be moved elsewhere; for example, an http_common.r2py + # library would work). + self._headers = headers + + # The number of bytes left in the current chunk, if the client's + # request body is transfer-encoded (integer, or None), or the + # number of bytes in the entire request body if it is not transfer- + # encoded. + self._leftinchunk = None + + # Whether or not the client's request body was transfer-encoded. + self._chunked = False + + # A flag set when we know we have finished reading the current + # request body, so we can return the empty string. + self._done = False + + # A lock used to serialize reads from this file-like object. + self._lock = createlock() + + # A flag set when we are finished reading HTTP "trailers". Only applies + # to client requests sent with chunked transfer-encoding. + self._trailersread = False + + # For chunked transfers only: Keep a queue of unconsumed but decoded + # data (string). + self._data = "" + + + # Deal with methods that cannot send a message body: + if verb in ("GET", "HEAD", "TRACE", "DELETE"): + if "Content-Length" in headers or \ + "Transfer-Encoding" in headers: + raise _httpserver_BadRequest("Method '" + verb + \ + "' cannot send an entity-body and therefore a " + \ + "Content-Length or Transfer-Encoding header is invalid.") + else: + self._done = True + return + + # Deal with methods that send a message body. + if "Content-Length" not in headers and "Transfer-Encoding" not in headers: + raise _httpserver_BadRequest("Method '" + str(verb) + \ + "' can send an entity-body and requires a Content-Length " + \ + "or Transfer-Encoding header.") + + if "Transfer-Encoding" in headers: + # Decode Transfer-coded messages + if len(headers["Transfer-Encoding"]) != 1: + raise _httpserver_BadRequest("Multiple Transfer-Encoding headers " + \ + "is unacceptable.") + + # "chunked" must be in the codings list, and it must be last. + codings = headers["Transfer-Encoding"][0].split(",") + codings.reverse() + + realcodings = [] + + # Strip 'identity' codings. + for coding in codings: + coding = coding.strip().lower() + token = coding.split(None, 1) + if token != "identity": + realcodings.append(coding) + + if len(realcodings) > 1 or realcodings[0] != "chunked": + raise _httpserver_BadTransferCoding("Cannot handle any transfer-" + \ + "codings other than chunked.") + + self._chunked = True + + else: + # If we get here, that means we have a Content-Length and no Transfer- + # Encoding, so we can read the message body directly. + msglen = headers["Content-Length"] + + if len(msglen) != 1: + raise _httpserver_BadRequest("Multiple Content-Length headers is " + \ + "unacceptable.") + + self._leftinchunk = int(msglen[0]) + + + + def read(self, size=None): + """ + + Read a sequence of bytes from an HTTP request body. + + + size (optional): + An upper limit on the number of bytes to return. + + + Any raised by socket.read(). + + + Possibly reads more from the socket that the HTTP request is passed + on. + + + A string of bytes comprising part of the HTTP message body. Does not + include any chunked encoding trailers. + + """ + + self._lock.acquire(True) # Serialize file-like object reads. + + # Keep the same API as file(), but use a more understandable variable + # name through this method. + requestsize = size + + # The following 'Try' block is used to always unlock self._lock, no + # matter how we return up the stack: + try: + # If we already know we are finished, simply return the empty string. + if self._done: + return "" + + if requestsize == 0: + return "" + + # If the client's request was not chunked, but instead they specified + # the Content-length header: + if not self._chunked: + # toyieldstr is the string we will return to the user this time, + # as if this were a python generator (which is a nice way to think + # about it). We determine the amount to return, toyieldlen: + toyieldlen = self._leftinchunk + if requestsize is not None: + toyieldlen = min(requestsize, toyieldlen) + + # And strive to return as much of it as possible: + toyieldstr, self._rawdata = _httpserver_getblock(toyieldlen, \ + self._sock, self._rawdata) + self._leftinchunk -= len(toyieldstr) + + # If there is nothing left in the request, we're done; keep a note + # for future read() calls. + if self._leftinchunk == 0: + self._done = True + + return toyieldstr + + # If the client's request was chunked: + else: + # Read until there isn't anymore, OR until we have enough to satisfy + # the user's request. + while requestsize is None or len(self._data) < requestsize: + # If we have more raw bytes to read from the socket before + # reaching the end of this chunk: + if self._leftinchunk > 0: + # Determine how many bytes to (attempt to) read from the client: + nextblocksize = self._leftinchunk + if requestsize is not None: + nextblocksize = min(self._leftinchunk, requestsize) + + # Try and request the rest of the chunk, or as much as is + # needed to fulfill the caller's request. + chunkstr, self._rawdata = _httpserver_getblock(nextblocksize, self._sock, \ + self._rawdata) + self._leftinchunk -= len(chunkstr) + self._data += chunkstr + + # We stop trying if we can't get as much data as we wanted to, + # because this means that the client has closed the socket. + if len(chunkstr) < nextblocksize: + break + + # We are finished with this chunk; now we must determine if there + # is another chunk, and what its length is. + else: + # HTTP chunks have "\r\n" appended to the end of them; if we + # just finished reading a chunk, read off the trailing "\r\n" + # and discard it. + if self._leftinchunk is not None: + _, self._rawdata = _httpserver_getblock(2, self._sock, \ + self._rawdata) + + # Read the next chunk's size information: + line, self._rawdata = _httpserver_getline(self._sock, \ + self._rawdata) + + # Remove optional chunk extensions (";" -> newline) that we don't + # understand (this is advised by the HTTP 1.1 RFC), and read the + # hex chunk size: + self._leftinchunk = int(line.split(";", 1)[0].strip(), 16) + + # A chunk size of '0' indicates the end of a chunked message: + if self._leftinchunk == 0: + self._done = True + break + + # Determine how much data we should return, and how much we should + # keep around for the next read. + retlen = len(self._data) + if requestsize is not None: + retlen = min(requestsize, retlen) + + retval, self._data = self._data[:retlen], self._data[retlen:] + return retval + + finally: + self._lock.release() + + + + def get_trailers(self): + """ + + Read any 'trailers' sent by the client. The caller does not need to + ensure that the entire message body has been read first, though they + should be aware that calling this method consumes any remaining + message body and immediately forgets it. + + Note: not multithread safe, not multi-call safe (calls after the + first call will simply return the empty dictionary). + + + None. + + + Any raised by socket.read(). + + + Possibly reads more from the socket that the HTTP request is passed + on. + + + A dictionary of headers in the same style as + _httpretrieve_parse_responseheaders(). + + """ + # Reads the rest of the message, and then reads and returns any trailer + # headers (only sent in chunked messages). + + # Discard extra message without filling RAM. No-op if the user function + # has already read the entire stream. + while True: + unuseddatastr = self.read(4096) + if len(unuseddatastr) == 0: + break + + if not self._chunked: + return {} + + if self._trailersread: + return {} + + trailers = {} + + # Read 'trailer' headers. + while True: + line, self._rawdata = _httpserver_getline(self._sock, self._rawdata) + + # Empty line? Then the trailers are done. + if len(line.strip("\r")) == 0: + break + + # Check for a multi-line header by peeking ahead: + while True: + nextchar, self._rawdata = _httpserver_getblock(1, self._sock, \ + self._rawdata) + self._rawdata = nextchar + self._rawdata + if nextchar in (" ", "\t"): + line2, self._rawdata = _httpserver_getline(self._sock, self._rawdata) + line += " " + line2.lstrip() + else: + break + + # Insert header into existing headers + hdrname, hdrval = line.split(":", 1) + if hdrname not in trailers: + trailers[hdrname] = [] + trailers[hdrname].append(hdrval.strip()) + + self._trailersread = True + return trailers + + + + + def _get_extra(self): + # Private function of httpserver, *should not be used by callback + # functions*! NOT parallel-safe, NOT meant to be called more than + # once. + + # Read the socket up to (at least) the end of the current message; + # if we read beyond the end of our message, return any extra. + + # Discard extra message without filling RAM + while True: + if len(self.read(4096)) == 0: + break + + # Discard trailers, if any are left: + if self._chunked: + self.get_trailers() + + rawdata = self._rawdata + self._rawdata = "" + + return rawdata + + + + +class _httpserver_StringIO: + # Implements a read-only file-like object encapsulating a string. + def __init__(self, string): + self._data = string + self._closed = False + + + + def read(self, limit=None): + if limit is None: + limit = 4096 + + if self._closed: + raise ValueError("Trying to read from a closed StringIO object.") + + res, self._data = self._data[:limit], self._data[limit:] + return res + + + + def close(self): + if self._closed: + raise ValueError("Trying to close a closed StringIO object.") + self._closed = True + + + + +def _httpserver_sendfile(sock, filelikeobj): + # Attempts to forward all of the data from filelikeobj to sock. + while True: + chunk = filelikeobj.read(4096) + if len(chunk) == 0: + break + _httpserver_sendAll(sock, chunk, besteffort=True) + + + + +def _httpserver_sendfile_chunked(sock, filelikeobj): + # Attempts to forward all of the data from filelikeobj to sock, using chunked + # encoding. + totallen = 0 + while True: + chunk = filelikeobj.read(4096) + if len(chunk) == 0: + break + # encode as HTTP/1.1 chunks: + totallen += len(chunk) + chunk = "%X\r\n%s\r\n" % (len(chunk), chunk) + _httpserver_sendAll(sock, chunk) + + lastchunk = "0\r\n" + lastchunk += ("Content-Length: %d\r\n" % totallen) + lastchunk += "\r\n" + _httpserver_sendAll(sock, lastchunk) + + + + +def _httpserver_process_single_request(sock, cbfunc, extradata, httpdid, \ + remoteip, remoteport): + # This function processes a single request in from sock, and either + # puts a response to the socket and returns, or raises an exception. + + # Read HTTP request off the socket + headerdata, extradata = _httpserver_readHTTPheader(sock, extradata) + + # Interpret the header. + reqinfo = _httpserver_parseHTTPheader(headerdata) + + # Wrap the (possibly) remaining data into a file-like object. + messagebodystream = _httpserver_bodystream(sock, \ + extradata, reqinfo['verb'], reqinfo['headers']) + reqinfo['datastream'] = messagebodystream + reqinfo['httpdid'] = httpdid + reqinfo['remoteipstr'] = remoteip + reqinfo['remoteportnum'] = remoteport + + # By default, we don't want to close the connection. (Though, nearly + # every case will change this to True -- only HTTP/1.1 sockets + # that don't set Connection: close will keep this False.) + closeconn = False + + # Send request information to callback. + try: + result = cbfunc(reqinfo) + + except Exception, e: + raise _httpserver_ServerError("httpserver: Callback function " + \ + "raised an exception: " + str(e)) + + # Get any extra data consumed from sock by the message body stream object, + # but that was not actually part of the message body. + extradata = messagebodystream._get_extra() + + # Interpret result of callback function + try: + version = result['version'] + statuscode = result['statuscode'] + statusmsg = result['statusmsg'] + headers = result['headers'] + messagestream = result['message'] + except (KeyError, TypeError): + raise _httpserver_ServerError("httpserver: Callback function " + \ + "returned malformed dictionary") + + # Do some basic sanity checks: + if None in (version, statuscode, statusmsg, headers, messagestream): + raise _httpserver_ServerError("httpserver: Callback function " + \ + "returned dictionary with None for some values.") + + if (type(version), type(statuscode), type(statusmsg), type(headers)) != \ + (str, int, str, dict): + raise _httpserver_ServerError("httpserver: Callback function " + \ + "returned dictionary with invalid values (wrong types).") + + # If the message object is a string, wrap it in a file-like object. + if type(messagestream) is str: + messagestream = _httpserver_StringIO(messagestream) + + # Don't let the callback function serve HTTP/1.1 responses to an HTTP/1.0 + # request. + if reqinfo['version'] == "1.0" and version == "1.1": + version = "1.0" + + # Send response as instructed by callback + if version == "0.9": + # HTTP/0.9 doesn't have response headers. + _httpserver_sendfile(sock, messagestream) + closeconn = True + + elif version == "1.0": + # Send the response headers: + response = "HTTP/1.0 " + str(statuscode) + " " + statusmsg + "\r\n" + for key, val in headers.items(): + response += key + ": " + val + "\r\n" + response += "\r\n" + _httpserver_sendAll(sock, response, besteffort=True) + + # Send the response body: + _httpserver_sendfile(sock, messagestream) + closeconn = True + + elif version == "1.1": + response = "HTTP/1.1 " + str(statuscode) + " " + statusmsg + "\r\n" + for key, val in headers.items(): + response += key + ": " + val + "\r\n" + response += "Transfer-Encoding: chunked\r\n" + response += "\r\n" + + # Close client socket if they or the callback function asked us + # to close. + if ("Connection" in headers and "close" == headers["Connection"]) \ + or ("Connection" in reqinfo['headers'] and "close" in \ + reqinfo['headers']["Connection"]): + closeconn = True + + try: + # Send response headers. + _httpserver_sendAll(sock, response) + + # Read chunks from the callback and efficiently send them to + # the client using HTTP/1.1 chunked encoding. + _httpserver_sendfile_chunked(sock, messagestream) + + except Exception, e: + if "socket" not in str(e).lower(): + raise + + # The exception we're trying to catch here is anything sock.send() + # raises. However, it just raises plain exceptions. + + # The reason we care about the data actually going through for HTTP/1.1 + # is that we keep connections open. If there is an error, we shouldn't + # keep going, so we indicate that the socket should be closed. + closeconn = True + + else: + # If the cbfunc's response dictionary didn't specify 0.9, 1.0, or 1.1, + # it's an error. + raise _httpserver_ServerError("httpserver: Callback function gave " + \ + "invalid HTTP version") + + # Clean up open file handles: + messagestream.close() + + return (closeconn, extradata) From a8360e9e53ddb54c6a8dd6c1a97f6645feaeab36 Mon Sep 17 00:00:00 2001 From: us341 Date: Wed, 3 Dec 2014 11:00:48 -0500 Subject: [PATCH 59/59] debugging in process for getting list out of index inside httpretrieve.r2py --- apps/allpairspingmap/allpairspingmap.r2py | 110 +++++++++++++--------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/apps/allpairspingmap/allpairspingmap.r2py b/apps/allpairspingmap/allpairspingmap.r2py index 48247f7..a0d8b3e 100644 --- a/apps/allpairspingmap/allpairspingmap.r2py +++ b/apps/allpairspingmap/allpairspingmap.r2py @@ -87,13 +87,13 @@ def probe_neighbors_forever(): while True: for neighborip in mycontext["neighborlist"]: mycontext['sendtime'][neighborip] = getruntime() - if neighborip == mycontext['ip']: - #skip if local and destination ip addresses and port match because we can't send message if local/dest ip and port match in repy v2 + 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['ip'],mycontext['port']) - sendmessage(neighborip,mycontext['port'],'share'+encode_row(mycontext["neighborlist"],mycontext['latency'].copy()),mycontext['ip'],mycontext['port']) + 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 to avoid so many responses at the same time + #sleep for 10 sec and start from while loop again sleep(10) @@ -134,7 +134,7 @@ def got_message(srcip,srcport,mess): -def encode_row(neighborlist, latencylist): +def encode_row(rowip, neighborlist, latencylist): ''' Prepares the local node's latency information into a format that is @@ -155,12 +155,15 @@ def encode_row(neighborlist, latencylist): between this node and the other neighbor nodes. ''' - retstring = "" + + retstring = ""+rowip+"" for neighborip in neighborlist: if neighborip in latencylist: - retstring += ""+str(latencylist[neighborip])[:4]+"s" + retstring = retstring + ""+str(latencylist[neighborip])[:4]+"s" else: - retstring += "Unknown" + retstring = retstring + "Unknown" + + retstring = retstring + "" return retstring @@ -286,14 +289,22 @@ def generate_status_page(): def handle_http_request(srcip,srcport,connobj): # Get the header total_data = '' - new_data = '' # The HTTP header ends once we see the char combination '\n\n', which # is an empty string. - while '\n\n' not in new_data: + while '\n\n' not in total_data: # Receive in chunks to avoid reading too much data - data = connobj.recv(4096) - new_data = data.replace('\r\n', '\n') - total_data += new_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 @@ -343,17 +354,19 @@ def handle_http_request(srcip,srcport,connobj): # send the response - try: - sent = 0 - while sent < len(data): - sent += connobj.send(data[sent:]) - # and we're done, so let's close this connection... - connobj.close() - except Exception, e: - if "Socket closed" in str(e): - # We can't do anything if the socket is closed + 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 - raise + # and we're done, so let's close this connection... + connobj.close() @@ -402,64 +415,71 @@ def handle_message_forever(): while True: try: srcip, srcport, mess = udpserversocket.getmessage() - got_message(srcip, srcport, mess) 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() - handle_http_request(ret_ip, ret_port, ret_socket) except SocketWouldBlockError: - sleep(0.1) + 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'] = [] + + mycontext['locationdata'] = {} try: fileobject = openfile('neighboriplist.txt',False) - filecontent = fileobject.readat(None,0) - neighbor_array = filecontent.splitlines() - for line in neighbor_array: - mycontext['neighborlist'].append(line.strip()) 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.") - # Contains the dictionaries for node location information. - mycontext['locationdata'] = {} + 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()) + - ip = getmyip() - if len(callargs) != 1: - raise Exception, "Must specify the port to use" - pingport = int(callargs[0]) - mycontext['port'] = pingport - mycontext['ip'] = ip - log(mycontext['ip']) - #listen for a new message and call handle_message in new thread - udpserversocket = listenformessage(mycontext['ip'], mycontext['port']) + #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['ip'],mycontext['port']) + connobj = listenforconnection(mycontext['myip'],mycontext['port']) createthread(handle_connection_forever) - # Getting geoip data takes a while, in the meanwhile we allow the user to # see a status webpage and display a notice there.