Detecting and Caching User Requests - | College of Engineering



Detecting and Caching User RequestsTeam 3’s project called for networking equipment to be turned on and off with a user requests. This could have been simply been done by having the user run an application. But the goal of this project was to activate network equipment with no user input outside of entering a URL. This section will describe how a modified proxy server, serial interface, and modified configuration of Firefox can be used to detect a connection, catch requests, and initiated a signal to turn on networking equipment.Tinyproxy is an open source, lightweight proxy server. It is currently being used in MSU’s multi-seat implementations in Tanzania for content filtering. Tinyproxy’s inputs come from a browser which is configured to send requests to it. For this configuration Tinyproxy will be configured to listen on port 8888. When a request is received by Tinyproxy on that port the request is examined. Depending on the local cache and content filter configuration either render a locally cached webpage to is returned to the end user or the request is repackaged and sent out over the network. When a response is received by Tinyproxy from a web server it is passed along to the user.When Tinyproxy is examining a request it is temporarily storing it in memory, effectively caching it. To take advantage of this feature to fulfill the needs of the project, the function that handles all outgoing data to a network interface was modified. The system()function was used to run a Python script that checks for a network connection and initializes a “turn-on” signal. The system() function is particularly useful because it prevents Tinyproxy from processing the request until a vale is returned. The value returned is an integer, if it is negative then an error has occurred and the event is logged. If the value returned is 0, then the script was successful.Python was chosen to modify Tinyproxy with for two reasons. The first was the developer responsible for this portion was most familiar with that language. The more significant reason is that modifications can be easily made in Tanzania if there are unforeseen problems. Furthermore, because of Python’s encapsulation of lower level commands this script can be kept relatively short and simple. It is broken up into 4 functions. The first function, getIP(), is used to check for an internet connection. It does this by pining , , and . It is highly unlikely for any of these three sites to be offline. It would be even more unlikely for all of them to be down at the same time and for that reason provide an accurate sampling to determine if there is internet connectivity. If one of those addresses can be reached then there is an internet connection and the getIP() function will return True. In other words, it will have been determined there is an active internet connection. Otherwise, if all the sites previously listed do not respond to a ping, the function will return False.The Next function is sendSig(). It uses a library called Py-Serial to open a serial COM port. The interface is opened for 1 second and is then closed. By doing this +3 V is sent over pin 4 of a 9 pin serial cable. While this is very simple, the only interface required is to turn on networking equipment by initiating a “turn on” request. As a result the presence of a voltage is used to signal the 433 MHz transmitter to generate a signal.The exiting()function can be thought of as an administrative function, but it is none the less critical. It redirects the stdout from outputting to this script’s log file, back to the Linux terminal. It also generates an exit code. This is the value that will be returned by the system()function that was added to Tinyproxy’s source code.The final function is the main()function. First it redirects stdout to the script’s log file. It then enters an infinite while loop. This continually checks for an active internet connection with the getIP()function. If it returns True then the sendSig() function is called. Then the exiting() function is called and the loop breaks. The sendSig() function is called because the “turn on” signal not only switchs on networking equipment, but also resets the timer used to determine when equipment is turned off at Baraka.If getIP() returns false then the loop continues. It will call the sendSig() function and then wait 5 seconds before running through the loop again. The sendSig() function is called multiple times to protect against a signal not being received due to factors such as interference. The number of times a turn on signal is sent during a loop is logged.The last step is to modify the configuration of Firefox. This must be done because Firefox will also detect the lack of an internet connection, thus preventing the user’s HTTP request from going to Tinyproxy. The settings are changed by typing about:config in the address bar and setting the following values:workmanager.disable = trueBrowser.offline = falseBrowser.offline.notify = falseCreating a WiFi repeaterNear the end of the project, Team 3 learned that the 433 MHz antenna used to transmit a turn on request and WiMAX data bridge was going to be placed about 150 meters away from the building housing the multi-seat computer at Rift Valley Secondary school. To avoid having to dig into volcanic rock to lay cable Team 3 decided to transmit signals wirelessly. For the data connection that meant creating another bridged connection, separate from the WiMAX point to point solution used to connect Rift Valley to Baraka.To accomplish this, two Linksys WRT54GL routers were flashed with the open source dd-wrt firmware. One was configured to be a router and outfitted with two aftermarket 15 dBi yagi antennas. This will be connected to the WiMAX data bridge via a CAT-5 ethernet cable as an input to the WAN port. Wireless security settings were then set using WPA2.The second router was configured as a repeater. By being set up as a repeater it can be a client of the first router. This is done by setting up a virtual interface on the device acting a repeater, configuring the interface to listen for the first router’s SSID and provide it with the WPA2 passkey. Finally to provide access to other client devices the repeater was set up to allocate IP addresses on its own subnet. In this way it is also acting a router.Testing – TinyproxyThe modifications to Tinyproxy were tested to ensure the application is caching user requests, detecting an active internet connection, and initiating a “turn on signal”. The application had the desired results. To show it worked log outputs were examined, the physical connection to the internet was disconnected and then reconnected, and LEDs were used to show an output was being sent on Pin 4 of the serial cable.Two log files were examined. They were both located in the /usr/local/var/log/ directory. They are called tinyproxy.log and python.log. Two terminal windows were opened. In one window the command tail –f tinyproxy.log was given. In the other tail –f python.log was entered. This allows the log outputs for Tinyproxy and the Python script to be monitored in real time. At this point the computer was connected to the internet and Firefox was used to load tism.msu.edu. The log outputs for this request are below.Tinyproxy.log:CONNECT Apr 25 16:59:01 [23241]: Beginning IP testCONNECT Apr 25 16:59:01 [23241]: Connection ConfirmedCONNECT Apr 25 16:59:01 [23241]: Connect (file descriptor 6): localhost [127.0.0.1]CONNECT Apr 25 16:59:01 [23241]: Request (file descriptor 6): GET HTTP/1.1INFO Apr 25 16:59:01 [23241]: No proxy for tism.msu.eduCONNECT Apr 25 16:59:01 [23241]: Established connection to host "tism.msu.edu" using file descriptor Apr 25 16:59:01 [23241]: Closed connection between local client (fd:6) and remote client (fd:7)In Firefox the webpage loaded as expected. At line 1 of the tinyproxy.log file, it shows the Python script was executed to check for an IP address. Then at line 2 the log file show an internet connection was detected successfully. Tinyproxy finally continues on to send out the user request and return it to the user when a response from tism.msu.edu is received.Python.log:2010-04-25 16:59:01 STATUS Internet Connection Confirmed2010-04-25 16:59:01 STATUS Sending turn on single2010-04-25 16:59:01 CLOSINGThe Python.log file looks as we would expect it to. It shows the script starting and since there is an active internet connection, at least one of the sites (, , ) can be pinged successfully. A turn on signal is sent and the script exits. It is evident from the time stamps these log entries occurred at the same time. Under the testing conditions it can be concluded they refer to the same HTTP requests. The next step is to test the ability to cache a user request.To test this functionality the Ethernet cable was unplugged from the computer and a request was made from Firefox. This time was visited because tism.msu.edu has been cached by Tinyproxy and the request may not have gone out to the network. Under normal circumstances Firefox would timeout, but the screen simply appears as though it is loading:Normally when an internet connection is not available Firefox would immediately time out.The output form tinyproxy.log is:CONNECT Apr 25 17:18:25 [24211]: Beginning IP testThis output only shows one line. That one line was the python application being executed. The log does not show successful completion of the script or an error being returned. This means the python application was running, if we look at the output for python.log this is confirmed:2010-04-25 17:17:58 STARTING Entering main loop.2010-04-25 17:17:58 STATUS Sending turn on single2010-04-25 17:17:58 STATUS Connection invalid, sending Turn on signal2010-04-25 17:17:58 STATUS turn on signal has been sent 1 times2010-04-25 17:18:03 STATUS Sending turn on single2010-04-25 17:18:03 STATUS Connection invalid, sending Turn on signal2010-04-25 17:18:03 STATUS turn on signal has been sent 2 times2010-04-25 17:18:08 STATUS Sending turn on single2010-04-25 17:18:08 STATUS Connection invalid, sending Turn on signal2010-04-25 17:18:08 STATUS turn on signal has been sent 3 timesIt should be noted that the output is truncated as it is rather long. The timestamps can be compared to from the two log outputs to show the events are related. The python.log file repeatedly shows no internet connection being detected. After each failed attempt to detect a connection a turn on signal is sent and the loop continues. The last set is to plug the Ethernet cable back into the computer to simulate an internet connection becoming available.After a couple of seconds the output from python.log is very similar to when there was an active internet connection. This means an internet connection was successfully detected. The Python script exited and allowed Tinyproxy to send out the HTTP request. The applicable log entries are below:2010-04-25 17:23:38 STATUS Internet Connection Confirmed2010-04-25 17:23:38 STATUS Sending turn on single2010-04-25 17:23:38 CLOSINGBy looking at the output from tinyproxy.log it is also evident that the Python script completed successfully (line 2 below). And the request was sent onto . A response was then received from the web server and the connection was closed:CONNECT Apr 25 17:18:25 [24211]: Beginning IP testCONNECT Apr 25 17:23:38 [25878]: Connection ConfirmedCONNECT Apr 25 17:23:38 [25878]: Connect (file descriptor 9): localhost [127.0.0.1]CONNECT Apr 25 17:23:38 [25878]: Request (file descriptor 9): GET HTTP/1.1INFO Apr 25 17:23:38 [25878]: No proxy for i.cdn.CONNECT Apr 25 17:23:38 [25878]: Established connection to host "i.cdn." using file descriptor Apr 25 17:23:38 [25878]: Closed connection between local client (fd:9) and remote client (fd:10)Finally by looking at Firefox it is evident that loaded:This is proof that the modifications to Tinyproxy allow it to detect the presence of an active internet connection and cache a user’s HTTP request in the even there is not a connection to the internet.The only criteria left to test is that the serial interface is capable of initiating a turn on signal by outputting a voltage on pin 4 of a serial cable. To do this a HTTP request is made with Firefox. As a result of the sendSig()function being called regardless of how the script is executed, there is no need to unplug the Ethernet cable. The following images are a time laps over about 3 seconds showing an LED on pin 4 tuning on for one second and then off again. This is a result of the sendSig()function executing.ImagesThe voltage outputted by the serial interface is then used as an input for the Transmitter.With this final test it can be concluded the modified Tinyproxy application works as expected. Testing Wifi RepeaterTo test the Wifi repeater it had to be shown that a device can connect to a network device outside of its subnet. The router had an IP address of 192.168.2.1. The repeater had an IP address of 10.0.0.1. An Ubuntu 9.10 laptop was connected to the repeater via WLAN, as see below:The labtop’s name is joe-laptop and it has an IP address of 10.0.148. This is confirmed locally on the computer via terminal with the command ipconfig wlan0. In Firefox the computer joe-laptop is connected to the repeater’s HTTP server. At this screen the repeater is showing its current status. There are two pieces of useful information. It shows the DHCP clients the repeater is acting as a router for. In this list is joe-laptop with an IP address of 10.0.0.148. When this is compared to the information collected locally it confirms the computer is connected wirelessly to the repeater.The other useful piece of information is the WAN or Wide Area Network IP. This assigned by the router who’s internet connection is being repeated. In the image above that IP address is 192.168.2.88. From the same computer we can attempt to connect to that router via Firefox. Upon completion of this request it is proven the computer can get to a networked device outside of the subnet it is in. As shown by terminal, the computer joe-laptop still has an IP address of 10.0.0.148.The image above also shows the router is acting as a DHCP host for one device with an IP address of 192.168.2.88. This is the same IP address of the repeater, confirming that repeater is paired with the router and configured correctly.Appendix – Tinyproxy source codeThe following code was added to the file reqc.c located in the {tinyproxy root}/src directory. The function that was edited is handle_connection(). This code was placed at the beginning of the function.void handle_connection (int fd){ int res; /* This is in the origonal Tinyproxy Source Code */ ssize_t i; struct conn_s *connptr; struct request_s *request = NULL; hashmap_t hashofheaders = NULL; char sock_ipaddr[IP_LENGTH]; char peer_ipaddr[IP_LENGTH]; char peer_string[HOSTNAME_LENGTH]; /*End of origonal source code */ /* code added for ECE project */ log_message (LOG_CONN, "Beginning IP test"); / res = system ("/home/ece480/test/test.py"); /*Call being made to python script */ if (res == 0)log_message (LOG_CONN, "Connection Confirmed"); log_message (LOG_CONN, "Error Running Python Script"); else log_message (LOG_CONN, "Error Running Python Script"); /* End of modifications to Tiny proxy */Appendix - Python Script Source Code#! /usr/bin/pythonimport sysimport timeimport subprocessimport serialsaveout=sys.stdoutfsock=open("/usr/local/var/log/python.log","a")def getIP(): # This function checks to see if the internet is accessable via a # a ping. It pings google, yahoo, and bbc. Upon one of these being # successfull the function returns True. If none of them are # reachable the function returns False domains = ["", "", ""] for domain in domains: ret = subprocess.call("ping -c 1 %s" % domain, shell=True) if ret==0: return True else: return False def exiting(): # This is a function that is used to clean up all loose ends when # ending this script. This includes, writing the exit to the log # redirecting stdout back to the terminal (or where ever it has to # go and closing the log file. print "%s CLOSING" % time.strftime("%Y-%m-%d %H:%M:%S") sys.stdout=saveout fsock.close sys.exit(0) def sendSig():# This function is where a call will be made to send a turn on signal# to Baraka from the satilite school (At time of writing this Rift Valley # and Manyara Secondary) ## All this does is open a serial connection for 1 second and then closes it. # this allows a signal to be sent to the transmitter. print "%s STATUS Sending turn on single" \ % time.strftime("%Y-%m-%d %H:%M:%S") s=serial.Serial(0) time.sleep(1) s.close()def main():# This is a where almost everything happens, like all good programs this is# rather short and should be easy to follow. All that is happening here# is there is a loop that is started which looks for the and active internet # connection. # If it is dectected the loop breaks and the program exits.# If the is no internet connection valid then a turn on signal is sent # and the loop continues until an active connection is detected. sys.stdout=fsock print "%s STARTING Entering main loop." \ % (time.strftime("%Y-%m-%d %H:%M:%S")) count=0 while True: n=getIP() if n==True: print "%s STATUS Internet Connection Confirmed" \ % time.strftime("%Y-%m-%d %H:%M:%S") sendSig() exiting() break else: sendSig() print "%s STATUS Connection invalid, sending Turn on signal" \ % (time.strftime("%Y-%m-%d %H:%M:%S")) count+=1 print "%s STATUS turn on signal has been sent %d times" \ % (time.strftime("%Y-%m-%d %H:%M:%S"), count) time.sleep(5) main() ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download